mirror of
https://github.com/corda/corda.git
synced 2025-04-25 05:19:44 +00:00
begin splitting out powerpc assembler
This commit is contained in:
parent
22d6ed1bec
commit
73dda9c26e
@ -14,129 +14,22 @@
|
|||||||
#include "alloc-vector.h"
|
#include "alloc-vector.h"
|
||||||
#include <avian/util/abort.h>
|
#include <avian/util/abort.h>
|
||||||
|
|
||||||
|
#include "encode.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "fixup.h"
|
||||||
|
#include "block.h"
|
||||||
|
|
||||||
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
||||||
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
|
#define CAST2(x) reinterpret_cast<BinaryOperationType>(x)
|
||||||
#define CAST3(x) reinterpret_cast<TernaryOperationType>(x)
|
#define CAST3(x) reinterpret_cast<TernaryOperationType>(x)
|
||||||
#define CAST_BRANCH(x) reinterpret_cast<BranchOperationType>(x)
|
#define CAST_BRANCH(x) reinterpret_cast<BranchOperationType>(x)
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
using namespace avian::codegen;
|
|
||||||
using namespace avian::util;
|
using namespace avian::util;
|
||||||
|
|
||||||
namespace {
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
namespace isa {
|
namespace powerpc {
|
||||||
// INSTRUCTION FORMATS
|
|
||||||
inline int D(int op, int rt, int ra, int d) { return op<<26|rt<<21|ra<<16|(d & 0xFFFF); }
|
|
||||||
// inline int DS(int op, int rt, int ra, int ds, int xo) { return op<<26|rt<<21|ra<<16|ds<<2|xo; }
|
|
||||||
inline int I(int op, int li, int aa, int lk) { return op<<26|(li & 0x3FFFFFC)|aa<<1|lk; }
|
|
||||||
inline int B(int op, int bo, int bi, int bd, int aa, int lk) { return op<<26|bo<<21|bi<<16|(bd & 0xFFFC)|aa<<1|lk; }
|
|
||||||
// inline int SC(int op, int lev) { return op<<26|lev<<5|2; }
|
|
||||||
inline int X(int op, int rt, int ra, int rb, int xo, int rc) { return op<<26|rt<<21|ra<<16|rb<<11|xo<<1|rc; }
|
|
||||||
inline int XL(int op, int bt, int ba, int bb, int xo, int lk) { return op<<26|bt<<21|ba<<16|bb<<11|xo<<1|lk; }
|
|
||||||
inline int XFX(int op, int rt, int spr, int xo) { return op<<26|rt<<21|((spr >> 5) | ((spr << 5) & 0x3E0))<<11|xo<<1; }
|
|
||||||
// inline int XFL(int op, int flm, int frb, int xo, int rc) { return op<<26|flm<<17|frb<<11|xo<<1|rc; }
|
|
||||||
// inline int XS(int op, int rs, int ra, int sh, int xo, int sh2, int rc) { return op<<26|rs<<21|ra<<16|sh<<11|xo<<2|sh2<<1|rc; }
|
|
||||||
inline int XO(int op, int rt, int ra, int rb, int oe, int xo, int rc) { return op<<26|rt<<21|ra<<16|rb<<11|oe<<10|xo<<1|rc; }
|
|
||||||
// inline int A(int op, int frt, int fra, int frb, int frc, int xo, int rc) { return op<<26|frt<<21|fra<<16|frb<<11|frc<<6|xo<<1|rc; }
|
|
||||||
inline int M(int op, int rs, int ra, int rb, int mb, int me, int rc) { return op<<26|rs<<21|ra<<16|rb<<11|mb<<6|me<<1|rc; }
|
|
||||||
// inline int MD(int op, int rs, int ra, int sh, int mb, int xo, int sh2, int rc) { return op<<26|rs<<21|ra<<16|sh<<11|mb<<5|xo<<2|sh2<<1|rc; }
|
|
||||||
// inline int MDS(int op, int rs, int ra, int rb, int mb, int xo, int rc) { return op<<26|rs<<21|ra<<16|rb<<11|mb<<5|xo<<1|rc; }
|
|
||||||
// INSTRUCTIONS
|
|
||||||
inline int lbz(int rt, int ra, int i) { return D(34, rt, ra, i); }
|
|
||||||
inline int lbzx(int rt, int ra, int rb) { return X(31, rt, ra, rb, 87, 0); }
|
|
||||||
inline int lha(int rt, int ra, int i) { return D(42, rt, ra, i); }
|
|
||||||
inline int lhax(int rt, int ra, int rb) { return X(31, rt, ra, rb, 343, 0); }
|
|
||||||
// inline int lhz(int rt, int ra, int i) { return D(40, rt, ra, i); }
|
|
||||||
inline int lhzx(int rt, int ra, int rb) { return X(31, rt, ra, rb, 279, 0); }
|
|
||||||
inline int lwz(int rt, int ra, int i) { return D(32, rt, ra, i); }
|
|
||||||
inline int lwzx(int rt, int ra, int rb) { return X(31, rt, ra, rb, 23, 0); }
|
|
||||||
inline int stb(int rs, int ra, int i) { return D(38, rs, ra, i); }
|
|
||||||
inline int stbx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 215, 0); }
|
|
||||||
inline int sth(int rs, int ra, int i) { return D(44, rs, ra, i); }
|
|
||||||
inline int sthx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 407, 0); }
|
|
||||||
inline int stw(int rs, int ra, int i) { return D(36, rs, ra, i); }
|
|
||||||
inline int stwu(int rs, int ra, int i) { return D(37, rs, ra, i); }
|
|
||||||
inline int stwux(int rs, int ra, int rb) { return X(31, rs, ra, rb, 183, 0); }
|
|
||||||
inline int stwx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 151, 0); }
|
|
||||||
inline int add(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 266, 0); }
|
|
||||||
inline int addc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 10, 0); }
|
|
||||||
inline int adde(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 138, 0); }
|
|
||||||
inline int addi(int rt, int ra, int i) { return D(14, rt, ra, i); }
|
|
||||||
inline int addic(int rt, int ra, int i) { return D(12, rt, ra, i); }
|
|
||||||
inline int addis(int rt, int ra, int i) { return D(15, rt, ra, i); }
|
|
||||||
inline int subf(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 40, 0); }
|
|
||||||
inline int subfc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 8, 0); }
|
|
||||||
inline int subfe(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 136, 0); }
|
|
||||||
inline int subfic(int rt, int ra, int i) { return D(8, rt, ra, i); }
|
|
||||||
inline int subfze(int rt, int ra) { return XO(31, rt, ra, 0, 0, 200, 0); }
|
|
||||||
inline int mullw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 235, 0); }
|
|
||||||
// inline int mulhw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 75, 0); }
|
|
||||||
inline int mulhwu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 11, 0); }
|
|
||||||
// inline int mulli(int rt, int ra, int i) { return D(7, rt, ra, i); }
|
|
||||||
inline int divw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 491, 0); }
|
|
||||||
// inline int divwu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 459, 0); }
|
|
||||||
// inline int divd(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 489, 0); }
|
|
||||||
// inline int divdu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 457, 0); }
|
|
||||||
inline int neg(int rt, int ra) { return XO(31, rt, ra, 0, 0, 104, 0); }
|
|
||||||
inline int and_(int rt, int ra, int rb) { return X(31, ra, rt, rb, 28, 0); }
|
|
||||||
inline int andi(int rt, int ra, int i) { return D(28, ra, rt, i); }
|
|
||||||
inline int andis(int rt, int ra, int i) { return D(29, ra, rt, i); }
|
|
||||||
inline int or_(int rt, int ra, int rb) { return X(31, ra, rt, rb, 444, 0); }
|
|
||||||
inline int ori(int rt, int ra, int i) { return D(24, rt, ra, i); }
|
|
||||||
inline int xor_(int rt, int ra, int rb) { return X(31, ra, rt, rb, 316, 0); }
|
|
||||||
inline int oris(int rt, int ra, int i) { return D(25, rt, ra, i); }
|
|
||||||
inline int xori(int rt, int ra, int i) { return D(26, rt, ra, i); }
|
|
||||||
inline int xoris(int rt, int ra, int i) { return D(27, rt, ra, i); }
|
|
||||||
inline int rlwinm(int rt, int ra, int i, int mb, int me) { return M(21, ra, rt, i, mb, me, 0); }
|
|
||||||
inline int rlwimi(int rt, int ra, int i, int mb, int me) { return M(20, ra, rt, i, mb, me, 0); }
|
|
||||||
inline int slw(int rt, int ra, int sh) { return X(31, ra, rt, sh, 24, 0); }
|
|
||||||
// inline int sld(int rt, int ra, int rb) { return X(31, ra, rt, rb, 27, 0); }
|
|
||||||
inline int srw(int rt, int ra, int sh) { return X(31, ra, rt, sh, 536, 0); }
|
|
||||||
inline int sraw(int rt, int ra, int sh) { return X(31, ra, rt, sh, 792, 0); }
|
|
||||||
inline int srawi(int rt, int ra, int sh) { return X(31, ra, rt, sh, 824, 0); }
|
|
||||||
inline int extsb(int rt, int rs) { return X(31, rs, rt, 0, 954, 0); }
|
|
||||||
inline int extsh(int rt, int rs) { return X(31, rs, rt, 0, 922, 0); }
|
|
||||||
inline int mfspr(int rt, int spr) { return XFX(31, rt, spr, 339); }
|
|
||||||
inline int mtspr(int spr, int rs) { return XFX(31, rs, spr, 467); }
|
|
||||||
inline int b(int i) { return I(18, i, 0, 0); }
|
|
||||||
inline int bl(int i) { return I(18, i, 0, 1); }
|
|
||||||
inline int bcctr(int bo, int bi, int lk) { return XL(19, bo, bi, 0, 528, lk); }
|
|
||||||
inline int bclr(int bo, int bi, int lk) { return XL(19, bo, bi, 0, 16, lk); }
|
|
||||||
inline int bc(int bo, int bi, int bd, int lk) { return B(16, bo, bi, bd, 0, lk); }
|
|
||||||
inline int cmp(int bf, int ra, int rb) { return X(31, bf << 2, ra, rb, 0, 0); }
|
|
||||||
inline int cmpl(int bf, int ra, int rb) { return X(31, bf << 2, ra, rb, 32, 0); }
|
|
||||||
inline int cmpi(int bf, int ra, int i) { return D(11, bf << 2, ra, i); }
|
|
||||||
inline int cmpli(int bf, int ra, int i) { return D(10, bf << 2, ra, i); }
|
|
||||||
inline int sync(int L) { return X(31, L, 0, 0, 598, 0); }
|
|
||||||
// PSEUDO-INSTRUCTIONS
|
|
||||||
inline int li(int rt, int i) { return addi(rt, 0, i); }
|
|
||||||
inline int lis(int rt, int i) { return addis(rt, 0, i); }
|
|
||||||
inline int slwi(int rt, int ra, int i) { return rlwinm(rt, ra, i, 0, 31-i); }
|
|
||||||
inline int srwi(int rt, int ra, int i) { return rlwinm(rt, ra, 32-i, i, 31); }
|
|
||||||
// inline int sub(int rt, int ra, int rb) { return subf(rt, rb, ra); }
|
|
||||||
// inline int subc(int rt, int ra, int rb) { return subfc(rt, rb, ra); }
|
|
||||||
// inline int subi(int rt, int ra, int i) { return addi(rt, ra, -i); }
|
|
||||||
// inline int subis(int rt, int ra, int i) { return addis(rt, ra, -i); }
|
|
||||||
inline int mr(int rt, int ra) { return or_(rt, ra, ra); }
|
|
||||||
inline int mflr(int rx) { return mfspr(rx, 8); }
|
|
||||||
inline int mtlr(int rx) { return mtspr(8, rx); }
|
|
||||||
inline int mtctr(int rd) { return mtspr(9, rd); }
|
|
||||||
inline int bctr() { return bcctr(20, 0, 0); }
|
|
||||||
inline int bctrl() { return bcctr(20, 0, 1); }
|
|
||||||
inline int blr() { return bclr(20, 0, 0); }
|
|
||||||
inline int blt(int i) { return bc(12, 0, i, 0); }
|
|
||||||
inline int bgt(int i) { return bc(12, 1, i, 0); }
|
|
||||||
inline int bge(int i) { return bc(4, 0, i, 0); }
|
|
||||||
inline int ble(int i) { return bc(4, 1, i, 0); }
|
|
||||||
inline int beq(int i) { return bc(12, 2, i, 0); }
|
|
||||||
inline int bne(int i) { return bc(4, 2, i, 0); }
|
|
||||||
inline int cmpw(int ra, int rb) { return cmp(0, ra, rb); }
|
|
||||||
inline int cmplw(int ra, int rb) { return cmpl(0, ra, rb); }
|
|
||||||
inline int cmpwi(int ra, int i) { return cmpi(0, ra, i); }
|
|
||||||
inline int cmplwi(int ra, int i) { return cmpli(0, ra, i); }
|
|
||||||
inline int trap() { return 0x7fe00008; } // todo: macro-ify
|
|
||||||
}
|
|
||||||
|
|
||||||
const int64_t MASK_LO32 = 0x0ffffffff;
|
const int64_t MASK_LO32 = 0x0ffffffff;
|
||||||
const int MASK_LO16 = 0x0ffff;
|
const int MASK_LO16 = 0x0ffff;
|
||||||
@ -189,10 +82,7 @@ const int ThreadRegister = 13;
|
|||||||
|
|
||||||
const bool DebugJumps = false;
|
const bool DebugJumps = false;
|
||||||
|
|
||||||
class Context;
|
|
||||||
class MyBlock;
|
|
||||||
class JumpOffset;
|
class JumpOffset;
|
||||||
class JumpEvent;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
resolve(MyBlock*);
|
resolve(MyBlock*);
|
||||||
@ -200,116 +90,12 @@ resolve(MyBlock*);
|
|||||||
unsigned
|
unsigned
|
||||||
padding(MyBlock*, unsigned);
|
padding(MyBlock*, unsigned);
|
||||||
|
|
||||||
class MyBlock: public Assembler::Block {
|
|
||||||
public:
|
|
||||||
MyBlock(Context* context, unsigned offset):
|
|
||||||
context(context), next(0), jumpOffsetHead(0), jumpOffsetTail(0),
|
|
||||||
lastJumpOffsetTail(0), jumpEventHead(0), jumpEventTail(0),
|
|
||||||
lastEventOffset(0), offset(offset), start(~0), size(0), resolved(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual unsigned resolve(unsigned start, Assembler::Block* next) {
|
|
||||||
this->start = start;
|
|
||||||
this->next = static_cast<MyBlock*>(next);
|
|
||||||
|
|
||||||
::resolve(this);
|
|
||||||
|
|
||||||
this->resolved = true;
|
|
||||||
|
|
||||||
return start + size + padding(this, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
Context* context;
|
|
||||||
MyBlock* next;
|
|
||||||
JumpOffset* jumpOffsetHead;
|
|
||||||
JumpOffset* jumpOffsetTail;
|
|
||||||
JumpOffset* lastJumpOffsetTail;
|
|
||||||
JumpEvent* jumpEventHead;
|
|
||||||
JumpEvent* jumpEventTail;
|
|
||||||
unsigned lastEventOffset;
|
|
||||||
unsigned offset;
|
|
||||||
unsigned start;
|
|
||||||
unsigned size;
|
|
||||||
bool resolved;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Task;
|
class Task;
|
||||||
class ConstantPoolEntry;
|
class ConstantPoolEntry;
|
||||||
|
|
||||||
class Context {
|
class OffsetPromise: public Promise {
|
||||||
public:
|
public:
|
||||||
Context(System* s, Allocator* a, Zone* zone):
|
OffsetPromise(Context* c, MyBlock* block, unsigned offset):
|
||||||
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
|
|
||||||
firstBlock(new(zone) MyBlock(this, 0)),
|
|
||||||
lastBlock(firstBlock), jumpOffsetHead(0), jumpOffsetTail(0),
|
|
||||||
constantPool(0), constantPoolCount(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
System* s;
|
|
||||||
Zone* zone;
|
|
||||||
Assembler::Client* client;
|
|
||||||
Vector code;
|
|
||||||
Task* tasks;
|
|
||||||
uint8_t* result;
|
|
||||||
MyBlock* firstBlock;
|
|
||||||
MyBlock* lastBlock;
|
|
||||||
JumpOffset* jumpOffsetHead;
|
|
||||||
JumpOffset* jumpOffsetTail;
|
|
||||||
ConstantPoolEntry* constantPool;
|
|
||||||
unsigned constantPoolCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Task {
|
|
||||||
public:
|
|
||||||
Task(Task* next): next(next) { }
|
|
||||||
|
|
||||||
virtual void run(Context* c) = 0;
|
|
||||||
|
|
||||||
Task* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*OperationType)(Context*);
|
|
||||||
|
|
||||||
typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*);
|
|
||||||
|
|
||||||
typedef void (*BinaryOperationType)
|
|
||||||
(Context*, unsigned, lir::Operand*, unsigned, lir::Operand*);
|
|
||||||
|
|
||||||
typedef void (*TernaryOperationType)
|
|
||||||
(Context*, unsigned, lir::Operand*, lir::Operand*,
|
|
||||||
lir::Operand*);
|
|
||||||
|
|
||||||
typedef void (*BranchOperationType)
|
|
||||||
(Context*, lir::TernaryOperation, unsigned, lir::Operand*,
|
|
||||||
lir::Operand*, lir::Operand*);
|
|
||||||
|
|
||||||
class ArchitectureContext {
|
|
||||||
public:
|
|
||||||
ArchitectureContext(System* s): s(s) { }
|
|
||||||
|
|
||||||
System* s;
|
|
||||||
OperationType operations[lir::OperationCount];
|
|
||||||
UnaryOperationType unaryOperations[lir::UnaryOperationCount
|
|
||||||
* lir::OperandTypeCount];
|
|
||||||
BinaryOperationType binaryOperations
|
|
||||||
[lir::BinaryOperationCount * lir::OperandTypeCount * lir::OperandTypeCount];
|
|
||||||
TernaryOperationType ternaryOperations
|
|
||||||
[lir::NonBranchTernaryOperationCount * lir::OperandTypeCount];
|
|
||||||
BranchOperationType branchOperations
|
|
||||||
[lir::BranchOperationCount * lir::OperandTypeCount * lir::OperandTypeCount];
|
|
||||||
};
|
|
||||||
|
|
||||||
inline Aborter* getAborter(Context* con) {
|
|
||||||
return con->s;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Aborter* getAborter(ArchitectureContext* con) {
|
|
||||||
return con->s;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Offset: public Promise {
|
|
||||||
public:
|
|
||||||
Offset(Context* c, MyBlock* block, unsigned offset):
|
|
||||||
c(c), block(block), offset(offset)
|
c(c), block(block), offset(offset)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -330,9 +116,9 @@ class Offset: public Promise {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Promise*
|
Promise*
|
||||||
offset(Context* c)
|
offsetPromise(Context* c)
|
||||||
{
|
{
|
||||||
return new(c->zone) Offset(c, c->lastBlock, c->code.length());
|
return new(c->zone) OffsetPromise(c, c->lastBlock, c->code.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -978,7 +764,7 @@ moveCR2(Context* c, unsigned, lir::Constant* src,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
appendImmediateTask
|
appendImmediateTask
|
||||||
(c, src->value, offset(c), TargetBytesPerWord, promiseOffset, false);
|
(c, src->value, offsetPromise(c), TargetBytesPerWord, promiseOffset, false);
|
||||||
emit(c, lis(dst->low, 0));
|
emit(c, lis(dst->low, 0));
|
||||||
emit(c, ori(dst->low, dst->low, 0));
|
emit(c, ori(dst->low, dst->low, 0));
|
||||||
}
|
}
|
||||||
@ -1505,7 +1291,7 @@ moveAR2(Context* c, unsigned srcSize UNUSED, lir::Address* src,
|
|||||||
lir::Memory memory(dst->low, 0, -1, 0);
|
lir::Memory memory(dst->low, 0, -1, 0);
|
||||||
|
|
||||||
appendImmediateTask
|
appendImmediateTask
|
||||||
(c, src->address, offset(c), TargetBytesPerWord, promiseOffset, true);
|
(c, src->address, offsetPromise(c), TargetBytesPerWord, promiseOffset, true);
|
||||||
|
|
||||||
emit(c, lis(dst->low, 0));
|
emit(c, lis(dst->low, 0));
|
||||||
moveMR(c, dstSize, &memory, dstSize, dst);
|
moveMR(c, dstSize, &memory, dstSize, dst);
|
||||||
@ -1622,7 +1408,7 @@ branch(Context* c, lir::TernaryOperation op)
|
|||||||
void
|
void
|
||||||
conditional(Context* c, int32_t branch, lir::Constant* target)
|
conditional(Context* c, int32_t branch, lir::Constant* target)
|
||||||
{
|
{
|
||||||
appendOffsetTask(c, target->value, offset(c), true);
|
appendOffsetTask(c, target->value, offsetPromise(c), true);
|
||||||
emit(c, branch);
|
emit(c, branch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1835,7 +1621,7 @@ callC(Context* c, unsigned size UNUSED, lir::Constant* target)
|
|||||||
{
|
{
|
||||||
assert(c, size == TargetBytesPerWord);
|
assert(c, size == TargetBytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), false);
|
appendOffsetTask(c, target->value, offsetPromise(c), false);
|
||||||
emit(c, bl(0));
|
emit(c, bl(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1888,7 +1674,7 @@ jumpC(Context* c, unsigned size UNUSED, lir::Constant* target)
|
|||||||
{
|
{
|
||||||
assert(c, size == TargetBytesPerWord);
|
assert(c, size == TargetBytesPerWord);
|
||||||
|
|
||||||
appendOffsetTask(c, target->value, offset(c), false);
|
appendOffsetTask(c, target->value, offsetPromise(c), false);
|
||||||
emit(c, b(0));
|
emit(c, b(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1901,7 +1687,7 @@ return_(Context* c)
|
|||||||
void
|
void
|
||||||
trap(Context* c)
|
trap(Context* c)
|
||||||
{
|
{
|
||||||
emit(c, trap());
|
emit(c, isa::trap());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2127,7 +1913,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned argumentFootprint(unsigned footprint) {
|
virtual unsigned argumentFootprint(unsigned footprint) {
|
||||||
return ::argumentFootprint(footprint);
|
return powerpc::argumentFootprint(footprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool argumentAlignment() {
|
virtual bool argumentAlignment() {
|
||||||
@ -2213,7 +1999,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
unsigned targetParameterFootprint, void** ip,
|
unsigned targetParameterFootprint, void** ip,
|
||||||
void** stack)
|
void** stack)
|
||||||
{
|
{
|
||||||
::nextFrame(&c, static_cast<int32_t*>(start), size, footprint, link,
|
powerpc::nextFrame(&c, static_cast<int32_t*>(start), size, footprint, link,
|
||||||
mostRecent, targetParameterFootprint, ip, stack);
|
mostRecent, targetParameterFootprint, ip, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2714,7 +2500,7 @@ class MyAssembler: public Assembler {
|
|||||||
|
|
||||||
bool jump = needJump(b);
|
bool jump = needJump(b);
|
||||||
if (jump) {
|
if (jump) {
|
||||||
write4(dst + dstOffset, ::b(jumpTableSize + TargetBytesPerWord));
|
write4(dst + dstOffset, isa::b(jumpTableSize + TargetBytesPerWord));
|
||||||
}
|
}
|
||||||
|
|
||||||
dstOffset += jumpTableSize + (jump ? TargetBytesPerWord : 0);
|
dstOffset += jumpTableSize + (jump ? TargetBytesPerWord : 0);
|
||||||
@ -2747,7 +2533,7 @@ class MyAssembler: public Assembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Promise* offset(bool) {
|
virtual Promise* offset(bool) {
|
||||||
return ::offset(&c);
|
return powerpc::offsetPromise(&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Block* endBlock(bool startNew) {
|
virtual Block* endBlock(bool startNew) {
|
||||||
@ -2815,15 +2601,12 @@ Assembler* MyArchitecture::makeAssembler(Allocator* allocator, Zone* zone) {
|
|||||||
return new(zone) MyAssembler(this->c.s, allocator, zone, this);
|
return new(zone) MyAssembler(this->c.s, allocator, zone, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace powerpc
|
||||||
|
|
||||||
namespace avian {
|
|
||||||
namespace codegen {
|
|
||||||
|
|
||||||
Assembler::Architecture*
|
Assembler::Architecture*
|
||||||
makeArchitecturePowerpc(System* system, bool)
|
makeArchitecturePowerpc(System* system, bool)
|
||||||
{
|
{
|
||||||
return new (allocate(system, sizeof(MyArchitecture))) MyArchitecture(system);
|
return new (allocate(system, sizeof(powerpc::MyArchitecture))) powerpc::MyArchitecture(system);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
|
42
src/codegen/powerpc/block.cpp
Normal file
42
src/codegen/powerpc/block.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
#include "block.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace powerpc {
|
||||||
|
|
||||||
|
void resolve(MyBlock*);
|
||||||
|
|
||||||
|
unsigned padding(MyBlock*, unsigned);
|
||||||
|
|
||||||
|
MyBlock::MyBlock(Context* context, unsigned offset):
|
||||||
|
context(context), next(0), jumpOffsetHead(0), jumpOffsetTail(0),
|
||||||
|
lastJumpOffsetTail(0), jumpEventHead(0), jumpEventTail(0),
|
||||||
|
lastEventOffset(0), offset(offset), start(~0), size(0), resolved(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
unsigned MyBlock::resolve(unsigned start, Assembler::Block* next) {
|
||||||
|
this->start = start;
|
||||||
|
this->next = static_cast<MyBlock*>(next);
|
||||||
|
|
||||||
|
powerpc::resolve(this);
|
||||||
|
|
||||||
|
this->resolved = true;
|
||||||
|
|
||||||
|
return start + size + padding(this, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace powerpc
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
44
src/codegen/powerpc/block.h
Normal file
44
src/codegen/powerpc/block.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_POWERPC_BLOCK_H
|
||||||
|
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_BLOCK_H
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace powerpc {
|
||||||
|
|
||||||
|
class JumpEvent;
|
||||||
|
|
||||||
|
class MyBlock: public Assembler::Block {
|
||||||
|
public:
|
||||||
|
MyBlock(Context* context, unsigned offset);
|
||||||
|
|
||||||
|
virtual unsigned resolve(unsigned start, Assembler::Block* next);
|
||||||
|
|
||||||
|
Context* context;
|
||||||
|
MyBlock* next;
|
||||||
|
JumpOffset* jumpOffsetHead;
|
||||||
|
JumpOffset* jumpOffsetTail;
|
||||||
|
JumpOffset* lastJumpOffsetTail;
|
||||||
|
JumpEvent* jumpEventHead;
|
||||||
|
JumpEvent* jumpEventTail;
|
||||||
|
unsigned lastEventOffset;
|
||||||
|
unsigned offset;
|
||||||
|
unsigned start;
|
||||||
|
unsigned size;
|
||||||
|
bool resolved;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace powerpc
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_BLOCK_H
|
29
src/codegen/powerpc/context.cpp
Normal file
29
src/codegen/powerpc/context.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
#include "block.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace powerpc {
|
||||||
|
|
||||||
|
|
||||||
|
Context::Context(vm::System* s, vm::Allocator* a, vm::Zone* zone):
|
||||||
|
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
|
||||||
|
firstBlock(new(zone) MyBlock(this, 0)),
|
||||||
|
lastBlock(firstBlock), jumpOffsetHead(0), jumpOffsetTail(0),
|
||||||
|
constantPool(0), constantPoolCount(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
} // namespace powerpc
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
95
src/codegen/powerpc/context.h
Normal file
95
src/codegen/powerpc/context.h
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
||||||
|
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
||||||
|
|
||||||
|
#include <avian/vm/codegen/assembler.h>
|
||||||
|
#include "alloc-vector.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace vm {
|
||||||
|
class System;
|
||||||
|
class Allocator;
|
||||||
|
class Zone;
|
||||||
|
} // namespace vm
|
||||||
|
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace powerpc {
|
||||||
|
|
||||||
|
class Task;
|
||||||
|
class JumpOffset;
|
||||||
|
class ConstantPoolEntry;
|
||||||
|
class MyBlock;
|
||||||
|
|
||||||
|
class Context {
|
||||||
|
public:
|
||||||
|
Context(vm::System* s, vm::Allocator* a, vm::Zone* zone);
|
||||||
|
|
||||||
|
vm::System* s;
|
||||||
|
vm::Zone* zone;
|
||||||
|
Assembler::Client* client;
|
||||||
|
vm::Vector code;
|
||||||
|
Task* tasks;
|
||||||
|
uint8_t* result;
|
||||||
|
MyBlock* firstBlock;
|
||||||
|
MyBlock* lastBlock;
|
||||||
|
JumpOffset* jumpOffsetHead;
|
||||||
|
JumpOffset* jumpOffsetTail;
|
||||||
|
ConstantPoolEntry* constantPool;
|
||||||
|
unsigned constantPoolCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*OperationType)(Context*);
|
||||||
|
|
||||||
|
typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*);
|
||||||
|
|
||||||
|
typedef void (*BinaryOperationType)
|
||||||
|
(Context*, unsigned, lir::Operand*, unsigned, lir::Operand*);
|
||||||
|
|
||||||
|
typedef void (*TernaryOperationType)
|
||||||
|
(Context*, unsigned, lir::Operand*, lir::Operand*,
|
||||||
|
lir::Operand*);
|
||||||
|
|
||||||
|
typedef void (*BranchOperationType)
|
||||||
|
(Context*, lir::TernaryOperation, unsigned, lir::Operand*,
|
||||||
|
lir::Operand*, lir::Operand*);
|
||||||
|
|
||||||
|
class ArchitectureContext {
|
||||||
|
public:
|
||||||
|
ArchitectureContext(vm::System* s): s(s) { }
|
||||||
|
|
||||||
|
vm::System* s;
|
||||||
|
OperationType operations[lir::OperationCount];
|
||||||
|
UnaryOperationType unaryOperations[lir::UnaryOperationCount
|
||||||
|
* lir::OperandTypeCount];
|
||||||
|
BinaryOperationType binaryOperations
|
||||||
|
[lir::BinaryOperationCount * lir::OperandTypeCount * lir::OperandTypeCount];
|
||||||
|
TernaryOperationType ternaryOperations
|
||||||
|
[lir::NonBranchTernaryOperationCount * lir::OperandTypeCount];
|
||||||
|
BranchOperationType branchOperations
|
||||||
|
[lir::BranchOperationCount * lir::OperandTypeCount * lir::OperandTypeCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
inline avian::util::Aborter* getAborter(Context* con) {
|
||||||
|
return con->s;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline avian::util::Aborter* getAborter(ArchitectureContext* con) {
|
||||||
|
return con->s;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace powerpc
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_CONTEXT_H
|
137
src/codegen/powerpc/encode.h
Normal file
137
src/codegen/powerpc/encode.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_POWERPC_ENCODE_H
|
||||||
|
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_ENCODE_H
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace powerpc {
|
||||||
|
|
||||||
|
namespace isa {
|
||||||
|
// INSTRUCTION FORMATS
|
||||||
|
inline int D(int op, int rt, int ra, int d) { return op<<26|rt<<21|ra<<16|(d & 0xFFFF); }
|
||||||
|
// inline int DS(int op, int rt, int ra, int ds, int xo) { return op<<26|rt<<21|ra<<16|ds<<2|xo; }
|
||||||
|
inline int I(int op, int li, int aa, int lk) { return op<<26|(li & 0x3FFFFFC)|aa<<1|lk; }
|
||||||
|
inline int B(int op, int bo, int bi, int bd, int aa, int lk) { return op<<26|bo<<21|bi<<16|(bd & 0xFFFC)|aa<<1|lk; }
|
||||||
|
// inline int SC(int op, int lev) { return op<<26|lev<<5|2; }
|
||||||
|
inline int X(int op, int rt, int ra, int rb, int xo, int rc) { return op<<26|rt<<21|ra<<16|rb<<11|xo<<1|rc; }
|
||||||
|
inline int XL(int op, int bt, int ba, int bb, int xo, int lk) { return op<<26|bt<<21|ba<<16|bb<<11|xo<<1|lk; }
|
||||||
|
inline int XFX(int op, int rt, int spr, int xo) { return op<<26|rt<<21|((spr >> 5) | ((spr << 5) & 0x3E0))<<11|xo<<1; }
|
||||||
|
// inline int XFL(int op, int flm, int frb, int xo, int rc) { return op<<26|flm<<17|frb<<11|xo<<1|rc; }
|
||||||
|
// inline int XS(int op, int rs, int ra, int sh, int xo, int sh2, int rc) { return op<<26|rs<<21|ra<<16|sh<<11|xo<<2|sh2<<1|rc; }
|
||||||
|
inline int XO(int op, int rt, int ra, int rb, int oe, int xo, int rc) { return op<<26|rt<<21|ra<<16|rb<<11|oe<<10|xo<<1|rc; }
|
||||||
|
// inline int A(int op, int frt, int fra, int frb, int frc, int xo, int rc) { return op<<26|frt<<21|fra<<16|frb<<11|frc<<6|xo<<1|rc; }
|
||||||
|
inline int M(int op, int rs, int ra, int rb, int mb, int me, int rc) { return op<<26|rs<<21|ra<<16|rb<<11|mb<<6|me<<1|rc; }
|
||||||
|
// inline int MD(int op, int rs, int ra, int sh, int mb, int xo, int sh2, int rc) { return op<<26|rs<<21|ra<<16|sh<<11|mb<<5|xo<<2|sh2<<1|rc; }
|
||||||
|
// inline int MDS(int op, int rs, int ra, int rb, int mb, int xo, int rc) { return op<<26|rs<<21|ra<<16|rb<<11|mb<<5|xo<<1|rc; }
|
||||||
|
// INSTRUCTIONS
|
||||||
|
inline int lbz(int rt, int ra, int i) { return D(34, rt, ra, i); }
|
||||||
|
inline int lbzx(int rt, int ra, int rb) { return X(31, rt, ra, rb, 87, 0); }
|
||||||
|
inline int lha(int rt, int ra, int i) { return D(42, rt, ra, i); }
|
||||||
|
inline int lhax(int rt, int ra, int rb) { return X(31, rt, ra, rb, 343, 0); }
|
||||||
|
// inline int lhz(int rt, int ra, int i) { return D(40, rt, ra, i); }
|
||||||
|
inline int lhzx(int rt, int ra, int rb) { return X(31, rt, ra, rb, 279, 0); }
|
||||||
|
inline int lwz(int rt, int ra, int i) { return D(32, rt, ra, i); }
|
||||||
|
inline int lwzx(int rt, int ra, int rb) { return X(31, rt, ra, rb, 23, 0); }
|
||||||
|
inline int stb(int rs, int ra, int i) { return D(38, rs, ra, i); }
|
||||||
|
inline int stbx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 215, 0); }
|
||||||
|
inline int sth(int rs, int ra, int i) { return D(44, rs, ra, i); }
|
||||||
|
inline int sthx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 407, 0); }
|
||||||
|
inline int stw(int rs, int ra, int i) { return D(36, rs, ra, i); }
|
||||||
|
inline int stwu(int rs, int ra, int i) { return D(37, rs, ra, i); }
|
||||||
|
inline int stwux(int rs, int ra, int rb) { return X(31, rs, ra, rb, 183, 0); }
|
||||||
|
inline int stwx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 151, 0); }
|
||||||
|
inline int add(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 266, 0); }
|
||||||
|
inline int addc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 10, 0); }
|
||||||
|
inline int adde(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 138, 0); }
|
||||||
|
inline int addi(int rt, int ra, int i) { return D(14, rt, ra, i); }
|
||||||
|
inline int addic(int rt, int ra, int i) { return D(12, rt, ra, i); }
|
||||||
|
inline int addis(int rt, int ra, int i) { return D(15, rt, ra, i); }
|
||||||
|
inline int subf(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 40, 0); }
|
||||||
|
inline int subfc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 8, 0); }
|
||||||
|
inline int subfe(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 136, 0); }
|
||||||
|
inline int subfic(int rt, int ra, int i) { return D(8, rt, ra, i); }
|
||||||
|
inline int subfze(int rt, int ra) { return XO(31, rt, ra, 0, 0, 200, 0); }
|
||||||
|
inline int mullw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 235, 0); }
|
||||||
|
// inline int mulhw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 75, 0); }
|
||||||
|
inline int mulhwu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 11, 0); }
|
||||||
|
// inline int mulli(int rt, int ra, int i) { return D(7, rt, ra, i); }
|
||||||
|
inline int divw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 491, 0); }
|
||||||
|
// inline int divwu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 459, 0); }
|
||||||
|
// inline int divd(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 489, 0); }
|
||||||
|
// inline int divdu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 457, 0); }
|
||||||
|
inline int neg(int rt, int ra) { return XO(31, rt, ra, 0, 0, 104, 0); }
|
||||||
|
inline int and_(int rt, int ra, int rb) { return X(31, ra, rt, rb, 28, 0); }
|
||||||
|
inline int andi(int rt, int ra, int i) { return D(28, ra, rt, i); }
|
||||||
|
inline int andis(int rt, int ra, int i) { return D(29, ra, rt, i); }
|
||||||
|
inline int or_(int rt, int ra, int rb) { return X(31, ra, rt, rb, 444, 0); }
|
||||||
|
inline int ori(int rt, int ra, int i) { return D(24, rt, ra, i); }
|
||||||
|
inline int xor_(int rt, int ra, int rb) { return X(31, ra, rt, rb, 316, 0); }
|
||||||
|
inline int oris(int rt, int ra, int i) { return D(25, rt, ra, i); }
|
||||||
|
inline int xori(int rt, int ra, int i) { return D(26, rt, ra, i); }
|
||||||
|
inline int xoris(int rt, int ra, int i) { return D(27, rt, ra, i); }
|
||||||
|
inline int rlwinm(int rt, int ra, int i, int mb, int me) { return M(21, ra, rt, i, mb, me, 0); }
|
||||||
|
inline int rlwimi(int rt, int ra, int i, int mb, int me) { return M(20, ra, rt, i, mb, me, 0); }
|
||||||
|
inline int slw(int rt, int ra, int sh) { return X(31, ra, rt, sh, 24, 0); }
|
||||||
|
// inline int sld(int rt, int ra, int rb) { return X(31, ra, rt, rb, 27, 0); }
|
||||||
|
inline int srw(int rt, int ra, int sh) { return X(31, ra, rt, sh, 536, 0); }
|
||||||
|
inline int sraw(int rt, int ra, int sh) { return X(31, ra, rt, sh, 792, 0); }
|
||||||
|
inline int srawi(int rt, int ra, int sh) { return X(31, ra, rt, sh, 824, 0); }
|
||||||
|
inline int extsb(int rt, int rs) { return X(31, rs, rt, 0, 954, 0); }
|
||||||
|
inline int extsh(int rt, int rs) { return X(31, rs, rt, 0, 922, 0); }
|
||||||
|
inline int mfspr(int rt, int spr) { return XFX(31, rt, spr, 339); }
|
||||||
|
inline int mtspr(int spr, int rs) { return XFX(31, rs, spr, 467); }
|
||||||
|
inline int b(int i) { return I(18, i, 0, 0); }
|
||||||
|
inline int bl(int i) { return I(18, i, 0, 1); }
|
||||||
|
inline int bcctr(int bo, int bi, int lk) { return XL(19, bo, bi, 0, 528, lk); }
|
||||||
|
inline int bclr(int bo, int bi, int lk) { return XL(19, bo, bi, 0, 16, lk); }
|
||||||
|
inline int bc(int bo, int bi, int bd, int lk) { return B(16, bo, bi, bd, 0, lk); }
|
||||||
|
inline int cmp(int bf, int ra, int rb) { return X(31, bf << 2, ra, rb, 0, 0); }
|
||||||
|
inline int cmpl(int bf, int ra, int rb) { return X(31, bf << 2, ra, rb, 32, 0); }
|
||||||
|
inline int cmpi(int bf, int ra, int i) { return D(11, bf << 2, ra, i); }
|
||||||
|
inline int cmpli(int bf, int ra, int i) { return D(10, bf << 2, ra, i); }
|
||||||
|
inline int sync(int L) { return X(31, L, 0, 0, 598, 0); }
|
||||||
|
// PSEUDO-INSTRUCTIONS
|
||||||
|
inline int li(int rt, int i) { return addi(rt, 0, i); }
|
||||||
|
inline int lis(int rt, int i) { return addis(rt, 0, i); }
|
||||||
|
inline int slwi(int rt, int ra, int i) { return rlwinm(rt, ra, i, 0, 31-i); }
|
||||||
|
inline int srwi(int rt, int ra, int i) { return rlwinm(rt, ra, 32-i, i, 31); }
|
||||||
|
// inline int sub(int rt, int ra, int rb) { return subf(rt, rb, ra); }
|
||||||
|
// inline int subc(int rt, int ra, int rb) { return subfc(rt, rb, ra); }
|
||||||
|
// inline int subi(int rt, int ra, int i) { return addi(rt, ra, -i); }
|
||||||
|
// inline int subis(int rt, int ra, int i) { return addis(rt, ra, -i); }
|
||||||
|
inline int mr(int rt, int ra) { return or_(rt, ra, ra); }
|
||||||
|
inline int mflr(int rx) { return mfspr(rx, 8); }
|
||||||
|
inline int mtlr(int rx) { return mtspr(8, rx); }
|
||||||
|
inline int mtctr(int rd) { return mtspr(9, rd); }
|
||||||
|
inline int bctr() { return bcctr(20, 0, 0); }
|
||||||
|
inline int bctrl() { return bcctr(20, 0, 1); }
|
||||||
|
inline int blr() { return bclr(20, 0, 0); }
|
||||||
|
inline int blt(int i) { return bc(12, 0, i, 0); }
|
||||||
|
inline int bgt(int i) { return bc(12, 1, i, 0); }
|
||||||
|
inline int bge(int i) { return bc(4, 0, i, 0); }
|
||||||
|
inline int ble(int i) { return bc(4, 1, i, 0); }
|
||||||
|
inline int beq(int i) { return bc(12, 2, i, 0); }
|
||||||
|
inline int bne(int i) { return bc(4, 2, i, 0); }
|
||||||
|
inline int cmpw(int ra, int rb) { return cmp(0, ra, rb); }
|
||||||
|
inline int cmplw(int ra, int rb) { return cmpl(0, ra, rb); }
|
||||||
|
inline int cmpwi(int ra, int i) { return cmpi(0, ra, i); }
|
||||||
|
inline int cmplwi(int ra, int i) { return cmpli(0, ra, i); }
|
||||||
|
inline int trap() { return 0x7fe00008; } // todo: macro-ify
|
||||||
|
|
||||||
|
} // namespace isa
|
||||||
|
|
||||||
|
} // namespace powerpc
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_ENCODE_H
|
||||||
|
|
32
src/codegen/powerpc/fixup.h
Normal file
32
src/codegen/powerpc/fixup.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* Copyright (c) 2008-2012, Avian Contributors
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software
|
||||||
|
for any purpose with or without fee is hereby granted, provided
|
||||||
|
that the above copyright notice and this permission notice appear
|
||||||
|
in all copies.
|
||||||
|
|
||||||
|
There is NO WARRANTY for this software. See license.txt for
|
||||||
|
details. */
|
||||||
|
|
||||||
|
#ifndef AVIAN_CODEGEN_ASSEMBLER_POWERPC_FIXUP_H
|
||||||
|
#define AVIAN_CODEGEN_ASSEMBLER_POWERPC_FIXUP_H
|
||||||
|
|
||||||
|
namespace avian {
|
||||||
|
namespace codegen {
|
||||||
|
namespace powerpc {
|
||||||
|
|
||||||
|
|
||||||
|
class Task {
|
||||||
|
public:
|
||||||
|
Task(Task* next): next(next) { }
|
||||||
|
|
||||||
|
virtual void run(Context* c) = 0;
|
||||||
|
|
||||||
|
Task* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace powerpc
|
||||||
|
} // namespace codegen
|
||||||
|
} // namespace avian
|
||||||
|
|
||||||
|
#endif // AVIAN_CODEGEN_ASSEMBLER_POWERPC_FIXUP_H
|
Loading…
x
Reference in New Issue
Block a user