From aacfb9ec858d948c6743117ec97d38a7c9575d31 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Tue, 12 Feb 2013 12:18:09 -0700 Subject: [PATCH 01/23] fix unused function warnings in codegen/powerpc/assembler.cpp when building with clang --- src/codegen/powerpc/assembler.cpp | 50 ++++++++++++++----------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/codegen/powerpc/assembler.cpp b/src/codegen/powerpc/assembler.cpp index 415ef3fa54..6517e59264 100644 --- a/src/codegen/powerpc/assembler.cpp +++ b/src/codegen/powerpc/assembler.cpp @@ -23,26 +23,26 @@ namespace { 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 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 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 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 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; } +// 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 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); } @@ -66,13 +66,13 @@ 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 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 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 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); } @@ -86,7 +86,7 @@ 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 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); } @@ -109,10 +109,10 @@ 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 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); } @@ -136,12 +136,12 @@ inline int trap() { return 0x7fe00008; } // todo: macro-ify const int64_t MASK_LO32 = 0x0ffffffff; const int MASK_LO16 = 0x0ffff; const int MASK_LO8 = 0x0ff; -inline int lo32(int64_t i) { return (int)(i & MASK_LO32); } -inline int hi32(int64_t i) { return lo32(i >> 32); } +// inline int lo32(int64_t i) { return (int)(i & MASK_LO32); } +// inline int hi32(int64_t i) { return lo32(i >> 32); } inline int lo16(int64_t i) { return (int)(i & MASK_LO16); } inline int hi16(int64_t i) { return lo16(i >> 16); } -inline int lo8(int64_t i) { return (int)(i & MASK_LO8); } -inline int hi8(int64_t i) { return lo8(i >> 8); } +// inline int lo8(int64_t i) { return (int)(i & MASK_LO8); } +// inline int hi8(int64_t i) { return lo8(i >> 8); } inline int ha16(int32_t i) { return ((i >> 16) + ((i & 0x8000) ? 1 : 0)) & 0xffff; @@ -634,12 +634,6 @@ isBranch(TernaryOperation op) return op > FloatMin; } -bool -isFloatBranch(TernaryOperation op) -{ - return op > JumpIfNotEqual; -} - inline unsigned index(ArchitectureContext* c UNUSED, TernaryOperation operation, From d7f088c9e7bf64041fe88d7520454aa368e8307c Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Mon, 11 Feb 2013 08:07:46 -0700 Subject: [PATCH 02/23] adjust package structure in codegen (vm -> avian::codegen and avian::codegen::lir) The eventual intent with the lir namespace is to formalize some of the important bits of Assembler interface, to be tested, debug-printed, and potentially, serialized. Also, group arguments to apply(...) in OperandInfos --- src/codegen/arm/assembler.cpp | 872 ++++++++++---------- src/codegen/assembler.h | 341 +------- src/codegen/compiler.cpp | 791 +++++++++--------- src/codegen/compiler.h | 14 +- src/codegen/lir-ops.inc.cpp | 62 ++ src/codegen/lir.cpp | 35 + src/codegen/lir.h | 174 ++++ src/codegen/powerpc/assembler.cpp | 783 +++++++++--------- src/codegen/promise.h | 159 ++++ src/codegen/targets.cpp | 2 +- src/codegen/targets.h | 8 +- src/codegen/x86/assembler.cpp | 1235 ++++++++++++++--------------- src/compile.cpp | 416 +++++----- src/processor.h | 10 +- 14 files changed, 2530 insertions(+), 2372 deletions(-) create mode 100644 src/codegen/lir-ops.inc.cpp create mode 100644 src/codegen/lir.cpp create mode 100644 src/codegen/lir.h create mode 100644 src/codegen/promise.h diff --git a/src/codegen/arm/assembler.cpp b/src/codegen/arm/assembler.cpp index 849a53b0cd..ecaad31007 100644 --- a/src/codegen/arm/assembler.cpp +++ b/src/codegen/arm/assembler.cpp @@ -20,6 +20,7 @@ #define CAST_BRANCH(x) reinterpret_cast(x) using namespace vm; +using namespace avian::codegen; namespace local { @@ -208,14 +209,14 @@ const uint64_t GPR_MASK64 = GPR_MASK | (uint64_t)GPR_MASK << 32; // making the following const somehow breaks debug symbol output in GDB /* const */ uint64_t FPR_MASK64 = FPR_MASK | (uint64_t)FPR_MASK << 32; -inline bool isFpr(Assembler::Register* reg) { +inline bool isFpr(lir::Register* reg) { return reg->low >= N_GPRS; } inline int fpr64(int reg) { return reg - N_GPRS; } -inline int fpr64(Assembler::Register* reg) { return fpr64(reg->low); } +inline int fpr64(lir::Register* reg) { return fpr64(reg->low); } inline int fpr32(int reg) { return fpr64(reg) << 1; } -inline int fpr32(Assembler::Register* reg) { return fpr64(reg) << 1; } +inline int fpr32(lir::Register* reg) { return fpr64(reg) << 1; } const unsigned FrameHeaderSize = 1; @@ -310,33 +311,33 @@ class Task { typedef void (*OperationType)(Context*); -typedef void (*UnaryOperationType)(Context*, unsigned, Assembler::Operand*); +typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*); typedef void (*BinaryOperationType) -(Context*, unsigned, Assembler::Operand*, unsigned, Assembler::Operand*); +(Context*, unsigned, lir::Operand*, unsigned, lir::Operand*); typedef void (*TernaryOperationType) -(Context*, unsigned, Assembler::Operand*, Assembler::Operand*, - Assembler::Operand*); +(Context*, unsigned, lir::Operand*, lir::Operand*, + lir::Operand*); typedef void (*BranchOperationType) -(Context*, TernaryOperation, unsigned, Assembler::Operand*, - Assembler::Operand*, Assembler::Operand*); +(Context*, lir::TernaryOperation, unsigned, lir::Operand*, + lir::Operand*, lir::Operand*); class ArchitectureContext { public: ArchitectureContext(System* s): s(s) { } System* s; - OperationType operations[OperationCount]; - UnaryOperationType unaryOperations[UnaryOperationCount - * OperandTypeCount]; + OperationType operations[lir::OperationCount]; + UnaryOperationType unaryOperations[lir::UnaryOperationCount + * lir::OperandTypeCount]; BinaryOperationType binaryOperations - [BinaryOperationCount * OperandTypeCount * OperandTypeCount]; + [lir::BinaryOperationCount * lir::OperandTypeCount * lir::OperandTypeCount]; TernaryOperationType ternaryOperations - [NonBranchTernaryOperationCount * OperandTypeCount]; + [lir::NonBranchTernaryOperationCount * lir::OperandTypeCount]; BranchOperationType branchOperations - [BranchOperationCount * OperandTypeCount * OperandTypeCount]; + [lir::BranchOperationCount * lir::OperandTypeCount * lir::OperandTypeCount]; }; inline void NO_RETURN @@ -469,49 +470,37 @@ appendOffsetTask(Context* con, Promise* promise, Promise* instructionOffset) } inline unsigned -index(ArchitectureContext*, UnaryOperation operation, OperandType operand) +index(ArchitectureContext*, lir::UnaryOperation operation, lir::OperandType operand) { - return operation + (UnaryOperationCount * operand); + return operation + (lir::UnaryOperationCount * operand); } inline unsigned index(ArchitectureContext*, - BinaryOperation operation, - OperandType operand1, - OperandType operand2) + lir::BinaryOperation operation, + lir::OperandType operand1, + lir::OperandType operand2) { return operation - + (BinaryOperationCount * operand1) - + (BinaryOperationCount * OperandTypeCount * operand2); -} - -bool -isBranch(TernaryOperation op) -{ - return op > FloatMin; -} - -bool UNUSED -isFloatBranch(TernaryOperation op) -{ - return op > JumpIfNotEqual; + + (lir::BinaryOperationCount * operand1) + + (lir::BinaryOperationCount * lir::OperandTypeCount * operand2); } inline unsigned index(ArchitectureContext* con UNUSED, - TernaryOperation operation, - OperandType operand1) + lir::TernaryOperation operation, + lir::OperandType operand1) { assert(con, not isBranch(operation)); - return operation + (NonBranchTernaryOperationCount * operand1); + return operation + (lir::NonBranchTernaryOperationCount * operand1); } unsigned -branchIndex(ArchitectureContext* con UNUSED, OperandType operand1, - OperandType operand2) +branchIndex(ArchitectureContext* con UNUSED, lir::OperandType operand1, + lir::OperandType operand2) { - return operand1 + (OperandTypeCount * operand2); + return operand1 + (lir::OperandTypeCount * operand2); } // BEGIN OPERATION COMPILERS @@ -533,23 +522,23 @@ inline void freeTemp(Context* con, int r) { con->client->releaseTemporary(r); } -inline int64_t getValue(Assembler::Constant* con) { +inline int64_t getValue(lir::Constant* con) { return con->value->value(); } -inline Assembler::Register makeTemp(Context* con) { - Assembler::Register tmp(newTemp(con)); +inline lir::Register makeTemp(Context* con) { + lir::Register tmp(newTemp(con)); return tmp; } -inline Assembler::Register makeTemp64(Context* con) { - Assembler::Register tmp(newTemp(con), newTemp(con)); +inline lir::Register makeTemp64(Context* con) { + lir::Register tmp(newTemp(con), newTemp(con)); return tmp; } -inline void freeTemp(Context* con, const Assembler::Register& tmp) { - if (tmp.low != NoRegister) freeTemp(con, tmp.low); - if (tmp.high != NoRegister) freeTemp(con, tmp.high); +inline void freeTemp(Context* con, const lir::Register& tmp) { + if (tmp.low != lir::NoRegister) freeTemp(con, tmp.low); + if (tmp.high != lir::NoRegister) freeTemp(con, tmp.high); } inline void @@ -559,16 +548,16 @@ write4(uint8_t* dst, uint32_t v) } void -andC(Context* con, unsigned size, Assembler::Constant* a, - Assembler::Register* b, Assembler::Register* dst); +andC(Context* con, unsigned size, lir::Constant* a, + lir::Register* b, lir::Register* dst); -void shiftLeftR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) +void shiftLeftR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if (size == 8) { int tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con); ResolvedPromise maskPromise(0x3F); - Assembler::Constant mask(&maskPromise); - Assembler::Register dst(tmp3); + lir::Constant mask(&maskPromise); + lir::Register dst(tmp3); andC(con, 4, &mask, a, &dst); emit(con, lsl(tmp1, b->high, tmp3)); emit(con, rsbi(tmp2, tmp3, 32)); @@ -581,8 +570,8 @@ void shiftLeftR(Context* con, unsigned size, Assembler::Register* a, Assembler:: } else { int tmp = newTemp(con); ResolvedPromise maskPromise(0x1F); - Assembler::Constant mask(&maskPromise); - Assembler::Register dst(tmp); + lir::Constant mask(&maskPromise); + lir::Register dst(tmp); andC(con, size, &mask, a, &dst); emit(con, lsl(t->low, b->low, tmp)); freeTemp(con, tmp); @@ -590,10 +579,10 @@ void shiftLeftR(Context* con, unsigned size, Assembler::Register* a, Assembler:: } void -moveRR(Context* con, unsigned srcSize, Assembler::Register* src, - unsigned dstSize, Assembler::Register* dst); +moveRR(Context* con, unsigned srcSize, lir::Register* src, + unsigned dstSize, lir::Register* dst); -void shiftLeftC(Context* con, unsigned size UNUSED, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) +void shiftLeftC(Context* con, unsigned size UNUSED, lir::Constant* a, lir::Register* b, lir::Register* t) { assert(con, size == TargetBytesPerWord); if (getValue(a) & 0x1F) { @@ -603,13 +592,13 @@ void shiftLeftC(Context* con, unsigned size UNUSED, Assembler::Constant* a, Asse } } -void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) +void shiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if (size == 8) { int tmp1 = newTemp(con), tmp2 = newTemp(con), tmp3 = newTemp(con); ResolvedPromise maskPromise(0x3F); - Assembler::Constant mask(&maskPromise); - Assembler::Register dst(tmp3); + lir::Constant mask(&maskPromise); + lir::Register dst(tmp3); andC(con, 4, &mask, a, &dst); emit(con, lsr(tmp1, b->low, tmp3)); emit(con, rsbi(tmp2, tmp3, 32)); @@ -622,15 +611,15 @@ void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler: } else { int tmp = newTemp(con); ResolvedPromise maskPromise(0x1F); - Assembler::Constant mask(&maskPromise); - Assembler::Register dst(tmp); + lir::Constant mask(&maskPromise); + lir::Register dst(tmp); andC(con, size, &mask, a, &dst); emit(con, asr(t->low, b->low, tmp)); freeTemp(con, tmp); } } -void shiftRightC(Context* con, unsigned size UNUSED, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) +void shiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, lir::Register* b, lir::Register* t) { assert(con, size == TargetBytesPerWord); if (getValue(a) & 0x1F) { @@ -640,12 +629,12 @@ void shiftRightC(Context* con, unsigned size UNUSED, Assembler::Constant* a, Ass } } -void unsignedShiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) +void unsignedShiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { int tmpShift = newTemp(con); ResolvedPromise maskPromise(size == 8 ? 0x3F : 0x1F); - Assembler::Constant mask(&maskPromise); - Assembler::Register dst(tmpShift); + lir::Constant mask(&maskPromise); + lir::Register dst(tmpShift); andC(con, 4, &mask, a, &dst); emit(con, lsr(t->low, b->low, tmpShift)); if (size == 8) { @@ -662,7 +651,7 @@ void unsignedShiftRightR(Context* con, unsigned size, Assembler::Register* a, As freeTemp(con, tmpShift); } -void unsignedShiftRightC(Context* con, unsigned size UNUSED, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) +void unsignedShiftRightC(Context* con, unsigned size UNUSED, lir::Constant* a, lir::Register* b, lir::Register* t) { assert(con, size == TargetBytesPerWord); if (getValue(a) & 0x1F) { @@ -873,20 +862,20 @@ resolve(MyBlock* b) } void -jumpR(Context* con, unsigned size UNUSED, Assembler::Register* target) +jumpR(Context* con, unsigned size UNUSED, lir::Register* target) { assert(con, size == TargetBytesPerWord); emit(con, bx(target->low)); } void -swapRR(Context* con, unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Register* b) +swapRR(Context* con, unsigned aSize, lir::Register* a, + unsigned bSize, lir::Register* b) { assert(con, aSize == TargetBytesPerWord); assert(con, bSize == TargetBytesPerWord); - Assembler::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); moveRR(con, aSize, a, bSize, &tmp); moveRR(con, bSize, b, aSize, a); moveRR(con, bSize, &tmp, bSize, b); @@ -894,8 +883,8 @@ swapRR(Context* con, unsigned aSize, Assembler::Register* a, } void -moveRR(Context* con, unsigned srcSize, Assembler::Register* src, - unsigned dstSize, Assembler::Register* dst) +moveRR(Context* con, unsigned srcSize, lir::Register* src, + unsigned dstSize, lir::Register* dst) { bool srcIsFpr = isFpr(src); bool dstIsFpr = isFpr(dst); @@ -932,8 +921,8 @@ moveRR(Context* con, unsigned srcSize, Assembler::Register* src, moveRR(con, 4, src, 4, dst); emit(con, asri(dst->high, src->low, 31)); } else if (srcSize == 8 and dstSize == 8) { - Assembler::Register srcHigh(src->high); - Assembler::Register dstHigh(dst->high); + lir::Register srcHigh(src->high); + lir::Register dstHigh(dst->high); if (src->high == dst->low) { if (src->low == dst->high) { @@ -956,8 +945,8 @@ moveRR(Context* con, unsigned srcSize, Assembler::Register* src, } void -moveZRR(Context* con, unsigned srcSize, Assembler::Register* src, - unsigned, Assembler::Register* dst) +moveZRR(Context* con, unsigned srcSize, lir::Register* src, + unsigned, lir::Register* dst) { switch (srcSize) { case 2: @@ -969,15 +958,15 @@ moveZRR(Context* con, unsigned srcSize, Assembler::Register* src, } } -void moveCR(Context* con, unsigned size, Assembler::Constant* src, - unsigned, Assembler::Register* dst); +void moveCR(Context* con, unsigned size, lir::Constant* src, + unsigned, lir::Register* dst); void -moveCR2(Context* con, unsigned size, Assembler::Constant* src, - Assembler::Register* dst, Promise* callOffset) +moveCR2(Context* con, unsigned size, lir::Constant* src, + lir::Register* dst, Promise* callOffset) { if (isFpr(dst)) { // floating-point - Assembler::Register tmp = size > 4 ? makeTemp64(con) : + lir::Register tmp = size > 4 ? makeTemp64(con) : makeTemp(con); moveCR(con, size, src, size, &tmp); moveRR(con, size, &tmp, size, dst); @@ -985,10 +974,10 @@ moveCR2(Context* con, unsigned size, Assembler::Constant* src, } else if (size > 4) { uint64_t value = (uint64_t)src->value->value(); ResolvedPromise loBits(value & MASK_LO32); - Assembler::Constant srcLo(&loBits); + lir::Constant srcLo(&loBits); ResolvedPromise hiBits(value >> 32); - Assembler::Constant srcHi(&hiBits); - Assembler::Register dstHi(dst->high); + lir::Constant srcHi(&hiBits); + lir::Register dstHi(dst->high); moveCR(con, 4, &srcLo, 4, dst); moveCR(con, 4, &srcHi, 4, &dstHi); } else if (src->value->resolved() and isOfWidth(getValue(src), 8)) { @@ -1000,13 +989,13 @@ moveCR2(Context* con, unsigned size, Assembler::Constant* src, } void -moveCR(Context* con, unsigned size, Assembler::Constant* src, - unsigned, Assembler::Register* dst) +moveCR(Context* con, unsigned size, lir::Constant* src, + unsigned, lir::Register* dst) { moveCR2(con, size, src, dst, 0); } -void addR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void addR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if (size == 8) { emit(con, SETS(add(t->low, a->low, b->low))); emit(con, adc(t->high, a->high, b->high)); @@ -1015,7 +1004,7 @@ void addR(Context* con, unsigned size, Assembler::Register* a, Assembler::Regist } } -void subR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void subR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if (size == 8) { emit(con, SETS(rsb(t->low, a->low, b->low))); emit(con, rsc(t->high, a->high, b->high)); @@ -1025,8 +1014,8 @@ void subR(Context* con, unsigned size, Assembler::Register* a, Assembler::Regist } void -addC(Context* con, unsigned size, Assembler::Constant* a, - Assembler::Register* b, Assembler::Register* dst) +addC(Context* con, unsigned size, lir::Constant* a, + lir::Register* b, lir::Register* dst) { assert(con, size == TargetBytesPerWord); @@ -1046,8 +1035,8 @@ addC(Context* con, unsigned size, Assembler::Constant* a, } void -subC(Context* con, unsigned size, Assembler::Constant* a, - Assembler::Register* b, Assembler::Register* dst) +subC(Context* con, unsigned size, lir::Constant* a, + lir::Register* b, lir::Register* dst) { assert(con, size == TargetBytesPerWord); @@ -1066,7 +1055,7 @@ subC(Context* con, unsigned size, Assembler::Constant* a, } } -void multiplyR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void multiplyR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if (size == 8) { bool useTemporaries = b->low == t->low; int tmpLow = useTemporaries ? con->client->acquireTemporary(GPR_MASK) : t->low; @@ -1087,7 +1076,7 @@ void multiplyR(Context* con, unsigned size, Assembler::Register* a, Assembler::R } } -void floatAbsoluteRR(Context* con, unsigned size, Assembler::Register* a, unsigned, Assembler::Register* b) { +void floatAbsoluteRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b) { if (size == 8) { emit(con, fabsd(fpr64(b), fpr64(a))); } else { @@ -1095,7 +1084,7 @@ void floatAbsoluteRR(Context* con, unsigned size, Assembler::Register* a, unsign } } -void floatNegateRR(Context* con, unsigned size, Assembler::Register* a, unsigned, Assembler::Register* b) { +void floatNegateRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b) { if (size == 8) { emit(con, fnegd(fpr64(b), fpr64(a))); } else { @@ -1103,7 +1092,7 @@ void floatNegateRR(Context* con, unsigned size, Assembler::Register* a, unsigned } } -void float2FloatRR(Context* con, unsigned size, Assembler::Register* a, unsigned, Assembler::Register* b) { +void float2FloatRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b) { if (size == 8) { emit(con, fcvtsd(fpr32(b), fpr64(a))); } else { @@ -1111,7 +1100,7 @@ void float2FloatRR(Context* con, unsigned size, Assembler::Register* a, unsigned } } -void float2IntRR(Context* con, unsigned size, Assembler::Register* a, unsigned, Assembler::Register* b) { +void float2IntRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b) { int tmp = newTemp(con, FPR_MASK); int ftmp = fpr32(tmp); if (size == 8) { // double to int @@ -1123,7 +1112,7 @@ void float2IntRR(Context* con, unsigned size, Assembler::Register* a, unsigned, freeTemp(con, tmp); } -void int2FloatRR(Context* con, unsigned, Assembler::Register* a, unsigned size, Assembler::Register* b) { +void int2FloatRR(Context* con, unsigned, lir::Register* a, unsigned size, lir::Register* b) { emit(con, fmsr(fpr32(b), a->low)); if (size == 8) { // int to double emit(con, fsitod(fpr64(b), fpr32(b))); @@ -1132,7 +1121,7 @@ void int2FloatRR(Context* con, unsigned, Assembler::Register* a, unsigned size, } // else thunked } -void floatSqrtRR(Context* con, unsigned size, Assembler::Register* a, unsigned, Assembler::Register* b) { +void floatSqrtRR(Context* con, unsigned size, lir::Register* a, unsigned, lir::Register* b) { if (size == 8) { emit(con, fsqrtd(fpr64(b), fpr64(a))); } else { @@ -1140,7 +1129,7 @@ void floatSqrtRR(Context* con, unsigned size, Assembler::Register* a, unsigned, } } -void floatAddR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void floatAddR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if (size == 8) { emit(con, faddd(fpr64(t), fpr64(a), fpr64(b))); } else { @@ -1148,7 +1137,7 @@ void floatAddR(Context* con, unsigned size, Assembler::Register* a, Assembler::R } } -void floatSubtractR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void floatSubtractR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if (size == 8) { emit(con, fsubd(fpr64(t), fpr64(b), fpr64(a))); } else { @@ -1156,7 +1145,7 @@ void floatSubtractR(Context* con, unsigned size, Assembler::Register* a, Assembl } } -void floatMultiplyR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void floatMultiplyR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if (size == 8) { emit(con, fmuld(fpr64(t), fpr64(a), fpr64(b))); } else { @@ -1164,7 +1153,7 @@ void floatMultiplyR(Context* con, unsigned size, Assembler::Register* a, Assembl } } -void floatDivideR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void floatDivideR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if (size == 8) { emit(con, fdivd(fpr64(t), fpr64(b), fpr64(a))); } else { @@ -1177,7 +1166,7 @@ normalize(Context* con, int offset, int index, unsigned scale, bool* preserveIndex, bool* release) { if (offset != 0 or scale != 1) { - Assembler::Register normalizedIndex + lir::Register normalizedIndex (*preserveIndex ? con->client->acquireTemporary(GPR_MASK) : index); if (*preserveIndex) { @@ -1190,10 +1179,10 @@ normalize(Context* con, int offset, int index, unsigned scale, int scaled; if (scale != 1) { - Assembler::Register unscaledIndex(index); + lir::Register unscaledIndex(index); ResolvedPromise scalePromise(log(scale)); - Assembler::Constant scaleConstant(&scalePromise); + lir::Constant scaleConstant(&scalePromise); shiftLeftC(con, TargetBytesPerWord, &scaleConstant, &unscaledIndex, &normalizedIndex); @@ -1204,12 +1193,12 @@ normalize(Context* con, int offset, int index, unsigned scale, } if (offset != 0) { - Assembler::Register untranslatedIndex(scaled); + lir::Register untranslatedIndex(scaled); ResolvedPromise offsetPromise(offset); - Assembler::Constant offsetConstant(&offsetPromise); + lir::Constant offsetConstant(&offsetPromise); - Assembler::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); moveCR(con, TargetBytesPerWord, &offsetConstant, TargetBytesPerWord, &tmp); addR(con, TargetBytesPerWord, &tmp, &untranslatedIndex, &normalizedIndex); con->client->releaseTemporary(tmp.low); @@ -1223,10 +1212,10 @@ normalize(Context* con, int offset, int index, unsigned scale, } void -store(Context* con, unsigned size, Assembler::Register* src, +store(Context* con, unsigned size, lir::Register* src, int base, int offset, int index, unsigned scale, bool preserveIndex) { - if (index != NoRegister) { + if (index != lir::NoRegister) { bool release; int normalized = normalize (con, offset, index, scale, &preserveIndex, &release); @@ -1246,7 +1235,7 @@ store(Context* con, unsigned size, Assembler::Register* src, break; case 8: { // split into 2 32-bit stores - Assembler::Register srcHigh(src->high); + lir::Register srcHigh(src->high); store(con, 4, &srcHigh, base, 0, normalized, 1, preserveIndex); store(con, 4, src, base, 4, normalized, 1, preserveIndex); } break; @@ -1254,7 +1243,7 @@ store(Context* con, unsigned size, Assembler::Register* src, default: abort(con); } } else { // FPR store - Assembler::Register base_(base), + lir::Register base_(base), normalized_(normalized), absAddr = makeTemp(con); // FPR stores have only bases, so we must add the index @@ -1286,9 +1275,9 @@ store(Context* con, unsigned size, Assembler::Register* src, break; case 8: { // split into 2 32-bit stores - Assembler::Register srcHigh(src->high); - store(con, 4, &srcHigh, base, offset, NoRegister, 1, false); - store(con, 4, src, base, offset + 4, NoRegister, 1, false); + lir::Register srcHigh(src->high); + store(con, 4, &srcHigh, base, offset, lir::NoRegister, 1, false); + store(con, 4, src, base, offset + 4, lir::NoRegister, 1, false); } break; default: abort(con); @@ -1300,9 +1289,9 @@ store(Context* con, unsigned size, Assembler::Register* src, else emit(con, fsts(fpr32(src), base, offset)); } } else { - Assembler::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); ResolvedPromise offsetPromise(offset); - Assembler::Constant offsetConstant(&offsetPromise); + lir::Constant offsetConstant(&offsetPromise); moveCR(con, TargetBytesPerWord, &offsetConstant, TargetBytesPerWord, &tmp); @@ -1313,8 +1302,8 @@ store(Context* con, unsigned size, Assembler::Register* src, } void -moveRM(Context* con, unsigned srcSize, Assembler::Register* src, - unsigned dstSize UNUSED, Assembler::Memory* dst) +moveRM(Context* con, unsigned srcSize, lir::Register* src, + unsigned dstSize UNUSED, lir::Memory* dst) { assert(con, srcSize == dstSize); @@ -1323,10 +1312,10 @@ moveRM(Context* con, unsigned srcSize, Assembler::Register* src, void load(Context* con, unsigned srcSize, int base, int offset, int index, - unsigned scale, unsigned dstSize, Assembler::Register* dst, + unsigned scale, unsigned dstSize, lir::Register* dst, bool preserveIndex, bool signExtend) { - if (index != NoRegister) { + if (index != lir::NoRegister) { bool release; int normalized = normalize (con, offset, index, scale, &preserveIndex, &release); @@ -1356,7 +1345,7 @@ load(Context* con, unsigned srcSize, int base, int offset, int index, false); moveRR(con, 4, dst, 8, dst); } else if (srcSize == 8 and dstSize == 8) { - Assembler::Register dstHigh(dst->high); + lir::Register dstHigh(dst->high); load(con, 4, base, 0, normalized, 1, 4, &dstHigh, preserveIndex, false); load(con, 4, base, 4, normalized, 1, 4, dst, preserveIndex, @@ -1369,7 +1358,7 @@ load(Context* con, unsigned srcSize, int base, int offset, int index, default: abort(con); } } else { // FPR load - Assembler::Register base_(base), + lir::Register base_(base), normalized_(normalized), absAddr = makeTemp(con); // VFP loads only have bases, so we must add the index @@ -1412,10 +1401,10 @@ load(Context* con, unsigned srcSize, int base, int offset, int index, case 8: { if (dstSize == 8) { - Assembler::Register dstHigh(dst->high); - load(con, 4, base, offset, NoRegister, 1, 4, &dstHigh, false, + lir::Register dstHigh(dst->high); + load(con, 4, base, offset, lir::NoRegister, 1, 4, &dstHigh, false, false); - load(con, 4, base, offset + 4, NoRegister, 1, 4, dst, false, + load(con, 4, base, offset + 4, lir::NoRegister, 1, 4, dst, false, false); } else { emit(con, ldri(dst->low, base, offset)); @@ -1431,9 +1420,9 @@ load(Context* con, unsigned srcSize, int base, int offset, int index, else emit(con, flds(fpr32(dst), base, offset)); } } else { - Assembler::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); ResolvedPromise offsetPromise(offset); - Assembler::Constant offsetConstant(&offsetPromise); + lir::Constant offsetConstant(&offsetPromise); moveCR(con, TargetBytesPerWord, &offsetConstant, TargetBytesPerWord, &tmp); @@ -1445,44 +1434,44 @@ load(Context* con, unsigned srcSize, int base, int offset, int index, } void -moveMR(Context* con, unsigned srcSize, Assembler::Memory* src, - unsigned dstSize, Assembler::Register* dst) +moveMR(Context* con, unsigned srcSize, lir::Memory* src, + unsigned dstSize, lir::Register* dst) { load(con, srcSize, src->base, src->offset, src->index, src->scale, dstSize, dst, true, true); } void -moveZMR(Context* con, unsigned srcSize, Assembler::Memory* src, - unsigned dstSize, Assembler::Register* dst) +moveZMR(Context* con, unsigned srcSize, lir::Memory* src, + unsigned dstSize, lir::Register* dst) { load(con, srcSize, src->base, src->offset, src->index, src->scale, dstSize, dst, true, false); } void -andR(Context* con, unsigned size, Assembler::Register* a, - Assembler::Register* b, Assembler::Register* dst) +andR(Context* con, unsigned size, lir::Register* a, + lir::Register* b, lir::Register* dst) { if (size == 8) emit(con, and_(dst->high, a->high, b->high)); emit(con, and_(dst->low, a->low, b->low)); } void -andC(Context* con, unsigned size, Assembler::Constant* a, - Assembler::Register* b, Assembler::Register* dst) +andC(Context* con, unsigned size, lir::Constant* a, + lir::Register* b, lir::Register* dst) { int64_t v = a->value->value(); if (size == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); - Assembler::Register dh(dst->high); + lir::Register bh(b->high); + lir::Register dh(dst->high); andC(con, 4, &al, b, dst); andC(con, 4, &ah, &bh, &dh); @@ -1498,7 +1487,7 @@ andC(Context* con, unsigned size, Assembler::Constant* a, // instruction bool useTemporary = b->low == dst->low; - Assembler::Register tmp(dst->low); + lir::Register tmp(dst->low); if (useTemporary) { tmp.low = con->client->acquireTemporary(GPR_MASK); } @@ -1517,44 +1506,44 @@ andC(Context* con, unsigned size, Assembler::Constant* a, } void -orR(Context* con, unsigned size, Assembler::Register* a, - Assembler::Register* b, Assembler::Register* dst) +orR(Context* con, unsigned size, lir::Register* a, + lir::Register* b, lir::Register* dst) { if (size == 8) emit(con, orr(dst->high, a->high, b->high)); emit(con, orr(dst->low, a->low, b->low)); } void -xorR(Context* con, unsigned size, Assembler::Register* a, - Assembler::Register* b, Assembler::Register* dst) +xorR(Context* con, unsigned size, lir::Register* a, + lir::Register* b, lir::Register* dst) { if (size == 8) emit(con, eor(dst->high, a->high, b->high)); emit(con, eor(dst->low, a->low, b->low)); } void -moveAR2(Context* con, unsigned srcSize, Assembler::Address* src, - unsigned dstSize, Assembler::Register* dst) +moveAR2(Context* con, unsigned srcSize, lir::Address* src, + unsigned dstSize, lir::Register* dst) { assert(con, srcSize == 4 and dstSize == 4); - Assembler::Constant constant(src->address); + lir::Constant constant(src->address); moveCR(con, srcSize, &constant, dstSize, dst); - Assembler::Memory memory(dst->low, 0, -1, 0); + lir::Memory memory(dst->low, 0, -1, 0); moveMR(con, dstSize, &memory, dstSize, dst); } void -moveAR(Context* con, unsigned srcSize, Assembler::Address* src, - unsigned dstSize, Assembler::Register* dst) +moveAR(Context* con, unsigned srcSize, lir::Address* src, + unsigned dstSize, lir::Register* dst) { moveAR2(con, srcSize, src, dstSize, dst); } void -compareRR(Context* con, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +compareRR(Context* con, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(con, !(isFpr(a) ^ isFpr(b))); // regs must be of the same type @@ -1571,8 +1560,8 @@ compareRR(Context* con, unsigned aSize, Assembler::Register* a, } void -compareCR(Context* con, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +compareCR(Context* con, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(con, aSize == 4 and bSize == 4); @@ -1580,7 +1569,7 @@ compareCR(Context* con, unsigned aSize, Assembler::Constant* a, isOfWidth(a->value->value(), 8)) { emit(con, cmpi(b->low, a->value->value())); } else { - Assembler::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); moveCR(con, aSize, a, bSize, &tmp); compareRR(con, bSize, &tmp, bSize, b); con->client->releaseTemporary(tmp.low); @@ -1588,63 +1577,63 @@ compareCR(Context* con, unsigned aSize, Assembler::Constant* a, } void -compareCM(Context* con, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Memory* b) +compareCM(Context* con, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Memory* b) { assert(con, aSize == 4 and bSize == 4); - Assembler::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); moveMR(con, bSize, b, bSize, &tmp); compareCR(con, aSize, a, bSize, &tmp); con->client->releaseTemporary(tmp.low); } void -compareRM(Context* con, unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Memory* b) +compareRM(Context* con, unsigned aSize, lir::Register* a, + unsigned bSize, lir::Memory* b) { assert(con, aSize == 4 and bSize == 4); - Assembler::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); moveMR(con, bSize, b, bSize, &tmp); compareRR(con, aSize, a, bSize, &tmp); con->client->releaseTemporary(tmp.low); } int32_t -branch(Context* con, TernaryOperation op) +branch(Context* con, lir::TernaryOperation op) { switch (op) { - case JumpIfEqual: - case JumpIfFloatEqual: + case lir::JumpIfEqual: + case lir::JumpIfFloatEqual: return beq(0); - case JumpIfNotEqual: - case JumpIfFloatNotEqual: + case lir::JumpIfNotEqual: + case lir::JumpIfFloatNotEqual: return bne(0); - case JumpIfLess: - case JumpIfFloatLess: - case JumpIfFloatLessOrUnordered: + case lir::JumpIfLess: + case lir::JumpIfFloatLess: + case lir::JumpIfFloatLessOrUnordered: return blt(0); - case JumpIfGreater: - case JumpIfFloatGreater: + case lir::JumpIfGreater: + case lir::JumpIfFloatGreater: return bgt(0); - case JumpIfLessOrEqual: - case JumpIfFloatLessOrEqual: - case JumpIfFloatLessOrEqualOrUnordered: + case lir::JumpIfLessOrEqual: + case lir::JumpIfFloatLessOrEqual: + case lir::JumpIfFloatLessOrEqualOrUnordered: return ble(0); - case JumpIfGreaterOrEqual: - case JumpIfFloatGreaterOrEqual: + case lir::JumpIfGreaterOrEqual: + case lir::JumpIfFloatGreaterOrEqual: return bge(0); - case JumpIfFloatGreaterOrUnordered: + case lir::JumpIfFloatGreaterOrUnordered: return bhi(0); - case JumpIfFloatGreaterOrEqualOrUnordered: + case lir::JumpIfFloatGreaterOrEqualOrUnordered: return bpl(0); default: @@ -1653,22 +1642,22 @@ branch(Context* con, TernaryOperation op) } void -conditional(Context* con, int32_t branch, Assembler::Constant* target) +conditional(Context* con, int32_t branch, lir::Constant* target) { appendOffsetTask(con, target->value, offset(con)); emit(con, branch); } void -branch(Context* con, TernaryOperation op, Assembler::Constant* target) +branch(Context* con, lir::TernaryOperation op, lir::Constant* target) { conditional(con, branch(con, op), target); } void -branchLong(Context* con, TernaryOperation op, Assembler::Operand* al, - Assembler::Operand* ah, Assembler::Operand* bl, - Assembler::Operand* bh, Assembler::Constant* target, +branchLong(Context* con, lir::TernaryOperation op, lir::Operand* al, + lir::Operand* ah, lir::Operand* bl, + lir::Operand* bh, lir::Constant* target, BinaryOperationType compareSigned, BinaryOperationType compareUnsigned) { @@ -1677,8 +1666,8 @@ branchLong(Context* con, TernaryOperation op, Assembler::Operand* al, unsigned next = 0; switch (op) { - case JumpIfEqual: - case JumpIfFloatEqual: + case lir::JumpIfEqual: + case lir::JumpIfFloatEqual: next = con->code.length(); emit(con, bne(0)); @@ -1686,16 +1675,16 @@ branchLong(Context* con, TernaryOperation op, Assembler::Operand* al, conditional(con, beq(0), target); break; - case JumpIfNotEqual: - case JumpIfFloatNotEqual: + case lir::JumpIfNotEqual: + case lir::JumpIfFloatNotEqual: conditional(con, bne(0), target); compareSigned(con, 4, al, 4, bl); conditional(con, bne(0), target); break; - case JumpIfLess: - case JumpIfFloatLess: + case lir::JumpIfLess: + case lir::JumpIfFloatLess: conditional(con, blt(0), target); next = con->code.length(); @@ -1705,8 +1694,8 @@ branchLong(Context* con, TernaryOperation op, Assembler::Operand* al, conditional(con, blo(0), target); break; - case JumpIfGreater: - case JumpIfFloatGreater: + case lir::JumpIfGreater: + case lir::JumpIfFloatGreater: conditional(con, bgt(0), target); next = con->code.length(); @@ -1716,8 +1705,8 @@ branchLong(Context* con, TernaryOperation op, Assembler::Operand* al, conditional(con, bhi(0), target); break; - case JumpIfLessOrEqual: - case JumpIfFloatLessOrEqual: + case lir::JumpIfLessOrEqual: + case lir::JumpIfFloatLessOrEqual: conditional(con, blt(0), target); next = con->code.length(); @@ -1727,8 +1716,8 @@ branchLong(Context* con, TernaryOperation op, Assembler::Operand* al, conditional(con, bls(0), target); break; - case JumpIfGreaterOrEqual: - case JumpIfFloatGreaterOrEqual: + case lir::JumpIfGreaterOrEqual: + case lir::JumpIfFloatGreaterOrEqual: conditional(con, bgt(0), target); next = con->code.length(); @@ -1750,13 +1739,13 @@ branchLong(Context* con, TernaryOperation op, Assembler::Operand* al, } void -branchRR(Context* con, TernaryOperation op, unsigned size, - Assembler::Register* a, Assembler::Register* b, - Assembler::Constant* target) +branchRR(Context* con, lir::TernaryOperation op, unsigned size, + lir::Register* a, lir::Register* b, + lir::Constant* target) { if (!isFpr(a) && size > TargetBytesPerWord) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register ah(a->high); + lir::Register bh(b->high); branchLong(con, op, a, &ah, b, &bh, target, CAST2(compareRR), CAST2(compareRR)); @@ -1767,9 +1756,9 @@ branchRR(Context* con, TernaryOperation op, unsigned size, } void -branchCR(Context* con, TernaryOperation op, unsigned size, - Assembler::Constant* a, Assembler::Register* b, - Assembler::Constant* target) +branchCR(Context* con, lir::TernaryOperation op, unsigned size, + lir::Constant* a, lir::Register* b, + lir::Constant* target) { assert(con, !isFloatBranch(op)); @@ -1777,12 +1766,12 @@ branchCR(Context* con, TernaryOperation op, unsigned size, int64_t v = a->value->value(); ResolvedPromise low(v & ~static_cast(0)); - Assembler::Constant al(&low); + lir::Constant al(&low); ResolvedPromise high((v >> 32) & ~static_cast(0)); - Assembler::Constant ah(&high); + lir::Constant ah(&high); - Assembler::Register bh(b->high); + lir::Register bh(b->high); branchLong(con, op, &al, &ah, b, &bh, target, CAST2(compareCR), CAST2(compareCR)); @@ -1793,9 +1782,9 @@ branchCR(Context* con, TernaryOperation op, unsigned size, } void -branchRM(Context* con, TernaryOperation op, unsigned size, - Assembler::Register* a, Assembler::Memory* b, - Assembler::Constant* target) +branchRM(Context* con, lir::TernaryOperation op, unsigned size, + lir::Register* a, lir::Memory* b, + lir::Constant* target) { assert(con, !isFloatBranch(op)); assert(con, size <= TargetBytesPerWord); @@ -1805,9 +1794,9 @@ branchRM(Context* con, TernaryOperation op, unsigned size, } void -branchCM(Context* con, TernaryOperation op, unsigned size, - Assembler::Constant* a, Assembler::Memory* b, - Assembler::Constant* target) +branchCM(Context* con, lir::TernaryOperation op, unsigned size, + lir::Constant* a, lir::Memory* b, + lir::Constant* target) { assert(con, !isFloatBranch(op)); assert(con, size <= TargetBytesPerWord); @@ -1823,17 +1812,17 @@ shiftMaskPromise(Context* con, Promise* base, unsigned shift, int64_t mask) } void -moveCM(Context* con, unsigned srcSize, Assembler::Constant* src, - unsigned dstSize, Assembler::Memory* dst) +moveCM(Context* con, unsigned srcSize, lir::Constant* src, + unsigned dstSize, lir::Memory* dst) { switch (dstSize) { case 8: { - Assembler::Constant srcHigh + lir::Constant srcHigh (shiftMaskPromise(con, src->value, 32, 0xFFFFFFFF)); - Assembler::Constant srcLow + lir::Constant srcLow (shiftMaskPromise(con, src->value, 0, 0xFFFFFFFF)); - Assembler::Memory dstLow + lir::Memory dstLow (dst->base, dst->offset + 4, dst->index, dst->scale); moveCM(con, 4, &srcLow, 4, &dstLow); @@ -1841,7 +1830,7 @@ moveCM(Context* con, unsigned srcSize, Assembler::Constant* src, } break; default: - Assembler::Register tmp(con->client->acquireTemporary(GPR_MASK)); + lir::Register tmp(con->client->acquireTemporary(GPR_MASK)); moveCR(con, srcSize, src, dstSize, &tmp); moveRM(con, dstSize, &tmp, dstSize, dst); con->client->releaseTemporary(tmp.low); @@ -1849,8 +1838,8 @@ moveCM(Context* con, unsigned srcSize, Assembler::Constant* src, } void -negateRR(Context* con, unsigned srcSize, Assembler::Register* src, - unsigned dstSize UNUSED, Assembler::Register* dst) +negateRR(Context* con, unsigned srcSize, lir::Register* src, + unsigned dstSize UNUSED, lir::Register* dst) { assert(con, srcSize == dstSize); @@ -1863,14 +1852,14 @@ negateRR(Context* con, unsigned srcSize, Assembler::Register* src, } void -callR(Context* con, unsigned size UNUSED, Assembler::Register* target) +callR(Context* con, unsigned size UNUSED, lir::Register* target) { assert(con, size == TargetBytesPerWord); emit(con, blx(target->low)); } void -callC(Context* con, unsigned size UNUSED, Assembler::Constant* target) +callC(Context* con, unsigned size UNUSED, lir::Constant* target) { assert(con, size == TargetBytesPerWord); @@ -1879,27 +1868,27 @@ callC(Context* con, unsigned size UNUSED, Assembler::Constant* target) } void -longCallC(Context* con, unsigned size UNUSED, Assembler::Constant* target) +longCallC(Context* con, unsigned size UNUSED, lir::Constant* target) { assert(con, size == TargetBytesPerWord); - Assembler::Register tmp(4); + lir::Register tmp(4); moveCR2(con, TargetBytesPerWord, target, &tmp, offset(con)); callR(con, TargetBytesPerWord, &tmp); } void -longJumpC(Context* con, unsigned size UNUSED, Assembler::Constant* target) +longJumpC(Context* con, unsigned size UNUSED, lir::Constant* target) { assert(con, size == TargetBytesPerWord); - Assembler::Register tmp(4); // a non-arg reg that we don't mind clobbering + lir::Register tmp(4); // a non-arg reg that we don't mind clobbering moveCR2(con, TargetBytesPerWord, target, &tmp, offset(con)); jumpR(con, TargetBytesPerWord, &tmp); } void -jumpC(Context* con, unsigned size UNUSED, Assembler::Constant* target) +jumpC(Context* con, unsigned size UNUSED, lir::Constant* target) { assert(con, size == TargetBytesPerWord); @@ -1991,10 +1980,10 @@ nextFrame(ArchitectureContext* con, uint32_t* start, unsigned size UNUSED, void populateTables(ArchitectureContext* con) { - const OperandType C = ConstantOperand; - const OperandType A = AddressOperand; - const OperandType R = RegisterOperand; - const OperandType M = MemoryOperand; + const lir::OperandType C = lir::ConstantOperand; + const lir::OperandType A = lir::AddressOperand; + const lir::OperandType R = lir::RegisterOperand; + const lir::OperandType M = lir::MemoryOperand; OperationType* zo = con->operations; UnaryOperationType* uo = con->unaryOperations; @@ -2002,78 +1991,78 @@ populateTables(ArchitectureContext* con) TernaryOperationType* to = con->ternaryOperations; BranchOperationType* bro = con->branchOperations; - zo[Return] = return_; - zo[LoadBarrier] = memoryBarrier; - zo[StoreStoreBarrier] = memoryBarrier; - zo[StoreLoadBarrier] = memoryBarrier; - zo[Trap] = trap; + zo[lir::Return] = return_; + zo[lir::LoadBarrier] = memoryBarrier; + zo[lir::StoreStoreBarrier] = memoryBarrier; + zo[lir::StoreLoadBarrier] = memoryBarrier; + zo[lir::Trap] = trap; - uo[index(con, LongCall, C)] = CAST1(longCallC); + uo[index(con, lir::LongCall, C)] = CAST1(longCallC); - uo[index(con, AlignedLongCall, C)] = CAST1(longCallC); + uo[index(con, lir::AlignedLongCall, C)] = CAST1(longCallC); - uo[index(con, LongJump, C)] = CAST1(longJumpC); + uo[index(con, lir::LongJump, C)] = CAST1(longJumpC); - uo[index(con, AlignedLongJump, C)] = CAST1(longJumpC); + uo[index(con, lir::AlignedLongJump, C)] = CAST1(longJumpC); - uo[index(con, Jump, R)] = CAST1(jumpR); - uo[index(con, Jump, C)] = CAST1(jumpC); + uo[index(con, lir::Jump, R)] = CAST1(jumpR); + uo[index(con, lir::Jump, C)] = CAST1(jumpC); - uo[index(con, AlignedJump, R)] = CAST1(jumpR); - uo[index(con, AlignedJump, C)] = CAST1(jumpC); + uo[index(con, lir::AlignedJump, R)] = CAST1(jumpR); + uo[index(con, lir::AlignedJump, C)] = CAST1(jumpC); - uo[index(con, Call, C)] = CAST1(callC); - uo[index(con, Call, R)] = CAST1(callR); + uo[index(con, lir::Call, C)] = CAST1(callC); + uo[index(con, lir::Call, R)] = CAST1(callR); - uo[index(con, AlignedCall, C)] = CAST1(callC); - uo[index(con, AlignedCall, R)] = CAST1(callR); + uo[index(con, lir::AlignedCall, C)] = CAST1(callC); + uo[index(con, lir::AlignedCall, R)] = CAST1(callR); - bo[index(con, Move, R, R)] = CAST2(moveRR); - bo[index(con, Move, C, R)] = CAST2(moveCR); - bo[index(con, Move, C, M)] = CAST2(moveCM); - bo[index(con, Move, M, R)] = CAST2(moveMR); - bo[index(con, Move, R, M)] = CAST2(moveRM); - bo[index(con, Move, A, R)] = CAST2(moveAR); + bo[index(con, lir::Move, R, R)] = CAST2(moveRR); + bo[index(con, lir::Move, C, R)] = CAST2(moveCR); + bo[index(con, lir::Move, C, M)] = CAST2(moveCM); + bo[index(con, lir::Move, M, R)] = CAST2(moveMR); + bo[index(con, lir::Move, R, M)] = CAST2(moveRM); + bo[index(con, lir::Move, A, R)] = CAST2(moveAR); - bo[index(con, MoveZ, R, R)] = CAST2(moveZRR); - bo[index(con, MoveZ, M, R)] = CAST2(moveZMR); - bo[index(con, MoveZ, C, R)] = CAST2(moveCR); + bo[index(con, lir::MoveZ, R, R)] = CAST2(moveZRR); + bo[index(con, lir::MoveZ, M, R)] = CAST2(moveZMR); + bo[index(con, lir::MoveZ, C, R)] = CAST2(moveCR); - bo[index(con, Negate, R, R)] = CAST2(negateRR); + bo[index(con, lir::Negate, R, R)] = CAST2(negateRR); - bo[index(con, FloatAbsolute, R, R)] = CAST2(floatAbsoluteRR); - bo[index(con, FloatNegate, R, R)] = CAST2(floatNegateRR); - bo[index(con, Float2Float, R, R)] = CAST2(float2FloatRR); - bo[index(con, Float2Int, R, R)] = CAST2(float2IntRR); - bo[index(con, Int2Float, R, R)] = CAST2(int2FloatRR); - bo[index(con, FloatSquareRoot, R, R)] = CAST2(floatSqrtRR); + bo[index(con, lir::FloatAbsolute, R, R)] = CAST2(floatAbsoluteRR); + bo[index(con, lir::FloatNegate, R, R)] = CAST2(floatNegateRR); + bo[index(con, lir::Float2Float, R, R)] = CAST2(float2FloatRR); + bo[index(con, lir::Float2Int, R, R)] = CAST2(float2IntRR); + bo[index(con, lir::Int2Float, R, R)] = CAST2(int2FloatRR); + bo[index(con, lir::FloatSquareRoot, R, R)] = CAST2(floatSqrtRR); - to[index(con, Add, R)] = CAST3(addR); + to[index(con, lir::Add, R)] = CAST3(addR); - to[index(con, Subtract, R)] = CAST3(subR); + to[index(con, lir::Subtract, R)] = CAST3(subR); - to[index(con, Multiply, R)] = CAST3(multiplyR); + to[index(con, lir::Multiply, R)] = CAST3(multiplyR); - to[index(con, FloatAdd, R)] = CAST3(floatAddR); - to[index(con, FloatSubtract, R)] = CAST3(floatSubtractR); - to[index(con, FloatMultiply, R)] = CAST3(floatMultiplyR); - to[index(con, FloatDivide, R)] = CAST3(floatDivideR); + to[index(con, lir::FloatAdd, R)] = CAST3(floatAddR); + to[index(con, lir::FloatSubtract, R)] = CAST3(floatSubtractR); + to[index(con, lir::FloatMultiply, R)] = CAST3(floatMultiplyR); + to[index(con, lir::FloatDivide, R)] = CAST3(floatDivideR); - to[index(con, ShiftLeft, R)] = CAST3(shiftLeftR); - to[index(con, ShiftLeft, C)] = CAST3(shiftLeftC); + to[index(con, lir::ShiftLeft, R)] = CAST3(shiftLeftR); + to[index(con, lir::ShiftLeft, C)] = CAST3(shiftLeftC); - to[index(con, ShiftRight, R)] = CAST3(shiftRightR); - to[index(con, ShiftRight, C)] = CAST3(shiftRightC); + to[index(con, lir::ShiftRight, R)] = CAST3(shiftRightR); + to[index(con, lir::ShiftRight, C)] = CAST3(shiftRightC); - to[index(con, UnsignedShiftRight, R)] = CAST3(unsignedShiftRightR); - to[index(con, UnsignedShiftRight, C)] = CAST3(unsignedShiftRightC); + to[index(con, lir::UnsignedShiftRight, R)] = CAST3(unsignedShiftRightR); + to[index(con, lir::UnsignedShiftRight, C)] = CAST3(unsignedShiftRightC); - to[index(con, And, R)] = CAST3(andR); - to[index(con, And, C)] = CAST3(andC); + to[index(con, lir::And, R)] = CAST3(andR); + to[index(con, lir::And, C)] = CAST3(andC); - to[index(con, Or, R)] = CAST3(orR); + to[index(con, lir::Or, R)] = CAST3(orR); - to[index(con, Xor, R)] = CAST3(xorR); + to[index(con, lir::Xor, R)] = CAST3(xorR); bro[branchIndex(con, R, R)] = CAST_BRANCH(branchRR); bro[branchIndex(con, C, R)] = CAST_BRANCH(branchCR); @@ -2198,23 +2187,23 @@ class MyArchitecture: public Assembler::Architecture { - reinterpret_cast(instruction))); } - virtual void updateCall(UnaryOperation op UNUSED, + virtual void updateCall(lir::UnaryOperation op UNUSED, void* returnAddress, void* newTarget) { switch (op) { - case Call: - case Jump: - case AlignedCall: - case AlignedJump: { + case lir::Call: + case lir::Jump: + case lir::AlignedCall: + case lir::AlignedJump: { updateOffset(con.s, static_cast(returnAddress) - 4, reinterpret_cast(newTarget)); } break; - case LongCall: - case LongJump: - case AlignedLongCall: - case AlignedLongJump: { + case lir::LongCall: + case lir::LongJump: + case lir::AlignedLongCall: + case lir::AlignedLongJump: { uint32_t* p = static_cast(returnAddress) - 2; *reinterpret_cast(p + (((*p & PoolOffsetMask) + 8) / 4)) = newTarget; @@ -2270,34 +2259,34 @@ class MyArchitecture: public Assembler::Architecture { return 0; } - virtual BinaryOperation hasBinaryIntrinsic(Thread*, object) { - return NoBinaryOperation; + virtual lir::BinaryOperation hasBinaryIntrinsic(Thread*, object) { + return lir::NoBinaryOperation; } - virtual TernaryOperation hasTernaryIntrinsic(Thread*, object) { - return NoTernaryOperation; + virtual lir::TernaryOperation hasTernaryIntrinsic(Thread*, object) { + return lir::NoTernaryOperation; } - virtual bool alwaysCondensed(BinaryOperation) { + virtual bool alwaysCondensed(lir::BinaryOperation) { return false; } - virtual bool alwaysCondensed(TernaryOperation) { + virtual bool alwaysCondensed(lir::TernaryOperation) { return false; } virtual void plan - (UnaryOperation, + (lir::UnaryOperation, unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask, bool* thunk) { - *aTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); *aRegisterMask = ~static_cast(0); *thunk = false; } virtual void planSource - (BinaryOperation op, + (lir::BinaryOperation op, unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask, unsigned bSize, bool* thunk) { @@ -2306,43 +2295,43 @@ class MyArchitecture: public Assembler::Architecture { *aRegisterMask = GPR_MASK64; switch (op) { - case Negate: - *aTypeMask = (1 << RegisterOperand); + case lir::Negate: + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = GPR_MASK64; break; - case Absolute: + case lir::Absolute: *thunk = true; break; - case FloatAbsolute: - case FloatSquareRoot: - case FloatNegate: - case Float2Float: + case lir::FloatAbsolute: + case lir::FloatSquareRoot: + case lir::FloatNegate: + case lir::Float2Float: if (vfpSupported()) { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = FPR_MASK64; } else { *thunk = true; } break; - case Float2Int: + case lir::Float2Int: // todo: Java requires different semantics than SSE for // converting floats to integers, we we need to either use // thunks or produce inline machine code which handles edge // cases properly. if (false && vfpSupported() && bSize == 4) { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = FPR_MASK64; } else { *thunk = true; } break; - case Int2Float: + case lir::Int2Float: if (vfpSupported() && aSize == 4) { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = GPR_MASK64; } else { *thunk = true; @@ -2355,36 +2344,36 @@ class MyArchitecture: public Assembler::Architecture { } virtual void planDestination - (BinaryOperation op, + (lir::BinaryOperation op, unsigned, uint8_t aTypeMask, uint64_t, unsigned , uint8_t* bTypeMask, uint64_t* bRegisterMask) { - *bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *bTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); *bRegisterMask = GPR_MASK64; switch (op) { - case Negate: - *bTypeMask = (1 << RegisterOperand); + case lir::Negate: + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = GPR_MASK64; break; - case FloatAbsolute: - case FloatSquareRoot: - case FloatNegate: - case Float2Float: - case Int2Float: - *bTypeMask = (1 << RegisterOperand); + case lir::FloatAbsolute: + case lir::FloatSquareRoot: + case lir::FloatNegate: + case lir::Float2Float: + case lir::Int2Float: + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = FPR_MASK64; break; - case Float2Int: - *bTypeMask = (1 << RegisterOperand); + case lir::Float2Int: + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = GPR_MASK64; break; - case Move: - if (!(aTypeMask & 1 << RegisterOperand)) { - *bTypeMask = 1 << RegisterOperand; + case lir::Move: + if (!(aTypeMask & 1 << lir::RegisterOperand)) { + *bTypeMask = 1 << lir::RegisterOperand; } break; @@ -2404,79 +2393,79 @@ class MyArchitecture: public Assembler::Architecture { *tmpTypeMask = 0; *tmpRegisterMask = 0; - if (dstTypeMask & (1 << MemoryOperand)) { + if (dstTypeMask & (1 << lir::MemoryOperand)) { // can't move directly from memory or constant to memory - *srcTypeMask = 1 << RegisterOperand; - *tmpTypeMask = 1 << RegisterOperand; + *srcTypeMask = 1 << lir::RegisterOperand; + *tmpTypeMask = 1 << lir::RegisterOperand; *tmpRegisterMask = GPR_MASK64; } else if (vfpSupported() && - dstTypeMask & 1 << RegisterOperand && + dstTypeMask & 1 << lir::RegisterOperand && dstRegisterMask & FPR_MASK) { - *srcTypeMask = *tmpTypeMask = 1 << RegisterOperand | - 1 << MemoryOperand; + *srcTypeMask = *tmpTypeMask = 1 << lir::RegisterOperand | + 1 << lir::MemoryOperand; *tmpRegisterMask = ~static_cast(0); } } virtual void planSource - (TernaryOperation op, + (lir::TernaryOperation op, unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask, unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask, unsigned, bool* thunk) { - *aTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); *aRegisterMask = GPR_MASK64; - *bTypeMask = (1 << RegisterOperand); + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = GPR_MASK64; *thunk = false; switch (op) { - case ShiftLeft: - case ShiftRight: - case UnsignedShiftRight: - if (bSize == 8) *aTypeMask = *bTypeMask = (1 << RegisterOperand); + case lir::ShiftLeft: + case lir::ShiftRight: + case lir::UnsignedShiftRight: + if (bSize == 8) *aTypeMask = *bTypeMask = (1 << lir::RegisterOperand); break; - case Add: - case Subtract: - case Or: - case Xor: - case Multiply: - *aTypeMask = *bTypeMask = (1 << RegisterOperand); + case lir::Add: + case lir::Subtract: + case lir::Or: + case lir::Xor: + case lir::Multiply: + *aTypeMask = *bTypeMask = (1 << lir::RegisterOperand); break; - case Divide: - case Remainder: - case FloatRemainder: + case lir::Divide: + case lir::Remainder: + case lir::FloatRemainder: *thunk = true; break; - case FloatAdd: - case FloatSubtract: - case FloatMultiply: - case FloatDivide: + case lir::FloatAdd: + case lir::FloatSubtract: + case lir::FloatMultiply: + case lir::FloatDivide: if (vfpSupported()) { - *aTypeMask = *bTypeMask = (1 << RegisterOperand); + *aTypeMask = *bTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = *bRegisterMask = FPR_MASK64; } else { *thunk = true; } break; - case JumpIfFloatEqual: - case JumpIfFloatNotEqual: - case JumpIfFloatLess: - case JumpIfFloatGreater: - case JumpIfFloatLessOrEqual: - case JumpIfFloatGreaterOrEqual: - case JumpIfFloatLessOrUnordered: - case JumpIfFloatGreaterOrUnordered: - case JumpIfFloatLessOrEqualOrUnordered: - case JumpIfFloatGreaterOrEqualOrUnordered: + case lir::JumpIfFloatEqual: + case lir::JumpIfFloatNotEqual: + case lir::JumpIfFloatLess: + case lir::JumpIfFloatGreater: + case lir::JumpIfFloatLessOrEqual: + case lir::JumpIfFloatGreaterOrEqual: + case lir::JumpIfFloatLessOrUnordered: + case lir::JumpIfFloatGreaterOrUnordered: + case lir::JumpIfFloatLessOrEqualOrUnordered: + case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (vfpSupported()) { - *aTypeMask = *bTypeMask = (1 << RegisterOperand); + *aTypeMask = *bTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = *bRegisterMask = FPR_MASK64; } else { *thunk = true; @@ -2489,16 +2478,16 @@ class MyArchitecture: public Assembler::Architecture { } virtual void planDestination - (TernaryOperation op, + (lir::TernaryOperation op, unsigned, uint8_t, uint64_t, unsigned, uint8_t, const uint64_t bRegisterMask, unsigned, uint8_t* cTypeMask, uint64_t* cRegisterMask) { if (isBranch(op)) { - *cTypeMask = (1 << ConstantOperand); + *cTypeMask = (1 << lir::ConstantOperand); *cRegisterMask = 0; } else { - *cTypeMask = (1 << RegisterOperand); + *cTypeMask = (1 << lir::RegisterOperand); *cRegisterMask = bRegisterMask; } } @@ -2537,28 +2526,28 @@ class MyAssembler: public Assembler { virtual void checkStackOverflow(uintptr_t handler, unsigned stackLimitOffsetFromThread) { - Register stack(StackRegister); - Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread); - Constant handlerConstant(new(con.zone) ResolvedPromise(handler)); - branchRM(&con, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, + lir::Register stack(StackRegister); + lir::Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread); + lir::Constant handlerConstant(new(con.zone) ResolvedPromise(handler)); + branchRM(&con, lir::JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, &handlerConstant); } virtual void saveFrame(unsigned stackOffset, unsigned ipOffset) { - Register link(LinkRegister); - Memory linkDst(ThreadRegister, ipOffset); + lir::Register link(LinkRegister); + lir::Memory linkDst(ThreadRegister, ipOffset); moveRM(&con, TargetBytesPerWord, &link, TargetBytesPerWord, &linkDst); - Register stack(StackRegister); - Memory stackDst(ThreadRegister, stackOffset); + lir::Register stack(StackRegister); + lir::Memory stackDst(ThreadRegister, stackOffset); moveRM(&con, TargetBytesPerWord, &stack, TargetBytesPerWord, &stackDst); } virtual void pushFrame(unsigned argumentCount, ...) { struct Argument { unsigned size; - OperandType type; - Operand* operand; + lir::OperandType type; + lir::Operand* operand; }; RUNTIME_ARRAY(Argument, arguments, argumentCount); @@ -2566,8 +2555,8 @@ class MyAssembler: public Assembler { unsigned footprint = 0; for (unsigned i = 0; i < argumentCount; ++i) { RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned); - RUNTIME_ARRAY_BODY(arguments)[i].type = static_cast(va_arg(a, int)); - RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, Operand*); + RUNTIME_ARRAY_BODY(arguments)[i].type = static_cast(va_arg(a, int)); + RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, lir::Operand*); footprint += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); } va_end(a); @@ -2577,24 +2566,27 @@ class MyAssembler: public Assembler { unsigned offset = 0; for (unsigned i = 0; i < argumentCount; ++i) { if (i < arch_->argumentRegisterCount()) { - Register dst(arch_->argumentRegister(i)); + lir::Register dst(arch_->argumentRegister(i)); - apply(Move, - RUNTIME_ARRAY_BODY(arguments)[i].size, - RUNTIME_ARRAY_BODY(arguments)[i].type, - RUNTIME_ARRAY_BODY(arguments)[i].operand, - pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), RegisterOperand, - &dst); + apply(lir::Move, + OperandInfo( + RUNTIME_ARRAY_BODY(arguments)[i].size, + RUNTIME_ARRAY_BODY(arguments)[i].type, + RUNTIME_ARRAY_BODY(arguments)[i].operand), + OperandInfo( + pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), lir::RegisterOperand, &dst)); offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); } else { - Memory dst(StackRegister, offset * TargetBytesPerWord); + lir::Memory dst(StackRegister, offset * TargetBytesPerWord); - apply(Move, - RUNTIME_ARRAY_BODY(arguments)[i].size, - RUNTIME_ARRAY_BODY(arguments)[i].type, - RUNTIME_ARRAY_BODY(arguments)[i].operand, - pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), MemoryOperand, &dst); + apply(lir::Move, + OperandInfo( + RUNTIME_ARRAY_BODY(arguments)[i].size, + RUNTIME_ARRAY_BODY(arguments)[i].type, + RUNTIME_ARRAY_BODY(arguments)[i].operand), + OperandInfo( + pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), lir::MemoryOperand, &dst)); offset += ceilingDivide(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); } @@ -2609,37 +2601,37 @@ class MyAssembler: public Assembler { // how to handle them: assert(&con, footprint < 256); - Register stack(StackRegister); + lir::Register stack(StackRegister); ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); - Constant footprintConstant(&footprintPromise); + lir::Constant footprintConstant(&footprintPromise); subC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); - Register returnAddress(LinkRegister); - Memory returnAddressDst + lir::Register returnAddress(LinkRegister); + lir::Memory returnAddressDst (StackRegister, (footprint - 1) * TargetBytesPerWord); moveRM(&con, TargetBytesPerWord, &returnAddress, TargetBytesPerWord, &returnAddressDst); } virtual void adjustFrame(unsigned difference) { - Register stack(StackRegister); + lir::Register stack(StackRegister); ResolvedPromise differencePromise(difference * TargetBytesPerWord); - Constant differenceConstant(&differencePromise); + lir::Constant differenceConstant(&differencePromise); subC(&con, TargetBytesPerWord, &differenceConstant, &stack, &stack); } virtual void popFrame(unsigned footprint) { footprint += FrameHeaderSize; - Register returnAddress(LinkRegister); - Memory returnAddressSrc + lir::Register returnAddress(LinkRegister); + lir::Memory returnAddressSrc (StackRegister, (footprint - 1) * TargetBytesPerWord); moveMR(&con, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, &returnAddress); - Register stack(StackRegister); + lir::Register stack(StackRegister); ResolvedPromise footprintPromise(footprint * TargetBytesPerWord); - Constant footprintConstant(&footprintPromise); + lir::Constant footprintConstant(&footprintPromise); addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); } @@ -2648,29 +2640,29 @@ class MyAssembler: public Assembler { int returnAddressSurrogate, int framePointerSurrogate UNUSED) { - assert(&con, framePointerSurrogate == NoRegister); + assert(&con, framePointerSurrogate == lir::NoRegister); if (TailCalls) { if (offset) { footprint += FrameHeaderSize; - Register link(LinkRegister); - Memory returnAddressSrc + lir::Register link(LinkRegister); + lir::Memory returnAddressSrc (StackRegister, (footprint - 1) * TargetBytesPerWord); moveMR(&con, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, &link); - Register stack(StackRegister); + lir::Register stack(StackRegister); ResolvedPromise footprintPromise ((footprint - offset) * TargetBytesPerWord); - Constant footprintConstant(&footprintPromise); + lir::Constant footprintConstant(&footprintPromise); addC(&con, TargetBytesPerWord, &footprintConstant, &stack, &stack); - if (returnAddressSurrogate != NoRegister) { + if (returnAddressSurrogate != lir::NoRegister) { assert(&con, offset > 0); - Register ras(returnAddressSurrogate); - Memory dst(StackRegister, (offset - 1) * TargetBytesPerWord); + lir::Register ras(returnAddressSurrogate); + lir::Memory dst(StackRegister, (offset - 1) * TargetBytesPerWord); moveRM(&con, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst); } } else { @@ -2693,9 +2685,9 @@ class MyAssembler: public Assembler { if (TailCalls and argumentFootprint > StackAlignmentInWords) { offset = argumentFootprint - StackAlignmentInWords; - Register stack(StackRegister); + lir::Register stack(StackRegister); ResolvedPromise adjustmentPromise(offset * TargetBytesPerWord); - Constant adjustment(&adjustmentPromise); + lir::Constant adjustment(&adjustmentPromise); addC(&con, TargetBytesPerWord, &adjustment, &stack, &stack); } else { offset = 0; @@ -2709,53 +2701,45 @@ class MyAssembler: public Assembler { { popFrame(frameFootprint); - Register stack(StackRegister); - Memory newStackSrc(ThreadRegister, stackOffsetFromThread); + lir::Register stack(StackRegister); + lir::Memory newStackSrc(ThreadRegister, stackOffsetFromThread); moveMR(&con, TargetBytesPerWord, &newStackSrc, TargetBytesPerWord, &stack); return_(&con); } - virtual void apply(Operation op) { + virtual void apply(lir::Operation op) { arch_->con.operations[op](&con); } - virtual void apply(UnaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand) + virtual void apply(lir::UnaryOperation op, OperandInfo a) { - arch_->con.unaryOperations[index(&(arch_->con), op, aType)] - (&con, aSize, aOperand); + arch_->con.unaryOperations[index(&(arch_->con), op, a.type)] + (&con, a.size, a.operand); } - virtual void apply(BinaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand, - unsigned bSize, OperandType bType, Operand* bOperand) + virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) { - arch_->con.binaryOperations[index(&(arch_->con), op, aType, bType)] - (&con, aSize, aOperand, bSize, bOperand); + arch_->con.binaryOperations[index(&(arch_->con), op, a.type, b.type)] + (&con, a.size, a.operand, b.size, b.operand); } - virtual void apply(TernaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand, - unsigned bSize, OperandType bType UNUSED, - Operand* bOperand, - unsigned cSize UNUSED, OperandType cType UNUSED, - Operand* cOperand) + virtual void apply(lir::TernaryOperation op, OperandInfo a, OperandInfo b, OperandInfo c) { if (isBranch(op)) { - assert(&con, aSize == bSize); - assert(&con, cSize == TargetBytesPerWord); - assert(&con, cType == ConstantOperand); + assert(&con, a.size == b.size); + assert(&con, c.size == TargetBytesPerWord); + assert(&con, c.type == lir::ConstantOperand); - arch_->con.branchOperations[branchIndex(&(arch_->con), aType, bType)] - (&con, op, aSize, aOperand, bOperand, cOperand); + arch_->con.branchOperations[branchIndex(&(arch_->con), a.type, b.type)] + (&con, op, a.size, a.operand, b.operand, c.operand); } else { - assert(&con, bSize == cSize); - assert(&con, bType == RegisterOperand); - assert(&con, cType == RegisterOperand); + assert(&con, b.size == c.size); + assert(&con, b.type == lir::RegisterOperand); + assert(&con, c.type == lir::RegisterOperand); - arch_->con.ternaryOperations[index(&(arch_->con), op, aType)] - (&con, bSize, aOperand, bOperand, cOperand); + arch_->con.ternaryOperations[index(&(arch_->con), op, a.type)] + (&con, b.size, a.operand, b.operand, c.operand); } } diff --git a/src/codegen/assembler.h b/src/codegen/assembler.h index fbe03b70ac..d6ef7dd262 100644 --- a/src/codegen/assembler.h +++ b/src/codegen/assembler.h @@ -8,13 +8,30 @@ There is NO WARRANTY for this software. See license.txt for details. */ -#ifndef ASSEMBLER_H -#define ASSEMBLER_H +#ifndef AVIAN_CODEGEN_ASSEMBLER_H +#define AVIAN_CODEGEN_ASSEMBLER_H #include "system.h" #include "zone.h" -namespace vm { +#include "codegen/lir.h" +#include "codegen/promise.h" + +namespace avian { +namespace codegen { + +class OperandInfo { +public: + const unsigned size; + const lir::OperandType type; + lir::Operand* const operand; + + inline OperandInfo(unsigned size, lir::OperandType type, lir::Operand* operand): + size(size), + type(type), + operand(operand) + { } +}; #ifdef AVIAN_TAILS const bool TailCalls = true; @@ -28,286 +45,8 @@ const bool UseFramePointer = true; const bool UseFramePointer = false; #endif -enum Operation { - Return, - LoadBarrier, - StoreStoreBarrier, - StoreLoadBarrier, - Trap -}; - -const unsigned OperationCount = Trap + 1; - -enum UnaryOperation { - Call, - LongCall, - AlignedLongCall, - AlignedCall, - Jump, - LongJump, - AlignedLongJump, - AlignedJump, - - NoUnaryOperation = -1 -}; - -const unsigned UnaryOperationCount = AlignedJump + 1; - -enum BinaryOperation { - Move, - MoveLow, - MoveHigh, - MoveZ, - Negate, - FloatNegate, - Float2Float, - Float2Int, - Int2Float, - FloatSquareRoot, - FloatAbsolute, - Absolute, - - NoBinaryOperation = -1 -}; - -const unsigned BinaryOperationCount = Absolute + 1; - -enum TernaryOperation { - Add, - Subtract, - Multiply, - Divide, - Remainder, - ShiftLeft, - ShiftRight, - UnsignedShiftRight, - And, - Or, - Xor, - FloatAdd, - FloatSubtract, - FloatMultiply, - FloatDivide, - FloatRemainder, - FloatMax, - FloatMin, - JumpIfLess, - JumpIfGreater, - JumpIfLessOrEqual, - JumpIfGreaterOrEqual, - JumpIfEqual, - JumpIfNotEqual, - JumpIfFloatEqual, - JumpIfFloatNotEqual, - JumpIfFloatLess, - JumpIfFloatGreater, - JumpIfFloatLessOrEqual, - JumpIfFloatGreaterOrEqual, - JumpIfFloatLessOrUnordered, - JumpIfFloatGreaterOrUnordered, - JumpIfFloatLessOrEqualOrUnordered, - JumpIfFloatGreaterOrEqualOrUnordered, - - NoTernaryOperation = -1 -}; - -const unsigned TernaryOperationCount -= JumpIfFloatGreaterOrEqualOrUnordered + 1; - -const unsigned NonBranchTernaryOperationCount = FloatMin + 1; -const unsigned BranchOperationCount -= JumpIfFloatGreaterOrEqualOrUnordered - FloatMin; - -enum OperandType { - ConstantOperand, - AddressOperand, - RegisterOperand, - MemoryOperand -}; - -enum ValueType { - ValueGeneral, - ValueFloat -}; - -const unsigned OperandTypeCount = MemoryOperand + 1; - -const int NoRegister = -1; - -class Promise { - public: - class Listener { - public: - virtual bool resolve(int64_t value, void** location) = 0; - - Listener* next; - }; - - virtual int64_t value() = 0; - virtual bool resolved() = 0; - virtual Listener* listen(unsigned) { return 0; } -}; - -class ResolvedPromise: public Promise { - public: - ResolvedPromise(int64_t value): value_(value) { } - - virtual int64_t value() { - return value_; - } - - virtual bool resolved() { - return true; - } - - int64_t value_; -}; - -class ShiftMaskPromise: public Promise { - public: - ShiftMaskPromise(Promise* base, unsigned shift, int64_t mask): - base(base), shift(shift), mask(mask) - { } - - virtual int64_t value() { - return (base->value() >> shift) & mask; - } - - virtual bool resolved() { - return base->resolved(); - } - - Promise* base; - unsigned shift; - int64_t mask; -}; - -class CombinedPromise: public Promise { - public: - CombinedPromise(Promise* low, Promise* high): - low(low), high(high) - { } - - virtual int64_t value() { - return low->value() | (high->value() << 32); - } - - virtual bool resolved() { - return low->resolved() and high->resolved(); - } - - Promise* low; - Promise* high; -}; - -class OffsetPromise: public Promise { - public: - OffsetPromise(Promise* base, int64_t offset): - base(base), offset(offset) - { } - - virtual int64_t value() { - return base->value() + offset; - } - - virtual bool resolved() { - return base->resolved(); - } - - Promise* base; - int64_t offset; -}; - -class ListenPromise: public Promise { - public: - ListenPromise(System* s, Allocator* allocator): - s(s), allocator(allocator), listener(0) - { } - - virtual int64_t value() { - abort(s); - } - - virtual bool resolved() { - return false; - } - - virtual Listener* listen(unsigned sizeInBytes) { - Listener* l = static_cast(allocator->allocate(sizeInBytes)); - l->next = listener; - listener = l; - return l; - } - - System* s; - Allocator* allocator; - Listener* listener; - Promise* promise; -}; - -class DelayedPromise: public ListenPromise { - public: - DelayedPromise(System* s, Allocator* allocator, Promise* basis, - DelayedPromise* next): - ListenPromise(s, allocator), basis(basis), next(next) - { } - - virtual int64_t value() { - abort(s); - } - - virtual bool resolved() { - return false; - } - - virtual Listener* listen(unsigned sizeInBytes) { - Listener* l = static_cast(allocator->allocate(sizeInBytes)); - l->next = listener; - listener = l; - return l; - } - - Promise* basis; - DelayedPromise* next; -}; - class Assembler { public: - class Operand { }; - - class Constant: public Operand { - public: - Constant(Promise* value): value(value) { } - - Promise* value; - }; - - class Address: public Operand { - public: - Address(Promise* address): address(address) { } - - Promise* address; - }; - - class Register: public Operand { - public: - Register(int low, int high = NoRegister): low(low), high(high) { } - - int low; - int high; - }; - - class Memory: public Operand { - public: - Memory(int base, int offset, int index = NoRegister, unsigned scale = 1): - base(base), offset(offset), index(index), scale(scale) - { } - - int base; - int offset; - int index; - unsigned scale; - }; class Client { public: @@ -342,8 +81,8 @@ class Assembler { virtual uintptr_t maximumImmediateJump() = 0; - virtual bool alwaysCondensed(BinaryOperation op) = 0; - virtual bool alwaysCondensed(TernaryOperation op) = 0; + virtual bool alwaysCondensed(lir::BinaryOperation op) = 0; + virtual bool alwaysCondensed(lir::TernaryOperation op) = 0; virtual bool reserved(int register_) = 0; @@ -360,7 +99,7 @@ class Assembler { virtual bool matchCall(void* returnAddress, void* target) = 0; - virtual void updateCall(UnaryOperation op, void* returnAddress, + virtual void updateCall(lir::UnaryOperation op, void* returnAddress, void* newTarget) = 0; virtual void setConstant(void* dst, uint64_t constant) = 0; @@ -379,17 +118,17 @@ class Assembler { virtual int framePointerOffset() = 0; virtual void plan - (UnaryOperation op, + (lir::UnaryOperation op, unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask, bool* thunk) = 0; virtual void planSource - (BinaryOperation op, + (lir::BinaryOperation op, unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask, unsigned bSize, bool* thunk) = 0; virtual void planDestination - (BinaryOperation op, + (lir::BinaryOperation op, unsigned aSize, uint8_t aTypeMask, uint64_t aRegisterMask, unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask) = 0; @@ -399,18 +138,18 @@ class Assembler { uint8_t dstTypeMask, uint64_t dstRegisterMask) = 0; virtual void planSource - (TernaryOperation op, + (lir::TernaryOperation op, unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask, unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask, unsigned cSize, bool* thunk) = 0; virtual void planDestination - (TernaryOperation op, + (lir::TernaryOperation op, unsigned aSize, uint8_t aTypeMask, uint64_t aRegisterMask, unsigned bSize, uint8_t bTypeMask, uint64_t bRegisterMask, unsigned cSize, uint8_t* cTypeMask, uint64_t* cRegisterMask) = 0; - virtual Assembler* makeAssembler(Allocator*, Zone*) = 0; + virtual Assembler* makeAssembler(vm::Allocator*, vm::Zone*) = 0; virtual void acquire() = 0; virtual void release() = 0; @@ -437,19 +176,10 @@ class Assembler { unsigned stackOffsetFromThread) = 0; - virtual void apply(Operation op) = 0; - - virtual void apply(UnaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand) = 0; - - virtual void apply(BinaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand, - unsigned bSize, OperandType bType, Operand* bOperand) = 0; - - virtual void apply(TernaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand, - unsigned bSize, OperandType bType, Operand* bOperand, - unsigned cSize, OperandType cType, Operand* cOperand) = 0; + virtual void apply(lir::Operation op) = 0; + virtual void apply(lir::UnaryOperation op, OperandInfo a) = 0; + virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) = 0; + virtual void apply(lir::TernaryOperation op, OperandInfo a, OperandInfo b, OperandInfo c) = 0; virtual void setDestination(uint8_t* dst) = 0; @@ -468,6 +198,7 @@ class Assembler { virtual void dispose() = 0; }; -} // namespace vm +} // namespace codegen +} // namespace avian -#endif//ASSEMBLER_H +#endif // AVIAN_CODEGEN_ASSEMBLER_H diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 90efb622b8..ae8e6dd269 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -15,6 +15,7 @@ #include "util/runtime-array.h" using namespace vm; +using namespace avian::codegen; namespace { @@ -64,16 +65,16 @@ class Snapshot; void NO_RETURN abort(Context*); void -apply(Context* c, UnaryOperation op, +apply(Context* c, lir::UnaryOperation op, unsigned s1Size, Site* s1Low, Site* s1High); void -apply(Context* c, BinaryOperation op, +apply(Context* c, lir::BinaryOperation op, unsigned s1Size, Site* s1Low, Site* s1High, unsigned s2Size, Site* s2Low, Site* s2High); void -apply(Context* c, TernaryOperation op, +apply(Context* c, lir::TernaryOperation op, unsigned s1Size, Site* s1Low, Site* s1High, unsigned s2Size, Site* s2Low, Site* s2High, unsigned s3Size, Site* s3Low, Site* s3High); @@ -130,9 +131,9 @@ class Site { virtual bool frozen(Context*) { return false; } - virtual OperandType type(Context*) = 0; + virtual lir::OperandType type(Context*) = 0; - virtual void asAssemblerOperand(Context*, Site*, Assembler::Operand*) = 0; + virtual void asAssemblerOperand(Context*, Site*, lir::Operand*) = 0; virtual Site* copy(Context*) = 0; @@ -320,7 +321,7 @@ intersect(const SiteMask& a, const SiteMask& b) class Value: public Compiler::Operand { public: - Value(Site* site, Site* target, ValueType type): + Value(Site* site, Site* target, lir::ValueType type): reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this), nextWord(this), home(NoFrameIndex), type(type), wordIndex(0) { } @@ -333,7 +334,7 @@ class Value: public Compiler::Operand { Value* buddy; Value* nextWord; int16_t home; - ValueType type; + lir::ValueType type; uint8_t wordIndex; }; @@ -1279,16 +1280,16 @@ class Target { Target(): cost(Impossible) { } - Target(int index, OperandType type, unsigned cost): + Target(int index, lir::OperandType type, unsigned cost): index(index), type(type), cost(cost) { } int16_t index; - OperandType type; + lir::OperandType type; uint8_t cost; }; -ValueType +lir::ValueType valueType(Context* c, Compiler::OperandType type) { switch (type) { @@ -1296,9 +1297,9 @@ valueType(Context* c, Compiler::OperandType type) case Compiler::AddressType: case Compiler::IntegerType: case Compiler::VoidType: - return ValueGeneral; + return lir::ValueGeneral; case Compiler::FloatType: - return ValueFloat; + return lir::ValueFloat; default: abort(c); } @@ -1344,7 +1345,7 @@ pickRegisterTarget(Context* c, int i, Value* v, uint32_t mask, int* target, if ((1 << i) & mask) { RegisterResource* r = c->registerResources + i; unsigned myCost = resourceCost - (c, v, r, 1 << RegisterOperand, 1 << i, NoFrameIndex, costCalculator) + (c, v, r, 1 << lir::RegisterOperand, 1 << i, NoFrameIndex, costCalculator) + Target::MinimumRegisterCost; if ((static_cast(1) << i) == mask) { @@ -1362,7 +1363,7 @@ int pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost, CostCalculator* costCalculator = 0) { - int target = NoRegister; + int target = lir::NoRegister; *cost = Target::Impossible; if (mask & c->arch->generalRegisterMask()) { @@ -1394,14 +1395,14 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask, { unsigned cost; int number = pickRegisterTarget(c, v, mask, &cost, costCalculator); - return Target(number, RegisterOperand, cost); + return Target(number, lir::RegisterOperand, cost); } unsigned frameCost(Context* c, Value* v, int frameIndex, CostCalculator* costCalculator) { return resourceCost - (c, v, c->frameResources + frameIndex, 1 << MemoryOperand, 0, frameIndex, + (c, v, c->frameResources + frameIndex, 1 << lir::MemoryOperand, 0, frameIndex, costCalculator) + Target::MinimumFrameCost; } @@ -1415,7 +1416,7 @@ pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator) do { if (p->home >= 0) { Target mine - (p->home, MemoryOperand, frameCost(c, v, p->home, costCalculator)); + (p->home, lir::MemoryOperand, frameCost(c, v, p->home, costCalculator)); if (mine.cost == Target::MinimumFrameCost) { return mine; @@ -1436,7 +1437,7 @@ pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator) unsigned count = totalFrameSize(c); for (unsigned i = 0; i < count; ++i) { - Target mine(i, MemoryOperand, frameCost(c, v, i, costCalculator)); + Target mine(i, lir::MemoryOperand, frameCost(c, v, i, costCalculator)); if (mine.cost == Target::MinimumFrameCost) { return mine; } else if (mine.cost < best.cost) { @@ -1452,7 +1453,7 @@ pickTarget(Context* c, Value* value, const SiteMask& mask, unsigned registerPenalty, Target best, CostCalculator* costCalculator) { - if (mask.typeMask & (1 << RegisterOperand)) { + if (mask.typeMask & (1 << lir::RegisterOperand)) { Target mine = pickRegisterTarget (c, value, mask.registerMask, costCalculator); @@ -1464,9 +1465,9 @@ pickTarget(Context* c, Value* value, const SiteMask& mask, } } - if (mask.typeMask & (1 << MemoryOperand)) { + if (mask.typeMask & (1 << lir::MemoryOperand)) { if (mask.frameIndex >= 0) { - Target mine(mask.frameIndex, MemoryOperand, + Target mine(mask.frameIndex, lir::MemoryOperand, frameCost(c, value, mask.frameIndex, costCalculator)); if (mine.cost == Target::MinimumFrameCost) { return mine; @@ -1497,12 +1498,12 @@ pickTarget(Context* c, Read* read, bool intersectRead, Value* value = read->value; uint32_t registerMask - = (value->type == ValueFloat ? ~0 : c->arch->generalRegisterMask()); + = (value->type == lir::ValueFloat ? ~0 : c->arch->generalRegisterMask()); SiteMask mask(~0, registerMask, AnyFrameIndex); read->intersect(&mask); - if (value->type == ValueFloat) { + if (value->type == lir::ValueFloat) { uint32_t floatMask = mask.registerMask & c->arch->floatRegisterMask(); if (floatMask) { mask.registerMask = floatMask; @@ -1616,7 +1617,7 @@ class ConstantSite: public Site { } virtual bool match(Context*, const SiteMask& mask) { - return mask.typeMask & (1 << ConstantOperand); + return mask.typeMask & (1 << lir::ConstantOperand); } virtual bool loneMatch(Context*, const SiteMask&) { @@ -1624,21 +1625,21 @@ class ConstantSite: public Site { } virtual bool matchNextWord(Context* c, Site* s, unsigned) { - return s->type(c) == ConstantOperand; + return s->type(c) == lir::ConstantOperand; } - virtual OperandType type(Context*) { - return ConstantOperand; + virtual lir::OperandType type(Context*) { + return lir::ConstantOperand; } virtual void asAssemblerOperand(Context* c, Site* high, - Assembler::Operand* result) + lir::Operand* result) { Promise* v = value; if (high != this) { v = combinedPromise(c, value, static_cast(high)->value); } - new (result) Assembler::Constant(v); + new (result) lir::Constant(v); } virtual Site* copy(Context* c) { @@ -1658,11 +1659,11 @@ class ConstantSite: public Site { } virtual SiteMask mask(Context*) { - return SiteMask(1 << ConstantOperand, 0, NoFrameIndex); + return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); } virtual SiteMask nextWordMask(Context*, unsigned) { - return SiteMask(1 << ConstantOperand, 0, NoFrameIndex); + return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); } Promise* value; @@ -1707,7 +1708,7 @@ class AddressSite: public Site { } virtual bool match(Context*, const SiteMask& mask) { - return mask.typeMask & (1 << AddressOperand); + return mask.typeMask & (1 << lir::AddressOperand); } virtual bool loneMatch(Context*, const SiteMask&) { @@ -1718,16 +1719,16 @@ class AddressSite: public Site { abort(c); } - virtual OperandType type(Context*) { - return AddressOperand; + virtual lir::OperandType type(Context*) { + return lir::AddressOperand; } virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, - Assembler::Operand* result) + lir::Operand* result) { assert(c, high == this); - new (result) Assembler::Address(address); + new (result) lir::Address(address); } virtual Site* copy(Context* c) { @@ -1747,7 +1748,7 @@ class AddressSite: public Site { } virtual SiteMask mask(Context*) { - return SiteMask(1 << AddressOperand, 0, NoFrameIndex); + return SiteMask(1 << lir::AddressOperand, 0, NoFrameIndex); } virtual SiteMask nextWordMask(Context* c, unsigned) { @@ -1773,7 +1774,7 @@ class RegisterSite: public Site { { } virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { - if (number != NoRegister) { + if (number != lir::NoRegister) { return vm::snprintf(buffer, bufferSize, "%p register %d", this, number); } else { return vm::snprintf(buffer, bufferSize, @@ -1782,11 +1783,11 @@ class RegisterSite: public Site { } virtual unsigned copyCost(Context* c, Site* s) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); if (s and (this == s or - (s->type(c) == RegisterOperand + (s->type(c) == lir::RegisterOperand and (static_cast(s)->mask_ & (1 << number))))) { return 0; @@ -1796,9 +1797,9 @@ class RegisterSite: public Site { } virtual bool match(Context* c UNUSED, const SiteMask& mask) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); - if ((mask.typeMask & (1 << RegisterOperand))) { + if ((mask.typeMask & (1 << lir::RegisterOperand))) { return ((static_cast(1) << number) & mask.registerMask); } else { return false; @@ -1806,9 +1807,9 @@ class RegisterSite: public Site { } virtual bool loneMatch(Context* c UNUSED, const SiteMask& mask) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); - if ((mask.typeMask & (1 << RegisterOperand))) { + if ((mask.typeMask & (1 << lir::RegisterOperand))) { return ((static_cast(1) << number) == mask.registerMask); } else { return false; @@ -1816,16 +1817,16 @@ class RegisterSite: public Site { } virtual bool matchNextWord(Context* c, Site* s, unsigned) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); - if (s->type(c) != RegisterOperand) { + if (s->type(c) != lir::RegisterOperand) { return false; } RegisterSite* rs = static_cast(s); unsigned size = rs->registerSize(c); if (size > TargetBytesPerWord) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); return number == rs->number; } else { uint32_t mask = c->arch->generalRegisterMask(); @@ -1835,8 +1836,8 @@ class RegisterSite: public Site { virtual void acquire(Context* c, Value* v) { Target target; - if (number != NoRegister) { - target = Target(number, RegisterOperand, 0); + if (number != lir::NoRegister) { + target = Target(number, lir::RegisterOperand, 0); } else { target = pickRegisterTarget(c, v, mask_); expect(c, target.cost < Target::Impossible); @@ -1849,53 +1850,53 @@ class RegisterSite: public Site { } virtual void release(Context* c, Value* v) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); local::release(c, c->registerResources + number, v, this); } virtual void freeze(Context* c, Value* v) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); c->registerResources[number].freeze(c, v); } virtual void thaw(Context* c, Value* v) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); c->registerResources[number].thaw(c, v); } virtual bool frozen(Context* c UNUSED) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); return c->registerResources[number].freezeCount != 0; } - virtual OperandType type(Context*) { - return RegisterOperand; + virtual lir::OperandType type(Context*) { + return lir::RegisterOperand; } virtual void asAssemblerOperand(Context* c UNUSED, Site* high, - Assembler::Operand* result) + lir::Operand* result) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); int highNumber; if (high != this) { highNumber = static_cast(high)->number; - assert(c, highNumber != NoRegister); + assert(c, highNumber != lir::NoRegister); } else { - highNumber = NoRegister; + highNumber = lir::NoRegister; } - new (result) Assembler::Register(number, highNumber); + new (result) lir::Register(number, highNumber); } virtual Site* copy(Context* c) { uint32_t mask; - if (number != NoRegister) { + if (number != lir::NoRegister) { mask = 1 << number; } else { mask = mask_; @@ -1913,30 +1914,30 @@ class RegisterSite: public Site { } virtual Site* makeNextWord(Context* c, unsigned) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); assert(c, ((1 << number) & c->arch->generalRegisterMask())); return freeRegisterSite(c, c->arch->generalRegisterMask()); } virtual SiteMask mask(Context* c UNUSED) { - return SiteMask(1 << RegisterOperand, mask_, NoFrameIndex); + return SiteMask(1 << lir::RegisterOperand, mask_, NoFrameIndex); } virtual SiteMask nextWordMask(Context* c, unsigned) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); if (registerSize(c) > TargetBytesPerWord) { return SiteMask - (1 << RegisterOperand, number, NoFrameIndex); + (1 << lir::RegisterOperand, number, NoFrameIndex); } else { return SiteMask - (1 << RegisterOperand, c->arch->generalRegisterMask(), NoFrameIndex); + (1 << lir::RegisterOperand, c->arch->generalRegisterMask(), NoFrameIndex); } } virtual unsigned registerSize(Context* c) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); if ((1 << number) & c->arch->floatRegisterMask()) { return c->arch->floatRegisterSize(); @@ -1946,7 +1947,7 @@ class RegisterSite: public Site { } virtual unsigned registerMask(Context* c UNUSED) { - assert(c, number != NoRegister); + assert(c, number != lir::NoRegister); return 1 << number; } @@ -1968,11 +1969,11 @@ registerSite(Context* c, int number) RegisterSite* freeRegisterSite(Context* c, uint32_t mask) { - return new(c->zone) RegisterSite(mask, NoRegister); + return new(c->zone) RegisterSite(mask, lir::NoRegister); } MemorySite* -memorySite(Context* c, int base, int offset = 0, int index = NoRegister, +memorySite(Context* c, int base, int offset = 0, int index = lir::NoRegister, unsigned scale = 1); class MemorySite: public Site { @@ -1995,7 +1996,7 @@ class MemorySite: public Site { if (s and (this == s or - (s->type(c) == MemoryOperand + (s->type(c) == lir::MemoryOperand and static_cast(s)->base == base and static_cast(s)->offset == offset and static_cast(s)->index == index @@ -2008,19 +2009,19 @@ class MemorySite: public Site { } bool conflicts(const SiteMask& mask) { - return (mask.typeMask & (1 << RegisterOperand)) != 0 + return (mask.typeMask & (1 << lir::RegisterOperand)) != 0 and (((1 << base) & mask.registerMask) == 0 - or (index != NoRegister + or (index != lir::NoRegister and ((1 << index) & mask.registerMask) == 0)); } virtual bool match(Context* c, const SiteMask& mask) { assert(c, acquired); - if (mask.typeMask & (1 << MemoryOperand)) { + if (mask.typeMask & (1 << lir::MemoryOperand)) { if (mask.frameIndex >= 0) { if (base == c->arch->stack()) { - assert(c, index == NoRegister); + assert(c, index == lir::NoRegister); return static_cast(frameIndexToOffset(c, mask.frameIndex)) == offset; } else { @@ -2037,9 +2038,9 @@ class MemorySite: public Site { virtual bool loneMatch(Context* c, const SiteMask& mask) { assert(c, acquired); - if (mask.typeMask & (1 << MemoryOperand)) { + if (mask.typeMask & (1 << lir::MemoryOperand)) { if (base == c->arch->stack()) { - assert(c, index == NoRegister); + assert(c, index == lir::NoRegister); if (mask.frameIndex == AnyFrameIndex) { return false; @@ -2052,7 +2053,7 @@ class MemorySite: public Site { } virtual bool matchNextWord(Context* c, Site* s, unsigned index) { - if (s->type(c) == MemoryOperand) { + if (s->type(c) == lir::MemoryOperand) { MemorySite* ms = static_cast(s); return ms->base == this->base and ((index == 1 and ms->offset == static_cast @@ -2068,12 +2069,12 @@ class MemorySite: public Site { virtual void acquire(Context* c, Value* v) { increment(c, c->registerResources + base); - if (index != NoRegister) { + if (index != lir::NoRegister) { increment(c, c->registerResources + index); } if (base == c->arch->stack()) { - assert(c, index == NoRegister); + assert(c, index == lir::NoRegister); assert (c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); @@ -2086,7 +2087,7 @@ class MemorySite: public Site { virtual void release(Context* c, Value* v) { if (base == c->arch->stack()) { - assert(c, index == NoRegister); + assert(c, index == lir::NoRegister); assert (c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); @@ -2095,7 +2096,7 @@ class MemorySite: public Site { } decrement(c, c->registerResources + base); - if (index != NoRegister) { + if (index != lir::NoRegister) { decrement(c, c->registerResources + index); } @@ -2107,7 +2108,7 @@ class MemorySite: public Site { c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v); } else { increment(c, c->registerResources + base); - if (index != NoRegister) { + if (index != lir::NoRegister) { increment(c, c->registerResources + index); } } @@ -2118,7 +2119,7 @@ class MemorySite: public Site { c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v); } else { decrement(c, c->registerResources + base); - if (index != NoRegister) { + if (index != lir::NoRegister) { decrement(c, c->registerResources + index); } } @@ -2129,12 +2130,12 @@ class MemorySite: public Site { and c->frameResources[offsetToFrameIndex(c, offset)].freezeCount != 0; } - virtual OperandType type(Context*) { - return MemoryOperand; + virtual lir::OperandType type(Context*) { + return lir::MemoryOperand; } virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, - Assembler::Operand* result) + lir::Operand* result) { // todo: endianness? assert(c, high == this @@ -2146,7 +2147,7 @@ class MemorySite: public Site { assert(c, acquired); - new (result) Assembler::Memory(base, offset, index, scale); + new (result) lir::Memory(base, offset, index, scale); } virtual Site* copy(Context* c) { @@ -2177,7 +2178,7 @@ class MemorySite: public Site { } virtual SiteMask mask(Context* c) { - return SiteMask(1 << MemoryOperand, 0, (base == c->arch->stack()) + return SiteMask(1 << lir::MemoryOperand, 0, (base == c->arch->stack()) ? static_cast(offsetToFrameIndex(c, offset)) : NoFrameIndex); } @@ -2185,13 +2186,13 @@ class MemorySite: public Site { virtual SiteMask nextWordMask(Context* c, unsigned index) { int frameIndex; if (base == c->arch->stack()) { - assert(c, this->index == NoRegister); + assert(c, this->index == lir::NoRegister); frameIndex = static_cast(offsetToFrameIndex(c, offset)) + ((index == 1) xor c->arch->bigEndian() ? 1 : -1); } else { frameIndex = NoFrameIndex; } - return SiteMask(1 << MemoryOperand, 0, frameIndex); + return SiteMask(1 << lir::MemoryOperand, 0, frameIndex); } virtual bool isVolatile(Context* c) { @@ -2216,7 +2217,7 @@ frameSite(Context* c, int frameIndex) { assert(c, frameIndex >= 0); return memorySite - (c, c->arch->stack(), frameIndexToOffset(c, frameIndex), NoRegister, 0); + (c, c->arch->stack(), frameIndexToOffset(c, frameIndex), lir::NoRegister, 0); } void @@ -2278,7 +2279,7 @@ pickTargetSite(Context* c, Read* read, bool intersectRead = false, expect(c, target.cost < Target::Impossible); - if (target.type == MemoryOperand) { + if (target.type == lir::MemoryOperand) { return frameSite(c, target.index); } else { return registerSite(c, target.index); @@ -2327,7 +2328,7 @@ class SingleRead: public Read { SingleRead* read(Context* c, const SiteMask& mask, Value* successor = 0) { - assert(c, (mask.typeMask != 1 << MemoryOperand) or mask.frameIndex >= 0); + assert(c, (mask.typeMask != 1 << lir::MemoryOperand) or mask.frameIndex >= 0); return new(c->zone) SingleRead(mask, successor); } @@ -2630,21 +2631,21 @@ SiteMask generalRegisterMask(Context* c) { return SiteMask - (1 << RegisterOperand, c->arch->generalRegisterMask(), NoFrameIndex); + (1 << lir::RegisterOperand, c->arch->generalRegisterMask(), NoFrameIndex); } SiteMask generalRegisterOrConstantMask(Context* c) { return SiteMask - ((1 << RegisterOperand) | (1 << ConstantOperand), + ((1 << lir::RegisterOperand) | (1 << lir::ConstantOperand), c->arch->generalRegisterMask(), NoFrameIndex); } SiteMask fixedRegisterMask(int number) { - return SiteMask(1 << RegisterOperand, 1 << number, NoFrameIndex); + return SiteMask(1 << lir::RegisterOperand, 1 << number, NoFrameIndex); } class MultiRead: public Read { @@ -2884,10 +2885,10 @@ bool acceptForResolve(Context* c, Site* s, Read* read, const SiteMask& mask) { if (acceptMatch(c, s, read, mask) and (not s->frozen(c))) { - if (s->type(c) == RegisterOperand) { + if (s->type(c) == lir::RegisterOperand) { return c->availableGeneralRegisterCount > ResolveRegisterReserveCount; } else { - assert(c, s->match(c, SiteMask(1 << MemoryOperand, 0, AnyFrameIndex))); + assert(c, s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex))); return isHome(read->value, offsetToFrameIndex (c, static_cast(s)->offset)); @@ -2923,19 +2924,19 @@ move(Context* c, Value* value, Site* src, Site* dst) } if (srcSize == dstSize) { - apply(c, Move, srcSize, src, src, dstSize, dst, dst); + apply(c, lir::Move, srcSize, src, src, dstSize, dst, dst); } else if (srcSize > TargetBytesPerWord) { Site* low, *high, *other = pickSiteOrGrow(c, value, dst, &low, &high); other->freeze(c, value->nextWord); - apply(c, Move, srcSize, src, src, srcSize, low, high); + apply(c, lir::Move, srcSize, src, src, srcSize, low, high); other->thaw(c, value->nextWord); } else { Site* low, *high, *other = pickSiteOrMove(c, value, src, &low, &high); other->freeze(c, value->nextWord); - apply(c, Move, dstSize, low, high, dstSize, dst, dst); + apply(c, lir::Move, dstSize, low, high, dstSize, dst, dst); other->thaw(c, value->nextWord); } @@ -2946,12 +2947,12 @@ move(Context* c, Value* value, Site* src, Site* dst) void asAssemblerOperand(Context* c, Site* low, Site* high, - Assembler::Operand* result) + lir::Operand* result) { low->asAssemblerOperand(c, high, result); } -class OperandUnion: public Assembler::Operand { +class OperandUnion: public lir::Operand { // must be large enough and aligned properly to hold any operand // type (we'd use an actual union type here, except that classes // with constructors cannot be used in a union): @@ -2959,37 +2960,39 @@ class OperandUnion: public Assembler::Operand { }; void -apply(Context* c, UnaryOperation op, +apply(Context* c, lir::UnaryOperation op, unsigned s1Size, Site* s1Low, Site* s1High) { assert(c, s1Low->type(c) == s1High->type(c)); - OperandType s1Type = s1Low->type(c); + lir::OperandType s1Type = s1Low->type(c); OperandUnion s1Union; asAssemblerOperand(c, s1Low, s1High, &s1Union); - c->assembler->apply(op, s1Size, s1Type, &s1Union); + c->assembler->apply(op, + OperandInfo(s1Size, s1Type, &s1Union)); } void -apply(Context* c, BinaryOperation op, +apply(Context* c, lir::BinaryOperation op, unsigned s1Size, Site* s1Low, Site* s1High, unsigned s2Size, Site* s2Low, Site* s2High) { assert(c, s1Low->type(c) == s1High->type(c)); assert(c, s2Low->type(c) == s2High->type(c)); - OperandType s1Type = s1Low->type(c); + lir::OperandType s1Type = s1Low->type(c); OperandUnion s1Union; asAssemblerOperand(c, s1Low, s1High, &s1Union); - OperandType s2Type = s2Low->type(c); + lir::OperandType s2Type = s2Low->type(c); OperandUnion s2Union; asAssemblerOperand(c, s2Low, s2High, &s2Union); - c->assembler->apply(op, s1Size, s1Type, &s1Union, - s2Size, s2Type, &s2Union); + c->assembler->apply(op, + OperandInfo(s1Size, s1Type, &s1Union), + OperandInfo(s2Size, s2Type, &s2Union)); } void -apply(Context* c, TernaryOperation op, +apply(Context* c, lir::TernaryOperation op, unsigned s1Size, Site* s1Low, Site* s1High, unsigned s2Size, Site* s2Low, Site* s2High, unsigned s3Size, Site* s3Low, Site* s3High) @@ -2998,18 +3001,19 @@ apply(Context* c, TernaryOperation op, assert(c, s2Low->type(c) == s2High->type(c)); assert(c, s3Low->type(c) == s3High->type(c)); - OperandType s1Type = s1Low->type(c); + lir::OperandType s1Type = s1Low->type(c); OperandUnion s1Union; asAssemblerOperand(c, s1Low, s1High, &s1Union); - OperandType s2Type = s2Low->type(c); + lir::OperandType s2Type = s2Low->type(c); OperandUnion s2Union; asAssemblerOperand(c, s2Low, s2High, &s2Union); - OperandType s3Type = s3Low->type(c); + lir::OperandType s3Type = s3Low->type(c); OperandUnion s3Union; asAssemblerOperand(c, s3Low, s3High, &s3Union); - c->assembler->apply(op, s1Size, s1Type, &s1Union, - s2Size, s2Type, &s2Union, - s3Size, s3Type, &s3Union); + c->assembler->apply(op, + OperandInfo(s1Size, s1Type, &s1Union), + OperandInfo(s2Size, s2Type, &s2Union), + OperandInfo(s3Size, s3Type, &s3Union)); } void @@ -3072,13 +3076,13 @@ clean(Context* c, Value* v, unsigned popIndex) { for (SiteIterator it(c, v); it.hasMore();) { Site* s = it.next(); - if (not (s->match(c, SiteMask(1 << MemoryOperand, 0, AnyFrameIndex)) + if (not (s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex)) and offsetToFrameIndex (c, static_cast(s)->offset) >= popIndex)) { if (false and - s->match(c, SiteMask(1 << MemoryOperand, 0, AnyFrameIndex))) + s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex))) { char buffer[256]; s->toString(c, buffer, 256); fprintf(stderr, "remove %s from %p at %d pop offset 0x%x\n", @@ -3132,7 +3136,7 @@ saveLocals(Context* c, Event* e) } addRead(c, e, local->value, SiteMask - (1 << MemoryOperand, 0, local::frameIndex(c, li))); + (1 << lir::MemoryOperand, 0, local::frameIndex(c, li))); } } } @@ -3198,7 +3202,7 @@ class CallEvent: public Event { fprintf(stderr, "stack %d arg read %p\n", frameIndex, s->value); } - targetMask = SiteMask(1 << MemoryOperand, 0, frameIndex); + targetMask = SiteMask(1 << lir::MemoryOperand, 0, frameIndex); } addRead(c, this, s->value, targetMask); @@ -3221,7 +3225,7 @@ class CallEvent: public Event { uint8_t typeMask; uint64_t planRegisterMask; c->arch->plan - ((flags & Compiler::Aligned) ? AlignedCall : Call, TargetBytesPerWord, + ((flags & Compiler::Aligned) ? lir::AlignedCall : lir::Call, TargetBytesPerWord, &typeMask, &planRegisterMask, &thunk); assert(c, not thunk); @@ -3290,7 +3294,7 @@ class CallEvent: public Event { framePointerSurrogate = v; addRead(c, this, v, generalRegisterMask(c)); } else { - addRead(c, this, v, SiteMask(1 << MemoryOperand, 0, frameIndex)); + addRead(c, this, v, SiteMask(1 << lir::MemoryOperand, 0, frameIndex)); } } } @@ -3321,7 +3325,7 @@ class CallEvent: public Event { } addRead(c, this, stack->value, SiteMask - (1 << MemoryOperand, 0, logicalIndex)); + (1 << lir::MemoryOperand, 0, logicalIndex)); } stack = stack->next; @@ -3336,25 +3340,25 @@ class CallEvent: public Event { } virtual void compile(Context* c) { - UnaryOperation op; + lir::UnaryOperation op; if (TailCalls and (flags & Compiler::TailJump)) { if (flags & Compiler::LongJumpOrCall) { if (flags & Compiler::Aligned) { - op = AlignedLongJump; + op = lir::AlignedLongJump; } else { - op = LongJump; + op = lir::LongJump; } } else if (flags & Compiler::Aligned) { - op = AlignedJump; + op = lir::AlignedJump; } else { - op = Jump; + op = lir::Jump; } assert(c, returnAddressSurrogate == 0 - or returnAddressSurrogate->source->type(c) == RegisterOperand); + or returnAddressSurrogate->source->type(c) == lir::RegisterOperand); assert(c, framePointerSurrogate == 0 - or framePointerSurrogate->source->type(c) == RegisterOperand); + or framePointerSurrogate->source->type(c) == lir::RegisterOperand); int ras; if (returnAddressSurrogate) { @@ -3363,7 +3367,7 @@ class CallEvent: public Event { ras = static_cast (returnAddressSurrogate->source)->number; } else { - ras = NoRegister; + ras = lir::NoRegister; } int fps; @@ -3373,7 +3377,7 @@ class CallEvent: public Event { fps = static_cast (framePointerSurrogate->source)->number; } else { - fps = NoRegister; + fps = lir::NoRegister; } int offset @@ -3383,14 +3387,14 @@ class CallEvent: public Event { c->assembler->popFrameForTailCall(c->alignedFrameSize, offset, ras, fps); } else if (flags & Compiler::LongJumpOrCall) { if (flags & Compiler::Aligned) { - op = AlignedLongCall; + op = lir::AlignedLongCall; } else { - op = LongCall; + op = lir::LongCall; } } else if (flags & Compiler::Aligned) { - op = AlignedCall; + op = lir::AlignedCall; } else { - op = Call; + op = lir::Call; } apply(c, op, TargetBytesPerWord, address->source, address->source); @@ -3504,7 +3508,7 @@ appendReturn(Context* c, unsigned size, Value* value) } void -maybeMove(Context* c, BinaryOperation type, unsigned srcSize, +maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst, const SiteMask& dstMask) { @@ -3526,10 +3530,10 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize, if (cost) { // todo: let c->arch->planMove decide this: - bool useTemporary = ((target->type(c) == MemoryOperand - and src->source->type(c) == MemoryOperand) + bool useTemporary = ((target->type(c) == lir::MemoryOperand + and src->source->type(c) == lir::MemoryOperand) or (srcSelectSize < dstSize - and target->type(c) != RegisterOperand)); + and target->type(c) != lir::RegisterOperand)); src->source->freeze(c, src); @@ -3539,7 +3543,7 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize, bool addOffset = srcSize != srcSelectSize and c->arch->bigEndian() - and src->source->type(c) == MemoryOperand; + and src->source->type(c) == lir::MemoryOperand; if (addOffset) { static_cast(src->source)->offset @@ -3575,12 +3579,12 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize, c->arch->planSource(type, dstSize, &srcTypeMask, &srcRegisterMask, dstSize, &thunk); - if (src->type == ValueGeneral) { + if (src->type == lir::ValueGeneral) { srcRegisterMask &= c->arch->generalRegisterMask(); } assert(c, thunk == 0); - assert(c, dstMask.typeMask & srcTypeMask & (1 << RegisterOperand)); + assert(c, dstMask.typeMask & srcTypeMask & (1 << lir::RegisterOperand)); Site* tmpTarget = freeRegisterSite (c, dstMask.registerMask & srcRegisterMask); @@ -3617,7 +3621,7 @@ maybeMove(Context* c, BinaryOperation type, unsigned srcSize, tmpTarget->freeze(c, dst); - apply(c, Move, dstSize, tmpTarget, tmpTarget, dstSize, target, target); + apply(c, lir::Move, dstSize, tmpTarget, tmpTarget, dstSize, target, target); tmpTarget->thaw(c, dst); @@ -3696,7 +3700,7 @@ pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord, } Value* -value(Context* c, ValueType type, Site* site = 0, Site* target = 0) +value(Context* c, lir::ValueType type, Site* site = 0, Site* target = 0) { return new(c->zone) Value(site, target, type); } @@ -3735,7 +3739,7 @@ maybeSplit(Context* c, Value* v) class MoveEvent: public Event { public: - MoveEvent(Context* c, BinaryOperation type, unsigned srcSize, + MoveEvent(Context* c, lir::BinaryOperation type, unsigned srcSize, unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst, const SiteMask& srcLowMask, const SiteMask& srcHighMask): Event(c), type(type), srcSize(srcSize), srcSelectSize(srcSelectSize), @@ -3786,7 +3790,7 @@ class MoveEvent: public Event { if (dst->target) { if (dstSize > TargetBytesPerWord) { if (src->source->registerSize(c) > TargetBytesPerWord) { - apply(c, Move, srcSelectSize, src->source, src->source, + apply(c, lir::Move, srcSelectSize, src->source, src->source, dstSize, dst->target, dst->target); if (live(c, dst) == 0) { @@ -3798,17 +3802,17 @@ class MoveEvent: public Event { } else { src->nextWord->source->freeze(c, src->nextWord); - maybeMove(c, Move, TargetBytesPerWord, TargetBytesPerWord, src, + maybeMove(c, lir::Move, TargetBytesPerWord, TargetBytesPerWord, src, TargetBytesPerWord, dst, dstLowMask); src->nextWord->source->thaw(c, src->nextWord); maybeMove - (c, Move, TargetBytesPerWord, TargetBytesPerWord, src->nextWord, + (c, lir::Move, TargetBytesPerWord, TargetBytesPerWord, src->nextWord, TargetBytesPerWord, dst->nextWord, dstHighMask); } } else { - maybeMove(c, Move, TargetBytesPerWord, TargetBytesPerWord, src, + maybeMove(c, lir::Move, TargetBytesPerWord, TargetBytesPerWord, src, TargetBytesPerWord, dst, dstLowMask); } } else { @@ -3827,7 +3831,7 @@ class MoveEvent: public Event { assert(c, srcSelectSize == TargetBytesPerWord); if (dst->nextWord->target or live(c, dst->nextWord)) { - assert(c, dstLowMask.typeMask & (1 << RegisterOperand)); + assert(c, dstLowMask.typeMask & (1 << lir::RegisterOperand)); Site* low = freeRegisterSite(c, dstLowMask.registerMask); @@ -3844,14 +3848,14 @@ class MoveEvent: public Event { srcb, dstb, src); } - apply(c, Move, TargetBytesPerWord, src->source, src->source, + apply(c, lir::Move, TargetBytesPerWord, src->source, src->source, TargetBytesPerWord, low, low); low->thaw(c, dst); src->source->thaw(c, src); - assert(c, dstHighMask.typeMask & (1 << RegisterOperand)); + assert(c, dstHighMask.typeMask & (1 << lir::RegisterOperand)); Site* high = freeRegisterSite(c, dstHighMask.registerMask); @@ -3868,7 +3872,7 @@ class MoveEvent: public Event { srcb, dstb, dst, dst->nextWord); } - apply(c, Move, TargetBytesPerWord, low, low, dstSize, low, high); + apply(c, lir::Move, TargetBytesPerWord, low, low, dstSize, low, high); high->thaw(c, dst->nextWord); @@ -3883,7 +3887,7 @@ class MoveEvent: public Event { } } - BinaryOperation type; + lir::BinaryOperation type; unsigned srcSize; unsigned srcSelectSize; Value* src; @@ -3892,7 +3896,7 @@ class MoveEvent: public Event { }; void -appendMove(Context* c, BinaryOperation type, unsigned srcSize, +appendMove(Context* c, lir::BinaryOperation type, unsigned srcSize, unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst) { bool thunk; @@ -3916,7 +3920,7 @@ findConstantSite(Context* c, Value* v) { for (SiteIterator it(c, v); it.hasMore();) { Site* s = it.next(); - if (s->type(c) == ConstantOperand) { + if (s->type(c) == lir::ConstantOperand) { return static_cast(s); } } @@ -3985,7 +3989,7 @@ thawSource(Context* c, unsigned size, Value* v) class CombineEvent: public Event { public: - CombineEvent(Context* c, TernaryOperation type, + CombineEvent(Context* c, lir::TernaryOperation type, unsigned firstSize, Value* first, unsigned secondSize, Value* second, unsigned resultSize, Value* result, @@ -4084,7 +4088,7 @@ class CombineEvent: public Event { } } - TernaryOperation type; + lir::TernaryOperation type; unsigned firstSize; Value* first; unsigned secondSize; @@ -4390,14 +4394,14 @@ register_(Context* c, int number) | c->arch->floatRegisterMask())); Site* s = registerSite(c, number); - ValueType type = ((1 << number) & c->arch->floatRegisterMask()) - ? ValueFloat: ValueGeneral; + lir::ValueType type = ((1 << number) & c->arch->floatRegisterMask()) + ? lir::ValueFloat: lir::ValueGeneral; return value(c, type, s, s); } void -appendCombine(Context* c, TernaryOperation type, +appendCombine(Context* c, lir::TernaryOperation type, unsigned firstSize, Value* first, unsigned secondSize, Value* second, unsigned resultSize, Value* result) @@ -4435,7 +4439,7 @@ appendCombine(Context* c, TernaryOperation type, c->stack = oldStack; appendCall - (c, value(c, ValueGeneral, constantSite(c, handler)), 0, 0, result, + (c, value(c, lir::ValueGeneral, constantSite(c, handler)), 0, 0, result, resultSize, argumentStack, stackSize, 0); } else { append @@ -4454,7 +4458,7 @@ appendCombine(Context* c, TernaryOperation type, class TranslateEvent: public Event { public: - TranslateEvent(Context* c, BinaryOperation type, unsigned valueSize, + TranslateEvent(Context* c, lir::BinaryOperation type, unsigned valueSize, Value* value, unsigned resultSize, Value* result, const SiteMask& valueLowMask, const SiteMask& valueHighMask): @@ -4521,7 +4525,7 @@ class TranslateEvent: public Event { } } - BinaryOperation type; + lir::BinaryOperation type; unsigned valueSize; unsigned resultSize; Value* value; @@ -4532,7 +4536,7 @@ class TranslateEvent: public Event { }; void -appendTranslate(Context* c, BinaryOperation type, unsigned firstSize, +appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize, Value* first, unsigned resultSize, Value* result) { bool thunk; @@ -4552,7 +4556,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize, appendCall (c, value - (c, ValueGeneral, constantSite + (c, lir::ValueGeneral, constantSite (c, c->client->getThunk(type, firstSize, resultSize))), 0, 0, result, resultSize, argumentStack, ceilingDivide(firstSize, TargetBytesPerWord), 0); @@ -4567,7 +4571,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize, class OperationEvent: public Event { public: - OperationEvent(Context* c, Operation op): + OperationEvent(Context* c, lir::Operation op): Event(c), op(op) { } @@ -4579,11 +4583,11 @@ class OperationEvent: public Event { c->assembler->apply(op); } - Operation op; + lir::Operation op; }; void -appendOperation(Context* c, Operation op) +appendOperation(Context* c, lir::Operation op) { append(c, new(c->zone) OperationEvent(c, op)); } @@ -4592,7 +4596,7 @@ void moveIfConflict(Context* c, Value* v, MemorySite* s) { if (v->reads) { - SiteMask mask(1 << RegisterOperand, ~0, AnyFrameIndex); + SiteMask mask(1 << lir::RegisterOperand, ~0, AnyFrameIndex); v->reads->intersect(&mask); if (s->conflicts(mask)) { maybeMove(c, v->reads, true, false); @@ -4626,23 +4630,23 @@ class MemoryEvent: public Event { ConstantSite* constant = findConstantSite(c, index); if (constant) { - indexRegister = NoRegister; + indexRegister = lir::NoRegister; displacement += (constant->value->value() * scale); scale = 1; } else { - assert(c, index->source->type(c) == RegisterOperand); + assert(c, index->source->type(c) == lir::RegisterOperand); indexRegister = static_cast(index->source)->number; } } else { - indexRegister = NoRegister; + indexRegister = lir::NoRegister; } - assert(c, base->source->type(c) == RegisterOperand); + assert(c, base->source->type(c) == lir::RegisterOperand); int baseRegister = static_cast(base->source)->number; popRead(c, this, base); if (index) { - if (TargetBytesPerWord == 8 and indexRegister != NoRegister) { - apply(c, Move, 4, index->source, index->source, + if (TargetBytesPerWord == 8 and indexRegister != lir::NoRegister) { + apply(c, lir::Move, 4, index->source, index->source, 8, index->source, index->source); } @@ -4701,59 +4705,59 @@ unordered(double a, double b) } bool -shouldJump(Context* c, TernaryOperation type, unsigned size, int64_t b, +shouldJump(Context* c, lir::TernaryOperation type, unsigned size, int64_t b, int64_t a) { switch (type) { - case JumpIfEqual: + case lir::JumpIfEqual: return a == b; - case JumpIfNotEqual: + case lir::JumpIfNotEqual: return a != b; - case JumpIfLess: + case lir::JumpIfLess: return a < b; - case JumpIfGreater: + case lir::JumpIfGreater: return a > b; - case JumpIfLessOrEqual: + case lir::JumpIfLessOrEqual: return a <= b; - case JumpIfGreaterOrEqual: + case lir::JumpIfGreaterOrEqual: return a >= b; - case JumpIfFloatEqual: + case lir::JumpIfFloatEqual: return asFloat(size, a) == asFloat(size, b); - case JumpIfFloatNotEqual: + case lir::JumpIfFloatNotEqual: return asFloat(size, a) != asFloat(size, b); - case JumpIfFloatLess: + case lir::JumpIfFloatLess: return asFloat(size, a) < asFloat(size, b); - case JumpIfFloatGreater: + case lir::JumpIfFloatGreater: return asFloat(size, a) > asFloat(size, b); - case JumpIfFloatLessOrEqual: + case lir::JumpIfFloatLessOrEqual: return asFloat(size, a) <= asFloat(size, b); - case JumpIfFloatGreaterOrEqual: + case lir::JumpIfFloatGreaterOrEqual: return asFloat(size, a) >= asFloat(size, b); - case JumpIfFloatLessOrUnordered: + case lir::JumpIfFloatLessOrUnordered: return asFloat(size, a) < asFloat(size, b) or unordered(asFloat(size, a), asFloat(size, b)); - case JumpIfFloatGreaterOrUnordered: + case lir::JumpIfFloatGreaterOrUnordered: return asFloat(size, a) > asFloat(size, b) or unordered(asFloat(size, a), asFloat(size, b)); - case JumpIfFloatLessOrEqualOrUnordered: + case lir::JumpIfFloatLessOrEqualOrUnordered: return asFloat(size, a) <= asFloat(size, b) or unordered(asFloat(size, a), asFloat(size, b)); - case JumpIfFloatGreaterOrEqualOrUnordered: + case lir::JumpIfFloatGreaterOrEqualOrUnordered: return asFloat(size, a) >= asFloat(size, b) or unordered(asFloat(size, a), asFloat(size, b)); @@ -4762,31 +4766,31 @@ shouldJump(Context* c, TernaryOperation type, unsigned size, int64_t b, } } -TernaryOperation -thunkBranch(Context* c, TernaryOperation type) +lir::TernaryOperation +thunkBranch(Context* c, lir::TernaryOperation type) { switch (type) { - case JumpIfFloatEqual: - return JumpIfEqual; + case lir::JumpIfFloatEqual: + return lir::JumpIfEqual; - case JumpIfFloatNotEqual: - return JumpIfNotEqual; + case lir::JumpIfFloatNotEqual: + return lir::JumpIfNotEqual; - case JumpIfFloatLess: - case JumpIfFloatLessOrUnordered: - return JumpIfLess; + case lir::JumpIfFloatLess: + case lir::JumpIfFloatLessOrUnordered: + return lir::JumpIfLess; - case JumpIfFloatGreater: - case JumpIfFloatGreaterOrUnordered: - return JumpIfGreater; + case lir::JumpIfFloatGreater: + case lir::JumpIfFloatGreaterOrUnordered: + return lir::JumpIfGreater; - case JumpIfFloatLessOrEqual: - case JumpIfFloatLessOrEqualOrUnordered: - return JumpIfLessOrEqual; + case lir::JumpIfFloatLessOrEqual: + case lir::JumpIfFloatLessOrEqualOrUnordered: + return lir::JumpIfLessOrEqual; - case JumpIfFloatGreaterOrEqual: - case JumpIfFloatGreaterOrEqualOrUnordered: - return JumpIfGreaterOrEqual; + case lir::JumpIfFloatGreaterOrEqual: + case lir::JumpIfFloatGreaterOrEqualOrUnordered: + return lir::JumpIfGreaterOrEqual; default: abort(c); @@ -4795,7 +4799,7 @@ thunkBranch(Context* c, TernaryOperation type) class BranchEvent: public Event { public: - BranchEvent(Context* c, TernaryOperation type, unsigned size, + BranchEvent(Context* c, lir::TernaryOperation type, unsigned size, Value* first, Value* second, Value* address, const SiteMask& firstLowMask, const SiteMask& firstHighMask, @@ -4840,7 +4844,7 @@ class BranchEvent: public Event { } if (shouldJump(c, type, size, firstValue, secondValue)) { - apply(c, Jump, TargetBytesPerWord, address->source, address->source); + apply(c, lir::Jump, TargetBytesPerWord, address->source, address->source); } } else { freezeSource(c, size, first); @@ -4864,7 +4868,7 @@ class BranchEvent: public Event { virtual bool isBranch() { return true; } - TernaryOperation type; + lir::TernaryOperation type; unsigned size; Value* first; Value* second; @@ -4872,7 +4876,7 @@ class BranchEvent: public Event { }; void -appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first, +appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first, Value* second, Value* address) { bool thunk; @@ -4900,14 +4904,14 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first, Stack* argumentStack = c->stack; c->stack = oldStack; - Value* result = value(c, ValueGeneral); + Value* result = value(c, lir::ValueGeneral); appendCall (c, value - (c, ValueGeneral, constantSite(c, handler)), 0, 0, result, 4, + (c, lir::ValueGeneral, constantSite(c, handler)), 0, 0, result, 4, argumentStack, ceilingDivide(size, TargetBytesPerWord) * 2, 0); appendBranch(c, thunkBranch(c, type), 4, value - (c, ValueGeneral, constantSite(c, static_cast(0))), + (c, lir::ValueGeneral, constantSite(c, static_cast(0))), result, address); } else { append @@ -4923,7 +4927,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first, class JumpEvent: public Event { public: - JumpEvent(Context* c, UnaryOperation type, Value* address, bool exit, + JumpEvent(Context* c, lir::UnaryOperation type, Value* address, bool exit, bool cleanLocals): Event(c), type(type), address(address), exit(exit), cleanLocals(cleanLocals) @@ -4965,14 +4969,14 @@ class JumpEvent: public Event { return exit or unreachable(this); } - UnaryOperation type; + lir::UnaryOperation type; Value* address; bool exit; bool cleanLocals; }; void -appendJump(Context* c, UnaryOperation type, Value* address, bool exit = false, +appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit = false, bool cleanLocals = false) { append(c, new(c->zone) JumpEvent(c, type, address, exit, cleanLocals)); @@ -5001,22 +5005,25 @@ class BoundsCheckEvent: public Event { if (constant) { if (constant->value->value() < 0) { - Assembler::Constant handlerConstant(resolved(c, handler)); - a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant); + lir::Constant handlerConstant(resolved(c, handler)); + a->apply(lir::Call, + OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &handlerConstant)); } } else { outOfBoundsPromise = codePromise(c, static_cast(0)); ConstantSite zero(resolved(c, 0)); ConstantSite oob(outOfBoundsPromise); - apply(c, JumpIfLess, 4, &zero, &zero, 4, index->source, index->source, - TargetBytesPerWord, &oob, &oob); + apply(c, lir::JumpIfLess, + 4, &zero, &zero, + 4, index->source, index->source, + TargetBytesPerWord, &oob, &oob); } if (constant == 0 or constant->value->value() >= 0) { - assert(c, object->source->type(c) == RegisterOperand); + assert(c, object->source->type(c) == lir::RegisterOperand); MemorySite length(static_cast(object->source)->number, - lengthOffset, NoRegister, 1); + lengthOffset, lir::NoRegister, 1); length.acquired = true; CodePromise* nextPromise = codePromise(c, static_cast(0)); @@ -5024,8 +5031,10 @@ class BoundsCheckEvent: public Event { freezeSource(c, TargetBytesPerWord, index); ConstantSite next(nextPromise); - apply(c, JumpIfGreater, 4, index->source, index->source, 4, &length, - &length, TargetBytesPerWord, &next, &next); + apply(c, lir::JumpIfGreater, + 4, index->source, + index->source, 4, &length, + &length, TargetBytesPerWord, &next, &next); thawSource(c, TargetBytesPerWord, index); @@ -5033,8 +5042,9 @@ class BoundsCheckEvent: public Event { outOfBoundsPromise->offset = a->offset(); } - Assembler::Constant handlerConstant(resolved(c, handler)); - a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant); + lir::Constant handlerConstant(resolved(c, handler)); + a->apply(lir::Call, + OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &handlerConstant)); nextPromise->offset = a->offset(); } @@ -5400,7 +5410,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen, buffer, v, el.localIndex, frameIndex(c, &el)); } - Value dummy(0, 0, ValueGeneral); + Value dummy(0, 0, lir::ValueGeneral); addSite(c, &dummy, s); removeSite(c, &dummy, s); freeze(c, frozen, s, 0); @@ -5420,7 +5430,7 @@ resolveSourceSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites) Read* r = live(c, v); if (r and sites[el.localIndex] == 0) { - SiteMask mask((1 << RegisterOperand) | (1 << MemoryOperand), + SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand), c->arch->generalRegisterMask(), AnyFrameIndex); Site* s = pickSourceSite @@ -5454,7 +5464,7 @@ resolveTargetSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites) Read* r = live(c, v); if (r and sites[el.localIndex] == 0) { - SiteMask mask((1 << RegisterOperand) | (1 << MemoryOperand), + SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand), c->arch->generalRegisterMask(), AnyFrameIndex); Site* s = pickSourceSite @@ -6057,7 +6067,7 @@ class MyCompiler: public Compiler { virtual void returnFromSubroutine(Subroutine* subroutine, Operand* address) { appendSaveLocals(&c); - appendJump(&c, Jump, static_cast(address), false, true); + appendJump(&c, lir::Jump, static_cast(address), false, true); static_cast(subroutine)->forkState = local::saveState(&c); } @@ -6216,17 +6226,17 @@ class MyCompiler: public Compiler { return p; } - virtual Operand* constant(int64_t value, OperandType type) { + virtual Operand* constant(int64_t value, Compiler::OperandType type) { return promiseConstant(resolved(&c, value), type); } - virtual Operand* promiseConstant(Promise* value, OperandType type) { + virtual Operand* promiseConstant(Promise* value, Compiler::OperandType type) { return local::value (&c, valueType(&c, type), local::constantSite(&c, value)); } virtual Operand* address(Promise* address) { - return value(&c, ValueGeneral, local::addressSite(&c, address)); + return value(&c, lir::ValueGeneral, local::addressSite(&c, address)); } virtual Operand* memory(Operand* base, @@ -6254,7 +6264,7 @@ class MyCompiler: public Compiler { virtual void push(unsigned footprint UNUSED) { assert(&c, footprint == 1); - Value* v = value(&c, ValueGeneral); + Value* v = value(&c, lir::ValueGeneral); Stack* s = local::stack(&c, v, c.stack); v->home = frameIndex(&c, s->index + c.localFootprint); @@ -6280,7 +6290,7 @@ class MyCompiler: public Compiler { } virtual void pushed() { - Value* v = value(&c, ValueGeneral); + Value* v = value(&c, lir::ValueGeneral); appendFrameSite (&c, v, frameIndex (&c, (c.stack ? c.stack->index : 0) + c.localFootprint)); @@ -6463,7 +6473,7 @@ class MyCompiler: public Compiler { Local* local = e->locals() + i; if (local->value) { initLocal - (1, i, local->value->type == ValueGeneral ? IntegerType : FloatType); + (1, i, local->value->type == lir::ValueGeneral ? IntegerType : FloatType); } } @@ -6492,7 +6502,7 @@ class MyCompiler: public Compiler { virtual void store(unsigned srcSize, Operand* src, unsigned dstSize, Operand* dst) { - appendMove(&c, Move, srcSize, srcSize, static_cast(src), + appendMove(&c, lir::Move, srcSize, srcSize, static_cast(src), dstSize, static_cast(dst)); } @@ -6502,7 +6512,7 @@ class MyCompiler: public Compiler { assert(&c, dstSize >= TargetBytesPerWord); Value* dst = value(&c, static_cast(src)->type); - appendMove(&c, Move, srcSize, srcSelectSize, static_cast(src), + appendMove(&c, lir::Move, srcSize, srcSelectSize, static_cast(src), dstSize, dst); return dst; } @@ -6513,7 +6523,7 @@ class MyCompiler: public Compiler { assert(&c, dstSize >= TargetBytesPerWord); Value* dst = value(&c, static_cast(src)->type); - appendMove(&c, MoveZ, srcSize, srcSelectSize, static_cast(src), + appendMove(&c, lir::MoveZ, srcSize, srcSelectSize, static_cast(src), dstSize, dst); return dst; } @@ -6521,140 +6531,140 @@ class MyCompiler: public Compiler { virtual void jumpIfEqual(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); - appendBranch(&c, JumpIfEqual, size, static_cast(a), + appendBranch(&c, lir::JumpIfEqual, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfNotEqual(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); - appendBranch(&c, JumpIfNotEqual, size, static_cast(a), + appendBranch(&c, lir::JumpIfNotEqual, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfLess(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); - appendBranch(&c, JumpIfLess, size, static_cast(a), + appendBranch(&c, lir::JumpIfLess, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfGreater(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); - appendBranch(&c, JumpIfGreater, size, static_cast(a), + appendBranch(&c, lir::JumpIfGreater, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfLessOrEqual(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); - appendBranch(&c, JumpIfLessOrEqual, size, static_cast(a), + appendBranch(&c, lir::JumpIfLessOrEqual, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfGreaterOrEqual(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); - appendBranch(&c, JumpIfGreaterOrEqual, size, static_cast(a), + appendBranch(&c, lir::JumpIfGreaterOrEqual, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfFloatEqual(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatEqual, size, static_cast(a), + appendBranch(&c, lir::JumpIfFloatEqual, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfFloatNotEqual(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatNotEqual, size, static_cast(a), + appendBranch(&c, lir::JumpIfFloatNotEqual, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfFloatLess(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatLess, size, static_cast(a), + appendBranch(&c, lir::JumpIfFloatLess, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfFloatGreater(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatGreater, size, static_cast(a), + appendBranch(&c, lir::JumpIfFloatGreater, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfFloatLessOrEqual(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatLessOrEqual, size, static_cast(a), + appendBranch(&c, lir::JumpIfFloatLessOrEqual, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfFloatGreaterOrEqual(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatGreaterOrEqual, size, static_cast(a), + appendBranch(&c, lir::JumpIfFloatGreaterOrEqual, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfFloatLessOrUnordered(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatLessOrUnordered, size, static_cast(a), + appendBranch(&c, lir::JumpIfFloatLessOrUnordered, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jumpIfFloatGreaterOrUnordered(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatGreaterOrUnordered, size, + appendBranch(&c, lir::JumpIfFloatGreaterOrUnordered, size, static_cast(a), static_cast(b), static_cast(address)); } @@ -6662,10 +6672,10 @@ class MyCompiler: public Compiler { virtual void jumpIfFloatLessOrEqualOrUnordered(unsigned size, Operand* a, Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatLessOrEqualOrUnordered, size, + appendBranch(&c, lir::JumpIfFloatLessOrEqualOrUnordered, size, static_cast(a), static_cast(b), static_cast(address)); } @@ -6674,240 +6684,239 @@ class MyCompiler: public Compiler { Operand* b, Operand* address) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); - appendBranch(&c, JumpIfFloatGreaterOrEqualOrUnordered, size, + appendBranch(&c, lir::JumpIfFloatGreaterOrEqualOrUnordered, size, static_cast(a), static_cast(b), static_cast(address)); } virtual void jmp(Operand* address) { - appendJump(&c, Jump, static_cast(address)); + appendJump(&c, lir::Jump, static_cast(address)); } virtual void exit(Operand* address) { - appendJump(&c, Jump, static_cast(address), true); + appendJump(&c, lir::Jump, static_cast(address), true); } virtual Operand* add(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, Add, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::Add, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* sub(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, Subtract, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::Subtract, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* mul(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, Multiply, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::Multiply, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* div(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, Divide, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::Divide, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* rem(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral - and static_cast(b)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, Remainder, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral + and static_cast(b)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::Remainder, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* fadd(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); - Value* result = value(&c, ValueFloat); - static_cast(a)->type = static_cast(b)->type = ValueFloat; - appendCombine(&c, FloatAdd, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueFloat); + static_cast(a)->type = static_cast(b)->type = lir::ValueFloat; + appendCombine(&c, lir::FloatAdd, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* fsub(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); - Value* result = value(&c, ValueFloat); - static_cast(a)->type = static_cast(b)->type = ValueFloat; - appendCombine(&c, FloatSubtract, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueFloat); + static_cast(a)->type = static_cast(b)->type = lir::ValueFloat; + appendCombine(&c, lir::FloatSubtract, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* fmul(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); - Value* result = value(&c, ValueFloat); - static_cast(a)->type = static_cast(b)->type = ValueFloat; - appendCombine(&c, FloatMultiply, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueFloat); + static_cast(a)->type = static_cast(b)->type = lir::ValueFloat; + appendCombine(&c, lir::FloatMultiply, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* fdiv(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); - Value* result = value(&c, ValueFloat); - appendCombine(&c, FloatDivide, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueFloat); + appendCombine(&c, lir::FloatDivide, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* frem(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueFloat - and static_cast(b)->type == ValueFloat); - Value* result = value(&c, ValueFloat); - appendCombine(&c, FloatRemainder, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueFloat + and static_cast(b)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueFloat); + appendCombine(&c, lir::FloatRemainder, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* shl(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, ShiftLeft, TargetBytesPerWord, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::ShiftLeft, TargetBytesPerWord, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* shr(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, ShiftRight, TargetBytesPerWord, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::ShiftRight, TargetBytesPerWord, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* ushr(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); + assert(&c, static_cast(a)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); appendCombine - (&c, UnsignedShiftRight, TargetBytesPerWord, static_cast(a), + (&c, lir::UnsignedShiftRight, TargetBytesPerWord, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* and_(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, And, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::And, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* or_(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, Or, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::Or, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* xor_(unsigned size, Operand* a, Operand* b) { - assert(&c, static_cast(a)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendCombine(&c, Xor, size, static_cast(a), + assert(&c, static_cast(a)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendCombine(&c, lir::Xor, size, static_cast(a), size, static_cast(b), size, result); return result; } virtual Operand* neg(unsigned size, Operand* a) { - assert(&c, static_cast(a)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendTranslate(&c, Negate, size, static_cast(a), size, result); + assert(&c, static_cast(a)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendTranslate(&c, lir::Negate, size, static_cast(a), size, result); return result; } virtual Operand* fneg(unsigned size, Operand* a) { - assert(&c, static_cast(a)->type == ValueFloat); - Value* result = value(&c, ValueFloat); - appendTranslate - (&c, FloatNegate, size, static_cast(a), size, result); + assert(&c, static_cast(a)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueFloat); + appendTranslate(&c, lir::FloatNegate, size, static_cast(a), size, result); return result; } virtual Operand* abs(unsigned size, Operand* a) { - assert(&c, static_cast(a)->type == ValueGeneral); - Value* result = value(&c, ValueGeneral); - appendTranslate(&c, Absolute, size, static_cast(a), size, result); + assert(&c, static_cast(a)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueGeneral); + appendTranslate(&c, lir::Absolute, size, static_cast(a), size, result); return result; } virtual Operand* fabs(unsigned size, Operand* a) { - assert(&c, static_cast(a)->type == ValueFloat); - Value* result = value(&c, ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueFloat); appendTranslate - (&c, FloatAbsolute, size, static_cast(a), size, result); + (&c, lir::FloatAbsolute, size, static_cast(a), size, result); return result; } virtual Operand* fsqrt(unsigned size, Operand* a) { - assert(&c, static_cast(a)->type == ValueFloat); - Value* result = value(&c, ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueFloat); appendTranslate - (&c, FloatSquareRoot, size, static_cast(a), size, result); + (&c, lir::FloatSquareRoot, size, static_cast(a), size, result); return result; } virtual Operand* f2f(unsigned aSize, unsigned resSize, Operand* a) { - assert(&c, static_cast(a)->type == ValueFloat); - Value* result = value(&c, ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueFloat); appendTranslate - (&c, Float2Float, aSize, static_cast(a), resSize, result); + (&c, lir::Float2Float, aSize, static_cast(a), resSize, result); return result; } virtual Operand* f2i(unsigned aSize, unsigned resSize, Operand* a) { - assert(&c, static_cast(a)->type == ValueFloat); - Value* result = value(&c, ValueGeneral); + assert(&c, static_cast(a)->type == lir::ValueFloat); + Value* result = value(&c, lir::ValueGeneral); appendTranslate - (&c, Float2Int, aSize, static_cast(a), resSize, result); + (&c, lir::Float2Int, aSize, static_cast(a), resSize, result); return result; } virtual Operand* i2f(unsigned aSize, unsigned resSize, Operand* a) { - assert(&c, static_cast(a)->type == ValueGeneral); - Value* result = value(&c, ValueFloat); + assert(&c, static_cast(a)->type == lir::ValueGeneral); + Value* result = value(&c, lir::ValueFloat); appendTranslate - (&c, Int2Float, aSize, static_cast(a), resSize, result); + (&c, lir::Int2Float, aSize, static_cast(a), resSize, result); return result; } virtual void trap() { - appendOperation(&c, Trap); + appendOperation(&c, lir::Trap); } virtual void loadBarrier() { - appendOperation(&c, LoadBarrier); + appendOperation(&c, lir::LoadBarrier); } virtual void storeStoreBarrier() { - appendOperation(&c, StoreStoreBarrier); + appendOperation(&c, lir::StoreStoreBarrier); } virtual void storeLoadBarrier() { - appendOperation(&c, StoreLoadBarrier); + appendOperation(&c, lir::StoreLoadBarrier); } virtual void compile(uintptr_t stackOverflowHandler, @@ -6982,7 +6991,8 @@ class MyCompiler: public Compiler { } // namespace -namespace vm { +namespace avian { +namespace codegen { Compiler* makeCompiler(System* system, Assembler* assembler, Zone* zone, @@ -6991,4 +7001,5 @@ makeCompiler(System* system, Assembler* assembler, Zone* zone, return new(zone) local::MyCompiler(system, assembler, zone, client); } -} // namespace vm +} // namespace codegen +} // namespace avian diff --git a/src/codegen/compiler.h b/src/codegen/compiler.h index e66c69a67c..fbaad83791 100644 --- a/src/codegen/compiler.h +++ b/src/codegen/compiler.h @@ -15,7 +15,8 @@ #include "zone.h" #include "assembler.h" -namespace vm { +namespace avian { +namespace codegen { class TraceHandler { public: @@ -26,10 +27,10 @@ class Compiler { public: class Client { public: - virtual intptr_t getThunk(UnaryOperation op, unsigned size) = 0; - virtual intptr_t getThunk(BinaryOperation op, unsigned size, + virtual intptr_t getThunk(lir::UnaryOperation op, unsigned size) = 0; + virtual intptr_t getThunk(lir::BinaryOperation op, unsigned size, unsigned resultSize) = 0; - virtual intptr_t getThunk(TernaryOperation op, unsigned size, + virtual intptr_t getThunk(lir::TernaryOperation op, unsigned size, unsigned resultSize, bool* threadParameter) = 0; }; @@ -200,9 +201,10 @@ class Compiler { }; Compiler* -makeCompiler(System* system, Assembler* assembler, Zone* zone, +makeCompiler(vm::System* system, Assembler* assembler, vm::Zone* zone, Compiler::Client* client); -} // namespace vm +} // namespace codegen +} // namespace avian #endif//COMPILER_H diff --git a/src/codegen/lir-ops.inc.cpp b/src/codegen/lir-ops.inc.cpp new file mode 100644 index 0000000000..cf038c6647 --- /dev/null +++ b/src/codegen/lir-ops.inc.cpp @@ -0,0 +1,62 @@ +LIR_OP_0(Return) +LIR_OP_0(LoadBarrier) +LIR_OP_0(StoreStoreBarrier) +LIR_OP_0(StoreLoadBarrier) +LIR_OP_0(Trap) + +LIR_OP_1(Call) +LIR_OP_1(LongCall) +LIR_OP_1(AlignedLongCall) +LIR_OP_1(AlignedCall) +LIR_OP_1(Jump) +LIR_OP_1(LongJump) +LIR_OP_1(AlignedLongJump) +LIR_OP_1(AlignedJump) + +LIR_OP_2(Move) +LIR_OP_2(MoveLow) +LIR_OP_2(MoveHigh) +LIR_OP_2(MoveZ) +LIR_OP_2(Negate) +LIR_OP_2(FloatNegate) +LIR_OP_2(Float2Float) +LIR_OP_2(Float2Int) +LIR_OP_2(Int2Float) +LIR_OP_2(FloatSquareRoot) +LIR_OP_2(FloatAbsolute) +LIR_OP_2(Absolute) + +LIR_OP_3(Add) +LIR_OP_3(Subtract) +LIR_OP_3(Multiply) +LIR_OP_3(Divide) +LIR_OP_3(Remainder) +LIR_OP_3(ShiftLeft) +LIR_OP_3(ShiftRight) +LIR_OP_3(UnsignedShiftRight) +LIR_OP_3(And) +LIR_OP_3(Or) +LIR_OP_3(Xor) +LIR_OP_3(FloatAdd) +LIR_OP_3(FloatSubtract) +LIR_OP_3(FloatMultiply) +LIR_OP_3(FloatDivide) +LIR_OP_3(FloatRemainder) +LIR_OP_3(FloatMax) +LIR_OP_3(FloatMin) +LIR_OP_3(JumpIfLess) +LIR_OP_3(JumpIfGreater) +LIR_OP_3(JumpIfLessOrEqual) +LIR_OP_3(JumpIfGreaterOrEqual) +LIR_OP_3(JumpIfEqual) +LIR_OP_3(JumpIfNotEqual) +LIR_OP_3(JumpIfFloatEqual) +LIR_OP_3(JumpIfFloatNotEqual) +LIR_OP_3(JumpIfFloatLess) +LIR_OP_3(JumpIfFloatGreater) +LIR_OP_3(JumpIfFloatLessOrEqual) +LIR_OP_3(JumpIfFloatGreaterOrEqual) +LIR_OP_3(JumpIfFloatLessOrUnordered) +LIR_OP_3(JumpIfFloatGreaterOrUnordered) +LIR_OP_3(JumpIfFloatLessOrEqualOrUnordered) +LIR_OP_3(JumpIfFloatGreaterOrEqualOrUnordered) diff --git a/src/codegen/lir.cpp b/src/codegen/lir.cpp new file mode 100644 index 0000000000..86c0839743 --- /dev/null +++ b/src/codegen/lir.cpp @@ -0,0 +1,35 @@ +/* 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 "lir.h" + +namespace { + +const char* lirOpcodeNames[] = { + #define LIR_OP_0(x) #x + #define LIR_OP_1(x) #x + #define LIR_OP_2(x) #x + #define LIR_OP_3(x) #x + #include "lir-ops.inc.cpp" + #undef LIR_OP_0 + #undef LIR_OP_1 + #undef LIR_OP_2 + #undef LIR_OP_3 +}; + +} + +namespace vm { + +const char* LirInstr::opcodeName(Opcode op) { + return lirOpcodeNames[op]; +} + +} \ No newline at end of file diff --git a/src/codegen/lir.h b/src/codegen/lir.h new file mode 100644 index 0000000000..b95e736f06 --- /dev/null +++ b/src/codegen/lir.h @@ -0,0 +1,174 @@ +/* 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_LIR_H +#define AVIAN_CODEGEN_LIR_H + +namespace avian { +namespace codegen { +class Promise; + +namespace lir { +enum Operation { + #define LIR_OP_0(x) x, + #define LIR_OP_1(x) + #define LIR_OP_2(x) + #define LIR_OP_3(x) + #include "lir-ops.inc.cpp" + #undef LIR_OP_0 + #undef LIR_OP_1 + #undef LIR_OP_2 + #undef LIR_OP_3 +}; + +const unsigned OperationCount = Trap + 1; + +enum UnaryOperation { + #define LIR_OP_0(x) + #define LIR_OP_1(x) x, + #define LIR_OP_2(x) + #define LIR_OP_3(x) + #include "lir-ops.inc.cpp" + #undef LIR_OP_0 + #undef LIR_OP_1 + #undef LIR_OP_2 + #undef LIR_OP_3 + + NoUnaryOperation = -1 +}; + +const unsigned UnaryOperationCount = AlignedJump + 1; + +enum BinaryOperation { + #define LIR_OP_0(x) + #define LIR_OP_1(x) + #define LIR_OP_2(x) x, + #define LIR_OP_3(x) + #include "lir-ops.inc.cpp" + #undef LIR_OP_0 + #undef LIR_OP_1 + #undef LIR_OP_2 + #undef LIR_OP_3 + + NoBinaryOperation = -1 +}; + +const unsigned BinaryOperationCount = Absolute + 1; + +enum TernaryOperation { + #define LIR_OP_0(x) + #define LIR_OP_1(x) + #define LIR_OP_2(x) + #define LIR_OP_3(x) x, + #include "lir-ops.inc.cpp" + #undef LIR_OP_0 + #undef LIR_OP_1 + #undef LIR_OP_2 + #undef LIR_OP_3 + + NoTernaryOperation = -1 +}; + +const unsigned TernaryOperationCount += JumpIfFloatGreaterOrEqualOrUnordered + 1; + +const unsigned NonBranchTernaryOperationCount = FloatMin + 1; +const unsigned BranchOperationCount += JumpIfFloatGreaterOrEqualOrUnordered - FloatMin; + +enum OperandType { + ConstantOperand, + AddressOperand, + RegisterOperand, + MemoryOperand +}; + +enum ValueType { + ValueGeneral, + ValueFloat +}; + +const unsigned OperandTypeCount = MemoryOperand + 1; + +const int NoRegister = -1; + + +inline bool isBranch(lir::TernaryOperation op) { + return op > FloatMin; +} + +inline bool isFloatBranch(lir::TernaryOperation op) { + return op > JumpIfNotEqual; +} + +class Operand { }; + +class Constant: public Operand { + public: + Constant(Promise* value): value(value) { } + + Promise* value; +}; + +class Address: public Operand { + public: + Address(Promise* address): address(address) { } + + Promise* address; +}; + +class Register: public Operand { + public: + Register(int low, int high = NoRegister): low(low), high(high) { } + + int low; + int high; +}; + +class Memory: public Operand { + public: + Memory(int base, int offset, int index = NoRegister, unsigned scale = 1): + base(base), offset(offset), index(index), scale(scale) + { } + + int base; + int offset; + int index; + unsigned scale; +}; + +class Instr { +public: + + enum Opcode { + #define LIR_OP_0(x) OP_##x, + #define LIR_OP_1(x) OP_##x, + #define LIR_OP_2(x) OP_##x, + #define LIR_OP_3(x) OP_##x, + #include "lir-ops.inc.cpp" + #undef LIR_OP_0 + #undef LIR_OP_1 + #undef LIR_OP_2 + #undef LIR_OP_3 + }; + + static const char* opcodeName(Opcode op); + + static Opcode opcodeFromNullary(Operation op); + static Opcode opcodeFromUnary(UnaryOperation op); + static Opcode opcodeFromBinary(BinaryOperation op); + static Opcode opcodeFromTernary(TernaryOperation op); +}; + +} // namespace lir +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_LIR_H diff --git a/src/codegen/powerpc/assembler.cpp b/src/codegen/powerpc/assembler.cpp index 6517e59264..ee263b25bc 100644 --- a/src/codegen/powerpc/assembler.cpp +++ b/src/codegen/powerpc/assembler.cpp @@ -17,6 +17,7 @@ #define CAST_BRANCH(x) reinterpret_cast(x) using namespace vm; +using namespace avian::codegen; namespace { @@ -263,33 +264,33 @@ class Task { typedef void (*OperationType)(Context*); -typedef void (*UnaryOperationType)(Context*, unsigned, Assembler::Operand*); +typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*); typedef void (*BinaryOperationType) -(Context*, unsigned, Assembler::Operand*, unsigned, Assembler::Operand*); +(Context*, unsigned, lir::Operand*, unsigned, lir::Operand*); typedef void (*TernaryOperationType) -(Context*, unsigned, Assembler::Operand*, Assembler::Operand*, - Assembler::Operand*); +(Context*, unsigned, lir::Operand*, lir::Operand*, + lir::Operand*); typedef void (*BranchOperationType) -(Context*, TernaryOperation, unsigned, Assembler::Operand*, - Assembler::Operand*, Assembler::Operand*); +(Context*, lir::TernaryOperation, unsigned, lir::Operand*, + lir::Operand*, lir::Operand*); class ArchitectureContext { public: ArchitectureContext(System* s): s(s) { } System* s; - OperationType operations[OperationCount]; - UnaryOperationType unaryOperations[UnaryOperationCount - * OperandTypeCount]; + OperationType operations[lir::OperationCount]; + UnaryOperationType unaryOperations[lir::UnaryOperationCount + * lir::OperandTypeCount]; BinaryOperationType binaryOperations - [BinaryOperationCount * OperandTypeCount * OperandTypeCount]; + [lir::BinaryOperationCount * lir::OperandTypeCount * lir::OperandTypeCount]; TernaryOperationType ternaryOperations - [NonBranchTernaryOperationCount * OperandTypeCount]; + [lir::NonBranchTernaryOperationCount * lir::OperandTypeCount]; BranchOperationType branchOperations - [BranchOperationCount * OperandTypeCount * OperandTypeCount]; + [lir::BranchOperationCount * lir::OperandTypeCount * lir::OperandTypeCount]; }; inline void NO_RETURN @@ -612,43 +613,37 @@ resolve(MyBlock* b) } inline unsigned -index(ArchitectureContext*, UnaryOperation operation, OperandType operand) +index(ArchitectureContext*, lir::UnaryOperation operation, lir::OperandType operand) { - return operation + (UnaryOperationCount * operand); + return operation + (lir::UnaryOperationCount * operand); } inline unsigned index(ArchitectureContext*, - BinaryOperation operation, - OperandType operand1, - OperandType operand2) + lir::BinaryOperation operation, + lir::OperandType operand1, + lir::OperandType operand2) { return operation - + (BinaryOperationCount * operand1) - + (BinaryOperationCount * OperandTypeCount * operand2); -} - -bool -isBranch(TernaryOperation op) -{ - return op > FloatMin; + + (lir::BinaryOperationCount * operand1) + + (lir::BinaryOperationCount * lir::OperandTypeCount * operand2); } inline unsigned index(ArchitectureContext* c UNUSED, - TernaryOperation operation, - OperandType operand1) + lir::TernaryOperation operation, + lir::OperandType operand1) { assert(c, not isBranch(operation)); - return operation + (NonBranchTernaryOperationCount * operand1); + return operation + (lir::NonBranchTernaryOperationCount * operand1); } unsigned -branchIndex(ArchitectureContext* c UNUSED, OperandType operand1, - OperandType operand2) +branchIndex(ArchitectureContext* c UNUSED, lir::OperandType operand1, + lir::OperandType operand2) { - return operand1 + (OperandTypeCount * operand2); + return operand1 + (lir::OperandTypeCount * operand2); } // BEGIN OPERATION COMPILERS @@ -658,7 +653,7 @@ using namespace isa; inline void emit(Context* con, int code) { con->code.append4(targetV4(code)); } inline int newTemp(Context* con) { return con->client->acquireTemporary(); } inline void freeTemp(Context* con, int r) { con->client->releaseTemporary(r); } -inline int64_t getValue(Assembler::Constant* c) { return c->value->value(); } +inline int64_t getValue(lir::Constant* c) { return c->value->value(); } inline void write4(uint8_t* dst, uint32_t v) @@ -667,13 +662,13 @@ write4(uint8_t* dst, uint32_t v) } void -andC(Context* c, unsigned size, Assembler::Constant* a, - Assembler::Register* b, Assembler::Register* dst); +andC(Context* c, unsigned size, lir::Constant* a, + lir::Register* b, lir::Register* dst); -void shiftLeftR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) +void shiftLeftR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if(size == 8) { - Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp; + lir::Register Tmp(newTemp(con), newTemp(con)); lir::Register* tmp = &Tmp; emit(con, subfic(tmp->high, a->low, 32)); emit(con, slw(t->high, b->high, a->low)); emit(con, srw(tmp->low, b->low, tmp->high)); @@ -689,10 +684,10 @@ void shiftLeftR(Context* con, unsigned size, Assembler::Register* a, Assembler:: } void -moveRR(Context* c, unsigned srcSize, Assembler::Register* src, - unsigned dstSize, Assembler::Register* dst); +moveRR(Context* c, unsigned srcSize, lir::Register* src, + unsigned dstSize, lir::Register* dst); -void shiftLeftC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) +void shiftLeftC(Context* con, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t) { int sh = getValue(a); if (size == 8) { @@ -714,10 +709,10 @@ void shiftLeftC(Context* con, unsigned size, Assembler::Constant* a, Assembler:: } } -void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) +void shiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if(size == 8) { - Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp; + lir::Register Tmp(newTemp(con), newTemp(con)); lir::Register* tmp = &Tmp; emit(con, subfic(tmp->high, a->low, 32)); emit(con, srw(t->low, b->low, a->low)); emit(con, slw(tmp->low, b->high, tmp->high)); @@ -733,7 +728,7 @@ void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler: } } -void shiftRightC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) +void shiftRightC(Context* con, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t) { int sh = getValue(a); if(size == 8) { @@ -755,11 +750,11 @@ void shiftRightC(Context* con, unsigned size, Assembler::Constant* a, Assembler: } } -void unsignedShiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) +void unsignedShiftRightR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { emit(con, srw(t->low, b->low, a->low)); if(size == 8) { - Assembler::Register Tmp(newTemp(con), newTemp(con)); Assembler::Register* tmp = &Tmp; + lir::Register Tmp(newTemp(con), newTemp(con)); lir::Register* tmp = &Tmp; emit(con, subfic(tmp->high, a->low, 32)); emit(con, slw(tmp->low, b->high, tmp->high)); emit(con, or_(t->low, t->low, tmp->low)); @@ -771,13 +766,13 @@ void unsignedShiftRightR(Context* con, unsigned size, Assembler::Register* a, As } } -void unsignedShiftRightC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) +void unsignedShiftRightC(Context* con, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t) { int sh = getValue(a); if (size == 8) { if (sh & 0x3F) { if (sh == 32) { - Assembler::Register high(b->high); + lir::Register high(b->high); moveRR(con, 4, &high, 4, t); emit(con, li(t->high,0)); } else if (sh < 32) { @@ -909,7 +904,7 @@ appendConstantPoolEntry(Context* c, Promise* constant) } void -jumpR(Context* c, unsigned size UNUSED, Assembler::Register* target) +jumpR(Context* c, unsigned size UNUSED, lir::Register* target) { assert(c, size == TargetBytesPerWord); @@ -918,13 +913,13 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* target) } void -swapRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Register* b) +swapRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == TargetBytesPerWord); assert(c, bSize == TargetBytesPerWord); - Assembler::Register tmp(c->client->acquireTemporary()); + lir::Register tmp(c->client->acquireTemporary()); moveRR(c, aSize, a, bSize, &tmp); moveRR(c, bSize, b, aSize, a); moveRR(c, bSize, &tmp, bSize, b); @@ -932,8 +927,8 @@ swapRR(Context* c, unsigned aSize, Assembler::Register* a, } void -moveRR(Context* c, unsigned srcSize, Assembler::Register* src, - unsigned dstSize, Assembler::Register* dst) +moveRR(Context* c, unsigned srcSize, lir::Register* src, + unsigned dstSize, lir::Register* dst) { switch (srcSize) { case 1: @@ -950,8 +945,8 @@ moveRR(Context* c, unsigned srcSize, Assembler::Register* src, moveRR(c, 4, src, 4, dst); emit(c, srawi(dst->high, src->low, 31)); } else if (srcSize == 8 and dstSize == 8) { - Assembler::Register srcHigh(src->high); - Assembler::Register dstHigh(dst->high); + lir::Register srcHigh(src->high); + lir::Register dstHigh(dst->high); if (src->high == dst->low) { if (src->low == dst->high) { @@ -974,8 +969,8 @@ moveRR(Context* c, unsigned srcSize, Assembler::Register* src, } void -moveZRR(Context* c, unsigned srcSize, Assembler::Register* src, - unsigned, Assembler::Register* dst) +moveZRR(Context* c, unsigned srcSize, lir::Register* src, + unsigned, lir::Register* dst) { switch (srcSize) { case 2: @@ -987,8 +982,8 @@ moveZRR(Context* c, unsigned srcSize, Assembler::Register* src, } void -moveCR2(Context* c, unsigned, Assembler::Constant* src, - unsigned dstSize, Assembler::Register* dst, unsigned promiseOffset) +moveCR2(Context* c, unsigned, lir::Constant* src, + unsigned dstSize, lir::Register* dst, unsigned promiseOffset) { if (dstSize <= 4) { if (src->value->resolved()) { @@ -1011,13 +1006,13 @@ moveCR2(Context* c, unsigned, Assembler::Constant* src, } void -moveCR(Context* c, unsigned srcSize, Assembler::Constant* src, - unsigned dstSize, Assembler::Register* dst) +moveCR(Context* c, unsigned srcSize, lir::Constant* src, + unsigned dstSize, lir::Register* dst) { moveCR2(c, srcSize, src, dstSize, dst, 0); } -void addR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void addR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if(size == 8) { emit(con, addc(t->low, a->low, b->low)); emit(con, adde(t->high, a->high, b->high)); @@ -1026,7 +1021,7 @@ void addR(Context* con, unsigned size, Assembler::Register* a, Assembler::Regist } } -void addC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) { +void addC(Context* con, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t) { assert(con, size == TargetBytesPerWord); int32_t i = getValue(a); @@ -1039,7 +1034,7 @@ void addC(Context* con, unsigned size, Assembler::Constant* a, Assembler::Regist } } -void subR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void subR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if(size == 8) { emit(con, subfc(t->low, a->low, b->low)); emit(con, subfe(t->high, a->high, b->high)); @@ -1048,15 +1043,15 @@ void subR(Context* con, unsigned size, Assembler::Register* a, Assembler::Regist } } -void subC(Context* c, unsigned size, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t) { +void subC(Context* c, unsigned size, lir::Constant* a, lir::Register* b, lir::Register* t) { assert(c, size == TargetBytesPerWord); ResolvedPromise promise(- a->value->value()); - Assembler::Constant constant(&promise); + lir::Constant constant(&promise); addC(c, size, &constant, b, t); } -void multiplyR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void multiplyR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { if(size == 8) { bool useTemporaries = b->low == t->low; int tmpLow; @@ -1085,14 +1080,14 @@ void multiplyR(Context* con, unsigned size, Assembler::Register* a, Assembler::R } } -void divideR(Context* con, unsigned size UNUSED, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void divideR(Context* con, unsigned size UNUSED, lir::Register* a, lir::Register* b, lir::Register* t) { assert(con, size == 4); emit(con, divw(t->low, b->low, a->low)); } -void remainderR(Context* con, unsigned size, Assembler::Register* a, Assembler::Register* b, Assembler::Register* t) { +void remainderR(Context* con, unsigned size, lir::Register* a, lir::Register* b, lir::Register* t) { bool useTemporary = b->low == t->low; - Assembler::Register tmp(t->low); + lir::Register tmp(t->low); if (useTemporary) { tmp.low = con->client->acquireTemporary(); } @@ -1111,7 +1106,7 @@ normalize(Context* c, int offset, int index, unsigned scale, bool* preserveIndex, bool* release) { if (offset != 0 or scale != 1) { - Assembler::Register normalizedIndex + lir::Register normalizedIndex (*preserveIndex ? c->client->acquireTemporary() : index); if (*preserveIndex) { @@ -1124,10 +1119,10 @@ normalize(Context* c, int offset, int index, unsigned scale, int scaled; if (scale != 1) { - Assembler::Register unscaledIndex(index); + lir::Register unscaledIndex(index); ResolvedPromise scalePromise(log(scale)); - Assembler::Constant scaleConstant(&scalePromise); + lir::Constant scaleConstant(&scalePromise); shiftLeftC(c, TargetBytesPerWord, &scaleConstant, &unscaledIndex, &normalizedIndex); @@ -1138,10 +1133,10 @@ normalize(Context* c, int offset, int index, unsigned scale, } if (offset != 0) { - Assembler::Register untranslatedIndex(scaled); + lir::Register untranslatedIndex(scaled); ResolvedPromise offsetPromise(offset); - Assembler::Constant offsetConstant(&offsetPromise); + lir::Constant offsetConstant(&offsetPromise); addC(c, TargetBytesPerWord, &offsetConstant, &untranslatedIndex, &normalizedIndex); @@ -1155,10 +1150,10 @@ normalize(Context* c, int offset, int index, unsigned scale, } void -store(Context* c, unsigned size, Assembler::Register* src, +store(Context* c, unsigned size, lir::Register* src, int base, int offset, int index, unsigned scale, bool preserveIndex) { - if (index != NoRegister) { + if (index != lir::NoRegister) { bool release; int normalized = normalize (c, offset, index, scale, &preserveIndex, &release); @@ -1177,7 +1172,7 @@ store(Context* c, unsigned size, Assembler::Register* src, break; case 8: { - Assembler::Register srcHigh(src->high); + lir::Register srcHigh(src->high); store(c, 4, &srcHigh, base, 0, normalized, 1, preserveIndex); store(c, 4, src, base, 4, normalized, 1, preserveIndex); } break; @@ -1201,9 +1196,9 @@ store(Context* c, unsigned size, Assembler::Register* src, break; case 8: { - Assembler::Register srcHigh(src->high); - store(c, 4, &srcHigh, base, offset, NoRegister, 1, false); - store(c, 4, src, base, offset + 4, NoRegister, 1, false); + lir::Register srcHigh(src->high); + store(c, 4, &srcHigh, base, offset, lir::NoRegister, 1, false); + store(c, 4, src, base, offset + 4, lir::NoRegister, 1, false); } break; default: abort(c); @@ -1212,8 +1207,8 @@ store(Context* c, unsigned size, Assembler::Register* src, } void -moveRM(Context* c, unsigned srcSize, Assembler::Register* src, - unsigned dstSize UNUSED, Assembler::Memory* dst) +moveRM(Context* c, unsigned srcSize, lir::Register* src, + unsigned dstSize UNUSED, lir::Memory* dst) { assert(c, srcSize == dstSize); @@ -1221,13 +1216,13 @@ moveRM(Context* c, unsigned srcSize, Assembler::Register* src, } void -moveAndUpdateRM(Context* c, unsigned srcSize UNUSED, Assembler::Register* src, - unsigned dstSize UNUSED, Assembler::Memory* dst) +moveAndUpdateRM(Context* c, unsigned srcSize UNUSED, lir::Register* src, + unsigned dstSize UNUSED, lir::Memory* dst) { assert(c, srcSize == TargetBytesPerWord); assert(c, dstSize == TargetBytesPerWord); - if (dst->index == NoRegister) { + if (dst->index == lir::NoRegister) { emit(c, stwu(src->low, dst->base, dst->offset)); } else { assert(c, dst->offset == 0); @@ -1239,10 +1234,10 @@ moveAndUpdateRM(Context* c, unsigned srcSize UNUSED, Assembler::Register* src, void load(Context* c, unsigned srcSize, int base, int offset, int index, - unsigned scale, unsigned dstSize, Assembler::Register* dst, + unsigned scale, unsigned dstSize, lir::Register* dst, bool preserveIndex, bool signExtend) { - if (index != NoRegister) { + if (index != lir::NoRegister) { bool release; int normalized = normalize (c, offset, index, scale, &preserveIndex, &release); @@ -1269,7 +1264,7 @@ load(Context* c, unsigned srcSize, int base, int offset, int index, load(c, 4, base, 0, normalized, 1, 4, dst, preserveIndex, false); moveRR(c, 4, dst, 8, dst); } else if (srcSize == 8 and dstSize == 8) { - Assembler::Register dstHigh(dst->high); + lir::Register dstHigh(dst->high); load(c, 4, base, 0, normalized, 1, 4, &dstHigh, preserveIndex, false); load(c, 4, base, 4, normalized, 1, 4, dst, preserveIndex, false); } else { @@ -1304,9 +1299,9 @@ load(Context* c, unsigned srcSize, int base, int offset, int index, case 8: { if (dstSize == 8) { - Assembler::Register dstHigh(dst->high); - load(c, 4, base, offset, NoRegister, 1, 4, &dstHigh, false, false); - load(c, 4, base, offset + 4, NoRegister, 1, 4, dst, false, false); + lir::Register dstHigh(dst->high); + load(c, 4, base, offset, lir::NoRegister, 1, 4, &dstHigh, false, false); + load(c, 4, base, offset + 4, lir::NoRegister, 1, 4, dst, false, false); } else { emit(c, lwzx(dst->low, base, offset)); } @@ -1318,29 +1313,29 @@ load(Context* c, unsigned srcSize, int base, int offset, int index, } void -moveMR(Context* c, unsigned srcSize, Assembler::Memory* src, - unsigned dstSize, Assembler::Register* dst) +moveMR(Context* c, unsigned srcSize, lir::Memory* src, + unsigned dstSize, lir::Register* dst) { load(c, srcSize, src->base, src->offset, src->index, src->scale, dstSize, dst, true, true); } void -moveZMR(Context* c, unsigned srcSize, Assembler::Memory* src, - unsigned dstSize, Assembler::Register* dst) +moveZMR(Context* c, unsigned srcSize, lir::Memory* src, + unsigned dstSize, lir::Register* dst) { load(c, srcSize, src->base, src->offset, src->index, src->scale, dstSize, dst, true, false); } void -andR(Context* c, unsigned size, Assembler::Register* a, - Assembler::Register* b, Assembler::Register* dst) +andR(Context* c, unsigned size, lir::Register* a, + lir::Register* b, lir::Register* dst) { if (size == 8) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); - Assembler::Register dh(dst->high); + lir::Register ah(a->high); + lir::Register bh(b->high); + lir::Register dh(dst->high); andR(c, 4, a, b, dst); andR(c, 4, &ah, &bh, &dh); @@ -1350,20 +1345,20 @@ andR(Context* c, unsigned size, Assembler::Register* a, } void -andC(Context* c, unsigned size, Assembler::Constant* a, - Assembler::Register* b, Assembler::Register* dst) +andC(Context* c, unsigned size, lir::Constant* a, + lir::Register* b, lir::Register* dst) { int64_t v = a->value->value(); if (size == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); - Assembler::Register dh(dst->high); + lir::Register bh(b->high); + lir::Register dh(dst->high); andC(c, 4, &al, b, dst); andC(c, 4, &ah, &bh, &dh); @@ -1403,7 +1398,7 @@ andC(Context* c, unsigned size, Assembler::Constant* a, emit(c, andis(dst->low, b->low, v32 >> 16)); } else { bool useTemporary = b->low == dst->low; - Assembler::Register tmp(dst->low); + lir::Register tmp(dst->low); if (useTemporary) { tmp.low = c->client->acquireTemporary(); } @@ -1434,13 +1429,13 @@ andC(Context* c, unsigned size, Assembler::Constant* a, } void -orR(Context* c, unsigned size, Assembler::Register* a, - Assembler::Register* b, Assembler::Register* dst) +orR(Context* c, unsigned size, lir::Register* a, + lir::Register* b, lir::Register* dst) { if (size == 8) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); - Assembler::Register dh(dst->high); + lir::Register ah(a->high); + lir::Register bh(b->high); + lir::Register dh(dst->high); orR(c, 4, a, b, dst); orR(c, 4, &ah, &bh, &dh); @@ -1450,20 +1445,20 @@ orR(Context* c, unsigned size, Assembler::Register* a, } void -orC(Context* c, unsigned size, Assembler::Constant* a, - Assembler::Register* b, Assembler::Register* dst) +orC(Context* c, unsigned size, lir::Constant* a, + lir::Register* b, lir::Register* dst) { int64_t v = a->value->value(); if (size == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); - Assembler::Register dh(dst->high); + lir::Register bh(b->high); + lir::Register dh(dst->high); orC(c, 4, &al, b, dst); orC(c, 4, &ah, &bh, &dh); @@ -1476,13 +1471,13 @@ orC(Context* c, unsigned size, Assembler::Constant* a, } void -xorR(Context* c, unsigned size, Assembler::Register* a, - Assembler::Register* b, Assembler::Register* dst) +xorR(Context* c, unsigned size, lir::Register* a, + lir::Register* b, lir::Register* dst) { if (size == 8) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); - Assembler::Register dh(dst->high); + lir::Register ah(a->high); + lir::Register bh(b->high); + lir::Register dh(dst->high); xorR(c, 4, a, b, dst); xorR(c, 4, &ah, &bh, &dh); @@ -1492,20 +1487,20 @@ xorR(Context* c, unsigned size, Assembler::Register* a, } void -xorC(Context* c, unsigned size, Assembler::Constant* a, - Assembler::Register* b, Assembler::Register* dst) +xorC(Context* c, unsigned size, lir::Constant* a, + lir::Register* b, lir::Register* dst) { uint64_t v = a->value->value(); if (size == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); - Assembler::Register dh(dst->high); + lir::Register bh(b->high); + lir::Register dh(dst->high); xorC(c, 4, &al, b, dst); xorC(c, 4, &ah, &bh, &dh); @@ -1520,12 +1515,12 @@ xorC(Context* c, unsigned size, Assembler::Constant* a, } void -moveAR2(Context* c, unsigned srcSize UNUSED, Assembler::Address* src, - unsigned dstSize, Assembler::Register* dst, unsigned promiseOffset) +moveAR2(Context* c, unsigned srcSize UNUSED, lir::Address* src, + unsigned dstSize, lir::Register* dst, unsigned promiseOffset) { assert(c, srcSize == 4 and dstSize == 4); - Assembler::Memory memory(dst->low, 0, -1, 0); + lir::Memory memory(dst->low, 0, -1, 0); appendImmediateTask (c, src->address, offset(c), TargetBytesPerWord, promiseOffset, true); @@ -1535,15 +1530,15 @@ moveAR2(Context* c, unsigned srcSize UNUSED, Assembler::Address* src, } void -moveAR(Context* c, unsigned srcSize, Assembler::Address* src, - unsigned dstSize, Assembler::Register* dst) +moveAR(Context* c, unsigned srcSize, lir::Address* src, + unsigned dstSize, lir::Register* dst) { moveAR2(c, srcSize, src, dstSize, dst, 0); } void -compareRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +compareRR(Context* c, unsigned aSize UNUSED, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == 4 and bSize == 4); @@ -1551,15 +1546,15 @@ compareRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, } void -compareCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +compareCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == 4 and bSize == 4); if (a->value->resolved() and isInt16(a->value->value())) { emit(c, cmpwi(b->low, a->value->value())); } else { - Assembler::Register tmp(c->client->acquireTemporary()); + lir::Register tmp(c->client->acquireTemporary()); moveCR(c, aSize, a, bSize, &tmp); compareRR(c, bSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -1567,32 +1562,32 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a, } void -compareCM(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Memory* b) +compareCM(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Memory* b) { assert(c, aSize == 4 and bSize == 4); - Assembler::Register tmp(c->client->acquireTemporary()); + lir::Register tmp(c->client->acquireTemporary()); moveMR(c, bSize, b, bSize, &tmp); compareCR(c, aSize, a, bSize, &tmp); c->client->releaseTemporary(tmp.low); } void -compareRM(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Memory* b) +compareRM(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize, lir::Memory* b) { assert(c, aSize == 4 and bSize == 4); - Assembler::Register tmp(c->client->acquireTemporary()); + lir::Register tmp(c->client->acquireTemporary()); moveMR(c, bSize, b, bSize, &tmp); compareRR(c, aSize, a, bSize, &tmp); c->client->releaseTemporary(tmp.low); } void -compareUnsignedRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +compareUnsignedRR(Context* c, unsigned aSize UNUSED, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == 4 and bSize == 4); @@ -1600,15 +1595,15 @@ compareUnsignedRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, } void -compareUnsignedCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +compareUnsignedCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == 4 and bSize == 4); if (a->value->resolved() and (a->value->value() >> 16) == 0) { emit(c, cmplwi(b->low, a->value->value())); } else { - Assembler::Register tmp(c->client->acquireTemporary()); + lir::Register tmp(c->client->acquireTemporary()); moveCR(c, aSize, a, bSize, &tmp); compareUnsignedRR(c, bSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -1616,25 +1611,25 @@ compareUnsignedCR(Context* c, unsigned aSize, Assembler::Constant* a, } int32_t -branch(Context* c, TernaryOperation op) +branch(Context* c, lir::TernaryOperation op) { switch (op) { - case JumpIfEqual: + case lir::JumpIfEqual: return beq(0); - case JumpIfNotEqual: + case lir::JumpIfNotEqual: return bne(0); - case JumpIfLess: + case lir::JumpIfLess: return blt(0); - case JumpIfGreater: + case lir::JumpIfGreater: return bgt(0); - case JumpIfLessOrEqual: + case lir::JumpIfLessOrEqual: return ble(0); - case JumpIfGreaterOrEqual: + case lir::JumpIfGreaterOrEqual: return bge(0); default: @@ -1643,22 +1638,22 @@ branch(Context* c, TernaryOperation op) } void -conditional(Context* c, int32_t branch, Assembler::Constant* target) +conditional(Context* c, int32_t branch, lir::Constant* target) { appendOffsetTask(c, target->value, offset(c), true); emit(c, branch); } void -branch(Context* c, TernaryOperation op, Assembler::Constant* target) +branch(Context* c, lir::TernaryOperation op, lir::Constant* target) { conditional(c, branch(c, op), target); } void -branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, - Assembler::Operand* ah, Assembler::Operand* bl, - Assembler::Operand* bh, Assembler::Constant* target, +branchLong(Context* c, lir::TernaryOperation op, lir::Operand* al, + lir::Operand* ah, lir::Operand* bl, + lir::Operand* bh, lir::Constant* target, BinaryOperationType compareSigned, BinaryOperationType compareUnsigned) { @@ -1667,7 +1662,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, unsigned next = 0; switch (op) { - case JumpIfEqual: + case lir::JumpIfEqual: next = c->code.length(); emit(c, bne(0)); @@ -1675,14 +1670,14 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, beq(0), target); break; - case JumpIfNotEqual: + case lir::JumpIfNotEqual: conditional(c, bne(0), target); compareSigned(c, 4, al, 4, bl); conditional(c, bne(0), target); break; - case JumpIfLess: + case lir::JumpIfLess: conditional(c, blt(0), target); next = c->code.length(); @@ -1692,7 +1687,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, blt(0), target); break; - case JumpIfGreater: + case lir::JumpIfGreater: conditional(c, bgt(0), target); next = c->code.length(); @@ -1702,7 +1697,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, bgt(0), target); break; - case JumpIfLessOrEqual: + case lir::JumpIfLessOrEqual: conditional(c, blt(0), target); next = c->code.length(); @@ -1712,7 +1707,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, ble(0), target); break; - case JumpIfGreaterOrEqual: + case lir::JumpIfGreaterOrEqual: conditional(c, bgt(0), target); next = c->code.length(); @@ -1734,13 +1729,13 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, } void -branchRR(Context* c, TernaryOperation op, unsigned size, - Assembler::Register* a, Assembler::Register* b, - Assembler::Constant* target) +branchRR(Context* c, lir::TernaryOperation op, unsigned size, + lir::Register* a, lir::Register* b, + lir::Constant* target) { if (size > TargetBytesPerWord) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register ah(a->high); + lir::Register bh(b->high); branchLong(c, op, a, &ah, b, &bh, target, CAST2(compareRR), CAST2(compareUnsignedRR)); @@ -1751,20 +1746,20 @@ branchRR(Context* c, TernaryOperation op, unsigned size, } void -branchCR(Context* c, TernaryOperation op, unsigned size, - Assembler::Constant* a, Assembler::Register* b, - Assembler::Constant* target) +branchCR(Context* c, lir::TernaryOperation op, unsigned size, + lir::Constant* a, lir::Register* b, + lir::Constant* target) { if (size > TargetBytesPerWord) { int64_t v = a->value->value(); ResolvedPromise low(v & ~static_cast(0)); - Assembler::Constant al(&low); + lir::Constant al(&low); ResolvedPromise high((v >> 32) & ~static_cast(0)); - Assembler::Constant ah(&high); + lir::Constant ah(&high); - Assembler::Register bh(b->high); + lir::Register bh(b->high); branchLong(c, op, &al, &ah, b, &bh, target, CAST2(compareCR), CAST2(compareUnsignedCR)); @@ -1775,9 +1770,9 @@ branchCR(Context* c, TernaryOperation op, unsigned size, } void -branchRM(Context* c, TernaryOperation op, unsigned size, - Assembler::Register* a, Assembler::Memory* b, - Assembler::Constant* target) +branchRM(Context* c, lir::TernaryOperation op, unsigned size, + lir::Register* a, lir::Memory* b, + lir::Constant* target) { assert(c, size <= TargetBytesPerWord); @@ -1786,9 +1781,9 @@ branchRM(Context* c, TernaryOperation op, unsigned size, } void -branchCM(Context* c, TernaryOperation op, unsigned size, - Assembler::Constant* a, Assembler::Memory* b, - Assembler::Constant* target) +branchCM(Context* c, lir::TernaryOperation op, unsigned size, + lir::Constant* a, lir::Memory* b, + lir::Constant* target) { assert(c, size <= TargetBytesPerWord); @@ -1803,17 +1798,17 @@ shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask) } void -moveCM(Context* c, unsigned srcSize, Assembler::Constant* src, - unsigned dstSize, Assembler::Memory* dst) +moveCM(Context* c, unsigned srcSize, lir::Constant* src, + unsigned dstSize, lir::Memory* dst) { switch (dstSize) { case 8: { - Assembler::Constant srcHigh + lir::Constant srcHigh (shiftMaskPromise(c, src->value, 32, 0xFFFFFFFF)); - Assembler::Constant srcLow + lir::Constant srcLow (shiftMaskPromise(c, src->value, 0, 0xFFFFFFFF)); - Assembler::Memory dstLow + lir::Memory dstLow (dst->base, dst->offset + 4, dst->index, dst->scale); moveCM(c, 4, &srcLow, 4, &dstLow); @@ -1821,7 +1816,7 @@ moveCM(Context* c, unsigned srcSize, Assembler::Constant* src, } break; default: - Assembler::Register tmp(c->client->acquireTemporary()); + lir::Register tmp(c->client->acquireTemporary()); moveCR(c, srcSize, src, dstSize, &tmp); moveRM(c, dstSize, &tmp, dstSize, dst); c->client->releaseTemporary(tmp.low); @@ -1829,13 +1824,13 @@ moveCM(Context* c, unsigned srcSize, Assembler::Constant* src, } void -negateRR(Context* c, unsigned srcSize, Assembler::Register* src, - unsigned dstSize UNUSED, Assembler::Register* dst) +negateRR(Context* c, unsigned srcSize, lir::Register* src, + unsigned dstSize UNUSED, lir::Register* dst) { assert(c, srcSize == dstSize); if (srcSize == 8) { - Assembler::Register dstHigh(dst->high); + lir::Register dstHigh(dst->high); emit(c, subfic(dst->low, src->low, 0)); emit(c, subfze(dst->high, src->high)); @@ -1845,7 +1840,7 @@ negateRR(Context* c, unsigned srcSize, Assembler::Register* src, } void -callR(Context* c, unsigned size UNUSED, Assembler::Register* target) +callR(Context* c, unsigned size UNUSED, lir::Register* target) { assert(c, size == TargetBytesPerWord); @@ -1854,7 +1849,7 @@ callR(Context* c, unsigned size UNUSED, Assembler::Register* target) } void -callC(Context* c, unsigned size UNUSED, Assembler::Constant* target) +callC(Context* c, unsigned size UNUSED, lir::Constant* target) { assert(c, size == TargetBytesPerWord); @@ -1863,51 +1858,51 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* target) } void -longCallC(Context* c, unsigned size UNUSED, Assembler::Constant* target) +longCallC(Context* c, unsigned size UNUSED, lir::Constant* target) { assert(c, size == TargetBytesPerWord); - Assembler::Register tmp(0); + lir::Register tmp(0); moveCR2(c, TargetBytesPerWord, target, TargetBytesPerWord, &tmp, 12); callR(c, TargetBytesPerWord, &tmp); } void -alignedLongCallC(Context* c, unsigned size UNUSED, Assembler::Constant* target) +alignedLongCallC(Context* c, unsigned size UNUSED, lir::Constant* target) { assert(c, size == TargetBytesPerWord); - Assembler::Register tmp(c->client->acquireTemporary()); - Assembler::Address address(appendConstantPoolEntry(c, target->value)); + lir::Register tmp(c->client->acquireTemporary()); + lir::Address address(appendConstantPoolEntry(c, target->value)); moveAR2(c, TargetBytesPerWord, &address, TargetBytesPerWord, &tmp, 12); callR(c, TargetBytesPerWord, &tmp); c->client->releaseTemporary(tmp.low); } void -longJumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target) +longJumpC(Context* c, unsigned size UNUSED, lir::Constant* target) { assert(c, size == TargetBytesPerWord); - Assembler::Register tmp(0); + lir::Register tmp(0); moveCR2(c, TargetBytesPerWord, target, TargetBytesPerWord, &tmp, 12); jumpR(c, TargetBytesPerWord, &tmp); } void -alignedLongJumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target) +alignedLongJumpC(Context* c, unsigned size UNUSED, lir::Constant* target) { assert(c, size == TargetBytesPerWord); - Assembler::Register tmp(c->client->acquireTemporary()); - Assembler::Address address(appendConstantPoolEntry(c, target->value)); + lir::Register tmp(c->client->acquireTemporary()); + lir::Address address(appendConstantPoolEntry(c, target->value)); moveAR2(c, TargetBytesPerWord, &address, TargetBytesPerWord, &tmp, 12); jumpR(c, TargetBytesPerWord, &tmp); c->client->releaseTemporary(tmp.low); } void -jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target) +jumpC(Context* c, unsigned size UNUSED, lir::Constant* target) { assert(c, size == TargetBytesPerWord); @@ -1993,10 +1988,10 @@ nextFrame(ArchitectureContext* c UNUSED, int32_t* start, unsigned size, void populateTables(ArchitectureContext* c) { - const OperandType C = ConstantOperand; - const OperandType A = AddressOperand; - const OperandType R = RegisterOperand; - const OperandType M = MemoryOperand; + const lir::OperandType C = lir::ConstantOperand; + const lir::OperandType A = lir::AddressOperand; + const lir::OperandType R = lir::RegisterOperand; + const lir::OperandType M = lir::MemoryOperand; OperationType* zo = c->operations; UnaryOperationType* uo = c->unaryOperations; @@ -2004,74 +1999,74 @@ populateTables(ArchitectureContext* c) TernaryOperationType* to = c->ternaryOperations; BranchOperationType* bro = c->branchOperations; - zo[Return] = return_; - zo[LoadBarrier] = memoryBarrier; - zo[StoreStoreBarrier] = memoryBarrier; - zo[StoreLoadBarrier] = memoryBarrier; - zo[Trap] = trap; + zo[lir::Return] = return_; + zo[lir::LoadBarrier] = memoryBarrier; + zo[lir::StoreStoreBarrier] = memoryBarrier; + zo[lir::StoreLoadBarrier] = memoryBarrier; + zo[lir::Trap] = trap; - uo[index(c, LongCall, C)] = CAST1(longCallC); + uo[index(c, lir::LongCall, C)] = CAST1(longCallC); - uo[index(c, AlignedLongCall, C)] = CAST1(alignedLongCallC); + uo[index(c, lir::AlignedLongCall, C)] = CAST1(alignedLongCallC); - uo[index(c, LongJump, C)] = CAST1(longJumpC); + uo[index(c, lir::LongJump, C)] = CAST1(longJumpC); - uo[index(c, AlignedLongJump, C)] = CAST1(alignedLongJumpC); + uo[index(c, lir::AlignedLongJump, C)] = CAST1(alignedLongJumpC); - uo[index(c, Jump, R)] = CAST1(jumpR); - uo[index(c, Jump, C)] = CAST1(jumpC); + uo[index(c, lir::Jump, R)] = CAST1(jumpR); + uo[index(c, lir::Jump, C)] = CAST1(jumpC); - uo[index(c, AlignedJump, R)] = CAST1(jumpR); - uo[index(c, AlignedJump, C)] = CAST1(jumpC); + uo[index(c, lir::AlignedJump, R)] = CAST1(jumpR); + uo[index(c, lir::AlignedJump, C)] = CAST1(jumpC); - uo[index(c, Call, C)] = CAST1(callC); - uo[index(c, Call, R)] = CAST1(callR); + uo[index(c, lir::Call, C)] = CAST1(callC); + uo[index(c, lir::Call, R)] = CAST1(callR); - uo[index(c, AlignedCall, C)] = CAST1(callC); - uo[index(c, AlignedCall, R)] = CAST1(callR); + uo[index(c, lir::AlignedCall, C)] = CAST1(callC); + uo[index(c, lir::AlignedCall, R)] = CAST1(callR); - bo[index(c, Move, R, R)] = CAST2(moveRR); - bo[index(c, Move, C, R)] = CAST2(moveCR); - bo[index(c, Move, C, M)] = CAST2(moveCM); - bo[index(c, Move, M, R)] = CAST2(moveMR); - bo[index(c, Move, R, M)] = CAST2(moveRM); - bo[index(c, Move, A, R)] = CAST2(moveAR); + bo[index(c, lir::Move, R, R)] = CAST2(moveRR); + bo[index(c, lir::Move, C, R)] = CAST2(moveCR); + bo[index(c, lir::Move, C, M)] = CAST2(moveCM); + bo[index(c, lir::Move, M, R)] = CAST2(moveMR); + bo[index(c, lir::Move, R, M)] = CAST2(moveRM); + bo[index(c, lir::Move, A, R)] = CAST2(moveAR); - bo[index(c, MoveZ, R, R)] = CAST2(moveZRR); - bo[index(c, MoveZ, M, R)] = CAST2(moveZMR); - bo[index(c, MoveZ, C, R)] = CAST2(moveCR); + bo[index(c, lir::MoveZ, R, R)] = CAST2(moveZRR); + bo[index(c, lir::MoveZ, M, R)] = CAST2(moveZMR); + bo[index(c, lir::MoveZ, C, R)] = CAST2(moveCR); - bo[index(c, Negate, R, R)] = CAST2(negateRR); + bo[index(c, lir::Negate, R, R)] = CAST2(negateRR); - to[index(c, Add, R)] = CAST3(addR); - to[index(c, Add, C)] = CAST3(addC); + to[index(c, lir::Add, R)] = CAST3(addR); + to[index(c, lir::Add, C)] = CAST3(addC); - to[index(c, Subtract, R)] = CAST3(subR); - to[index(c, Subtract, C)] = CAST3(subC); + to[index(c, lir::Subtract, R)] = CAST3(subR); + to[index(c, lir::Subtract, C)] = CAST3(subC); - to[index(c, Multiply, R)] = CAST3(multiplyR); + to[index(c, lir::Multiply, R)] = CAST3(multiplyR); - to[index(c, Divide, R)] = CAST3(divideR); + to[index(c, lir::Divide, R)] = CAST3(divideR); - to[index(c, Remainder, R)] = CAST3(remainderR); + to[index(c, lir::Remainder, R)] = CAST3(remainderR); - to[index(c, ShiftLeft, R)] = CAST3(shiftLeftR); - to[index(c, ShiftLeft, C)] = CAST3(shiftLeftC); + to[index(c, lir::ShiftLeft, R)] = CAST3(shiftLeftR); + to[index(c, lir::ShiftLeft, C)] = CAST3(shiftLeftC); - to[index(c, ShiftRight, R)] = CAST3(shiftRightR); - to[index(c, ShiftRight, C)] = CAST3(shiftRightC); + to[index(c, lir::ShiftRight, R)] = CAST3(shiftRightR); + to[index(c, lir::ShiftRight, C)] = CAST3(shiftRightC); - to[index(c, UnsignedShiftRight, R)] = CAST3(unsignedShiftRightR); - to[index(c, UnsignedShiftRight, C)] = CAST3(unsignedShiftRightC); + to[index(c, lir::UnsignedShiftRight, R)] = CAST3(unsignedShiftRightR); + to[index(c, lir::UnsignedShiftRight, C)] = CAST3(unsignedShiftRightC); - to[index(c, And, C)] = CAST3(andC); - to[index(c, And, R)] = CAST3(andR); + to[index(c, lir::And, C)] = CAST3(andC); + to[index(c, lir::And, R)] = CAST3(andR); - to[index(c, Or, C)] = CAST3(orC); - to[index(c, Or, R)] = CAST3(orR); + to[index(c, lir::Or, C)] = CAST3(orC); + to[index(c, lir::Or, R)] = CAST3(orR); - to[index(c, Xor, C)] = CAST3(xorC); - to[index(c, Xor, R)] = CAST3(xorR); + to[index(c, lir::Xor, C)] = CAST3(xorC); + to[index(c, lir::Xor, R)] = CAST3(xorR); bro[branchIndex(c, R, R)] = CAST_BRANCH(branchRR); bro[branchIndex(c, C, R)] = CAST_BRANCH(branchCR); @@ -2114,7 +2109,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual int returnHigh() { - return (TargetBytesPerWord == 4 ? 3 : NoRegister); + return (TargetBytesPerWord == 4 ? 3 : lir::NoRegister); } virtual int virtualCallTarget() { @@ -2191,28 +2186,28 @@ class MyArchitecture: public Assembler::Architecture { - reinterpret_cast(instruction))); } - virtual void updateCall(UnaryOperation op UNUSED, + virtual void updateCall(lir::UnaryOperation op UNUSED, void* returnAddress, void* newTarget) { switch (op) { - case Call: - case Jump: - case AlignedCall: - case AlignedJump: { + case lir::Call: + case lir::Jump: + case lir::AlignedCall: + case lir::AlignedJump: { updateOffset(c.s, static_cast(returnAddress) - 4, false, reinterpret_cast(newTarget), 0); } break; - case LongCall: - case LongJump: { + case lir::LongCall: + case lir::LongJump: { updateImmediate (c.s, static_cast(returnAddress) - 12, reinterpret_cast(newTarget), TargetBytesPerWord, false); } break; - case AlignedLongCall: - case AlignedLongJump: { + case lir::AlignedLongCall: + case lir::AlignedLongJump: { uint32_t* p = static_cast(returnAddress) - 4; *reinterpret_cast(unha16(p[0] & 0xFFFF, p[1] & 0xFFFF)) = newTarget; @@ -2268,34 +2263,34 @@ class MyArchitecture: public Assembler::Architecture { return 0; } - virtual BinaryOperation hasBinaryIntrinsic(Thread*, object) { - return NoBinaryOperation; + virtual lir::BinaryOperation hasBinaryIntrinsic(Thread*, object) { + return lir::NoBinaryOperation; } - virtual TernaryOperation hasTernaryIntrinsic(Thread*, object) { - return NoTernaryOperation; + virtual lir::TernaryOperation hasTernaryIntrinsic(Thread*, object) { + return lir::NoTernaryOperation; } - virtual bool alwaysCondensed(BinaryOperation) { + virtual bool alwaysCondensed(lir::BinaryOperation) { return false; } - virtual bool alwaysCondensed(TernaryOperation) { + virtual bool alwaysCondensed(lir::TernaryOperation) { return false; } virtual void plan - (UnaryOperation, + (lir::UnaryOperation, unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask, bool* thunk) { - *aTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); *aRegisterMask = ~static_cast(0); *thunk = false; } virtual void planSource - (BinaryOperation op, + (lir::BinaryOperation op, unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask, unsigned, bool* thunk) { @@ -2305,17 +2300,17 @@ class MyArchitecture: public Assembler::Architecture { *thunk = false; switch (op) { - case Negate: - *aTypeMask = (1 << RegisterOperand); + case lir::Negate: + *aTypeMask = (1 << lir::RegisterOperand); break; - case Absolute: - case FloatAbsolute: - case FloatSquareRoot: - case FloatNegate: - case Float2Float: - case Float2Int: - case Int2Float: + case lir::Absolute: + case lir::FloatAbsolute: + case lir::FloatSquareRoot: + case lir::FloatNegate: + case lir::Float2Float: + case lir::Float2Int: + case lir::Int2Float: *thunk = true; break; @@ -2325,16 +2320,16 @@ class MyArchitecture: public Assembler::Architecture { } virtual void planDestination - (BinaryOperation op, + (lir::BinaryOperation op, unsigned, uint8_t, uint64_t, unsigned, uint8_t* bTypeMask, uint64_t* bRegisterMask) { - *bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *bTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); *bRegisterMask = ~static_cast(0); switch (op) { - case Negate: - *bTypeMask = (1 << RegisterOperand); + case lir::Negate: + *bTypeMask = (1 << lir::RegisterOperand); break; default: @@ -2353,42 +2348,42 @@ class MyArchitecture: public Assembler::Architecture { *tmpTypeMask = 0; *tmpRegisterMask = 0; - if (dstTypeMask & (1 << MemoryOperand)) { + if (dstTypeMask & (1 << lir::MemoryOperand)) { // can't move directly from memory or constant to memory - *srcTypeMask = 1 << RegisterOperand; - *tmpTypeMask = 1 << RegisterOperand; + *srcTypeMask = 1 << lir::RegisterOperand; + *tmpTypeMask = 1 << lir::RegisterOperand; *tmpRegisterMask = ~static_cast(0); } } virtual void planSource - (TernaryOperation op, + (lir::TernaryOperation op, unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask, unsigned, uint8_t* bTypeMask, uint64_t* bRegisterMask, unsigned, bool* thunk) { - *aTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); *aRegisterMask = ~static_cast(0); - *bTypeMask = (1 << RegisterOperand); + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = ~static_cast(0); *thunk = false; switch (op) { - case Add: - case Subtract: + case lir::Add: + case lir::Subtract: if (aSize == 8) { - *aTypeMask = *bTypeMask = (1 << RegisterOperand); + *aTypeMask = *bTypeMask = (1 << lir::RegisterOperand); } break; - case Multiply: - *aTypeMask = *bTypeMask = (1 << RegisterOperand); + case lir::Multiply: + *aTypeMask = *bTypeMask = (1 << lir::RegisterOperand); break; - case Divide: - case Remainder: + case lir::Divide: + case lir::Remainder: // todo: we shouldn't need to defer to thunks for integers which // are smaller than or equal to tne native word size, but // PowerPC doesn't generate traps for divide by zero, so we'd @@ -2398,25 +2393,25 @@ class MyArchitecture: public Assembler::Architecture { if (true) {//if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); } break; - case FloatAdd: - case FloatSubtract: - case FloatMultiply: - case FloatDivide: - case FloatRemainder: - case JumpIfFloatEqual: - case JumpIfFloatNotEqual: - case JumpIfFloatLess: - case JumpIfFloatGreater: - case JumpIfFloatLessOrEqual: - case JumpIfFloatGreaterOrEqual: - case JumpIfFloatLessOrUnordered: - case JumpIfFloatGreaterOrUnordered: - case JumpIfFloatLessOrEqualOrUnordered: - case JumpIfFloatGreaterOrEqualOrUnordered: + case lir::FloatAdd: + case lir::FloatSubtract: + case lir::FloatMultiply: + case lir::FloatDivide: + case lir::FloatRemainder: + case lir::JumpIfFloatEqual: + case lir::JumpIfFloatNotEqual: + case lir::JumpIfFloatLess: + case lir::JumpIfFloatGreater: + case lir::JumpIfFloatLessOrEqual: + case lir::JumpIfFloatGreaterOrEqual: + case lir::JumpIfFloatLessOrUnordered: + case lir::JumpIfFloatGreaterOrUnordered: + case lir::JumpIfFloatLessOrEqualOrUnordered: + case lir::JumpIfFloatGreaterOrEqualOrUnordered: *thunk = true; break; @@ -2426,16 +2421,16 @@ class MyArchitecture: public Assembler::Architecture { } virtual void planDestination - (TernaryOperation op, + (lir::TernaryOperation op, unsigned, uint8_t, uint64_t, unsigned, uint8_t, const uint64_t, unsigned, uint8_t* cTypeMask, uint64_t* cRegisterMask) { if (isBranch(op)) { - *cTypeMask = (1 << ConstantOperand); + *cTypeMask = (1 << lir::ConstantOperand); *cRegisterMask = 0; } else { - *cTypeMask = (1 << RegisterOperand); + *cTypeMask = (1 << lir::RegisterOperand); *cRegisterMask = ~static_cast(0); } } @@ -2474,41 +2469,41 @@ class MyAssembler: public Assembler { virtual void checkStackOverflow(uintptr_t handler, unsigned stackLimitOffsetFromThread) { - Register stack(StackRegister); - Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread); - Constant handlerConstant + lir::Register stack(StackRegister); + lir::Memory stackLimit(ThreadRegister, stackLimitOffsetFromThread); + lir::Constant handlerConstant (new(c.zone) ResolvedPromise(handler)); - branchRM(&c, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, + branchRM(&c, lir::JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, &handlerConstant); } virtual void saveFrame(unsigned stackOffset, unsigned) { - Register returnAddress(0); + lir::Register returnAddress(0); emit(&c, mflr(returnAddress.low)); - Memory returnAddressDst + lir::Memory returnAddressDst (StackRegister, ReturnAddressOffset * TargetBytesPerWord); moveRM(&c, TargetBytesPerWord, &returnAddress, TargetBytesPerWord, &returnAddressDst); - Register stack(StackRegister); - Memory stackDst(ThreadRegister, stackOffset); + lir::Register stack(StackRegister); + lir::Memory stackDst(ThreadRegister, stackOffset); moveRM(&c, TargetBytesPerWord, &stack, TargetBytesPerWord, &stackDst); } virtual void pushFrame(unsigned argumentCount, ...) { struct { unsigned size; - OperandType type; - Operand* operand; + lir::OperandType type; + lir::Operand* operand; } arguments[argumentCount]; va_list a; va_start(a, argumentCount); unsigned footprint = 0; for (unsigned i = 0; i < argumentCount; ++i) { arguments[i].size = va_arg(a, unsigned); - arguments[i].type = static_cast(va_arg(a, int)); - arguments[i].operand = va_arg(a, Operand*); + arguments[i].type = static_cast(va_arg(a, int)); + arguments[i].operand = va_arg(a, lir::Operand*); footprint += ceilingDivide(arguments[i].size, TargetBytesPerWord); } va_end(a); @@ -2518,21 +2513,21 @@ class MyAssembler: public Assembler { unsigned offset = 0; for (unsigned i = 0; i < argumentCount; ++i) { if (i < arch_->argumentRegisterCount()) { - Register dst(arch_->argumentRegister(i)); + lir::Register dst(arch_->argumentRegister(i)); - apply(Move, - arguments[i].size, arguments[i].type, arguments[i].operand, - pad(arguments[i].size, TargetBytesPerWord), RegisterOperand, - &dst); + apply(lir::Move, + OperandInfo(arguments[i].size, arguments[i].type, arguments[i].operand), + OperandInfo(pad(arguments[i].size, TargetBytesPerWord), lir::RegisterOperand, + &dst)); offset += ceilingDivide(arguments[i].size, TargetBytesPerWord); } else { - Memory dst + lir::Memory dst (ThreadRegister, (offset + FrameFooterSize) * TargetBytesPerWord); - apply(Move, - arguments[i].size, arguments[i].type, arguments[i].operand, - pad(arguments[i].size, TargetBytesPerWord), MemoryOperand, &dst); + apply(lir::Move, + OperandInfo(arguments[i].size, arguments[i].type, arguments[i].operand), + OperandInfo(pad(arguments[i].size, TargetBytesPerWord), lir::MemoryOperand, &dst)); offset += ceilingDivide(arguments[i].size, TargetBytesPerWord); } @@ -2540,37 +2535,37 @@ class MyAssembler: public Assembler { } virtual void allocateFrame(unsigned footprint) { - Register returnAddress(0); + lir::Register returnAddress(0); emit(&c, mflr(returnAddress.low)); - Memory returnAddressDst + lir::Memory returnAddressDst (StackRegister, ReturnAddressOffset * TargetBytesPerWord); moveRM(&c, TargetBytesPerWord, &returnAddress, TargetBytesPerWord, &returnAddressDst); - Register stack(StackRegister); - Memory stackDst(StackRegister, -footprint * TargetBytesPerWord); + lir::Register stack(StackRegister); + lir::Memory stackDst(StackRegister, -footprint * TargetBytesPerWord); moveAndUpdateRM (&c, TargetBytesPerWord, &stack, TargetBytesPerWord, &stackDst); } virtual void adjustFrame(unsigned difference) { - Register nextStack(0); - Memory stackSrc(StackRegister, 0); + lir::Register nextStack(0); + lir::Memory stackSrc(StackRegister, 0); moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &nextStack); - Memory stackDst(StackRegister, -difference * TargetBytesPerWord); + lir::Memory stackDst(StackRegister, -difference * TargetBytesPerWord); moveAndUpdateRM (&c, TargetBytesPerWord, &nextStack, TargetBytesPerWord, &stackDst); } virtual void popFrame(unsigned) { - Register stack(StackRegister); - Memory stackSrc(StackRegister, 0); + lir::Register stack(StackRegister); + lir::Memory stackSrc(StackRegister, 0); moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &stack); - Register returnAddress(0); - Memory returnAddressSrc + lir::Register returnAddress(0); + lir::Memory returnAddressSrc (StackRegister, ReturnAddressOffset * TargetBytesPerWord); moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, &returnAddress); @@ -2585,8 +2580,8 @@ class MyAssembler: public Assembler { { if (TailCalls) { if (offset) { - Register tmp(0); - Memory returnAddressSrc + lir::Register tmp(0); + lir::Memory returnAddressSrc (StackRegister, (ReturnAddressOffset + footprint) * TargetBytesPerWord); moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, @@ -2594,29 +2589,29 @@ class MyAssembler: public Assembler { emit(&c, mtlr(tmp.low)); - Memory stackSrc(StackRegister, footprint * TargetBytesPerWord); + lir::Memory stackSrc(StackRegister, footprint * TargetBytesPerWord); moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &tmp); - Memory stackDst + lir::Memory stackDst (StackRegister, (footprint - offset) * TargetBytesPerWord); moveAndUpdateRM (&c, TargetBytesPerWord, &tmp, TargetBytesPerWord, &stackDst); - if (returnAddressSurrogate != NoRegister) { + if (returnAddressSurrogate != lir::NoRegister) { assert(&c, offset > 0); - Register ras(returnAddressSurrogate); - Memory dst + lir::Register ras(returnAddressSurrogate); + lir::Memory dst (StackRegister, (ReturnAddressOffset + offset) * TargetBytesPerWord); moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst); } - if (framePointerSurrogate != NoRegister) { + if (framePointerSurrogate != lir::NoRegister) { assert(&c, offset > 0); - Register fps(framePointerSurrogate); - Memory dst(StackRegister, offset * TargetBytesPerWord); + lir::Register fps(framePointerSurrogate); + lir::Memory dst(StackRegister, offset * TargetBytesPerWord); moveRM(&c, TargetBytesPerWord, &fps, TargetBytesPerWord, &dst); } } else { @@ -2636,11 +2631,11 @@ class MyAssembler: public Assembler { assert(&c, (argumentFootprint % StackAlignmentInWords) == 0); if (TailCalls and argumentFootprint > StackAlignmentInWords) { - Register tmp(0); - Memory stackSrc(StackRegister, 0); + lir::Register tmp(0); + lir::Memory stackSrc(StackRegister, 0); moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &tmp); - Memory stackDst(StackRegister, + lir::Memory stackDst(StackRegister, (argumentFootprint - StackAlignmentInWords) * TargetBytesPerWord); moveAndUpdateRM @@ -2655,64 +2650,56 @@ class MyAssembler: public Assembler { { popFrame(frameFootprint); - Register tmp1(0); - Memory stackSrc(StackRegister, 0); + lir::Register tmp1(0); + lir::Memory stackSrc(StackRegister, 0); moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &tmp1); - Register tmp2(5); - Memory newStackSrc(ThreadRegister, stackOffsetFromThread); + lir::Register tmp2(5); + lir::Memory newStackSrc(ThreadRegister, stackOffsetFromThread); moveMR(&c, TargetBytesPerWord, &newStackSrc, TargetBytesPerWord, &tmp2); - Register stack(StackRegister); + lir::Register stack(StackRegister); subR(&c, TargetBytesPerWord, &stack, &tmp2, &tmp2); - Memory stackDst(StackRegister, 0, tmp2.low); + lir::Memory stackDst(StackRegister, 0, tmp2.low); moveAndUpdateRM (&c, TargetBytesPerWord, &tmp1, TargetBytesPerWord, &stackDst); return_(&c); } - virtual void apply(Operation op) { + virtual void apply(lir::Operation op) { arch_->c.operations[op](&c); } - virtual void apply(UnaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand) + virtual void apply(lir::UnaryOperation op, OperandInfo a) { - arch_->c.unaryOperations[index(&(arch_->c), op, aType)] - (&c, aSize, aOperand); + arch_->c.unaryOperations[index(&(arch_->c), op, a.type)] + (&c, a.size, a.operand); } - virtual void apply(BinaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand, - unsigned bSize, OperandType bType, Operand* bOperand) + virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) { - arch_->c.binaryOperations[index(&(arch_->c), op, aType, bType)] - (&c, aSize, aOperand, bSize, bOperand); + arch_->c.binaryOperations[index(&(arch_->c), op, a.type, b.type)] + (&c, a.size, a.operand, b.size, b.operand); } - virtual void apply(TernaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand, - unsigned bSize, OperandType bType UNUSED, - Operand* bOperand, - unsigned cSize UNUSED, OperandType cType UNUSED, - Operand* cOperand) + virtual void apply(lir::TernaryOperation op, OperandInfo a, OperandInfo b, OperandInfo c) { if (isBranch(op)) { - assert(&c, aSize == bSize); - assert(&c, cSize == TargetBytesPerWord); - assert(&c, cType == ConstantOperand); + assert(&this->c, a.size == b.size); + assert(&this->c, c.size == TargetBytesPerWord); + assert(&this->c, c.type == lir::ConstantOperand); - arch_->c.branchOperations[branchIndex(&(arch_->c), aType, bType)] - (&c, op, aSize, aOperand, bOperand, cOperand); + arch_->c.branchOperations[branchIndex(&(arch_->c), a.type, b.type)] + (&this->c, op, a.size, a.operand, b.operand, c.operand); } else { - assert(&c, bSize == cSize); - assert(&c, bType == RegisterOperand); - assert(&c, cType == RegisterOperand); + assert(&this->c, b.size == c.size); + assert(&this->c, b.type == lir::RegisterOperand); + assert(&this->c, c.type == lir::RegisterOperand); - arch_->c.ternaryOperations[index(&(arch_->c), op, aType)] - (&c, bSize, aOperand, bOperand, cOperand); + arch_->c.ternaryOperations[index(&(arch_->c), op, a.type)] + (&this->c, b.size, a.operand, b.operand, c.operand); } } diff --git a/src/codegen/promise.h b/src/codegen/promise.h new file mode 100644 index 0000000000..1e21943999 --- /dev/null +++ b/src/codegen/promise.h @@ -0,0 +1,159 @@ +/* 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_PROMISE_H +#define AVIAN_CODEGEN_PROMISE_H + +#include "allocator.h" + +namespace avian { +namespace codegen { + +class Promise { + public: + class Listener { + public: + virtual bool resolve(int64_t value, void** location) = 0; + + Listener* next; + }; + + virtual int64_t value() = 0; + virtual bool resolved() = 0; + virtual Listener* listen(unsigned) { return 0; } +}; + +class ResolvedPromise: public Promise { + public: + ResolvedPromise(int64_t value): value_(value) { } + + virtual int64_t value() { + return value_; + } + + virtual bool resolved() { + return true; + } + + int64_t value_; +}; + +class ShiftMaskPromise: public Promise { + public: + ShiftMaskPromise(Promise* base, unsigned shift, int64_t mask): + base(base), shift(shift), mask(mask) + { } + + virtual int64_t value() { + return (base->value() >> shift) & mask; + } + + virtual bool resolved() { + return base->resolved(); + } + + Promise* base; + unsigned shift; + int64_t mask; +}; + +class CombinedPromise: public Promise { + public: + CombinedPromise(Promise* low, Promise* high): + low(low), high(high) + { } + + virtual int64_t value() { + return low->value() | (high->value() << 32); + } + + virtual bool resolved() { + return low->resolved() and high->resolved(); + } + + Promise* low; + Promise* high; +}; + +class OffsetPromise: public Promise { + public: + OffsetPromise(Promise* base, int64_t offset): + base(base), offset(offset) + { } + + virtual int64_t value() { + return base->value() + offset; + } + + virtual bool resolved() { + return base->resolved(); + } + + Promise* base; + int64_t offset; +}; + +class ListenPromise: public Promise { + public: + ListenPromise(vm::System* s, vm::Allocator* allocator): + s(s), allocator(allocator), listener(0) + { } + + virtual int64_t value() { + abort(s); + } + + virtual bool resolved() { + return false; + } + + virtual Listener* listen(unsigned sizeInBytes) { + Listener* l = static_cast(allocator->allocate(sizeInBytes)); + l->next = listener; + listener = l; + return l; + } + + vm::System* s; + vm::Allocator* allocator; + Listener* listener; + Promise* promise; +}; + +class DelayedPromise: public ListenPromise { + public: + DelayedPromise(vm::System* s, vm::Allocator* allocator, Promise* basis, + DelayedPromise* next): + ListenPromise(s, allocator), basis(basis), next(next) + { } + + virtual int64_t value() { + abort(s); + } + + virtual bool resolved() { + return false; + } + + virtual Listener* listen(unsigned sizeInBytes) { + Listener* l = static_cast(allocator->allocate(sizeInBytes)); + l->next = listener; + listener = l; + return l; + } + + Promise* basis; + DelayedPromise* next; +}; + +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_PROMISE_H \ No newline at end of file diff --git a/src/codegen/targets.cpp b/src/codegen/targets.cpp index 64b5a0f630..2df6636120 100644 --- a/src/codegen/targets.cpp +++ b/src/codegen/targets.cpp @@ -14,7 +14,7 @@ namespace avian { namespace codegen { -vm::Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures UNUSED) { +Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures UNUSED) { #ifndef AVIAN_TARGET_ARCH #error "Must specify native target!" #endif diff --git a/src/codegen/targets.h b/src/codegen/targets.h index c4070b4641..1d146e4b4d 100644 --- a/src/codegen/targets.h +++ b/src/codegen/targets.h @@ -16,11 +16,11 @@ namespace avian { namespace codegen { -vm::Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures); +Assembler::Architecture* makeArchitectureNative(vm::System* system, bool useNativeFeatures); -vm::Assembler::Architecture* makeArchitectureX86(vm::System* system, bool useNativeFeatures); -vm::Assembler::Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures); -vm::Assembler::Architecture* makeArchitecturePowerpc(vm::System* system, bool useNativeFeatures); +Assembler::Architecture* makeArchitectureX86(vm::System* system, bool useNativeFeatures); +Assembler::Architecture* makeArchitectureArm(vm::System* system, bool useNativeFeatures); +Assembler::Architecture* makeArchitecturePowerpc(vm::System* system, bool useNativeFeatures); } // namespace codegen } // namespace avian diff --git a/src/codegen/x86/assembler.cpp b/src/codegen/x86/assembler.cpp index e1f107dc32..02836f40a3 100644 --- a/src/codegen/x86/assembler.cpp +++ b/src/codegen/x86/assembler.cpp @@ -21,6 +21,7 @@ #define CAST_BRANCH(x) reinterpret_cast(x) using namespace vm; +using namespace avian::codegen; namespace { @@ -126,14 +127,14 @@ class MyBlock: public Assembler::Block { typedef void (*OperationType)(Context*); -typedef void (*UnaryOperationType)(Context*, unsigned, Assembler::Operand*); +typedef void (*UnaryOperationType)(Context*, unsigned, lir::Operand*); typedef void (*BinaryOperationType) -(Context*, unsigned, Assembler::Operand*, unsigned, Assembler::Operand*); +(Context*, unsigned, lir::Operand*, unsigned, lir::Operand*); typedef void (*BranchOperationType) -(Context*, TernaryOperation, unsigned, Assembler::Operand*, - Assembler::Operand*, Assembler::Operand*); +(Context*, lir::TernaryOperation, unsigned, lir::Operand*, + lir::Operand*, lir::Operand*); class ArchitectureContext { public: @@ -143,17 +144,17 @@ class ArchitectureContext { System* s; bool useNativeFeatures; - OperationType operations[OperationCount]; - UnaryOperationType unaryOperations[UnaryOperationCount - * OperandTypeCount]; + OperationType operations[lir::OperationCount]; + UnaryOperationType unaryOperations[lir::UnaryOperationCount + * lir::OperandTypeCount]; BinaryOperationType binaryOperations - [(BinaryOperationCount + NonBranchTernaryOperationCount) - * OperandTypeCount - * OperandTypeCount]; + [(lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) + * lir::OperandTypeCount + * lir::OperandTypeCount]; BranchOperationType branchOperations - [(BranchOperationCount) - * OperandTypeCount - * OperandTypeCount]; + [lir::BranchOperationCount + * lir::OperandTypeCount + * lir::OperandTypeCount]; }; class Context { @@ -482,44 +483,44 @@ void maybeRex(Context* c, unsigned size, int a, int index, int base, } else { byte = REX_NONE; } - if (a != NoRegister and (a & 8)) byte |= REX_R; - if (index != NoRegister and (index & 8)) byte |= REX_X; - if (base != NoRegister and (base & 8)) byte |= REX_B; + if (a != lir::NoRegister and (a & 8)) byte |= REX_R; + if (index != lir::NoRegister and (index & 8)) byte |= REX_X; + if (base != lir::NoRegister and (base & 8)) byte |= REX_B; if (always or byte != REX_NONE) c->code.append(byte); } } void -maybeRex(Context* c, unsigned size, Assembler::Register* a, - Assembler::Register* b) +maybeRex(Context* c, unsigned size, lir::Register* a, + lir::Register* b) { - maybeRex(c, size, a->low, NoRegister, b->low, false); + maybeRex(c, size, a->low, lir::NoRegister, b->low, false); } void -alwaysRex(Context* c, unsigned size, Assembler::Register* a, - Assembler::Register* b) +alwaysRex(Context* c, unsigned size, lir::Register* a, + lir::Register* b) { - maybeRex(c, size, a->low, NoRegister, b->low, true); + maybeRex(c, size, a->low, lir::NoRegister, b->low, true); } void -maybeRex(Context* c, unsigned size, Assembler::Register* a) +maybeRex(Context* c, unsigned size, lir::Register* a) { - maybeRex(c, size, NoRegister, NoRegister, a->low, false); + maybeRex(c, size, lir::NoRegister, lir::NoRegister, a->low, false); } void -maybeRex(Context* c, unsigned size, Assembler::Register* a, - Assembler::Memory* b) +maybeRex(Context* c, unsigned size, lir::Register* a, + lir::Memory* b) { maybeRex(c, size, a->low, b->index, b->base, size == 1 and (a->low & 4)); } void -maybeRex(Context* c, unsigned size, Assembler::Memory* a) +maybeRex(Context* c, unsigned size, lir::Memory* a) { - maybeRex(c, size, NoRegister, a->index, a->base, false); + maybeRex(c, size, lir::NoRegister, a->index, a->base, false); } int @@ -529,7 +530,7 @@ regCode(int a) } int -regCode(Assembler::Register* a) +regCode(lir::Register* a) { return regCode(a->low); } @@ -541,7 +542,7 @@ modrm(Context* c, uint8_t mod, int a, int b) } void -modrm(Context* c, uint8_t mod, Assembler::Register* a, Assembler::Register* b) +modrm(Context* c, uint8_t mod, lir::Register* a, lir::Register* b) { modrm(c, mod, a->low, b->low); } @@ -555,7 +556,7 @@ sib(Context* c, unsigned scale, int index, int base) void modrmSib(Context* c, int width, int a, int scale, int index, int base) { - if (index == NoRegister) { + if (index == lir::NoRegister) { modrm(c, width, base, a); if (regCode(base) == rsp) { sib(c, 0x00, rsp, rsp); @@ -582,7 +583,7 @@ modrmSibImm(Context* c, int a, int scale, int index, int base, int offset) void -modrmSibImm(Context* c, Assembler::Register* a, Assembler::Memory* b) +modrmSibImm(Context* c, lir::Register* a, lir::Memory* b) { modrmSibImm(c, a->low, b->scale, b->index, b->base, b->offset); } @@ -638,7 +639,7 @@ storeLoadBarrier(Context* c) } void -unconditional(Context* c, unsigned jump, Assembler::Constant* a) +unconditional(Context* c, unsigned jump, lir::Constant* a) { appendOffsetTask(c, a->value, offset(c), 5); @@ -647,7 +648,7 @@ unconditional(Context* c, unsigned jump, Assembler::Constant* a) } void -conditional(Context* c, unsigned condition, Assembler::Constant* a) +conditional(Context* c, unsigned condition, lir::Constant* a) { appendOffsetTask(c, a->value, offset(c), 6); @@ -656,66 +657,54 @@ conditional(Context* c, unsigned condition, Assembler::Constant* a) } unsigned -index(ArchitectureContext*, UnaryOperation operation, OperandType operand) +index(ArchitectureContext*, lir::UnaryOperation operation, lir::OperandType operand) { - return operation + (UnaryOperationCount * operand); + return operation + (lir::UnaryOperationCount * operand); } unsigned -index(ArchitectureContext*, BinaryOperation operation, - OperandType operand1, - OperandType operand2) +index(ArchitectureContext*, lir::BinaryOperation operation, + lir::OperandType operand1, + lir::OperandType operand2) { return operation - + ((BinaryOperationCount + NonBranchTernaryOperationCount) * operand1) - + ((BinaryOperationCount + NonBranchTernaryOperationCount) - * OperandTypeCount * operand2); -} - -bool -isBranch(TernaryOperation op) -{ - return op > FloatMin; -} - -bool -isFloatBranch(TernaryOperation op) -{ - return op > JumpIfNotEqual; + + ((lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) * operand1) + + ((lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) + * lir::OperandTypeCount * operand2); } unsigned -index(ArchitectureContext* c UNUSED, TernaryOperation operation, - OperandType operand1, OperandType operand2) +index(ArchitectureContext* c UNUSED, lir::TernaryOperation operation, + lir::OperandType operand1, lir::OperandType operand2) { assert(c, not isBranch(operation)); - return BinaryOperationCount + operation - + ((BinaryOperationCount + NonBranchTernaryOperationCount) * operand1) - + ((BinaryOperationCount + NonBranchTernaryOperationCount) - * OperandTypeCount * operand2); + return lir::BinaryOperationCount + operation + + ((lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) * operand1) + + ((lir::BinaryOperationCount + lir::NonBranchTernaryOperationCount) + * lir::OperandTypeCount * operand2); } unsigned -branchIndex(ArchitectureContext* c UNUSED, OperandType operand1, - OperandType operand2) +branchIndex(ArchitectureContext* c UNUSED, lir::OperandType operand1, + lir::OperandType operand2) { - return operand1 + (OperandTypeCount * operand2); + return operand1 + (lir::OperandTypeCount * operand2); } void -moveCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b); +moveCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b); void -moveCR2(Context*, unsigned, Assembler::Constant*, unsigned, - Assembler::Register*, unsigned); +moveCR2(Context*, unsigned, lir::Constant*, unsigned, + lir::Register*, unsigned); void -callR(Context*, unsigned, Assembler::Register*); +callR(Context*, unsigned, lir::Register*); void -callC(Context* c, unsigned size UNUSED, Assembler::Constant* a) +callC(Context* c, unsigned size UNUSED, lir::Constant* a) { assert(c, size == TargetBytesPerWord); @@ -723,12 +712,12 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* a) } void -longCallC(Context* c, unsigned size, Assembler::Constant* a) +longCallC(Context* c, unsigned size, lir::Constant* a) { assert(c, size == TargetBytesPerWord); if (TargetBytesPerWord == 8) { - Assembler::Register r(LongJumpRegister); + lir::Register r(LongJumpRegister); moveCR2(c, size, a, size, &r, 11); callR(c, size, &r); } else { @@ -737,7 +726,7 @@ longCallC(Context* c, unsigned size, Assembler::Constant* a) } void -jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a) +jumpR(Context* c, unsigned size UNUSED, lir::Register* a) { assert(c, size == TargetBytesPerWord); @@ -746,7 +735,7 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a) } void -jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a) +jumpC(Context* c, unsigned size UNUSED, lir::Constant* a) { assert(c, size == TargetBytesPerWord); @@ -754,7 +743,7 @@ jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a) } void -jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a) +jumpM(Context* c, unsigned size UNUSED, lir::Memory* a) { assert(c, size == TargetBytesPerWord); @@ -764,12 +753,12 @@ jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a) } void -longJumpC(Context* c, unsigned size, Assembler::Constant* a) +longJumpC(Context* c, unsigned size, lir::Constant* a) { assert(c, size == TargetBytesPerWord); if (TargetBytesPerWord == 8) { - Assembler::Register r(LongJumpRegister); + lir::Register r(LongJumpRegister); moveCR2(c, size, a, size, &r, 11); jumpR(c, size, &r); } else { @@ -778,7 +767,7 @@ longJumpC(Context* c, unsigned size, Assembler::Constant* a) } void -callR(Context* c, unsigned size UNUSED, Assembler::Register* a) +callR(Context* c, unsigned size UNUSED, lir::Register* a) { assert(c, size == TargetBytesPerWord); @@ -788,7 +777,7 @@ callR(Context* c, unsigned size UNUSED, Assembler::Register* a) } void -callM(Context* c, unsigned size UNUSED, Assembler::Memory* a) +callM(Context* c, unsigned size UNUSED, lir::Memory* a) { assert(c, size == TargetBytesPerWord); @@ -798,14 +787,14 @@ callM(Context* c, unsigned size UNUSED, Assembler::Memory* a) } void -alignedCallC(Context* c, unsigned size, Assembler::Constant* a) +alignedCallC(Context* c, unsigned size, lir::Constant* a) { new(c->zone) AlignmentPadding(c, 1, 4); callC(c, size, a); } void -alignedLongCallC(Context* c, unsigned size, Assembler::Constant* a) +alignedLongCallC(Context* c, unsigned size, lir::Constant* a) { assert(c, size == TargetBytesPerWord); @@ -818,14 +807,14 @@ alignedLongCallC(Context* c, unsigned size, Assembler::Constant* a) } void -alignedJumpC(Context* c, unsigned size, Assembler::Constant* a) +alignedJumpC(Context* c, unsigned size, lir::Constant* a) { new (c->zone) AlignmentPadding(c, 1, 4); jumpC(c, size, a); } void -alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a) +alignedLongJumpC(Context* c, unsigned size, lir::Constant* a) { assert(c, size == TargetBytesPerWord); @@ -838,10 +827,10 @@ alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a) } void -pushR(Context* c, unsigned size, Assembler::Register* a) +pushR(Context* c, unsigned size, lir::Register* a) { if (TargetBytesPerWord == 4 and size == 8) { - Assembler::Register ah(a->high); + lir::Register ah(a->high); pushR(c, 4, &ah); pushR(c, 4, a); @@ -852,14 +841,14 @@ pushR(Context* c, unsigned size, Assembler::Register* a) } void -moveRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Register* b); +moveRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize, lir::Register* b); void -popR(Context* c, unsigned size, Assembler::Register* a) +popR(Context* c, unsigned size, lir::Register* a) { if (TargetBytesPerWord == 4 and size == 8) { - Assembler::Register ah(a->high); + lir::Register ah(a->high); popR(c, 4, a); popR(c, 4, &ah); @@ -873,19 +862,19 @@ popR(Context* c, unsigned size, Assembler::Register* a) } void -addCarryCR(Context* c, unsigned size, Assembler::Constant* a, - Assembler::Register* b); +addCarryCR(Context* c, unsigned size, lir::Constant* a, + lir::Register* b); void -negateR(Context* c, unsigned size, Assembler::Register* a) +negateR(Context* c, unsigned size, lir::Register* a) { if (TargetBytesPerWord == 4 and size == 8) { assert(c, a->low == rax and a->high == rdx); ResolvedPromise zeroPromise(0); - Assembler::Constant zero(&zeroPromise); + lir::Constant zero(&zeroPromise); - Assembler::Register ah(a->high); + lir::Register ah(a->high); negateR(c, 4, a); addCarryCR(c, 4, &zero, &ah); @@ -897,8 +886,8 @@ negateR(Context* c, unsigned size, Assembler::Register* a) } void -negateRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b UNUSED) +negateRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b UNUSED) { assert(c, aSize == bSize); @@ -906,19 +895,19 @@ negateRR(Context* c, unsigned aSize, Assembler::Register* a, } void -moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a, - UNUSED unsigned bSize, Assembler::Register* b, unsigned promiseOffset) +moveCR2(Context* c, UNUSED unsigned aSize, lir::Constant* a, + UNUSED unsigned bSize, lir::Register* b, unsigned promiseOffset) { if (TargetBytesPerWord == 4 and bSize == 8) { int64_t v = a->value->value(); ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); + lir::Register bh(b->high); moveCR(c, 4, &al, 4, b); moveCR(c, 4, &ah, 4, &bh); @@ -936,14 +925,14 @@ moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a, } bool -floatReg(Assembler::Register* a) +floatReg(lir::Register* a) { return a->low >= xmm0; } void -sseMoveRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +sseMoveRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize >= 4); assert(c, aSize == bSize); @@ -974,19 +963,19 @@ sseMoveRR(Context* c, unsigned aSize, Assembler::Register* a, } void -sseMoveCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +sseMoveCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize <= TargetBytesPerWord); - Assembler::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR2(c, aSize, a, aSize, &tmp, 0); sseMoveRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); } void -moveCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +moveCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { if (floatReg(b)) { sseMoveCR(c, aSize, a, bSize, b); @@ -996,8 +985,8 @@ moveCR(Context* c, unsigned aSize, Assembler::Constant* a, } void -swapRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +swapRR(Context* c, unsigned aSize UNUSED, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == bSize); assert(c, aSize == TargetBytesPerWord); @@ -1008,8 +997,8 @@ swapRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, } void -moveRR(Context* c, unsigned aSize, Assembler::Register* a, - UNUSED unsigned bSize, Assembler::Register* b) +moveRR(Context* c, unsigned aSize, lir::Register* a, + UNUSED unsigned bSize, lir::Register* b) { if (floatReg(a) or floatReg(b)) { sseMoveRR(c, aSize, a, bSize, b); @@ -1017,8 +1006,8 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, } if (TargetBytesPerWord == 4 and aSize == 8 and bSize == 8) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register ah(a->high); + lir::Register bh(b->high); if (a->high == b->low) { if (a->low == b->high) { @@ -1089,8 +1078,8 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a, } void -sseMoveMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize UNUSED, Assembler::Register* b) +sseMoveMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize >= 4); @@ -1107,8 +1096,8 @@ sseMoveMR(Context* c, unsigned aSize, Assembler::Memory* a, } void -moveMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize, Assembler::Register* b) +moveMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize, lir::Register* b) { if (floatReg(b)) { sseMoveMR(c, aSize, a, bSize, b); @@ -1149,8 +1138,8 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a, case 8: if (TargetBytesPerWord == 4 and bSize == 8) { - Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale); - Assembler::Register bh(b->high); + lir::Memory ah(a->base, a->offset + 4, a->index, a->scale); + lir::Register bh(b->high); moveMR(c, 4, a, 4, b); moveMR(c, 4, &ah, 4, &bh); @@ -1166,8 +1155,8 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a, } void -sseMoveRM(Context* c, unsigned aSize, Assembler::Register* a, - UNUSED unsigned bSize, Assembler::Memory* b) +sseMoveRM(Context* c, unsigned aSize, lir::Register* a, + UNUSED unsigned bSize, lir::Memory* b) { assert(c, aSize >= 4); assert(c, aSize == bSize); @@ -1185,8 +1174,8 @@ sseMoveRM(Context* c, unsigned aSize, Assembler::Register* a, } void -moveRM(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Memory* b) +moveRM(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Memory* b) { assert(c, aSize == bSize); @@ -1227,8 +1216,8 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a, opcode(c, 0x89); modrmSibImm(c, a, b); } else { - Assembler::Register ah(a->high); - Assembler::Memory bh(b->base, b->offset + 4, b->index, b->scale); + lir::Register ah(a->high); + lir::Memory bh(b->base, b->offset + 4, b->index, b->scale); moveRM(c, 4, a, 4, b); moveRM(c, 4, &ah, 4, &bh); @@ -1240,13 +1229,13 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a, } void -moveAR(Context* c, unsigned aSize, Assembler::Address* a, - unsigned bSize, Assembler::Register* b) +moveAR(Context* c, unsigned aSize, lir::Address* a, + unsigned bSize, lir::Register* b) { assert(c, TargetBytesPerWord == 8 or (aSize == 4 and bSize == 4)); - Assembler::Constant constant(a->address); - Assembler::Memory memory(b->low, 0, -1, 0); + lir::Constant constant(a->address); + lir::Memory memory(b->low, 0, -1, 0); moveCR(c, aSize, &constant, bSize, b); moveMR(c, bSize, &memory, bSize, b); @@ -1259,8 +1248,8 @@ shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask) } void -moveCM(Context* c, unsigned aSize UNUSED, Assembler::Constant* a, - unsigned bSize, Assembler::Memory* b) +moveCM(Context* c, unsigned aSize UNUSED, lir::Constant* a, + unsigned bSize, lir::Memory* b) { switch (bSize) { case 1: @@ -1298,17 +1287,17 @@ moveCM(Context* c, unsigned aSize UNUSED, Assembler::Constant* a, modrmSibImm(c, 0, b->scale, b->index, b->base, b->offset); c->code.append4(a->value->value()); } else { - Assembler::Register tmp + lir::Register tmp (c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, 8, a, 8, &tmp); moveRM(c, 8, &tmp, 8, b); c->client->releaseTemporary(tmp.low); } } else { - Assembler::Constant ah(shiftMaskPromise(c, a->value, 32, 0xFFFFFFFF)); - Assembler::Constant al(shiftMaskPromise(c, a->value, 0, 0xFFFFFFFF)); + lir::Constant ah(shiftMaskPromise(c, a->value, 32, 0xFFFFFFFF)); + lir::Constant al(shiftMaskPromise(c, a->value, 0, 0xFFFFFFFF)); - Assembler::Memory bh(b->base, b->offset + 4, b->index, b->scale); + lir::Memory bh(b->base, b->offset + 4, b->index, b->scale); moveCM(c, 4, &al, 4, b); moveCM(c, 4, &ah, 4, &bh); @@ -1320,8 +1309,8 @@ moveCM(Context* c, unsigned aSize UNUSED, Assembler::Constant* a, } void -moveZRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +moveZRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { switch (aSize) { case 2: @@ -1335,8 +1324,8 @@ moveZRR(Context* c, unsigned aSize, Assembler::Register* a, } void -moveZMR(Context* c, unsigned aSize UNUSED, Assembler::Memory* a, - unsigned bSize UNUSED, Assembler::Register* b) +moveZMR(Context* c, unsigned aSize UNUSED, lir::Memory* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, bSize == TargetBytesPerWord); assert(c, aSize == 2); @@ -1347,8 +1336,8 @@ moveZMR(Context* c, unsigned aSize UNUSED, Assembler::Memory* a, } void -addCarryRR(Context* c, unsigned size, Assembler::Register* a, - Assembler::Register* b) +addCarryRR(Context* c, unsigned size, lir::Register* a, + lir::Register* b) { assert(c, TargetBytesPerWord == 8 or size == 4); @@ -1358,14 +1347,14 @@ addCarryRR(Context* c, unsigned size, Assembler::Register* a, } void -addRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +addRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == bSize); if (TargetBytesPerWord == 4 and aSize == 8) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register ah(a->high); + lir::Register bh(b->high); addRR(c, 4, a, 4, b); addCarryRR(c, 4, &ah, &bh); @@ -1377,8 +1366,8 @@ addRR(Context* c, unsigned aSize, Assembler::Register* a, } void -addCarryCR(Context* c, unsigned size, Assembler::Constant* a, - Assembler::Register* b) +addCarryCR(Context* c, unsigned size, lir::Constant* a, + lir::Register* b) { int64_t v = a->value->value(); @@ -1393,8 +1382,8 @@ addCarryCR(Context* c, unsigned size, Assembler::Constant* a, } void -addCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +addCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == bSize); @@ -1402,12 +1391,12 @@ addCR(Context* c, unsigned aSize, Assembler::Constant* a, if (v) { if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); + lir::Register bh(b->high); addCR(c, 4, &al, 4, b); addCarryCR(c, 4, &ah, &bh); @@ -1422,7 +1411,7 @@ addCR(Context* c, unsigned aSize, Assembler::Constant* a, c->code.append4(v); } } else { - Assembler::Register tmp + lir::Register tmp (c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); addRR(c, aSize, &tmp, bSize, b); @@ -1433,8 +1422,8 @@ addCR(Context* c, unsigned aSize, Assembler::Constant* a, } void -subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, - Assembler::Register* b) +subtractBorrowCR(Context* c, unsigned size UNUSED, lir::Constant* a, + lir::Register* b) { assert(c, TargetBytesPerWord == 8 or size == 4); @@ -1449,12 +1438,12 @@ subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, } void -subtractRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Register* b); +subtractRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize, lir::Register* b); void -subtractCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +subtractCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == bSize); @@ -1462,12 +1451,12 @@ subtractCR(Context* c, unsigned aSize, Assembler::Constant* a, if (v) { if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); + lir::Register bh(b->high); subtractCR(c, 4, &al, 4, b); subtractBorrowCR(c, 4, &ah, &bh); @@ -1482,7 +1471,7 @@ subtractCR(Context* c, unsigned aSize, Assembler::Constant* a, c->code.append4(v); } } else { - Assembler::Register tmp + lir::Register tmp (c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); subtractRR(c, aSize, &tmp, bSize, b); @@ -1493,8 +1482,8 @@ subtractCR(Context* c, unsigned aSize, Assembler::Constant* a, } void -subtractBorrowRR(Context* c, unsigned size, Assembler::Register* a, - Assembler::Register* b) +subtractBorrowRR(Context* c, unsigned size, lir::Register* a, + lir::Register* b) { assert(c, TargetBytesPerWord == 8 or size == 4); @@ -1504,14 +1493,14 @@ subtractBorrowRR(Context* c, unsigned size, Assembler::Register* a, } void -subtractRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +subtractRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == bSize); if (TargetBytesPerWord == 4 and aSize == 8) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register ah(a->high); + lir::Register bh(b->high); subtractRR(c, 4, a, 4, b); subtractBorrowRR(c, 4, &ah, &bh); @@ -1523,15 +1512,15 @@ subtractRR(Context* c, unsigned aSize, Assembler::Register* a, } void -andRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +andRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == bSize); if (TargetBytesPerWord == 4 and aSize == 8) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register ah(a->high); + lir::Register bh(b->high); andRR(c, 4, a, 4, b); andRR(c, 4, &ah, 4, &bh); @@ -1543,8 +1532,8 @@ andRR(Context* c, unsigned aSize, Assembler::Register* a, } void -andCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +andCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == bSize); @@ -1552,12 +1541,12 @@ andCR(Context* c, unsigned aSize, Assembler::Constant* a, if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); + lir::Register bh(b->high); andCR(c, 4, &al, 4, b); andCR(c, 4, &ah, 4, &bh); @@ -1572,7 +1561,7 @@ andCR(Context* c, unsigned aSize, Assembler::Constant* a, c->code.append4(v); } } else { - Assembler::Register tmp + lir::Register tmp (c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); andRR(c, aSize, &tmp, bSize, b); @@ -1582,14 +1571,14 @@ andCR(Context* c, unsigned aSize, Assembler::Constant* a, } void -orRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +orRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == bSize); if (TargetBytesPerWord == 4 and aSize == 8) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register ah(a->high); + lir::Register bh(b->high); orRR(c, 4, a, 4, b); orRR(c, 4, &ah, 4, &bh); @@ -1601,8 +1590,8 @@ orRR(Context* c, unsigned aSize, Assembler::Register* a, } void -orCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +orCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == bSize); @@ -1610,12 +1599,12 @@ orCR(Context* c, unsigned aSize, Assembler::Constant* a, if (v) { if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); + lir::Register bh(b->high); orCR(c, 4, &al, 4, b); orCR(c, 4, &ah, 4, &bh); @@ -1630,7 +1619,7 @@ orCR(Context* c, unsigned aSize, Assembler::Constant* a, c->code.append4(v); } } else { - Assembler::Register tmp + lir::Register tmp (c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); orRR(c, aSize, &tmp, bSize, b); @@ -1641,12 +1630,12 @@ orCR(Context* c, unsigned aSize, Assembler::Constant* a, } void -xorRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +xorRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { if (TargetBytesPerWord == 4 and aSize == 8) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register ah(a->high); + lir::Register bh(b->high); xorRR(c, 4, a, 4, b); xorRR(c, 4, &ah, 4, &bh); @@ -1658,8 +1647,8 @@ xorRR(Context* c, unsigned aSize, Assembler::Register* a, } void -xorCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +xorCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == bSize); @@ -1667,12 +1656,12 @@ xorCR(Context* c, unsigned aSize, Assembler::Constant* a, if (v) { if (TargetBytesPerWord == 4 and bSize == 8) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF); - Assembler::Constant ah(&high); + lir::Constant ah(&high); ResolvedPromise low(v & 0xFFFFFFFF); - Assembler::Constant al(&low); + lir::Constant al(&low); - Assembler::Register bh(b->high); + lir::Register bh(b->high); xorCR(c, 4, &al, 4, b); xorCR(c, 4, &ah, 4, &bh); @@ -1687,7 +1676,7 @@ xorCR(Context* c, unsigned aSize, Assembler::Constant* a, c->code.append4(v); } } else { - Assembler::Register tmp + lir::Register tmp (c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); xorRR(c, aSize, &tmp, bSize, b); @@ -1698,8 +1687,8 @@ xorCR(Context* c, unsigned aSize, Assembler::Constant* a, } void -multiplyRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +multiplyRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == bSize); @@ -1712,12 +1701,12 @@ multiplyRR(Context* c, unsigned aSize, Assembler::Register* a, c->client->save(rax); - Assembler::Register axdx(rax, rdx); - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register axdx(rax, rdx); + lir::Register ah(a->high); + lir::Register bh(b->high); - Assembler::Register tmp(-1); - Assembler::Register* scratch; + lir::Register tmp(-1); + lir::Register* scratch; if (a->low == b->low) { tmp.low = c->client->acquireTemporary (GeneralRegisterMask & ~(1 << rax)); @@ -1749,30 +1738,30 @@ multiplyRR(Context* c, unsigned aSize, Assembler::Register* a, } void -branch(Context* c, TernaryOperation op, Assembler::Constant* target) +branch(Context* c, lir::TernaryOperation op, lir::Constant* target) { switch (op) { - case JumpIfEqual: + case lir::JumpIfEqual: conditional(c, 0x84, target); break; - case JumpIfNotEqual: + case lir::JumpIfNotEqual: conditional(c, 0x85, target); break; - case JumpIfLess: + case lir::JumpIfLess: conditional(c, 0x8c, target); break; - case JumpIfGreater: + case lir::JumpIfGreater: conditional(c, 0x8f, target); break; - case JumpIfLessOrEqual: + case lir::JumpIfLessOrEqual: conditional(c, 0x8e, target); break; - case JumpIfGreaterOrEqual: + case lir::JumpIfGreaterOrEqual: conditional(c, 0x8d, target); break; @@ -1782,49 +1771,49 @@ branch(Context* c, TernaryOperation op, Assembler::Constant* target) } void -branchFloat(Context* c, TernaryOperation op, Assembler::Constant* target) +branchFloat(Context* c, lir::TernaryOperation op, lir::Constant* target) { switch (op) { - case JumpIfFloatEqual: + case lir::JumpIfFloatEqual: conditional(c, 0x84, target); break; - case JumpIfFloatNotEqual: + case lir::JumpIfFloatNotEqual: conditional(c, 0x85, target); break; - case JumpIfFloatLess: + case lir::JumpIfFloatLess: conditional(c, 0x82, target); break; - case JumpIfFloatGreater: + case lir::JumpIfFloatGreater: conditional(c, 0x87, target); break; - case JumpIfFloatLessOrEqual: + case lir::JumpIfFloatLessOrEqual: conditional(c, 0x86, target); break; - case JumpIfFloatGreaterOrEqual: + case lir::JumpIfFloatGreaterOrEqual: conditional(c, 0x83, target); break; - case JumpIfFloatLessOrUnordered: + case lir::JumpIfFloatLessOrUnordered: conditional(c, 0x82, target); conditional(c, 0x8a, target); break; - case JumpIfFloatGreaterOrUnordered: + case lir::JumpIfFloatGreaterOrUnordered: conditional(c, 0x87, target); conditional(c, 0x8a, target); break; - case JumpIfFloatLessOrEqualOrUnordered: + case lir::JumpIfFloatLessOrEqualOrUnordered: conditional(c, 0x86, target); conditional(c, 0x8a, target); break; - case JumpIfFloatGreaterOrEqualOrUnordered: + case lir::JumpIfFloatGreaterOrEqualOrUnordered: conditional(c, 0x83, target); conditional(c, 0x8a, target); break; @@ -1835,8 +1824,8 @@ branchFloat(Context* c, TernaryOperation op, Assembler::Constant* target) } void -compareRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +compareRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == bSize); assert(c, aSize <= TargetBytesPerWord); @@ -1847,8 +1836,8 @@ compareRR(Context* c, unsigned aSize, Assembler::Register* a, } void -compareCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +compareCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == bSize); assert(c, TargetBytesPerWord == 8 or aSize == 4); @@ -1864,7 +1853,7 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a, c->code.append4(v); } } else { - Assembler::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); compareRR(c, aSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -1872,8 +1861,8 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a, } void -compareRM(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Memory* b) +compareRM(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Memory* b) { assert(c, aSize == bSize); assert(c, TargetBytesPerWord == 8 or aSize == 4); @@ -1887,8 +1876,8 @@ compareRM(Context* c, unsigned aSize, Assembler::Register* a, } void -compareCM(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Memory* b) +compareCM(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Memory* b) { assert(c, aSize == bSize); assert(c, TargetBytesPerWord == 8 or aSize == 4); @@ -1907,7 +1896,7 @@ compareCM(Context* c, unsigned aSize, Assembler::Constant* a, abort(c); } } else { - Assembler::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); + lir::Register tmp(c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, bSize, &tmp); compareRM(c, bSize, &tmp, bSize, b); c->client->releaseTemporary(tmp.low); @@ -1915,8 +1904,8 @@ compareCM(Context* c, unsigned aSize, Assembler::Constant* a, } void -compareFloatRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +compareFloatRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == bSize); @@ -1929,9 +1918,9 @@ compareFloatRR(Context* c, unsigned aSize, Assembler::Register* a, } void -branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, - Assembler::Operand* ah, Assembler::Operand* bl, - Assembler::Operand* bh, Assembler::Constant* target, +branchLong(Context* c, lir::TernaryOperation op, lir::Operand* al, + lir::Operand* ah, lir::Operand* bl, + lir::Operand* bh, lir::Constant* target, BinaryOperationType compare) { compare(c, 4, ah, 4, bh); @@ -1939,7 +1928,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, unsigned next = 0; switch (op) { - case JumpIfEqual: + case lir::JumpIfEqual: opcode(c, 0x75); // jne next = c->code.length(); c->code.append(0); @@ -1948,14 +1937,14 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, 0x84, target); // je break; - case JumpIfNotEqual: + case lir::JumpIfNotEqual: conditional(c, 0x85, target); // jne compare(c, 4, al, 4, bl); conditional(c, 0x85, target); // jne break; - case JumpIfLess: + case lir::JumpIfLess: conditional(c, 0x8c, target); // jl opcode(c, 0x7f); // jg @@ -1966,7 +1955,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, 0x82, target); // jb break; - case JumpIfGreater: + case lir::JumpIfGreater: conditional(c, 0x8f, target); // jg opcode(c, 0x7c); // jl @@ -1977,7 +1966,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, 0x87, target); // ja break; - case JumpIfLessOrEqual: + case lir::JumpIfLessOrEqual: conditional(c, 0x8c, target); // jl opcode(c, 0x7f); // jg @@ -1988,7 +1977,7 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, conditional(c, 0x86, target); // jbe break; - case JumpIfGreaterOrEqual: + case lir::JumpIfGreaterOrEqual: conditional(c, 0x8f, target); // jg opcode(c, 0x7c); // jl @@ -2010,16 +1999,16 @@ branchLong(Context* c, TernaryOperation op, Assembler::Operand* al, } void -branchRR(Context* c, TernaryOperation op, unsigned size, - Assembler::Register* a, Assembler::Register* b, - Assembler::Constant* target) +branchRR(Context* c, lir::TernaryOperation op, unsigned size, + lir::Register* a, lir::Register* b, + lir::Constant* target) { if (isFloatBranch(op)) { compareFloatRR(c, size, a, size, b); branchFloat(c, op, target); } else if (size > TargetBytesPerWord) { - Assembler::Register ah(a->high); - Assembler::Register bh(b->high); + lir::Register ah(a->high); + lir::Register bh(b->high); branchLong(c, op, a, &ah, b, &bh, target, CAST2(compareRR)); } else { @@ -2029,9 +2018,9 @@ branchRR(Context* c, TernaryOperation op, unsigned size, } void -branchCR(Context* c, TernaryOperation op, unsigned size, - Assembler::Constant* a, Assembler::Register* b, - Assembler::Constant* target) +branchCR(Context* c, lir::TernaryOperation op, unsigned size, + lir::Constant* a, lir::Register* b, + lir::Constant* target) { assert(c, not isFloatBranch(op)); @@ -2039,12 +2028,12 @@ branchCR(Context* c, TernaryOperation op, unsigned size, int64_t v = a->value->value(); ResolvedPromise low(v & ~static_cast(0)); - Assembler::Constant al(&low); + lir::Constant al(&low); ResolvedPromise high((v >> 32) & ~static_cast(0)); - Assembler::Constant ah(&high); + lir::Constant ah(&high); - Assembler::Register bh(b->high); + lir::Register bh(b->high); branchLong(c, op, &al, &ah, b, &bh, target, CAST2(compareCR)); } else { @@ -2054,9 +2043,9 @@ branchCR(Context* c, TernaryOperation op, unsigned size, } void -branchRM(Context* c, TernaryOperation op, unsigned size, - Assembler::Register* a, Assembler::Memory* b, - Assembler::Constant* target) +branchRM(Context* c, lir::TernaryOperation op, unsigned size, + lir::Register* a, lir::Memory* b, + lir::Constant* target) { assert(c, not isFloatBranch(op)); assert(c, size <= TargetBytesPerWord); @@ -2066,9 +2055,9 @@ branchRM(Context* c, TernaryOperation op, unsigned size, } void -branchCM(Context* c, TernaryOperation op, unsigned size, - Assembler::Constant* a, Assembler::Memory* b, - Assembler::Constant* target) +branchCM(Context* c, lir::TernaryOperation op, unsigned size, + lir::Constant* a, lir::Memory* b, + lir::Constant* target) { assert(c, not isFloatBranch(op)); assert(c, size <= TargetBytesPerWord); @@ -2078,14 +2067,14 @@ branchCM(Context* c, TernaryOperation op, unsigned size, } void -multiplyCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +multiplyCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { assert(c, aSize == bSize); if (TargetBytesPerWord == 4 and aSize == 8) { const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); - Assembler::Register tmp(c->client->acquireTemporary(mask), + lir::Register tmp(c->client->acquireTemporary(mask), c->client->acquireTemporary(mask)); moveCR(c, aSize, a, aSize, &tmp); @@ -2107,7 +2096,7 @@ multiplyCR(Context* c, unsigned aSize, Assembler::Constant* a, c->code.append4(v); } } else { - Assembler::Register tmp + lir::Register tmp (c->client->acquireTemporary(GeneralRegisterMask)); moveCR(c, aSize, a, aSize, &tmp); multiplyRR(c, aSize, &tmp, bSize, b); @@ -2118,8 +2107,8 @@ multiplyCR(Context* c, unsigned aSize, Assembler::Constant* a, } void -divideRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b UNUSED) +divideRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b UNUSED) { assert(c, aSize == bSize); @@ -2135,8 +2124,8 @@ divideRR(Context* c, unsigned aSize, Assembler::Register* a, } void -remainderRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +remainderRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, aSize == bSize); @@ -2150,25 +2139,25 @@ remainderRR(Context* c, unsigned aSize, Assembler::Register* a, maybeRex(c, aSize, b, a); opcode(c, 0xf7, 0xf8 + regCode(a)); - Assembler::Register dx(rdx); + lir::Register dx(rdx); moveRR(c, TargetBytesPerWord, &dx, TargetBytesPerWord, b); } void doShift(Context* c, UNUSED void (*shift) - (Context*, unsigned, Assembler::Register*, unsigned, - Assembler::Register*), - int type, UNUSED unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) + (Context*, unsigned, lir::Register*, unsigned, + lir::Register*), + int type, UNUSED unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { int64_t v = a->value->value(); if (TargetBytesPerWord == 4 and bSize == 8) { c->client->save(rcx); - Assembler::Register cx(rcx); + lir::Register cx(rcx); ResolvedPromise promise(v & 0x3F); - Assembler::Constant masked(&promise); + lir::Constant masked(&promise); moveCR(c, 4, &masked, 4, &cx); shift(c, aSize, &cx, bSize, b); } else { @@ -2185,15 +2174,15 @@ doShift(Context* c, UNUSED void (*shift) } void -shiftLeftRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Register* b) +shiftLeftRR(Context* c, UNUSED unsigned aSize, lir::Register* a, + unsigned bSize, lir::Register* b) { if (TargetBytesPerWord == 4 and bSize == 8) { - Assembler::Register cx(rcx); + lir::Register cx(rcx); if (a->low != rcx) { c->client->save(rcx); ResolvedPromise promise(0x3F); - Assembler::Constant mask(&promise); + lir::Constant mask(&promise); moveRR(c, 4, a, 4, &cx); andCR(c, 4, &mask, 4, &cx); } @@ -2206,13 +2195,13 @@ shiftLeftRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, opcode(c, 0xd3, 0xe0 + b->low); ResolvedPromise promise(32); - Assembler::Constant constant(&promise); + lir::Constant constant(&promise); compareCR(c, aSize, &constant, aSize, &cx); opcode(c, 0x7c); //jl c->code.append(2 + 2); - Assembler::Register bh(b->high); + lir::Register bh(b->high); moveRR(c, 4, b, 4, &bh); // 2 bytes xorRR(c, 4, b, 4, b); // 2 bytes } else { @@ -2224,22 +2213,22 @@ shiftLeftRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, } void -shiftLeftCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +shiftLeftCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { doShift(c, shiftLeftRR, 0xe0, aSize, a, bSize, b); } void -shiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Register* b) +shiftRightRR(Context* c, UNUSED unsigned aSize, lir::Register* a, + unsigned bSize, lir::Register* b) { if (TargetBytesPerWord == 4 and bSize == 8) { - Assembler::Register cx(rcx); + lir::Register cx(rcx); if (a->low != rcx) { c->client->save(rcx); ResolvedPromise promise(0x3F); - Assembler::Constant mask(&promise); + lir::Constant mask(&promise); moveRR(c, 4, a, 4, &cx); andCR(c, 4, &mask, 4, &cx); } @@ -2252,13 +2241,13 @@ shiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, opcode(c, 0xd3, 0xf8 + b->high); ResolvedPromise promise(32); - Assembler::Constant constant(&promise); + lir::Constant constant(&promise); compareCR(c, aSize, &constant, aSize, &cx); opcode(c, 0x7c); //jl c->code.append(2 + 3); - Assembler::Register bh(b->high); + lir::Register bh(b->high); moveRR(c, 4, &bh, 4, b); // 2 bytes // sar 31,high @@ -2273,22 +2262,22 @@ shiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, } void -shiftRightCR(Context* c, unsigned aSize, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +shiftRightCR(Context* c, unsigned aSize, lir::Constant* a, + unsigned bSize, lir::Register* b) { doShift(c, shiftRightRR, 0xf8, aSize, a, bSize, b); } void -unsignedShiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Register* b) +unsignedShiftRightRR(Context* c, UNUSED unsigned aSize, lir::Register* a, + unsigned bSize, lir::Register* b) { if (TargetBytesPerWord == 4 and bSize == 8) { - Assembler::Register cx(rcx); + lir::Register cx(rcx); if (a->low != rcx) { c->client->save(rcx); ResolvedPromise promise(0x3F); - Assembler::Constant mask(&promise); + lir::Constant mask(&promise); moveRR(c, 4, a, 4, &cx); andCR(c, 4, &mask, 4, &cx); } @@ -2301,13 +2290,13 @@ unsignedShiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, opcode(c, 0xd3, 0xe8 + b->high); ResolvedPromise promise(32); - Assembler::Constant constant(&promise); + lir::Constant constant(&promise); compareCR(c, aSize, &constant, aSize, &cx); opcode(c, 0x7c); //jl c->code.append(2 + 2); - Assembler::Register bh(b->high); + lir::Register bh(b->high); moveRR(c, 4, &bh, 4, b); // 2 bytes xorRR(c, 4, &bh, 4, &bh); // 2 bytes } else { @@ -2319,15 +2308,15 @@ unsignedShiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a, } void -unsignedShiftRightCR(Context* c, unsigned aSize UNUSED, Assembler::Constant* a, - unsigned bSize, Assembler::Register* b) +unsignedShiftRightCR(Context* c, unsigned aSize UNUSED, lir::Constant* a, + unsigned bSize, lir::Register* b) { doShift(c, unsignedShiftRightRR, 0xe8, aSize, a, bSize, b); } void -floatRegOp(Context* c, unsigned aSize, Assembler::Register* a, unsigned bSize, - Assembler::Register* b, uint8_t op, uint8_t mod = 0xc0) +floatRegOp(Context* c, unsigned aSize, lir::Register* a, unsigned bSize, + lir::Register* b, uint8_t op, uint8_t mod = 0xc0) { if (aSize == 4) { opcode(c, 0xf3); @@ -2340,8 +2329,8 @@ floatRegOp(Context* c, unsigned aSize, Assembler::Register* a, unsigned bSize, } void -floatMemOp(Context* c, unsigned aSize, Assembler::Memory* a, unsigned bSize, - Assembler::Register* b, uint8_t op) +floatMemOp(Context* c, unsigned aSize, lir::Memory* a, unsigned bSize, + lir::Register* b, uint8_t op) { if (aSize == 4) { opcode(c, 0xf3); @@ -2354,130 +2343,130 @@ floatMemOp(Context* c, unsigned aSize, Assembler::Memory* a, unsigned bSize, } void -floatSqrtRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatSqrtRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { floatRegOp(c, aSize, a, 4, b, 0x51); } void -floatSqrtMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatSqrtMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize UNUSED, lir::Register* b) { floatMemOp(c, aSize, a, 4, b, 0x51); } void -floatAddRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatAddRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { floatRegOp(c, aSize, a, 4, b, 0x58); } void -floatAddMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatAddMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize UNUSED, lir::Register* b) { floatMemOp(c, aSize, a, 4, b, 0x58); } void -floatSubtractRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatSubtractRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { floatRegOp(c, aSize, a, 4, b, 0x5c); } void -floatSubtractMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatSubtractMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize UNUSED, lir::Register* b) { floatMemOp(c, aSize, a, 4, b, 0x5c); } void -floatMultiplyRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatMultiplyRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { floatRegOp(c, aSize, a, 4, b, 0x59); } void -floatMultiplyMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatMultiplyMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize UNUSED, lir::Register* b) { floatMemOp(c, aSize, a, 4, b, 0x59); } void -floatDivideRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatDivideRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { floatRegOp(c, aSize, a, 4, b, 0x5e); } void -floatDivideMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatDivideMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize UNUSED, lir::Register* b) { floatMemOp(c, aSize, a, 4, b, 0x5e); } void -float2FloatRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +float2FloatRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { floatRegOp(c, aSize, a, 4, b, 0x5a); } void -float2FloatMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize UNUSED, Assembler::Register* b) +float2FloatMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize UNUSED, lir::Register* b) { floatMemOp(c, aSize, a, 4, b, 0x5a); } void -float2IntRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Register* b) +float2IntRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize, lir::Register* b) { assert(c, not floatReg(b)); floatRegOp(c, aSize, a, bSize, b, 0x2c); } void -float2IntMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize, Assembler::Register* b) +float2IntMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize, lir::Register* b) { floatMemOp(c, aSize, a, bSize, b, 0x2c); } void -int2FloatRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize, Assembler::Register* b) +int2FloatRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize, lir::Register* b) { floatRegOp(c, bSize, a, aSize, b, 0x2a); } void -int2FloatMR(Context* c, unsigned aSize, Assembler::Memory* a, - unsigned bSize, Assembler::Register* b) +int2FloatMR(Context* c, unsigned aSize, lir::Memory* a, + unsigned bSize, lir::Register* b) { floatMemOp(c, bSize, a, aSize, b, 0x2a); } void -floatNegateRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatNegateRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, floatReg(a) and floatReg(b)); // unlike most of the other floating point code, this does NOT // support doubles: assert(c, aSize == 4); ResolvedPromise pcon(0x80000000); - Assembler::Constant con(&pcon); + lir::Constant con(&pcon); if (a->low == b->low) { - Assembler::Register tmp(c->client->acquireTemporary(FloatRegisterMask)); + lir::Register tmp(c->client->acquireTemporary(FloatRegisterMask)); moveCR(c, 4, &con, 4, &tmp); maybeRex(c, 4, a, &tmp); opcode(c, 0x0f, 0x57); @@ -2493,17 +2482,17 @@ floatNegateRR(Context* c, unsigned aSize, Assembler::Register* a, } void -floatAbsoluteRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b) +floatAbsoluteRR(Context* c, unsigned aSize UNUSED, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b) { assert(c, floatReg(a) and floatReg(b)); // unlike most of the other floating point code, this does NOT // support doubles: assert(c, aSize == 4); ResolvedPromise pcon(0x7fffffff); - Assembler::Constant con(&pcon); + lir::Constant con(&pcon); if (a->low == b->low) { - Assembler::Register tmp(c->client->acquireTemporary(FloatRegisterMask)); + lir::Register tmp(c->client->acquireTemporary(FloatRegisterMask)); moveCR(c, 4, &con, 4, &tmp); maybeRex(c, 4, a, &tmp); opcode(c, 0x0f, 0x54); @@ -2518,11 +2507,11 @@ floatAbsoluteRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a, } void -absoluteRR(Context* c, unsigned aSize, Assembler::Register* a, - unsigned bSize UNUSED, Assembler::Register* b UNUSED) +absoluteRR(Context* c, unsigned aSize, lir::Register* a, + unsigned bSize UNUSED, lir::Register* b UNUSED) { assert(c, aSize == bSize and a->low == rax and b->low == rax); - Assembler::Register d + lir::Register d (c->client->acquireTemporary(static_cast(1) << rdx)); maybeRex(c, aSize, a, b); opcode(c, 0x99); @@ -2624,114 +2613,114 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED, void populateTables(ArchitectureContext* c) { - const OperandType C = ConstantOperand; - const OperandType A = AddressOperand; - const OperandType R = RegisterOperand; - const OperandType M = MemoryOperand; + const lir::OperandType C = lir::ConstantOperand; + const lir::OperandType A = lir::AddressOperand; + const lir::OperandType R = lir::RegisterOperand; + const lir::OperandType M = lir::MemoryOperand; OperationType* zo = c->operations; UnaryOperationType* uo = c->unaryOperations; BinaryOperationType* bo = c->binaryOperations; BranchOperationType* bro = c->branchOperations; - zo[Return] = return_; - zo[LoadBarrier] = ignore; - zo[StoreStoreBarrier] = ignore; - zo[StoreLoadBarrier] = storeLoadBarrier; - zo[Trap] = trap; + zo[lir::Return] = return_; + zo[lir::LoadBarrier] = ignore; + zo[lir::StoreStoreBarrier] = ignore; + zo[lir::StoreLoadBarrier] = storeLoadBarrier; + zo[lir::Trap] = trap; - uo[index(c, Call, C)] = CAST1(callC); - uo[index(c, Call, R)] = CAST1(callR); - uo[index(c, Call, M)] = CAST1(callM); + uo[index(c, lir::Call, C)] = CAST1(callC); + uo[index(c, lir::Call, R)] = CAST1(callR); + uo[index(c, lir::Call, M)] = CAST1(callM); - uo[index(c, AlignedCall, C)] = CAST1(alignedCallC); + uo[index(c, lir::AlignedCall, C)] = CAST1(alignedCallC); - uo[index(c, LongCall, C)] = CAST1(longCallC); + uo[index(c, lir::LongCall, C)] = CAST1(longCallC); - uo[index(c, AlignedLongCall, C)] = CAST1(alignedLongCallC); + uo[index(c, lir::AlignedLongCall, C)] = CAST1(alignedLongCallC); - uo[index(c, Jump, R)] = CAST1(jumpR); - uo[index(c, Jump, C)] = CAST1(jumpC); - uo[index(c, Jump, M)] = CAST1(jumpM); + uo[index(c, lir::Jump, R)] = CAST1(jumpR); + uo[index(c, lir::Jump, C)] = CAST1(jumpC); + uo[index(c, lir::Jump, M)] = CAST1(jumpM); - uo[index(c, AlignedJump, C)] = CAST1(alignedJumpC); + uo[index(c, lir::AlignedJump, C)] = CAST1(alignedJumpC); - uo[index(c, LongJump, C)] = CAST1(longJumpC); + uo[index(c, lir::LongJump, C)] = CAST1(longJumpC); - uo[index(c, AlignedLongJump, C)] = CAST1(alignedLongJumpC); + uo[index(c, lir::AlignedLongJump, C)] = CAST1(alignedLongJumpC); - bo[index(c, Negate, R, R)] = CAST2(negateRR); + bo[index(c, lir::Negate, R, R)] = CAST2(negateRR); - bo[index(c, FloatNegate, R, R)] = CAST2(floatNegateRR); + bo[index(c, lir::FloatNegate, R, R)] = CAST2(floatNegateRR); - bo[index(c, Move, R, R)] = CAST2(moveRR); - bo[index(c, Move, C, R)] = CAST2(moveCR); - bo[index(c, Move, M, R)] = CAST2(moveMR); - bo[index(c, Move, R, M)] = CAST2(moveRM); - bo[index(c, Move, C, M)] = CAST2(moveCM); - bo[index(c, Move, A, R)] = CAST2(moveAR); + bo[index(c, lir::Move, R, R)] = CAST2(moveRR); + bo[index(c, lir::Move, C, R)] = CAST2(moveCR); + bo[index(c, lir::Move, M, R)] = CAST2(moveMR); + bo[index(c, lir::Move, R, M)] = CAST2(moveRM); + bo[index(c, lir::Move, C, M)] = CAST2(moveCM); + bo[index(c, lir::Move, A, R)] = CAST2(moveAR); - bo[index(c, FloatSquareRoot, R, R)] = CAST2(floatSqrtRR); - bo[index(c, FloatSquareRoot, M, R)] = CAST2(floatSqrtMR); + bo[index(c, lir::FloatSquareRoot, R, R)] = CAST2(floatSqrtRR); + bo[index(c, lir::FloatSquareRoot, M, R)] = CAST2(floatSqrtMR); - bo[index(c, MoveZ, R, R)] = CAST2(moveZRR); - bo[index(c, MoveZ, M, R)] = CAST2(moveZMR); - bo[index(c, MoveZ, C, R)] = CAST2(moveCR); + bo[index(c, lir::MoveZ, R, R)] = CAST2(moveZRR); + bo[index(c, lir::MoveZ, M, R)] = CAST2(moveZMR); + bo[index(c, lir::MoveZ, C, R)] = CAST2(moveCR); - bo[index(c, Add, R, R)] = CAST2(addRR); - bo[index(c, Add, C, R)] = CAST2(addCR); + bo[index(c, lir::Add, R, R)] = CAST2(addRR); + bo[index(c, lir::Add, C, R)] = CAST2(addCR); - bo[index(c, Subtract, C, R)] = CAST2(subtractCR); - bo[index(c, Subtract, R, R)] = CAST2(subtractRR); + bo[index(c, lir::Subtract, C, R)] = CAST2(subtractCR); + bo[index(c, lir::Subtract, R, R)] = CAST2(subtractRR); - bo[index(c, FloatAdd, R, R)] = CAST2(floatAddRR); - bo[index(c, FloatAdd, M, R)] = CAST2(floatAddMR); + bo[index(c, lir::FloatAdd, R, R)] = CAST2(floatAddRR); + bo[index(c, lir::FloatAdd, M, R)] = CAST2(floatAddMR); - bo[index(c, FloatSubtract, R, R)] = CAST2(floatSubtractRR); - bo[index(c, FloatSubtract, M, R)] = CAST2(floatSubtractMR); + bo[index(c, lir::FloatSubtract, R, R)] = CAST2(floatSubtractRR); + bo[index(c, lir::FloatSubtract, M, R)] = CAST2(floatSubtractMR); - bo[index(c, And, R, R)] = CAST2(andRR); - bo[index(c, And, C, R)] = CAST2(andCR); + bo[index(c, lir::And, R, R)] = CAST2(andRR); + bo[index(c, lir::And, C, R)] = CAST2(andCR); - bo[index(c, Or, R, R)] = CAST2(orRR); - bo[index(c, Or, C, R)] = CAST2(orCR); + bo[index(c, lir::Or, R, R)] = CAST2(orRR); + bo[index(c, lir::Or, C, R)] = CAST2(orCR); - bo[index(c, Xor, R, R)] = CAST2(xorRR); - bo[index(c, Xor, C, R)] = CAST2(xorCR); + bo[index(c, lir::Xor, R, R)] = CAST2(xorRR); + bo[index(c, lir::Xor, C, R)] = CAST2(xorCR); - bo[index(c, Multiply, R, R)] = CAST2(multiplyRR); - bo[index(c, Multiply, C, R)] = CAST2(multiplyCR); + bo[index(c, lir::Multiply, R, R)] = CAST2(multiplyRR); + bo[index(c, lir::Multiply, C, R)] = CAST2(multiplyCR); - bo[index(c, Divide, R, R)] = CAST2(divideRR); + bo[index(c, lir::Divide, R, R)] = CAST2(divideRR); - bo[index(c, FloatMultiply, R, R)] = CAST2(floatMultiplyRR); - bo[index(c, FloatMultiply, M, R)] = CAST2(floatMultiplyMR); + bo[index(c, lir::FloatMultiply, R, R)] = CAST2(floatMultiplyRR); + bo[index(c, lir::FloatMultiply, M, R)] = CAST2(floatMultiplyMR); - bo[index(c, FloatDivide, R, R)] = CAST2(floatDivideRR); - bo[index(c, FloatDivide, M, R)] = CAST2(floatDivideMR); + bo[index(c, lir::FloatDivide, R, R)] = CAST2(floatDivideRR); + bo[index(c, lir::FloatDivide, M, R)] = CAST2(floatDivideMR); - bo[index(c, Remainder, R, R)] = CAST2(remainderRR); + bo[index(c, lir::Remainder, R, R)] = CAST2(remainderRR); - bo[index(c, ShiftLeft, R, R)] = CAST2(shiftLeftRR); - bo[index(c, ShiftLeft, C, R)] = CAST2(shiftLeftCR); + bo[index(c, lir::ShiftLeft, R, R)] = CAST2(shiftLeftRR); + bo[index(c, lir::ShiftLeft, C, R)] = CAST2(shiftLeftCR); - bo[index(c, ShiftRight, R, R)] = CAST2(shiftRightRR); - bo[index(c, ShiftRight, C, R)] = CAST2(shiftRightCR); + bo[index(c, lir::ShiftRight, R, R)] = CAST2(shiftRightRR); + bo[index(c, lir::ShiftRight, C, R)] = CAST2(shiftRightCR); - bo[index(c, UnsignedShiftRight, R, R)] = CAST2(unsignedShiftRightRR); - bo[index(c, UnsignedShiftRight, C, R)] = CAST2(unsignedShiftRightCR); + bo[index(c, lir::UnsignedShiftRight, R, R)] = CAST2(unsignedShiftRightRR); + bo[index(c, lir::UnsignedShiftRight, C, R)] = CAST2(unsignedShiftRightCR); - bo[index(c, Float2Float, R, R)] = CAST2(float2FloatRR); - bo[index(c, Float2Float, M, R)] = CAST2(float2FloatMR); + bo[index(c, lir::Float2Float, R, R)] = CAST2(float2FloatRR); + bo[index(c, lir::Float2Float, M, R)] = CAST2(float2FloatMR); - bo[index(c, Float2Int, R, R)] = CAST2(float2IntRR); - bo[index(c, Float2Int, M, R)] = CAST2(float2IntMR); + bo[index(c, lir::Float2Int, R, R)] = CAST2(float2IntRR); + bo[index(c, lir::Float2Int, M, R)] = CAST2(float2IntMR); - bo[index(c, Int2Float, R, R)] = CAST2(int2FloatRR); - bo[index(c, Int2Float, M, R)] = CAST2(int2FloatMR); + bo[index(c, lir::Int2Float, R, R)] = CAST2(int2FloatRR); + bo[index(c, lir::Int2Float, M, R)] = CAST2(int2FloatMR); - bo[index(c, Absolute, R, R)] = CAST2(absoluteRR); - bo[index(c, FloatAbsolute, R, R)] = CAST2(floatAbsoluteRR); + bo[index(c, lir::Absolute, R, R)] = CAST2(absoluteRR); + bo[index(c, lir::FloatAbsolute, R, R)] = CAST2(floatAbsoluteRR); bro[branchIndex(c, R, R)] = CAST_BRANCH(branchRR); bro[branchIndex(c, C, R)] = CAST_BRANCH(branchCR); @@ -2780,7 +2769,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual int returnHigh() { - return (TargetBytesPerWord == 4 ? rdx : NoRegister); + return (TargetBytesPerWord == 4 ? rdx : lir::NoRegister); } virtual int virtualCallTarget() { @@ -2891,28 +2880,28 @@ class MyArchitecture: public Assembler::Architecture { return *instruction == 0xE8 and actualTarget == target; } - virtual void updateCall(UnaryOperation op, void* returnAddress, + virtual void updateCall(lir::UnaryOperation op, void* returnAddress, void* newTarget) { bool assertAlignment UNUSED; switch (op) { - case AlignedCall: - op = Call; + case lir::AlignedCall: + op = lir::Call; assertAlignment = true; break; - case AlignedJump: - op = Jump; + case lir::AlignedJump: + op = lir::Jump; assertAlignment = true; break; - case AlignedLongCall: - op = LongCall; + case lir::AlignedLongCall: + op = lir::LongCall; assertAlignment = true; break; - case AlignedLongJump: - op = LongJump; + case lir::AlignedLongJump: + op = lir::LongJump; assertAlignment = true; break; @@ -2920,11 +2909,11 @@ class MyArchitecture: public Assembler::Architecture { assertAlignment = false; } - if (TargetBytesPerWord == 4 or op == Call or op == Jump) { + if (TargetBytesPerWord == 4 or op == lir::Call or op == lir::Jump) { uint8_t* instruction = static_cast(returnAddress) - 5; - assert(&c, ((op == Call or op == LongCall) and *instruction == 0xE8) - or ((op == Jump or op == LongJump) and *instruction == 0xE9)); + assert(&c, ((op == lir::Call or op == lir::LongCall) and *instruction == 0xE8) + or ((op == lir::Jump or op == lir::LongJump) and *instruction == 0xE9)); assert(&c, (not assertAlignment) or reinterpret_cast(instruction + 1) % 4 == 0); @@ -2942,8 +2931,8 @@ class MyArchitecture: public Assembler::Architecture { assert(&c, instruction[0] == 0x49 and instruction[1] == 0xBA); assert(&c, instruction[10] == 0x41 and instruction[11] == 0xFF); - assert(&c, (op == LongCall and instruction[12] == 0xD2) - or (op == LongJump and instruction[12] == 0xE2)); + assert(&c, (op == lir::LongCall and instruction[12] == 0xD2) + or (op == lir::LongJump and instruction[12] == 0xE2)); assert(&c, (not assertAlignment) or reinterpret_cast(instruction + 2) % 8 == 0); @@ -2987,18 +2976,18 @@ class MyArchitecture: public Assembler::Architecture { return 0; } - virtual bool alwaysCondensed(BinaryOperation op) { + virtual bool alwaysCondensed(lir::BinaryOperation op) { switch(op) { - case Float2Float: - case Float2Int: - case Int2Float: - case FloatAbsolute: - case FloatNegate: - case FloatSquareRoot: + case lir::Float2Float: + case lir::Float2Int: + case lir::Int2Float: + case lir::FloatAbsolute: + case lir::FloatNegate: + case lir::FloatSquareRoot: return false; - case Negate: - case Absolute: + case lir::Negate: + case lir::Absolute: return true; default: @@ -3006,7 +2995,7 @@ class MyArchitecture: public Assembler::Architecture { } } - virtual bool alwaysCondensed(TernaryOperation) { + virtual bool alwaysCondensed(lir::TernaryOperation) { return true; } @@ -3019,18 +3008,18 @@ class MyArchitecture: public Assembler::Architecture { } virtual void plan - (UnaryOperation, + (lir::UnaryOperation, unsigned, uint8_t* aTypeMask, uint64_t* aRegisterMask, bool* thunk) { - *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand) - | (1 << ConstantOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand) + | (1 << lir::ConstantOperand); *aRegisterMask = ~static_cast(0); *thunk = false; } virtual void planSource - (BinaryOperation op, + (lir::BinaryOperation op, unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask, unsigned bSize, bool* thunk) { @@ -3041,24 +3030,24 @@ class MyArchitecture: public Assembler::Architecture { *thunk = false; switch (op) { - case Negate: - *aTypeMask = (1 << RegisterOperand); + case lir::Negate: + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = (static_cast(1) << (rdx + 32)) | (static_cast(1) << rax); break; - case Absolute: + case lir::Absolute: if (aSize <= TargetBytesPerWord) { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = (static_cast(1) << rax); } else { *thunk = true; } break; - case FloatAbsolute: + case lir::FloatAbsolute: if (useSSE(&c)) { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; } else { @@ -3066,19 +3055,19 @@ class MyArchitecture: public Assembler::Architecture { } break; - case FloatNegate: + case lir::FloatNegate: // floatNegateRR does not support doubles if (useSSE(&c) and aSize == 4 and bSize == 4) { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = FloatRegisterMask; } else { *thunk = true; } break; - case FloatSquareRoot: + case lir::FloatSquareRoot: if (useSSE(&c)) { - *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); *aRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; } else { @@ -3086,9 +3075,9 @@ class MyArchitecture: public Assembler::Architecture { } break; - case Float2Float: + case lir::Float2Float: if (useSSE(&c)) { - *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); *aRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; } else { @@ -3096,13 +3085,13 @@ class MyArchitecture: public Assembler::Architecture { } break; - case Float2Int: + case lir::Float2Int: // todo: Java requires different semantics than SSE for // converting floats to integers, we we need to either use // thunks or produce inline machine code which handles edge // cases properly. if (false and useSSE(&c) and bSize <= TargetBytesPerWord) { - *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); *aRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; } else { @@ -3110,9 +3099,9 @@ class MyArchitecture: public Assembler::Architecture { } break; - case Int2Float: + case lir::Int2Float: if (useSSE(&c) and aSize <= TargetBytesPerWord) { - *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); *aRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); } else { @@ -3120,18 +3109,18 @@ class MyArchitecture: public Assembler::Architecture { } break; - case Move: + case lir::Move: *aTypeMask = ~0; *aRegisterMask = ~static_cast(0); if (TargetBytesPerWord == 4) { if (aSize == 4 and bSize == 8) { - *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); *aRegisterMask = (static_cast(mask) << 32) | mask; } else if (aSize == 1 or bSize == 1) { - *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); const uint32_t mask = (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); *aRegisterMask = (static_cast(mask) << 32) | mask; @@ -3145,7 +3134,7 @@ class MyArchitecture: public Assembler::Architecture { } virtual void planDestination - (BinaryOperation op, unsigned aSize, uint8_t aTypeMask, + (lir::BinaryOperation op, unsigned aSize, uint8_t aTypeMask, uint64_t aRegisterMask, unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask) { @@ -3154,42 +3143,42 @@ class MyArchitecture: public Assembler::Architecture { | (static_cast(GeneralRegisterMask) << 32); switch (op) { - case Absolute: - *bTypeMask = (1 << RegisterOperand); + case lir::Absolute: + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = (static_cast(1) << rax); break; - case FloatAbsolute: - *bTypeMask = (1 << RegisterOperand); + case lir::FloatAbsolute: + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = aRegisterMask; break; - case Negate: - *bTypeMask = (1 << RegisterOperand); + case lir::Negate: + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = aRegisterMask; break; - case FloatNegate: - case FloatSquareRoot: - case Float2Float: - case Int2Float: - *bTypeMask = (1 << RegisterOperand); + case lir::FloatNegate: + case lir::FloatSquareRoot: + case lir::Float2Float: + case lir::Int2Float: + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; break; - case Float2Int: - *bTypeMask = (1 << RegisterOperand); + case lir::Float2Int: + *bTypeMask = (1 << lir::RegisterOperand); break; - case Move: - if (aTypeMask & ((1 << MemoryOperand) | 1 << AddressOperand)) { - *bTypeMask = (1 << RegisterOperand); + case lir::Move: + if (aTypeMask & ((1 << lir::MemoryOperand) | 1 << lir::AddressOperand)) { + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32) | FloatRegisterMask; - } else if (aTypeMask & (1 << RegisterOperand)) { - *bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + } else if (aTypeMask & (1 << lir::RegisterOperand)) { + *bTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); if (aRegisterMask & FloatRegisterMask) { *bRegisterMask = FloatRegisterMask; } else { @@ -3197,7 +3186,7 @@ class MyArchitecture: public Assembler::Architecture { | (static_cast(GeneralRegisterMask) << 32); } } else { - *bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *bTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); } if (TargetBytesPerWord == 4) { @@ -3228,33 +3217,33 @@ class MyArchitecture: public Assembler::Architecture { *tmpTypeMask = 0; *tmpRegisterMask = 0; - if (dstTypeMask & (1 << MemoryOperand)) { + if (dstTypeMask & (1 << lir::MemoryOperand)) { // can't move directly from memory to memory - *srcTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand); - *tmpTypeMask = 1 << RegisterOperand; + *srcTypeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); + *tmpTypeMask = 1 << lir::RegisterOperand; *tmpRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); - } else if (dstTypeMask & (1 << RegisterOperand)) { + } else if (dstTypeMask & (1 << lir::RegisterOperand)) { if (size > TargetBytesPerWord) { // can't move directly from FPR to GPR or vice-versa for // values larger than the GPR size if (dstRegisterMask & FloatRegisterMask) { *srcRegisterMask = FloatRegisterMask | (static_cast(FloatRegisterMask) << 32); - *tmpTypeMask = 1 << MemoryOperand; + *tmpTypeMask = 1 << lir::MemoryOperand; } else if (dstRegisterMask & GeneralRegisterMask) { *srcRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); - *tmpTypeMask = 1 << MemoryOperand; + *tmpTypeMask = 1 << lir::MemoryOperand; } } if (dstRegisterMask & FloatRegisterMask) { // can't move directly from constant to FPR - *srcTypeMask &= ~(1 << ConstantOperand); + *srcTypeMask &= ~(1 << lir::ConstantOperand); if (size > TargetBytesPerWord) { - *tmpTypeMask = 1 << MemoryOperand; + *tmpTypeMask = 1 << lir::MemoryOperand; } else { - *tmpTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); + *tmpTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); *tmpRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); } @@ -3263,29 +3252,29 @@ class MyArchitecture: public Assembler::Architecture { } virtual void planSource - (TernaryOperation op, + (lir::TernaryOperation op, unsigned aSize, uint8_t *aTypeMask, uint64_t *aRegisterMask, unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask, unsigned, bool* thunk) { - *aTypeMask = (1 << RegisterOperand) | (1 << ConstantOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::ConstantOperand); *aRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); - *bTypeMask = (1 << RegisterOperand); + *bTypeMask = (1 << lir::RegisterOperand); *bRegisterMask = GeneralRegisterMask | (static_cast(GeneralRegisterMask) << 32); *thunk = false; switch (op) { - case FloatAdd: - case FloatSubtract: - case FloatMultiply: - case FloatDivide: + case lir::FloatAdd: + case lir::FloatSubtract: + case lir::FloatMultiply: + case lir::FloatDivide: if (useSSE(&c)) { - *aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand); - *bTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand) | (1 << lir::MemoryOperand); + *bTypeMask = (1 << lir::RegisterOperand); const uint64_t mask = (static_cast(FloatRegisterMask) << 32) @@ -3297,11 +3286,11 @@ class MyArchitecture: public Assembler::Architecture { } break; - case FloatRemainder: + case lir::FloatRemainder: *thunk = true; break; - case Multiply: + case lir::Multiply: if (TargetBytesPerWord == 4 and aSize == 8) { const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); *aRegisterMask = (static_cast(mask) << 32) | mask; @@ -3312,29 +3301,29 @@ class MyArchitecture: public Assembler::Architecture { } break; - case Divide: + case lir::Divide: if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); *bRegisterMask = 1 << rax; } break; - case Remainder: + case lir::Remainder: if (TargetBytesPerWord == 4 and aSize == 8) { *thunk = true; } else { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx)); *bRegisterMask = 1 << rax; } break; - case ShiftLeft: - case ShiftRight: - case UnsignedShiftRight: { + case lir::ShiftLeft: + case lir::ShiftRight: + case lir::UnsignedShiftRight: { if (TargetBytesPerWord == 4 and bSize == 8) { const uint32_t mask = GeneralRegisterMask & ~(1 << rcx); *aRegisterMask = (static_cast(mask) << 32) | mask; @@ -3347,18 +3336,18 @@ class MyArchitecture: public Assembler::Architecture { } } break; - case JumpIfFloatEqual: - case JumpIfFloatNotEqual: - case JumpIfFloatLess: - case JumpIfFloatGreater: - case JumpIfFloatLessOrEqual: - case JumpIfFloatGreaterOrEqual: - case JumpIfFloatLessOrUnordered: - case JumpIfFloatGreaterOrUnordered: - case JumpIfFloatLessOrEqualOrUnordered: - case JumpIfFloatGreaterOrEqualOrUnordered: + case lir::JumpIfFloatEqual: + case lir::JumpIfFloatNotEqual: + case lir::JumpIfFloatLess: + case lir::JumpIfFloatGreater: + case lir::JumpIfFloatLessOrEqual: + case lir::JumpIfFloatGreaterOrEqual: + case lir::JumpIfFloatLessOrUnordered: + case lir::JumpIfFloatGreaterOrUnordered: + case lir::JumpIfFloatLessOrEqualOrUnordered: + case lir::JumpIfFloatGreaterOrEqualOrUnordered: if (useSSE(&c)) { - *aTypeMask = (1 << RegisterOperand); + *aTypeMask = (1 << lir::RegisterOperand); *aRegisterMask = (static_cast(FloatRegisterMask) << 32) | FloatRegisterMask; *bTypeMask = *aTypeMask; @@ -3374,15 +3363,15 @@ class MyArchitecture: public Assembler::Architecture { } virtual void planDestination - (TernaryOperation op, unsigned, uint8_t, uint64_t, unsigned, uint8_t, + (lir::TernaryOperation op, unsigned, uint8_t, uint64_t, unsigned, uint8_t, uint64_t bRegisterMask, unsigned, uint8_t* cTypeMask, uint64_t* cRegisterMask) { if (isBranch(op)) { - *cTypeMask = (1 << ConstantOperand); + *cTypeMask = (1 << lir::ConstantOperand); *cRegisterMask = 0; } else { - *cTypeMask = (1 << RegisterOperand); + *cTypeMask = (1 << lir::RegisterOperand); *cRegisterMask = bRegisterMask; } } @@ -3421,25 +3410,27 @@ class MyAssembler: public Assembler { virtual void checkStackOverflow(uintptr_t handler, unsigned stackLimitOffsetFromThread) { - Register stack(rsp); - Memory stackLimit(rbx, stackLimitOffsetFromThread); - Constant handlerConstant(resolved(&c, handler)); - branchRM(&c, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, + lir::Register stack(rsp); + lir::Memory stackLimit(rbx, stackLimitOffsetFromThread); + lir::Constant handlerConstant(resolved(&c, handler)); + branchRM(&c, lir::JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit, &handlerConstant); } virtual void saveFrame(unsigned stackOffset, unsigned) { - Register stack(rsp); - Memory stackDst(rbx, stackOffset); - apply(Move, TargetBytesPerWord, RegisterOperand, &stack, - TargetBytesPerWord, MemoryOperand, &stackDst); + lir::Register stack(rsp); + lir::Memory stackDst(rbx, stackOffset); + apply(lir::Move, + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), + OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &stackDst)); } virtual void pushFrame(unsigned argumentCount, ...) { + // TODO: Argument should be replaced by OperandInfo... struct Argument { unsigned size; - OperandType type; - Operand* operand; + lir::OperandType type; + lir::Operand* operand; }; RUNTIME_ARRAY(Argument, arguments, argumentCount); va_list a; va_start(a, argumentCount); @@ -3447,8 +3438,8 @@ class MyAssembler: public Assembler { for (unsigned i = 0; i < argumentCount; ++i) { RUNTIME_ARRAY_BODY(arguments)[i].size = va_arg(a, unsigned); RUNTIME_ARRAY_BODY(arguments)[i].type - = static_cast(va_arg(a, int)); - RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, Operand*); + = static_cast(va_arg(a, int)); + RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, lir::Operand*); footprint += ceilingDivide (RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); } @@ -3459,23 +3450,27 @@ class MyAssembler: public Assembler { unsigned offset = 0; for (unsigned i = 0; i < argumentCount; ++i) { if (i < arch_->argumentRegisterCount()) { - Register dst(arch_->argumentRegister(i)); - apply(Move, - RUNTIME_ARRAY_BODY(arguments)[i].size, - RUNTIME_ARRAY_BODY(arguments)[i].type, - RUNTIME_ARRAY_BODY(arguments)[i].operand, - pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), - RegisterOperand, - &dst); + lir::Register dst(arch_->argumentRegister(i)); + apply(lir::Move, + OperandInfo( + RUNTIME_ARRAY_BODY(arguments)[i].size, + RUNTIME_ARRAY_BODY(arguments)[i].type, + RUNTIME_ARRAY_BODY(arguments)[i].operand), + OperandInfo( + pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), + lir::RegisterOperand, + &dst)); } else { - Memory dst(rsp, offset * TargetBytesPerWord); - apply(Move, - RUNTIME_ARRAY_BODY(arguments)[i].size, - RUNTIME_ARRAY_BODY(arguments)[i].type, - RUNTIME_ARRAY_BODY(arguments)[i].operand, - pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), - MemoryOperand, - &dst); + lir::Memory dst(rsp, offset * TargetBytesPerWord); + apply(lir::Move, + OperandInfo( + RUNTIME_ARRAY_BODY(arguments)[i].size, + RUNTIME_ARRAY_BODY(arguments)[i].type, + RUNTIME_ARRAY_BODY(arguments)[i].operand), + OperandInfo( + pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord), + lir::MemoryOperand, + &dst)); offset += ceilingDivide (RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord); } @@ -3483,44 +3478,49 @@ class MyAssembler: public Assembler { } virtual void allocateFrame(unsigned footprint) { - Register stack(rsp); + lir::Register stack(rsp); if (UseFramePointer) { - Register base(rbp); + lir::Register base(rbp); pushR(&c, TargetBytesPerWord, &base); - apply(Move, TargetBytesPerWord, RegisterOperand, &stack, - TargetBytesPerWord, RegisterOperand, &base); + apply(lir::Move, + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &base)); } - Constant footprintConstant(resolved(&c, footprint * TargetBytesPerWord)); - apply(Subtract, TargetBytesPerWord, ConstantOperand, &footprintConstant, - TargetBytesPerWord, RegisterOperand, &stack, - TargetBytesPerWord, RegisterOperand, &stack); + lir::Constant footprintConstant(resolved(&c, footprint * TargetBytesPerWord)); + apply(lir::Subtract, + OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &footprintConstant), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); } virtual void adjustFrame(unsigned difference) { - Register stack(rsp); - Constant differenceConstant(resolved(&c, difference * TargetBytesPerWord)); - apply(Subtract, TargetBytesPerWord, ConstantOperand, &differenceConstant, - TargetBytesPerWord, RegisterOperand, &stack, - TargetBytesPerWord, RegisterOperand, &stack); + lir::Register stack(rsp); + lir::Constant differenceConstant(resolved(&c, difference * TargetBytesPerWord)); + apply(lir::Subtract, + OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &differenceConstant), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); } virtual void popFrame(unsigned frameFootprint) { if (UseFramePointer) { - Register base(rbp); - Register stack(rsp); - apply(Move, TargetBytesPerWord, RegisterOperand, &base, - TargetBytesPerWord, RegisterOperand, &stack); + lir::Register base(rbp); + lir::Register stack(rsp); + apply(lir::Move, + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &base), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); popR(&c, TargetBytesPerWord, &base); } else { - Register stack(rsp); - Constant footprint(resolved(&c, frameFootprint * TargetBytesPerWord)); - apply(Add, TargetBytesPerWord, ConstantOperand, &footprint, - TargetBytesPerWord, RegisterOperand, &stack, - TargetBytesPerWord, RegisterOperand, &stack); + lir::Register stack(rsp); + lir::Constant footprint(resolved(&c, frameFootprint * TargetBytesPerWord)); + apply(lir::Add, + OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &footprint), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &stack)); } } @@ -3531,16 +3531,16 @@ class MyAssembler: public Assembler { { if (TailCalls) { if (offset) { - Register tmp(c.client->acquireTemporary()); + lir::Register tmp(c.client->acquireTemporary()); unsigned baseSize = UseFramePointer ? 1 : 0; - Memory returnAddressSrc + lir::Memory returnAddressSrc (rsp, (frameFootprint + baseSize) * TargetBytesPerWord); moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord, &tmp); - Memory returnAddressDst + lir::Memory returnAddressDst (rsp, (frameFootprint - offset + baseSize) * TargetBytesPerWord); moveRM(&c, TargetBytesPerWord, &tmp, TargetBytesPerWord, &returnAddressDst); @@ -3548,31 +3548,31 @@ class MyAssembler: public Assembler { c.client->releaseTemporary(tmp.low); if (UseFramePointer) { - Memory baseSrc(rsp, frameFootprint * TargetBytesPerWord); - Register base(rbp); + lir::Memory baseSrc(rsp, frameFootprint * TargetBytesPerWord); + lir::Register base(rbp); moveMR(&c, TargetBytesPerWord, &baseSrc, TargetBytesPerWord, &base); } - Register stack(rsp); - Constant footprint + lir::Register stack(rsp); + lir::Constant footprint (resolved (&c, (frameFootprint - offset + baseSize) * TargetBytesPerWord)); addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack); - if (returnAddressSurrogate != NoRegister) { + if (returnAddressSurrogate != lir::NoRegister) { assert(&c, offset > 0); - Register ras(returnAddressSurrogate); - Memory dst(rsp, offset * TargetBytesPerWord); + lir::Register ras(returnAddressSurrogate); + lir::Memory dst(rsp, offset * TargetBytesPerWord); moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst); } - if (framePointerSurrogate != NoRegister) { + if (framePointerSurrogate != lir::NoRegister) { assert(&c, offset > 0); - Register fps(framePointerSurrogate); - Memory dst(rsp, (offset - 1) * TargetBytesPerWord); + lir::Register fps(framePointerSurrogate); + lir::Memory dst(rsp, (offset - 1) * TargetBytesPerWord); moveRM(&c, TargetBytesPerWord, &fps, TargetBytesPerWord, &dst); } } else { @@ -3592,11 +3592,11 @@ class MyAssembler: public Assembler { assert(&c, (argumentFootprint % StackAlignmentInWords) == 0); if (TailCalls and argumentFootprint > StackAlignmentInWords) { - Register returnAddress(rcx); + lir::Register returnAddress(rcx); popR(&c, TargetBytesPerWord, &returnAddress); - Register stack(rsp); - Constant adjustment + lir::Register stack(rsp); + lir::Constant adjustment (resolved(&c, (argumentFootprint - StackAlignmentInWords) * TargetBytesPerWord)); addCR(&c, TargetBytesPerWord, &adjustment, TargetBytesPerWord, &stack); @@ -3612,54 +3612,47 @@ class MyAssembler: public Assembler { { popFrame(frameFootprint); - Register returnAddress(rcx); + lir::Register returnAddress(rcx); popR(&c, TargetBytesPerWord, &returnAddress); - Register stack(rsp); - Memory stackSrc(rbx, stackOffsetFromThread); + lir::Register stack(rsp); + lir::Memory stackSrc(rbx, stackOffsetFromThread); moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &stack); jumpR(&c, TargetBytesPerWord, &returnAddress); } - virtual void apply(Operation op) { + virtual void apply(lir::Operation op) { arch_->c.operations[op](&c); } - virtual void apply(UnaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand) + virtual void apply(lir::UnaryOperation op, OperandInfo a) { - arch_->c.unaryOperations[index(&(arch_->c), op, aType)] - (&c, aSize, aOperand); + arch_->c.unaryOperations[index(&(arch_->c), op, a.type)] + (&c, a.size, a.operand); } - virtual void apply(BinaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand, - unsigned bSize, OperandType bType, Operand* bOperand) + virtual void apply(lir::BinaryOperation op, OperandInfo a, OperandInfo b) { - arch_->c.binaryOperations[index(&(arch_->c), op, aType, bType)] - (&c, aSize, aOperand, bSize, bOperand); + arch_->c.binaryOperations[index(&(arch_->c), op, a.type, b.type)] + (&c, a.size, a.operand, b.size, b.operand); } - virtual void apply(TernaryOperation op, - unsigned aSize, OperandType aType, Operand* aOperand, - unsigned bSize, OperandType bType, Operand* bOperand, - unsigned cSize UNUSED, OperandType cType UNUSED, - Operand* cOperand) + virtual void apply(lir::TernaryOperation op, OperandInfo a, OperandInfo b, OperandInfo c) { if (isBranch(op)) { - assert(&c, aSize == bSize); - assert(&c, cSize == TargetBytesPerWord); - assert(&c, cType == ConstantOperand); + assert(&this->c, a.size == b.size); + assert(&this->c, c.size == TargetBytesPerWord); + assert(&this->c, c.type == lir::ConstantOperand); - arch_->c.branchOperations[branchIndex(&(arch_->c), aType, bType)] - (&c, op, aSize, aOperand, bOperand, cOperand); + arch_->c.branchOperations[branchIndex(&(arch_->c), a.type, b.type)] + (&this->c, op, a.size, a.operand, b.operand, c.operand); } else { - assert(&c, bSize == cSize); - assert(&c, bType == cType); + assert(&this->c, b.size == c.size); + assert(&this->c, b.type == c.type); - arch_->c.binaryOperations[index(&(arch_->c), op, aType, bType)] - (&c, aSize, aOperand, bSize, bOperand); + arch_->c.binaryOperations[index(&(arch_->c), op, a.type, b.type)] + (&this->c, a.size, a.operand, b.size, b.operand); } } diff --git a/src/compile.cpp b/src/compile.cpp index b01e56bee6..5b9245df15 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -37,6 +37,8 @@ vmJumpAndInvoke(void* thread, void* function, void* stack, unsigned argumentFootprint, uintptr_t* arguments, unsigned frameSize); +using avian::codegen::Compiler; + namespace { namespace local { @@ -291,7 +293,7 @@ class MyThread: public Thread { void** thunkTable; CallTrace* trace; Reference* reference; - Assembler::Architecture* arch; + avian::codegen::Assembler::Architecture* arch; Context* transition; TraceContext* traceContext; uintptr_t stackLimit; @@ -737,7 +739,7 @@ stackForFrame(MyThread* t, void* frame, object method) return static_cast(frame) - stackOffsetFromFrame(t, method); } -class PoolElement: public Promise { +class PoolElement: public avian::codegen::Promise { public: PoolElement(Thread* t, object target, PoolElement* next): t(t), target(target), address(0), next(next) @@ -793,7 +795,7 @@ class SubroutinePath; class SubroutineCall { public: - SubroutineCall(Subroutine* subroutine, Promise* returnAddress): + SubroutineCall(Subroutine* subroutine, avian::codegen::Promise* returnAddress): subroutine(subroutine), returnAddress(returnAddress), paths(0), @@ -804,7 +806,7 @@ class SubroutineCall { } Subroutine* subroutine; - Promise* returnAddress; + avian::codegen::Promise* returnAddress; SubroutinePath* paths; SubroutineCall* next; }; @@ -863,7 +865,7 @@ class SubroutineTrace { uintptr_t map[0]; }; -class TraceElement: public TraceHandler { +class TraceElement: public avian::codegen::TraceHandler { public: static const unsigned VirtualCall = 1 << 0; static const unsigned TailCall = 1 << 1; @@ -885,7 +887,7 @@ class TraceElement: public TraceHandler { memset(map, 0xFF, mapSize * BytesPerWord); } - virtual void handleTrace(Promise* address, unsigned argumentIndex) { + virtual void handleTrace(avian::codegen::Promise* address, unsigned argumentIndex) { if (this->address == 0) { this->address = address; this->argumentIndex = argumentIndex; @@ -893,7 +895,7 @@ class TraceElement: public TraceHandler { } Context* context; - Promise* address; + avian::codegen::Promise* address; TraceElement* next; SubroutineTrace* subroutineTrace; object target; @@ -905,7 +907,7 @@ class TraceElement: public TraceHandler { uintptr_t map[0]; }; -class TraceElementPromise: public Promise { +class TraceElementPromise: public avian::codegen::Promise { public: TraceElementPromise(System* s, TraceElement* trace): s(s), trace(trace) { } @@ -994,7 +996,7 @@ class BootContext { }; BootContext(Thread* t, object constants, object calls, - DelayedPromise* addresses, Zone* zone, OffsetResolver* resolver): + avian::codegen::DelayedPromise* addresses, Zone* zone, OffsetResolver* resolver): protector(t, this), constants(constants), calls(calls), addresses(addresses), addressSentinal(addresses), zone(zone), resolver(resolver) @@ -1003,8 +1005,8 @@ class BootContext { MyProtector protector; object constants; object calls; - DelayedPromise* addresses; - DelayedPromise* addressSentinal; + avian::codegen::DelayedPromise* addresses; + avian::codegen::DelayedPromise* addressSentinal; Zone* zone; OffsetResolver* resolver; }; @@ -1045,32 +1047,32 @@ class Context { public: MyClient(MyThread* t): t(t) { } - virtual intptr_t getThunk(UnaryOperation, unsigned) { + virtual intptr_t getThunk(avian::codegen::lir::UnaryOperation, unsigned) { abort(t); } - virtual intptr_t getThunk(BinaryOperation op, unsigned size, + virtual intptr_t getThunk(avian::codegen::lir::BinaryOperation op, unsigned size, unsigned resultSize) { if (size == 8) { switch(op) { - case Absolute: + case avian::codegen::lir::Absolute: assert(t, resultSize == 8); return local::getThunk(t, absoluteLongThunk); - case FloatNegate: + case avian::codegen::lir::FloatNegate: assert(t, resultSize == 8); return local::getThunk(t, negateDoubleThunk); - case FloatSquareRoot: + case avian::codegen::lir::FloatSquareRoot: assert(t, resultSize == 8); return local::getThunk(t, squareRootDoubleThunk); - case Float2Float: + case avian::codegen::lir::Float2Float: assert(t, resultSize == 4); return local::getThunk(t, doubleToFloatThunk); - case Float2Int: + case avian::codegen::lir::Float2Int: if (resultSize == 8) { return local::getThunk(t, doubleToLongThunk); } else { @@ -1078,7 +1080,7 @@ class Context { return local::getThunk(t, doubleToIntThunk); } - case Int2Float: + case avian::codegen::lir::Int2Float: if (resultSize == 8) { return local::getThunk(t, longToDoubleThunk); } else { @@ -1092,23 +1094,23 @@ class Context { assert(t, size == 4); switch(op) { - case Absolute: + case avian::codegen::lir::Absolute: assert(t, resultSize == 4); return local::getThunk(t, absoluteIntThunk); - case FloatNegate: + case avian::codegen::lir::FloatNegate: assert(t, resultSize == 4); return local::getThunk(t, negateFloatThunk); - case FloatAbsolute: + case avian::codegen::lir::FloatAbsolute: assert(t, resultSize == 4); return local::getThunk(t, absoluteFloatThunk); - case Float2Float: + case avian::codegen::lir::Float2Float: assert(t, resultSize == 8); return local::getThunk(t, floatToDoubleThunk); - case Float2Int: + case avian::codegen::lir::Float2Int: if (resultSize == 4) { return local::getThunk(t, floatToIntThunk); } else { @@ -1116,7 +1118,7 @@ class Context { return local::getThunk(t, floatToLongThunk); } - case Int2Float: + case avian::codegen::lir::Int2Float: if (resultSize == 4) { return local::getThunk(t, intToFloatThunk); } else { @@ -1129,48 +1131,48 @@ class Context { } } - virtual intptr_t getThunk(TernaryOperation op, unsigned size, unsigned, + virtual intptr_t getThunk(avian::codegen::lir::TernaryOperation op, unsigned size, unsigned, bool* threadParameter) { *threadParameter = false; if (size == 8) { switch (op) { - case Divide: + case avian::codegen::lir::Divide: *threadParameter = true; return local::getThunk(t, divideLongThunk); - case Remainder: + case avian::codegen::lir::Remainder: *threadParameter = true; return local::getThunk(t, moduloLongThunk); - case FloatAdd: + case avian::codegen::lir::FloatAdd: return local::getThunk(t, addDoubleThunk); - case FloatSubtract: + case avian::codegen::lir::FloatSubtract: return local::getThunk(t, subtractDoubleThunk); - case FloatMultiply: + case avian::codegen::lir::FloatMultiply: return local::getThunk(t, multiplyDoubleThunk); - case FloatDivide: + case avian::codegen::lir::FloatDivide: return local::getThunk(t, divideDoubleThunk); - case FloatRemainder: + case avian::codegen::lir::FloatRemainder: return local::getThunk(t, moduloDoubleThunk); - case JumpIfFloatEqual: - case JumpIfFloatNotEqual: - case JumpIfFloatLess: - case JumpIfFloatGreater: - case JumpIfFloatLessOrEqual: - case JumpIfFloatGreaterOrUnordered: - case JumpIfFloatGreaterOrEqualOrUnordered: + case avian::codegen::lir::JumpIfFloatEqual: + case avian::codegen::lir::JumpIfFloatNotEqual: + case avian::codegen::lir::JumpIfFloatLess: + case avian::codegen::lir::JumpIfFloatGreater: + case avian::codegen::lir::JumpIfFloatLessOrEqual: + case avian::codegen::lir::JumpIfFloatGreaterOrUnordered: + case avian::codegen::lir::JumpIfFloatGreaterOrEqualOrUnordered: return local::getThunk(t, compareDoublesGThunk); - case JumpIfFloatGreaterOrEqual: - case JumpIfFloatLessOrUnordered: - case JumpIfFloatLessOrEqualOrUnordered: + case avian::codegen::lir::JumpIfFloatGreaterOrEqual: + case avian::codegen::lir::JumpIfFloatLessOrUnordered: + case avian::codegen::lir::JumpIfFloatLessOrEqualOrUnordered: return local::getThunk(t, compareDoublesLThunk); default: abort(t); @@ -1178,41 +1180,41 @@ class Context { } else { assert(t, size == 4); switch (op) { - case Divide: + case avian::codegen::lir::Divide: *threadParameter = true; return local::getThunk(t, divideIntThunk); - case Remainder: + case avian::codegen::lir::Remainder: *threadParameter = true; return local::getThunk(t, moduloIntThunk); - case FloatAdd: + case avian::codegen::lir::FloatAdd: return local::getThunk(t, addFloatThunk); - case FloatSubtract: + case avian::codegen::lir::FloatSubtract: return local::getThunk(t, subtractFloatThunk); - case FloatMultiply: + case avian::codegen::lir::FloatMultiply: return local::getThunk(t, multiplyFloatThunk); - case FloatDivide: + case avian::codegen::lir::FloatDivide: return local::getThunk(t, divideFloatThunk); - case FloatRemainder: + case avian::codegen::lir::FloatRemainder: return local::getThunk(t, moduloFloatThunk); - case JumpIfFloatEqual: - case JumpIfFloatNotEqual: - case JumpIfFloatLess: - case JumpIfFloatGreater: - case JumpIfFloatLessOrEqual: - case JumpIfFloatGreaterOrUnordered: - case JumpIfFloatGreaterOrEqualOrUnordered: + case avian::codegen::lir::JumpIfFloatEqual: + case avian::codegen::lir::JumpIfFloatNotEqual: + case avian::codegen::lir::JumpIfFloatLess: + case avian::codegen::lir::JumpIfFloatGreater: + case avian::codegen::lir::JumpIfFloatLessOrEqual: + case avian::codegen::lir::JumpIfFloatGreaterOrUnordered: + case avian::codegen::lir::JumpIfFloatGreaterOrEqualOrUnordered: return local::getThunk(t, compareFloatsGThunk); - case JumpIfFloatGreaterOrEqual: - case JumpIfFloatLessOrUnordered: - case JumpIfFloatLessOrEqualOrUnordered: + case avian::codegen::lir::JumpIfFloatGreaterOrEqual: + case avian::codegen::lir::JumpIfFloatLessOrUnordered: + case avian::codegen::lir::JumpIfFloatLessOrEqualOrUnordered: return local::getThunk(t, compareFloatsLThunk); default: abort(t); @@ -1297,9 +1299,9 @@ class Context { MyThread* thread; Zone zone; - Assembler* assembler; + avian::codegen::Assembler* assembler; MyClient client; - Compiler* compiler; + avian::codegen::Compiler* compiler; object method; BootContext* bootContext; PoolElement* objectPool; @@ -1359,6 +1361,8 @@ class Frame { Object }; + typedef Compiler::Operand* Value; + Frame(Context* context, uint8_t* stackMap): context(context), t(context->thread), @@ -1400,10 +1404,10 @@ class Frame { } } - Compiler::Operand* append(object o) { + Value append(object o) { BootContext* bc = context->bootContext; if (bc) { - Promise* p = new (bc->zone) ListenPromise(t->m->system, bc->zone); + avian::codegen::Promise* p = new (bc->zone) avian::codegen::ListenPromise(t->m->system, bc->zone); PROTECT(t, o); object pointer = makePointer(t, p); @@ -1623,34 +1627,34 @@ class Frame { set(sp - 2, saved); } - Promise* addressPromise(Promise* p) { + avian::codegen::Promise* addressPromise(avian::codegen::Promise* p) { BootContext* bc = context->bootContext; if (bc) { - bc->addresses = new(bc->zone) DelayedPromise(t->m->system, bc->zone, p, bc->addresses); + bc->addresses = new(bc->zone) avian::codegen::DelayedPromise(t->m->system, bc->zone, p, bc->addresses); return bc->addresses; } else { return p; } } - Compiler::Operand* addressOperand(Promise* p) { + Value addressOperand(avian::codegen::Promise* p) { return c->promiseConstant(p, Compiler::AddressType); } - Compiler::Operand* absoluteAddressOperand(Promise* p) { + Value absoluteAddressOperand(avian::codegen::Promise* p) { return context->bootContext ? c->add (TargetBytesPerWord, c->memory (c->register_(t->arch->thread()), Compiler::AddressType, TARGET_THREAD_CODEIMAGE), c->promiseConstant (new(&context->zone) - OffsetPromise + avian::codegen::OffsetPromise (p, - reinterpret_cast(codeAllocator(t)->base)), Compiler::AddressType)) : addressOperand(p); } - Compiler::Operand* machineIp(unsigned logicalIp) { + Value machineIp(unsigned logicalIp) { return c->promiseConstant(c->machineIp(logicalIp), Compiler::AddressType); } @@ -1674,35 +1678,33 @@ class Frame { this->ip = ip; } - void pushQuiet(unsigned footprint, Compiler::Operand* o) { + void pushQuiet(unsigned footprint, Value o) { c->push(footprint, o); } - void pushLongQuiet(Compiler::Operand* o) { + void pushLongQuiet(Value o) { pushQuiet(2, o); } - Compiler::Operand* popQuiet(unsigned footprint) { + Value popQuiet(unsigned footprint) { return c->pop(footprint); } - Compiler::Operand* popLongQuiet() { - Compiler::Operand* r = popQuiet(2); - - return r; + Value popLongQuiet() { + return popQuiet(2); } - void pushInt(Compiler::Operand* o) { + void pushInt(Value o) { pushQuiet(1, o); pushedInt(); } - void pushAddress(Compiler::Operand* o) { + void pushAddress(Value o) { pushQuiet(1, o); pushedInt(); } - void pushObject(Compiler::Operand* o) { + void pushObject(Value o) { pushQuiet(1, o); pushedObject(); } @@ -1713,7 +1715,7 @@ class Frame { pushedObject(); } - void pushLong(Compiler::Operand* o) { + void pushLong(Value o) { pushLongQuiet(o); pushedLong(); } @@ -1723,17 +1725,17 @@ class Frame { c->popped(count); } - Compiler::Operand* popInt() { + Value popInt() { poppedInt(); return popQuiet(1); } - Compiler::Operand* popLong() { + Value popLong() { poppedLong(); return popLongQuiet(); } - Compiler::Operand* popObject() { + Value popObject() { poppedObject(); return popQuiet(1); } @@ -1789,8 +1791,8 @@ class Frame { } void dupX1() { - Compiler::Operand* s0 = popQuiet(1); - Compiler::Operand* s1 = popQuiet(1); + Value s0 = popQuiet(1); + Value s1 = popQuiet(1); pushQuiet(1, s0); pushQuiet(1, s1); @@ -1800,17 +1802,17 @@ class Frame { } void dupX2() { - Compiler::Operand* s0 = popQuiet(1); + Value s0 = popQuiet(1); if (get(sp - 2) == Long) { - Compiler::Operand* s1 = popLongQuiet(); + Value s1 = popLongQuiet(); pushQuiet(1, s0); pushLongQuiet(s1); pushQuiet(1, s0); } else { - Compiler::Operand* s1 = popQuiet(1); - Compiler::Operand* s2 = popQuiet(1); + Value s1 = popQuiet(1); + Value s2 = popQuiet(1); pushQuiet(1, s0); pushQuiet(1, s2); @@ -1825,8 +1827,8 @@ class Frame { if (get(sp - 1) == Long) { pushLongQuiet(c->peek(2, 0)); } else { - Compiler::Operand* s0 = popQuiet(1); - Compiler::Operand* s1 = popQuiet(1); + Value s0 = popQuiet(1); + Value s1 = popQuiet(1); pushQuiet(1, s1); pushQuiet(1, s0); @@ -1839,16 +1841,16 @@ class Frame { void dup2X1() { if (get(sp - 1) == Long) { - Compiler::Operand* s0 = popLongQuiet(); - Compiler::Operand* s1 = popQuiet(1); + Value s0 = popLongQuiet(); + Value s1 = popQuiet(1); pushLongQuiet(s0); pushQuiet(1, s1); pushLongQuiet(s0); } else { - Compiler::Operand* s0 = popQuiet(1); - Compiler::Operand* s1 = popQuiet(1); - Compiler::Operand* s2 = popQuiet(1); + Value s0 = popQuiet(1); + Value s1 = popQuiet(1); + Value s2 = popQuiet(1); pushQuiet(1, s1); pushQuiet(1, s0); @@ -1862,17 +1864,17 @@ class Frame { void dup2X2() { if (get(sp - 1) == Long) { - Compiler::Operand* s0 = popLongQuiet(); + Value s0 = popLongQuiet(); if (get(sp - 3) == Long) { - Compiler::Operand* s1 = popLongQuiet(); + Value s1 = popLongQuiet(); pushLongQuiet(s0); pushLongQuiet(s1); pushLongQuiet(s0); } else { - Compiler::Operand* s1 = popQuiet(1); - Compiler::Operand* s2 = popQuiet(1); + Value s1 = popQuiet(1); + Value s2 = popQuiet(1); pushLongQuiet(s0); pushQuiet(1, s2); @@ -1880,10 +1882,10 @@ class Frame { pushLongQuiet(s0); } } else { - Compiler::Operand* s0 = popQuiet(1); - Compiler::Operand* s1 = popQuiet(1); - Compiler::Operand* s2 = popQuiet(1); - Compiler::Operand* s3 = popQuiet(1); + Value s0 = popQuiet(1); + Value s1 = popQuiet(1); + Value s2 = popQuiet(1); + Value s3 = popQuiet(1); pushQuiet(1, s1); pushQuiet(1, s0); @@ -1897,8 +1899,8 @@ class Frame { } void swap() { - Compiler::Operand* s0 = popQuiet(1); - Compiler::Operand* s1 = popQuiet(1); + Value s0 = popQuiet(1); + Value s1 = popQuiet(1); pushQuiet(1, s0); pushQuiet(1, s1); @@ -1921,7 +1923,7 @@ class Frame { return e; } - unsigned startSubroutine(unsigned ip, Promise* returnAddress) { + unsigned startSubroutine(unsigned ip, avian::codegen::Promise* returnAddress) { pushAddress(absoluteAddressOperand(returnAddress)); Subroutine* subroutine = 0; @@ -1989,7 +1991,7 @@ class Frame { Context* context; MyThread* t; - Compiler* c; + avian::codegen::Compiler* c; Subroutine* subroutine; uint8_t* stackMap; unsigned ip; @@ -2194,7 +2196,7 @@ makeCurrentContinuation(MyThread* t, void** targetIp, void** targetStack) unsigned argumentFootprint = t->arch->argumentFootprint(methodParameterFootprint(t, target)); unsigned alignment = t->arch->stackAlignmentInWords(); - if (TailCalls and argumentFootprint > alignment) { + if (avian::codegen::TailCalls and argumentFootprint > alignment) { top += argumentFootprint - alignment; } @@ -3379,11 +3381,11 @@ useLongJump(MyThread* t, uintptr_t target) Compiler::Operand* compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall, - bool useThunk, unsigned rSize, Promise* addressPromise) + bool useThunk, unsigned rSize, avian::codegen::Promise* addressPromise) { - Compiler* c = frame->c; + avian::codegen::Compiler* c = frame->c; - unsigned flags = (TailCalls and tailCall ? Compiler::TailJump : 0); + unsigned flags = (avian::codegen::TailCalls and tailCall ? Compiler::TailJump : 0); unsigned traceFlags; if (addressPromise == 0 and useLongJump(t, methodAddress(t, target))) { @@ -3394,18 +3396,18 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall, } if (useThunk - or (TailCalls and tailCall and (methodFlags(t, target) & ACC_NATIVE))) + or (avian::codegen::TailCalls and tailCall and (methodFlags(t, target) & ACC_NATIVE))) { if (frame->context->bootContext == 0) { flags |= Compiler::Aligned; } - if (TailCalls and tailCall) { + if (avian::codegen::TailCalls and tailCall) { traceFlags |= TraceElement::TailCall; TraceElement* trace = frame->trace(target, traceFlags); - Promise* returnAddressPromise = new + avian::codegen::Promise* returnAddressPromise = new (frame->context->zone.allocate(sizeof(TraceElementPromise))) TraceElementPromise(t->m->system, trace); @@ -3471,10 +3473,10 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall) if (bc) { if ((methodClass(t, target) == methodClass(t, frame->context->method) or (not classNeedsInit(t, methodClass(t, target)))) - and (not (TailCalls and tailCall + and (not (avian::codegen::TailCalls and tailCall and (methodFlags(t, target) & ACC_NATIVE)))) { - Promise* p = new(bc->zone) ListenPromise(t->m->system, bc->zone); + avian::codegen::Promise* p = new(bc->zone) avian::codegen::ListenPromise(t->m->system, bc->zone); PROTECT(t, target); object pointer = makePointer(t, p); @@ -3557,7 +3559,7 @@ void compileDirectReferenceInvoke(MyThread* t, Frame* frame, Thunk thunk, object reference, bool isStatic, bool tailCall) { - Compiler* c = frame->c; + avian::codegen::Compiler* c = frame->c; PROTECT(t, reference); @@ -3603,7 +3605,7 @@ void compileDirectAbstractInvoke(MyThread* t, Frame* frame, Thunk thunk, object target, bool tailCall) { - Compiler* c = frame->c; + avian::codegen::Compiler* c = frame->c; compileAbstractInvoke (t, frame, c->call @@ -3619,7 +3621,7 @@ compileDirectAbstractInvoke(MyThread* t, Frame* frame, Thunk thunk, void handleMonitorEvent(MyThread* t, Frame* frame, intptr_t function) { - Compiler* c = frame->c; + avian::codegen::Compiler* c = frame->c; object method = frame->context->method; if (methodFlags(t, method) & ACC_SYNCHRONIZED) { @@ -3728,7 +3730,7 @@ bool isTailCall(MyThread* t, object code, unsigned ip, object caller, int calleeReturnCode) { - return TailCalls + return avian::codegen::TailCalls and ((methodFlags(t, caller) & ACC_SYNCHRONIZED) == 0) and (not inTryBlock(t, code, ip - 1)) and (not needsReturnBarrier(t, caller)) @@ -3760,7 +3762,7 @@ integerBranch(MyThread* t, Frame* frame, object code, unsigned& ip, return false; } - Compiler* c = frame->c; + avian::codegen::Compiler* c = frame->c; unsigned instruction = codeBody(t, code, ip++); uint32_t offset = codeReadInt16(t, code, ip); uint32_t newIp = (ip - 3) + offset; @@ -3811,7 +3813,7 @@ floatBranch(MyThread* t, Frame* frame, object code, unsigned& ip, return false; } - Compiler* c = frame->c; + avian::codegen::Compiler* c = frame->c; unsigned instruction = codeBody(t, code, ip++); uint32_t offset = codeReadInt16(t, code, ip); uint32_t newIp = (ip - 3) + offset; @@ -3886,7 +3888,7 @@ intrinsic(MyThread* t, Frame* frame, object target) object className = vm::className(t, methodClass(t, target)); if (UNLIKELY(MATCH(className, "java/lang/Math"))) { - Compiler* c = frame->c; + avian::codegen::Compiler* c = frame->c; if (MATCH(methodName(t, target), "sqrt") and MATCH(methodSpec(t, target), "(D)D")) { @@ -3905,7 +3907,7 @@ intrinsic(MyThread* t, Frame* frame, object target) } } } else if (UNLIKELY(MATCH(className, "sun/misc/Unsafe"))) { - Compiler* c = frame->c; + avian::codegen::Compiler* c = frame->c; if (MATCH(methodName(t, target), "getByte") and MATCH(methodSpec(t, target), "(J)B")) { @@ -4099,7 +4101,7 @@ class SwitchState { unsigned count, unsigned defaultIp, Compiler::Operand* key, - Promise* start, + avian::codegen::Promise* start, int bottom, int top): state(state), @@ -4126,7 +4128,7 @@ class SwitchState { unsigned count; unsigned defaultIp; Compiler::Operand* key; - Promise* start; + avian::codegen::Promise* start; int bottom; int top; unsigned index; @@ -4146,7 +4148,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, }; Frame* frame = initialFrame; - Compiler* c = frame->c; + avian::codegen::Compiler* c = frame->c; Context* context = frame->context; unsigned stackSize = codeMaxStack(t, methodCode(t, context->method)); Stack stack(t); @@ -5673,7 +5675,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, Compiler::Operand* default_ = frame->addressOperand (frame->addressPromise(c->machineIp(defaultIp))); - Promise* start = 0; + avian::codegen::Promise* start = 0; uint32_t* ipTable = static_cast (stack.push(sizeof(uint32_t) * pairCount)); for (int32_t i = 0; i < pairCount; ++i) { @@ -5684,7 +5686,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, ipTable[i] = newIp; - Promise* p = c->poolAppend(key); + avian::codegen::Promise* p = c->poolAppend(key); if (i == 0) { start = p; } @@ -6199,7 +6201,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, int32_t bottom = codeReadInt32(t, code, ip); int32_t top = codeReadInt32(t, code, ip); - Promise* start = 0; + avian::codegen::Promise* start = 0; unsigned count = top - bottom + 1; uint32_t* ipTable = static_cast (stack.push(sizeof(uint32_t) * count)); @@ -6210,7 +6212,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, ipTable[i] = newIp; - Promise* p = c->poolAppendPromise + avian::codegen::Promise* p = c->poolAppendPromise (frame->addressPromise(c->machineIp(newIp))); if (i == 0) { start = p; @@ -6489,7 +6491,7 @@ truncateLineNumberTable(Thread* t, object table, unsigned length) object translateExceptionHandlerTable(MyThread* t, Context* context, intptr_t start) { - Compiler* c = context->compiler; + avian::codegen::Compiler* c = context->compiler; object oldTable = codeExceptionHandlerTable (t, methodCode(t, context->method)); @@ -6935,7 +6937,7 @@ simpleFrameMapTableSize(MyThread* t, object method, object map) } uint8_t* -finish(MyThread* t, FixedAllocator* allocator, Assembler* a, const char* name, +finish(MyThread* t, FixedAllocator* allocator, avian::codegen::Assembler* a, const char* name, unsigned length) { uint8_t* start = static_cast @@ -7214,7 +7216,7 @@ makeSimpleFrameMapTable(MyThread* t, Context* context, uint8_t* start, void finish(MyThread* t, FixedAllocator* allocator, Context* context) { - Compiler* c = context->compiler; + avian::codegen::Compiler* c = context->compiler; if (false) { logCompile @@ -7291,11 +7293,11 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context) BootContext* bc = context->bootContext; if (bc) { - for (DelayedPromise* p = bc->addresses; + for (avian::codegen::DelayedPromise* p = bc->addresses; p != bc->addressSentinal; p = p->next) { - p->basis = new(bc->zone) ResolvedPromise(p->basis->value()); + p->basis = new(bc->zone) avian::codegen::ResolvedPromise(p->basis->value()); } } @@ -7400,7 +7402,7 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context) void compile(MyThread* t, Context* context) { - Compiler* c = context->compiler; + avian::codegen::Compiler* c = context->compiler; // fprintf(stderr, "compiling %s.%s%s\n", // &byteArrayBody(t, className(t, methodClass(t, context->method)), 0), @@ -7534,7 +7536,7 @@ compile(MyThread* t, Context* context) } void -updateCall(MyThread* t, UnaryOperation op, void* returnAddress, void* target) +updateCall(MyThread* t, avian::codegen::lir::UnaryOperation op, void* returnAddress, void* target) { t->arch->updateCall(op, returnAddress, target); } @@ -7827,7 +7829,7 @@ invokeNative(MyThread* t) uintptr_t* stack = static_cast(t->stack); - if (TailCalls + if (avian::codegen::TailCalls and t->arch->argumentFootprint(parameterFootprint) > t->arch->stackAlignmentInWords()) { @@ -9264,7 +9266,7 @@ class MyProcessor: public Processor { } virtual void compileMethod(Thread* vmt, Zone* zone, object* constants, - object* calls, DelayedPromise** addresses, + object* calls, avian::codegen::DelayedPromise** addresses, object method, OffsetResolver* resolver) { MyThread* t = static_cast(vmt); @@ -9505,17 +9507,17 @@ compileMethod2(MyThread* t, void* ip) } if (updateCaller) { - UnaryOperation op; + avian::codegen::lir::UnaryOperation op; if (callNodeFlags(t, node) & TraceElement::LongCall) { if (callNodeFlags(t, node) & TraceElement::TailCall) { - op = AlignedLongJump; + op = avian::codegen::lir::AlignedLongJump; } else { - op = AlignedLongCall; + op = avian::codegen::lir::AlignedLongCall; } } else if (callNodeFlags(t, node) & TraceElement::TailCall) { - op = AlignedJump; + op = avian::codegen::lir::AlignedJump; } else { - op = AlignedCall; + op = avian::codegen::lir::AlignedCall; } updateCall(t, op, updateIp, reinterpret_cast(address)); @@ -10045,27 +10047,34 @@ thunkToThunk(const MyProcessor::Thunk& thunk, uint8_t* base) (thunk.start - base, thunk.frameSavedOffset, thunk.length); } +using avian::codegen::OperandInfo; +namespace lir = avian::codegen::lir; + void compileCall(MyThread* t, Context* c, ThunkIndex index, bool call = true) { - Assembler* a = c->assembler; + avian::codegen::Assembler* a = c->assembler; if (processor(t)->bootImage) { - Assembler::Memory table(t->arch->thread(), TARGET_THREAD_THUNKTABLE); - Assembler::Register scratch(t->arch->scratch()); - a->apply(Move, TargetBytesPerWord, MemoryOperand, &table, - TargetBytesPerWord, RegisterOperand, &scratch); - Assembler::Memory proc(scratch.low, index * TargetBytesPerWord); - a->apply(Move, TargetBytesPerWord, MemoryOperand, &proc, - TargetBytesPerWord, RegisterOperand, &scratch); + lir::Memory table(t->arch->thread(), TARGET_THREAD_THUNKTABLE); + lir::Register scratch(t->arch->scratch()); + a->apply(lir::Move, + OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &table), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &scratch)); + lir::Memory proc(scratch.low, index * TargetBytesPerWord); + a->apply(lir::Move, + OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &proc), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &scratch)); a->apply - (call ? Call : Jump, TargetBytesPerWord, RegisterOperand, &scratch); + (call ? lir::Call : lir::Jump, + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &scratch)); } else { - Assembler::Constant proc - (new(&c->zone) ResolvedPromise(reinterpret_cast(t->thunkTable[index]))); + lir::Constant proc + (new(&c->zone) avian::codegen::ResolvedPromise(reinterpret_cast(t->thunkTable[index]))); a->apply - (call ? LongCall : LongJump, TargetBytesPerWord, ConstantOperand, &proc); + (call ? lir::LongCall : lir::LongJump, + OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &proc)); } } @@ -10075,21 +10084,22 @@ compileThunks(MyThread* t, FixedAllocator* allocator) MyProcessor* p = processor(t); { Context context(t); - Assembler* a = context.assembler; + avian::codegen::Assembler* a = context.assembler; a->saveFrame(TARGET_THREAD_STACK, TARGET_THREAD_IP); p->thunks.default_.frameSavedOffset = a->length(); - Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); + lir::Register thread(t->arch->thread()); + a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); compileCall(t, &context, compileMethodIndex); a->popFrame(t->arch->alignFrameSize(1)); - Assembler::Register result(t->arch->returnLow()); - a->apply(Jump, TargetBytesPerWord, RegisterOperand, &result); + lir::Register result(t->arch->returnLow()); + a->apply(lir::Jump, + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &result)); p->thunks.default_.length = a->endBlock(false)->resolve(0, 0); @@ -10098,43 +10108,47 @@ compileThunks(MyThread* t, FixedAllocator* allocator) } { Context context(t); - Assembler* a = context.assembler; + avian::codegen::Assembler* a = context.assembler; - Assembler::Register class_(t->arch->virtualCallTarget()); - Assembler::Memory virtualCallTargetSrc + lir::Register class_(t->arch->virtualCallTarget()); + lir::Memory virtualCallTargetSrc (t->arch->stack(), (t->arch->frameFooterSize() + t->arch->frameReturnAddressSize()) * TargetBytesPerWord); - a->apply(Move, TargetBytesPerWord, MemoryOperand, &virtualCallTargetSrc, - TargetBytesPerWord, RegisterOperand, &class_); + a->apply(lir::Move, + OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &virtualCallTargetSrc), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &class_)); - Assembler::Memory virtualCallTargetDst + lir::Memory virtualCallTargetDst (t->arch->thread(), TARGET_THREAD_VIRTUALCALLTARGET); - a->apply(Move, TargetBytesPerWord, RegisterOperand, &class_, - TargetBytesPerWord, MemoryOperand, &virtualCallTargetDst); + a->apply(lir::Move, + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &class_), + OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &virtualCallTargetDst)); - Assembler::Register index(t->arch->virtualCallIndex()); - Assembler::Memory virtualCallIndex + lir::Register index(t->arch->virtualCallIndex()); + lir::Memory virtualCallIndex (t->arch->thread(), TARGET_THREAD_VIRTUALCALLINDEX); - a->apply(Move, TargetBytesPerWord, RegisterOperand, &index, - TargetBytesPerWord, MemoryOperand, &virtualCallIndex); + a->apply(lir::Move, + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &index), + OperandInfo(TargetBytesPerWord, lir::MemoryOperand, &virtualCallIndex)); a->saveFrame(TARGET_THREAD_STACK, TARGET_THREAD_IP); p->thunks.defaultVirtual.frameSavedOffset = a->length(); - Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); + lir::Register thread(t->arch->thread()); + a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); compileCall(t, &context, compileVirtualMethodIndex); a->popFrame(t->arch->alignFrameSize(1)); - Assembler::Register result(t->arch->returnLow()); - a->apply(Jump, TargetBytesPerWord, RegisterOperand, &result); + lir::Register result(t->arch->returnLow()); + a->apply(lir::Jump, + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &result)); p->thunks.defaultVirtual.length = a->endBlock(false)->resolve(0, 0); @@ -10143,14 +10157,14 @@ compileThunks(MyThread* t, FixedAllocator* allocator) } { Context context(t); - Assembler* a = context.assembler; + avian::codegen::Assembler* a = context.assembler; a->saveFrame(TARGET_THREAD_STACK, TARGET_THREAD_IP); p->thunks.native.frameSavedOffset = a->length(); - Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); + lir::Register thread(t->arch->thread()); + a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); compileCall(t, &context, invokeNativeIndex); @@ -10164,14 +10178,14 @@ compileThunks(MyThread* t, FixedAllocator* allocator) } { Context context(t); - Assembler* a = context.assembler; + avian::codegen::Assembler* a = context.assembler; a->saveFrame(TARGET_THREAD_STACK, TARGET_THREAD_IP); p->thunks.aioob.frameSavedOffset = a->length(); - Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); + lir::Register thread(t->arch->thread()); + a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); compileCall(t, &context, throwArrayIndexOutOfBoundsIndex); @@ -10182,14 +10196,14 @@ compileThunks(MyThread* t, FixedAllocator* allocator) } { Context context(t); - Assembler* a = context.assembler; + avian::codegen::Assembler* a = context.assembler; a->saveFrame(TARGET_THREAD_STACK, TARGET_THREAD_IP); p->thunks.stackOverflow.frameSavedOffset = a->length(); - Assembler::Register thread(t->arch->thread()); - a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread); + lir::Register thread(t->arch->thread()); + a->pushFrame(1, TargetBytesPerWord, lir::RegisterOperand, &thread); compileCall(t, &context, throwStackOverflowIndex); @@ -10200,7 +10214,7 @@ compileThunks(MyThread* t, FixedAllocator* allocator) } { { Context context(t); - Assembler* a = context.assembler; + avian::codegen::Assembler* a = context.assembler; a->saveFrame(TARGET_THREAD_STACK, TARGET_THREAD_IP); @@ -10219,7 +10233,7 @@ compileThunks(MyThread* t, FixedAllocator* allocator) #define THUNK(s) { \ Context context(t); \ - Assembler* a = context.assembler; \ + avian::codegen::Assembler* a = context.assembler; \ \ a->saveFrame(TARGET_THREAD_STACK, TARGET_THREAD_IP); \ \ @@ -10317,17 +10331,19 @@ uintptr_t compileVirtualThunk(MyThread* t, unsigned index, unsigned* size) { Context context(t); - Assembler* a = context.assembler; + avian::codegen::Assembler* a = context.assembler; - ResolvedPromise indexPromise(index); - Assembler::Constant indexConstant(&indexPromise); - Assembler::Register indexRegister(t->arch->virtualCallIndex()); - a->apply(Move, TargetBytesPerWord, ConstantOperand, &indexConstant, - TargetBytesPerWord, RegisterOperand, &indexRegister); + avian::codegen::ResolvedPromise indexPromise(index); + lir::Constant indexConstant(&indexPromise); + lir::Register indexRegister(t->arch->virtualCallIndex()); + a->apply(lir::Move, + OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &indexConstant), + OperandInfo(TargetBytesPerWord, lir::RegisterOperand, &indexRegister)); - ResolvedPromise defaultVirtualThunkPromise(defaultVirtualThunk(t)); - Assembler::Constant thunk(&defaultVirtualThunkPromise); - a->apply(Jump, TargetBytesPerWord, ConstantOperand, &thunk); + avian::codegen::ResolvedPromise defaultVirtualThunkPromise(defaultVirtualThunk(t)); + lir::Constant thunk(&defaultVirtualThunkPromise); + a->apply(lir::Jump, + OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &thunk)); *size = a->endBlock(false)->resolve(0, 0); diff --git a/src/processor.h b/src/processor.h index ab9d68e1aa..1c1de3e577 100644 --- a/src/processor.h +++ b/src/processor.h @@ -18,9 +18,13 @@ #include "heapwalk.h" #include "zone.h" -namespace vm { - +namespace avian { +namespace codegen { class DelayedPromise; +} +} + +namespace vm { class Processor { public: @@ -143,7 +147,7 @@ class Processor { virtual void compileMethod(Thread* t, Zone* zone, object* constants, object* calls, - DelayedPromise** addresses, object method, + avian::codegen::DelayedPromise** addresses, object method, OffsetResolver* resolver) = 0; virtual void From 34471e5d607f2b6485d273984732f01323b823f3 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Mon, 11 Feb 2013 18:51:39 -0700 Subject: [PATCH 03/23] factor out assert / abort / expect implementations --- src/codegen/arm/assembler.cpp | 33 ++++--------------------- src/codegen/compiler.cpp | 28 +++++---------------- src/codegen/powerpc/assembler.cpp | 33 ++++--------------------- src/codegen/x86/assembler.cpp | 27 ++++---------------- src/heap.cpp | 19 +++----------- src/machine.cpp | 6 ++--- src/machine.h | 20 ++------------- src/system.h | 39 +++++++++++------------------ src/util/abort.h | 41 +++++++++++++++++++++++++++++++ src/util/runtime-array.h | 6 ++--- 10 files changed, 88 insertions(+), 164 deletions(-) create mode 100644 src/util/abort.h diff --git a/src/codegen/arm/assembler.cpp b/src/codegen/arm/assembler.cpp index ecaad31007..d92648aa2b 100644 --- a/src/codegen/arm/assembler.cpp +++ b/src/codegen/arm/assembler.cpp @@ -9,6 +9,7 @@ details. */ #include "alloc-vector.h" +#include "util/abort.h" #include "codegen/assembler.h" @@ -340,36 +341,12 @@ class ArchitectureContext { [lir::BranchOperationCount * lir::OperandTypeCount * lir::OperandTypeCount]; }; -inline void NO_RETURN -abort(Context* con) -{ - abort(con->s); +inline Aborter* getAborter(Context* con) { + return con->s; } -inline void NO_RETURN -abort(ArchitectureContext* con) -{ - abort(con->s); -} - -#ifndef NDEBUG -inline void -assert(Context* con, bool v) -{ - assert(con->s, v); -} - -inline void -assert(ArchitectureContext* con, bool v) -{ - assert(con->s, v); -} -#endif // not NDEBUG - -inline void -expect(Context* con, bool v) -{ - expect(con->s, v); +inline Aborter* getAborter(ArchitectureContext* con) { + return con->s; } class Offset: public Promise { diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index ae8e6dd269..14777717ae 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -62,8 +62,6 @@ class StubRead; class Block; class Snapshot; -void NO_RETURN abort(Context*); - void apply(Context* c, lir::UnaryOperation op, unsigned s1Size, Site* s1Low, Site* s1High); @@ -79,6 +77,8 @@ apply(Context* c, lir::TernaryOperation op, unsigned s2Size, Site* s2Low, Site* s2High, unsigned s3Size, Site* s3Low, Site* s3High); +inline Aborter* getAborter(Context* c); + class Cell { public: Cell(Cell* next, void* value): next(next), value(value) { } @@ -453,6 +453,10 @@ class Context { unsigned availableGeneralRegisterCount; }; +inline Aborter* getAborter(Context* c) { + return c->system; +} + unsigned RegisterResource::index(Context* c) { @@ -545,26 +549,6 @@ class IpPromise: public Promise { int logicalIp; }; -inline void NO_RETURN -abort(Context* c) -{ - abort(c->system); -} - -#ifndef NDEBUG -inline void -assert(Context* c, bool v) -{ - assert(c->system, v); -} -#endif // not NDEBUG - -inline void -expect(Context* c, bool v) -{ - expect(c->system, v); -} - unsigned count(Cell* c) { diff --git a/src/codegen/powerpc/assembler.cpp b/src/codegen/powerpc/assembler.cpp index ee263b25bc..87060c3b9b 100644 --- a/src/codegen/powerpc/assembler.cpp +++ b/src/codegen/powerpc/assembler.cpp @@ -10,6 +10,7 @@ #include "codegen/assembler.h" #include "alloc-vector.h" +#include "util/abort.h" #define CAST1(x) reinterpret_cast(x) #define CAST2(x) reinterpret_cast(x) @@ -293,36 +294,12 @@ class ArchitectureContext { [lir::BranchOperationCount * lir::OperandTypeCount * lir::OperandTypeCount]; }; -inline void NO_RETURN -abort(Context* c) -{ - abort(c->s); +inline Aborter* getAborter(Context* con) { + return con->s; } -inline void NO_RETURN -abort(ArchitectureContext* c) -{ - abort(c->s); -} - -#ifndef NDEBUG -inline void -assert(Context* c, bool v) -{ - assert(c->s, v); -} - -inline void -assert(ArchitectureContext* c, bool v) -{ - assert(c->s, v); -} -#endif // not NDEBUG - -inline void -expect(Context* c, bool v) -{ - expect(c->s, v); +inline Aborter* getAborter(ArchitectureContext* con) { + return con->s; } class Offset: public Promise { diff --git a/src/codegen/x86/assembler.cpp b/src/codegen/x86/assembler.cpp index 02836f40a3..633dd49486 100644 --- a/src/codegen/x86/assembler.cpp +++ b/src/codegen/x86/assembler.cpp @@ -15,6 +15,7 @@ #include "codegen/assembler.h" #include "util/runtime-array.h" +#include "util/abort.h" #define CAST1(x) reinterpret_cast(x) #define CAST2(x) reinterpret_cast(x) @@ -176,32 +177,14 @@ class Context { ArchitectureContext* ac; }; -void NO_RETURN -abort(Context* c) -{ - abort(c->s); +Aborter* getAborter(Context* c) { + return c->s; } -void NO_RETURN -abort(ArchitectureContext* c) -{ - abort(c->s); +Aborter* getAborter(ArchitectureContext* c) { + return c->s; } -#ifndef NDEBUG -void -assert(Context* c, bool v) -{ - assert(c->s, v); -} - -void -assert(ArchitectureContext* c, bool v) -{ - assert(c->s, v); -} -#endif // not NDEBUG - ResolvedPromise* resolved(Context* c, int64_t value) { diff --git a/src/heap.cpp b/src/heap.cpp index f706bca253..eadb13ef78 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -55,10 +55,7 @@ class MutexLock { class Context; -void NO_RETURN abort(Context*); -#ifndef NDEBUG -void assert(Context*, bool); -#endif +Aborter* getAborter(Context* c); void* tryAllocate(Context* c, unsigned size); void* allocate(Context* c, unsigned size); @@ -745,20 +742,10 @@ segment(Context* c, void* p) } } -inline void NO_RETURN -abort(Context* c) -{ - abort(c->system); +inline Aborter* getAborter(Context* c) { + return c->system; } -#ifndef NDEBUG -inline void -assert(Context* c, bool v) -{ - assert(c->system, v); -} -#endif - inline unsigned minimumNextGen1Capacity(Context* c) { diff --git a/src/machine.cpp b/src/machine.cpp index 677a7f9b92..395413e660 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -3966,7 +3966,7 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size, Client(Thread* t): t(t) { } virtual void NO_RETURN handleError() { - vm::abort(t); + abort(t); } private: @@ -4853,11 +4853,11 @@ makeTrace(Thread* t, Processor::StackWalker* walker) virtual bool visit(Processor::StackWalker* walker) { if (trace == 0) { trace = makeObjectArray(t, walker->count()); - vm_assert(t, trace); + assert(t, trace); } object e = makeTraceElement(t, walker->method(), walker->ip()); - vm_assert(t, index < objectArrayLength(t, trace)); + assert(t, index < objectArrayLength(t, trace)); set(t, trace, ArrayBody + (index * BytesPerWord), e); ++ index; return true; diff --git a/src/machine.h b/src/machine.h index 909b647c01..d31b4bf7b1 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1761,24 +1761,8 @@ class RawMonitorResource: public Thread::Resource { System::Monitor* m; }; -inline void NO_RETURN -abort(Thread* t) -{ - abort(t->m->system); -} - -#ifndef NDEBUG -inline void -assert(Thread* t, bool v) -{ - assert(t->m->system, v); -} -#endif // not NDEBUG - -inline void -expect(Thread* t, bool v) -{ - expect(t->m->system, v); +inline Aborter* getAborter(Thread* t) { + return t->m->system; } class FixedAllocator: public Allocator { diff --git a/src/system.h b/src/system.h index ef69317f0b..1a95980da3 100644 --- a/src/system.h +++ b/src/system.h @@ -13,10 +13,11 @@ #include "common.h" #include "allocator.h" +#include "util/abort.h" namespace vm { -class System { +class System : public Aborter { public: typedef intptr_t Status; @@ -150,7 +151,6 @@ class System { virtual int64_t now() = 0; virtual void yield() = 0; virtual void exit(int code) = 0; - virtual void abort() = 0; virtual void dispose() = 0; }; @@ -165,11 +165,8 @@ allocate(System* s, unsigned size) #define ACQUIRE_MONITOR(t, m) \ System::MonitorResource MAKE_NAME(monitorResource_) (t, m) -inline void NO_RETURN -abort(System* s) -{ - s->abort(); // this should not return - ::abort(); +inline Aborter* getAborter(System* s) { + return s; } inline void NO_RETURN @@ -178,28 +175,22 @@ sysAbort(System* s) abort(s); } -inline void -expect(System* s, bool v) -{ - if (UNLIKELY(not v)) abort(s); -} +// #ifdef NDEBUG -#ifdef NDEBUG +// # define assert(a, b) +// # define vm_assert(a, b) -# define assert(a, b) -# define vm_assert(a, b) +// #else // not NDEBUG -#else // not NDEBUG +// inline void +// assert(System* s, bool v) +// { +// expect(s, v); +// } -inline void -assert(System* s, bool v) -{ - expect(s, v); -} +// # define vm_assert(a, b) vm::assert(a, b) -# define vm_assert(a, b) vm::assert(a, b) - -#endif // not NDEBUG +// #endif // not NDEBUG JNIEXPORT System* makeSystem(const char* crashDumpDirectory); diff --git a/src/util/abort.h b/src/util/abort.h new file mode 100644 index 0000000000..7624ea5b8f --- /dev/null +++ b/src/util/abort.h @@ -0,0 +1,41 @@ +/* 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_UTIL_ABORT_H +#define AVIAN_UTIL_ABORT_H + +class Aborter { +public: + virtual void NO_RETURN abort() = 0; +}; + +template +inline void NO_RETURN abort(T t) { + getAborter(t)->abort(); + ::abort(); +} + +template +inline void expect(T t, bool v) { + if(UNLIKELY(!v)) { + abort(t); + } +} + +#ifdef NDEBUG +#define assert(t, v) +#else +template +inline void assert(T t, bool v) { + expect(t, v); +} +#endif + +#endif // AVIAN_UTIL_ABORT_H \ No newline at end of file diff --git a/src/util/runtime-array.h b/src/util/runtime-array.h index 378718708d..ffd8e3348b 100644 --- a/src/util/runtime-array.h +++ b/src/util/runtime-array.h @@ -8,8 +8,8 @@ There is NO WARRANTY for this software. See license.txt for details. */ -#ifndef UTIL_RUNTIME_ARRAY_H -#define UTIL_RUNTIME_ARRAY_H +#ifndef AVIAN_UTIL_RUNTIME_ARRAY_H +#define AVIAN_UTIL_RUNTIME_ARRAY_H #ifdef _MSC_VER @@ -37,4 +37,4 @@ class RuntimeArray { #endif -#endif \ No newline at end of file +#endif // AVIAN_UTIL_RUNTIME_ARRAY_H \ No newline at end of file From ef5e534e1ef5b32c7f062016f67c2faef9b21ed4 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Mon, 11 Feb 2013 21:31:19 -0700 Subject: [PATCH 04/23] begin moving register allocator out of compiler.cpp --- makefile | 2 + src/codegen/arm/assembler.cpp | 16 ++-- src/codegen/assembler.h | 5 +- src/codegen/compiler.cpp | 130 +++++++++++------------------- src/codegen/compiler.h | 6 +- src/codegen/powerpc/assembler.cpp | 12 +-- src/codegen/regalloc.cpp | 24 ++++++ src/codegen/regalloc.h | 37 +++++++++ src/codegen/registers.cpp | 35 ++++++++ src/codegen/registers.h | 51 ++++++++++++ src/codegen/x86/assembler.cpp | 16 ++-- 11 files changed, 225 insertions(+), 109 deletions(-) create mode 100644 src/codegen/regalloc.cpp create mode 100644 src/codegen/regalloc.h create mode 100644 src/codegen/registers.cpp create mode 100644 src/codegen/registers.h diff --git a/makefile b/makefile index f62fcb2346..4ff3aef558 100755 --- a/makefile +++ b/makefile @@ -953,6 +953,8 @@ embed-objects = $(call cpp-objects,$(embed-sources),$(src),$(build-embed)) ifeq ($(process),compile) vm-sources += \ $(src)/codegen/compiler.cpp \ + $(src)/codegen/regalloc.cpp \ + $(src)/codegen/registers.cpp \ $(src)/codegen/targets.cpp ifeq ($(codegen-targets),native) diff --git a/src/codegen/arm/assembler.cpp b/src/codegen/arm/assembler.cpp index d92648aa2b..c15007835f 100644 --- a/src/codegen/arm/assembler.cpp +++ b/src/codegen/arm/assembler.cpp @@ -8,11 +8,12 @@ There is NO WARRANTY for this software. See license.txt for details. */ +#include "codegen/assembler.h" +#include "codegen/registers.h" + #include "alloc-vector.h" #include "util/abort.h" -#include "codegen/assembler.h" - #include "util/runtime-array.h" #define CAST1(x) reinterpret_cast(x) @@ -210,6 +211,9 @@ const uint64_t GPR_MASK64 = GPR_MASK | (uint64_t)GPR_MASK << 32; // making the following const somehow breaks debug symbol output in GDB /* const */ uint64_t FPR_MASK64 = FPR_MASK | (uint64_t)FPR_MASK << 32; +const RegisterFile MyRegisterFileWithoutFloats(GPR_MASK, 0); +const RegisterFile MyRegisterFileWithFloats(GPR_MASK, FPR_MASK); + inline bool isFpr(lir::Register* reg) { return reg->low >= N_GPRS; } @@ -2057,12 +2061,8 @@ class MyArchitecture: public Assembler::Architecture { return vfpSupported() ? 8 : 0; } - virtual uint32_t generalRegisterMask() { - return GPR_MASK; - } - - virtual uint32_t floatRegisterMask() { - return vfpSupported() ? FPR_MASK : 0; + virtual const RegisterFile* registerFile() { + return vfpSupported() ? &MyRegisterFileWithFloats : &MyRegisterFileWithoutFloats; } virtual int scratch() { diff --git a/src/codegen/assembler.h b/src/codegen/assembler.h index d6ef7dd262..21301fd71f 100644 --- a/src/codegen/assembler.h +++ b/src/codegen/assembler.h @@ -20,6 +20,8 @@ namespace avian { namespace codegen { +class RegisterFile; + class OperandInfo { public: const unsigned size; @@ -66,8 +68,7 @@ class Assembler { public: virtual unsigned floatRegisterSize() = 0; - virtual uint32_t generalRegisterMask() = 0; - virtual uint32_t floatRegisterMask() = 0; + virtual const RegisterFile* registerFile() = 0; virtual int scratch() = 0; virtual int stack() = 0; diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 14777717ae..768b91748d 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -8,12 +8,14 @@ There is NO WARRANTY for this software. See license.txt for details. */ -#include "compiler.h" -#include "assembler.h" #include "target.h" #include "util/runtime-array.h" +#include "codegen/compiler.h" +#include "codegen/assembler.h" +#include "codegen/regalloc.h" + using namespace vm; using namespace avian::codegen; @@ -338,30 +340,6 @@ class Value: public Compiler::Operand { uint8_t wordIndex; }; -uint32_t -registerMask(Assembler::Architecture* arch) -{ - return arch->generalRegisterMask() | arch->floatRegisterMask(); -} - -unsigned -maskStart(uint32_t mask) -{ - for (int i = 0; i <= 31; ++i) { - if (mask & (1 << i)) return i; - } - return 32; -} - -unsigned -maskLimit(uint32_t mask) -{ - for (int i = 31; i >= 0; --i) { - if (mask & (1 << i)) return i + 1; - } - return 0; -} - class Context { public: Context(System* system, Assembler* assembler, Zone* zone, @@ -376,15 +354,11 @@ class Context { saved(0), predecessor(0), logicalCode(0), - registerStart(maskStart(registerMask(arch))), - registerLimit(maskLimit(registerMask(arch))), - generalRegisterStart(maskStart(arch->generalRegisterMask())), - generalRegisterLimit(maskLimit(arch->generalRegisterMask())), - floatRegisterStart(maskStart(arch->floatRegisterMask())), - floatRegisterLimit(maskLimit(arch->floatRegisterMask())), + regFile(arch->registerFile()), + regAlloc(system, arch->registerFile()), registerResources (static_cast - (zone->allocate(sizeof(RegisterResource) * registerLimit))), + (zone->allocate(sizeof(RegisterResource) * regFile->allRegisters.limit))), frameResources(0), acquiredResources(0), firstConstant(0), @@ -402,16 +376,16 @@ class Context { localFootprint(0), machineCodeSize(0), alignedFrameSize(0), - availableGeneralRegisterCount(generalRegisterLimit - generalRegisterStart) + availableGeneralRegisterCount(regFile->generalRegisters.limit - regFile->generalRegisters.start) { - for (unsigned i = generalRegisterStart; i < generalRegisterLimit; ++i) { + for (unsigned i = regFile->generalRegisters.start; i < regFile->generalRegisters.limit; ++i) { new (registerResources + i) RegisterResource(arch->reserved(i)); if (registerResources[i].reserved) { -- availableGeneralRegisterCount; } } - for (unsigned i = floatRegisterStart; i < floatRegisterLimit; ++i) { + for (unsigned i = regFile->floatRegisters.start; i < regFile->floatRegisters.limit; ++i) { new (registerResources + i) RegisterResource(arch->reserved(i)); } } @@ -426,12 +400,8 @@ class Context { Cell* saved; Event* predecessor; LogicalInstruction** logicalCode; - uint8_t registerStart; - uint8_t registerLimit; - uint8_t generalRegisterStart; - uint8_t generalRegisterLimit; - uint8_t floatRegisterStart; - uint8_t floatRegisterLimit; + const RegisterFile* regFile; + regalloc::RegisterAllocator regAlloc; RegisterResource* registerResources; FrameResource* frameResources; Resource* acquiredResources; @@ -1158,7 +1128,7 @@ increment(Context* c, RegisterResource* r) ++ r->referenceCount; if (r->referenceCount == 1 - and ((1 << r->index(c)) & c->arch->generalRegisterMask())) + and ((1 << r->index(c)) & c->regFile->generalRegisters.mask)) { decrementAvailableGeneralRegisterCount(c); } @@ -1179,7 +1149,7 @@ decrement(Context* c, RegisterResource* r) -- r->referenceCount; if (r->referenceCount == 0 - and ((1 << r->index(c)) & c->arch->generalRegisterMask())) + and ((1 << r->index(c)) & c->regFile->generalRegisters.mask)) { incrementAvailableGeneralRegisterCount(c); } @@ -1204,7 +1174,7 @@ RegisterResource::freeze(Context* c, Value* v) freezeResource(c, this, v); if (freezeCount == 1 - and ((1 << index(c)) & c->arch->generalRegisterMask())) + and ((1 << index(c)) & c->regFile->generalRegisters.mask)) { decrementAvailableGeneralRegisterCount(c); } @@ -1239,7 +1209,7 @@ RegisterResource::thaw(Context* c, Value* v) thawResource(c, this, v); if (freezeCount == 0 - and ((1 << index(c)) & c->arch->generalRegisterMask())) + and ((1 << index(c)) & c->regFile->generalRegisters.mask)) { incrementAvailableGeneralRegisterCount(c); } @@ -1291,20 +1261,18 @@ valueType(Context* c, Compiler::OperandType type) class CostCalculator { public: - virtual unsigned cost(Context* c, uint8_t typeMask, uint32_t registerMask, - int frameIndex) = 0; + virtual unsigned cost(Context* c, SiteMask mask) = 0; }; unsigned -resourceCost(Context* c, Value* v, Resource* r, uint8_t typeMask, - uint32_t registerMask, int frameIndex, +resourceCost(Context* c, Value* v, Resource* r, SiteMask mask, CostCalculator* costCalculator) { if (r->reserved or r->freezeCount or r->referenceCount) { return Target::Impossible; } else { - unsigned baseCost = costCalculator ? costCalculator->cost - (c, typeMask, registerMask, frameIndex) : 0; + unsigned baseCost = + costCalculator ? costCalculator->cost(c, mask) : 0; if (r->value) { assert(c, findSite(c, r->value, r->site)); @@ -1329,7 +1297,7 @@ pickRegisterTarget(Context* c, int i, Value* v, uint32_t mask, int* target, if ((1 << i) & mask) { RegisterResource* r = c->registerResources + i; unsigned myCost = resourceCost - (c, v, r, 1 << lir::RegisterOperand, 1 << i, NoFrameIndex, costCalculator) + (c, v, r, SiteMask(1 << lir::RegisterOperand, 1 << i, NoFrameIndex), costCalculator) + Target::MinimumRegisterCost; if ((static_cast(1) << i) == mask) { @@ -1350,9 +1318,9 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost, int target = lir::NoRegister; *cost = Target::Impossible; - if (mask & c->arch->generalRegisterMask()) { - for (int i = c->generalRegisterLimit - 1; - i >= c->generalRegisterStart; --i) + if (mask & c->regFile->generalRegisters.mask) { + for (int i = c->regFile->generalRegisters.limit - 1; + i >= c->regFile->generalRegisters.start; --i) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; @@ -1360,9 +1328,9 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost, } } - if (mask & c->arch->floatRegisterMask()) { - for (int i = c->floatRegisterStart; - i < static_cast(c->floatRegisterLimit); ++i) + if (mask & c->regFile->floatRegisters.mask) { + for (int i = c->regFile->floatRegisters.start; + i < static_cast(c->regFile->floatRegisters.limit); ++i) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { return i; @@ -1386,7 +1354,7 @@ unsigned frameCost(Context* c, Value* v, int frameIndex, CostCalculator* costCalculator) { return resourceCost - (c, v, c->frameResources + frameIndex, 1 << lir::MemoryOperand, 0, frameIndex, + (c, v, c->frameResources + frameIndex, SiteMask(1 << lir::MemoryOperand, 0, frameIndex), costCalculator) + Target::MinimumFrameCost; } @@ -1482,13 +1450,13 @@ pickTarget(Context* c, Read* read, bool intersectRead, Value* value = read->value; uint32_t registerMask - = (value->type == lir::ValueFloat ? ~0 : c->arch->generalRegisterMask()); + = (value->type == lir::ValueFloat ? ~0 : c->regFile->generalRegisters.mask); SiteMask mask(~0, registerMask, AnyFrameIndex); read->intersect(&mask); if (value->type == lir::ValueFloat) { - uint32_t floatMask = mask.registerMask & c->arch->floatRegisterMask(); + uint32_t floatMask = mask.registerMask & c->regFile->floatRegisters.mask; if (floatMask) { mask.registerMask = floatMask; } @@ -1813,7 +1781,7 @@ class RegisterSite: public Site { assert(c, number != lir::NoRegister); return number == rs->number; } else { - uint32_t mask = c->arch->generalRegisterMask(); + uint32_t mask = c->regFile->generalRegisters.mask; return ((1 << number) & mask) and ((1 << rs->number) & mask); } } @@ -1899,9 +1867,9 @@ class RegisterSite: public Site { virtual Site* makeNextWord(Context* c, unsigned) { assert(c, number != lir::NoRegister); - assert(c, ((1 << number) & c->arch->generalRegisterMask())); + assert(c, ((1 << number) & c->regFile->generalRegisters.mask)); - return freeRegisterSite(c, c->arch->generalRegisterMask()); + return freeRegisterSite(c, c->regFile->generalRegisters.mask); } virtual SiteMask mask(Context* c UNUSED) { @@ -1916,14 +1884,14 @@ class RegisterSite: public Site { (1 << lir::RegisterOperand, number, NoFrameIndex); } else { return SiteMask - (1 << lir::RegisterOperand, c->arch->generalRegisterMask(), NoFrameIndex); + (1 << lir::RegisterOperand, c->regFile->generalRegisters.mask, NoFrameIndex); } } virtual unsigned registerSize(Context* c) { assert(c, number != lir::NoRegister); - if ((1 << number) & c->arch->floatRegisterMask()) { + if ((1 << number) & c->regFile->floatRegisters.mask) { return c->arch->floatRegisterSize(); } else { return TargetBytesPerWord; @@ -1944,8 +1912,8 @@ RegisterSite* registerSite(Context* c, int number) { assert(c, number >= 0); - assert(c, (1 << number) & (c->arch->generalRegisterMask() - | c->arch->floatRegisterMask())); + assert(c, (1 << number) & (c->regFile->generalRegisters.mask + | c->regFile->floatRegisters.mask)); return new(c->zone) RegisterSite(1 << number, number); } @@ -2382,8 +2350,7 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord, includeNextWord(includeNextWord) { } - virtual unsigned cost(Context* c, uint8_t typeMask, uint32_t registerMask, - int frameIndex) + virtual unsigned cost(Context* c, SiteMask dstMask) { uint8_t srcTypeMask; uint64_t srcRegisterMask; @@ -2392,10 +2359,9 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord, c->arch->planMove (size, &srcTypeMask, &srcRegisterMask, &tmpTypeMask, &tmpRegisterMask, - typeMask, registerMask); + dstMask.typeMask, dstMask.registerMask); SiteMask srcMask(srcTypeMask, srcRegisterMask, AnyFrameIndex); - SiteMask dstMask(typeMask, registerMask, frameIndex); for (SiteIterator it(c, value, true, includeNextWord); it.hasMore();) { Site* s = it.next(); if (s->match(c, srcMask) or s->match(c, dstMask)) { @@ -2615,7 +2581,7 @@ SiteMask generalRegisterMask(Context* c) { return SiteMask - (1 << lir::RegisterOperand, c->arch->generalRegisterMask(), NoFrameIndex); + (1 << lir::RegisterOperand, c->regFile->generalRegisters.mask, NoFrameIndex); } SiteMask @@ -2623,7 +2589,7 @@ generalRegisterOrConstantMask(Context* c) { return SiteMask ((1 << lir::RegisterOperand) | (1 << lir::ConstantOperand), - c->arch->generalRegisterMask(), NoFrameIndex); + c->regFile->generalRegisters.mask, NoFrameIndex); } SiteMask @@ -3143,7 +3109,7 @@ class CallEvent: public Event { resultSize(resultSize), stackArgumentFootprint(stackArgumentFootprint) { - uint32_t registerMask = c->arch->generalRegisterMask(); + uint32_t registerMask = c->regFile->generalRegisters.mask; if (argumentCount) { assert(c, (flags & Compiler::TailJump) == 0); @@ -3564,7 +3530,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, dstSize, &thunk); if (src->type == lir::ValueGeneral) { - srcRegisterMask &= c->arch->generalRegisterMask(); + srcRegisterMask &= c->regFile->generalRegisters.mask; } assert(c, thunk == 0); @@ -4374,11 +4340,11 @@ loadLocal(Context* c, unsigned footprint, unsigned index) Value* register_(Context* c, int number) { - assert(c, (1 << number) & (c->arch->generalRegisterMask() - | c->arch->floatRegisterMask())); + assert(c, (1 << number) & (c->regFile->generalRegisters.mask + | c->regFile->floatRegisters.mask)); Site* s = registerSite(c, number); - lir::ValueType type = ((1 << number) & c->arch->floatRegisterMask()) + lir::ValueType type = ((1 << number) & c->regFile->floatRegisters.mask) ? lir::ValueFloat: lir::ValueGeneral; return value(c, type, s, s); @@ -5415,7 +5381,7 @@ resolveSourceSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites) if (r and sites[el.localIndex] == 0) { SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand), - c->arch->generalRegisterMask(), AnyFrameIndex); + c->regFile->generalRegisters.mask, AnyFrameIndex); Site* s = pickSourceSite (c, r, 0, 0, &mask, true, false, true, acceptForResolve); @@ -5449,7 +5415,7 @@ resolveTargetSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites) if (r and sites[el.localIndex] == 0) { SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand), - c->arch->generalRegisterMask(), AnyFrameIndex); + c->regFile->generalRegisters.mask, AnyFrameIndex); Site* s = pickSourceSite (c, r, 0, 0, &mask, false, true, true, acceptForResolve); diff --git a/src/codegen/compiler.h b/src/codegen/compiler.h index fbaad83791..b7aeeed2dc 100644 --- a/src/codegen/compiler.h +++ b/src/codegen/compiler.h @@ -8,8 +8,8 @@ There is NO WARRANTY for this software. See license.txt for details. */ -#ifndef COMPILER_H -#define COMPILER_H +#ifndef AVIAN_CODEGEN_COMPILER_H +#define AVIAN_CODEGEN_COMPILER_H #include "system.h" #include "zone.h" @@ -207,4 +207,4 @@ makeCompiler(vm::System* system, Assembler* assembler, vm::Zone* zone, } // namespace codegen } // namespace avian -#endif//COMPILER_H +#endif // AVIAN_CODEGEN_COMPILER_H diff --git a/src/codegen/powerpc/assembler.cpp b/src/codegen/powerpc/assembler.cpp index 87060c3b9b..426891d475 100644 --- a/src/codegen/powerpc/assembler.cpp +++ b/src/codegen/powerpc/assembler.cpp @@ -9,6 +9,8 @@ details. */ #include "codegen/assembler.h" +#include "codegen/registers.h" + #include "alloc-vector.h" #include "util/abort.h" @@ -153,6 +155,8 @@ inline int unha16(int32_t high, int32_t low) { return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low; } +const RegisterFile MyRegisterFile(0xFFFFFFFF, 0); + inline bool isInt16(target_intptr_t v) { @@ -2061,12 +2065,8 @@ class MyArchitecture: public Assembler::Architecture { return 0; } - virtual uint32_t generalRegisterMask() { - return 0xFFFFFFFF; - } - - virtual uint32_t floatRegisterMask() { - return 0; + virtual const RegisterFile* registerFile() { + return &MyRegisterFile; } virtual int scratch() { diff --git a/src/codegen/regalloc.cpp b/src/codegen/regalloc.cpp new file mode 100644 index 0000000000..bc8abf926b --- /dev/null +++ b/src/codegen/regalloc.cpp @@ -0,0 +1,24 @@ +/* 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 "codegen/regalloc.h" + +namespace avian { +namespace codegen { +namespace regalloc { + +RegisterAllocator::RegisterAllocator(Aborter* a, const RegisterFile* registerFile): + a(a), + registerFile(registerFile) +{ } + +} // namespace regalloc +} // namespace codegen +} // namespace avian \ No newline at end of file diff --git a/src/codegen/regalloc.h b/src/codegen/regalloc.h new file mode 100644 index 0000000000..83fbd878f3 --- /dev/null +++ b/src/codegen/regalloc.h @@ -0,0 +1,37 @@ +/* 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_REGALLOC_H +#define AVIAN_CODEGEN_REGALLOC_H + +#include "common.h" + +#include "codegen/registers.h" + +class Aborter; + +namespace avian { +namespace codegen { +namespace regalloc { + +class RegisterAllocator { +public: + Aborter* a; + const RegisterFile* registerFile; + + RegisterAllocator(Aborter* a, const RegisterFile* registerFile); + +}; + +} // namespace regalloc +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_REGALLOC_H \ No newline at end of file diff --git a/src/codegen/registers.cpp b/src/codegen/registers.cpp new file mode 100644 index 0000000000..6e8dea822a --- /dev/null +++ b/src/codegen/registers.cpp @@ -0,0 +1,35 @@ +/* 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 "codegen/registers.h" + +namespace avian { +namespace codegen { + +unsigned +RegisterMask::maskStart(uint32_t mask) +{ + for (int i = 0; i <= 31; ++i) { + if (mask & (1 << i)) return i; + } + return 32; +} + +unsigned +RegisterMask::maskLimit(uint32_t mask) +{ + for (int i = 31; i >= 0; --i) { + if (mask & (1 << i)) return i + 1; + } + return 0; +} + +} // namespace codegen +} // namespace avian diff --git a/src/codegen/registers.h b/src/codegen/registers.h new file mode 100644 index 0000000000..317bb2215a --- /dev/null +++ b/src/codegen/registers.h @@ -0,0 +1,51 @@ +/* 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_REGISTERS_H +#define AVIAN_CODEGEN_REGISTERS_H + +#include "common.h" + +namespace avian { +namespace codegen { + +class RegisterMask { +public: + uint32_t mask; + uint8_t start; + uint8_t limit; + + static unsigned maskStart(uint32_t mask); + static unsigned maskLimit(uint32_t mask); + + inline RegisterMask(uint32_t mask): + mask(mask), + start(maskStart(mask)), + limit(maskLimit(mask)) + { } +}; + +class RegisterFile { +public: + RegisterMask allRegisters; + RegisterMask generalRegisters; + RegisterMask floatRegisters; + + inline RegisterFile(uint32_t generalRegisterMask, uint32_t floatRegisterMask): + allRegisters(generalRegisterMask | floatRegisterMask), + generalRegisters(generalRegisterMask), + floatRegisters(floatRegisterMask) + { } +}; + +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_REGISTERS_H \ No newline at end of file diff --git a/src/codegen/x86/assembler.cpp b/src/codegen/x86/assembler.cpp index 633dd49486..5e3fa6aa3c 100644 --- a/src/codegen/x86/assembler.cpp +++ b/src/codegen/x86/assembler.cpp @@ -13,6 +13,7 @@ #include "alloc-vector.h" #include "codegen/assembler.h" +#include "codegen/registers.h" #include "util/runtime-array.h" #include "util/abort.h" @@ -72,6 +73,8 @@ const unsigned GeneralRegisterMask const unsigned FloatRegisterMask = TargetBytesPerWord == 4 ? 0x00ff0000 : 0xffff0000; +const RegisterFile MyRegisterFile(GeneralRegisterMask, FloatRegisterMask); + const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1); const int LongJumpRegister = r10; @@ -2714,7 +2717,8 @@ populateTables(ArchitectureContext* c) class MyArchitecture: public Assembler::Architecture { public: MyArchitecture(System* system, bool useNativeFeatures): - c(system, useNativeFeatures), referenceCount(0) + c(system, useNativeFeatures), + referenceCount(0) { populateTables(&c); } @@ -2726,13 +2730,9 @@ class MyArchitecture: public Assembler::Architecture { return 0; } } - - virtual uint32_t generalRegisterMask() { - return GeneralRegisterMask; - } - - virtual uint32_t floatRegisterMask() { - return useSSE(&c) ? FloatRegisterMask : 0; + + virtual const RegisterFile* registerFile() { + return &MyRegisterFile; } virtual int scratch() { From 740886d58e5dcac8cd2d2787eaed17fde00a0dda Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 12:11:47 -0700 Subject: [PATCH 05/23] begin splitting up compiler.cpp --- makefile | 4 +- src/codegen/compiler.cpp | 412 ++++-------------------------- src/codegen/compiler/context.cpp | 68 +++++ src/codegen/compiler/context.h | 84 ++++++ src/codegen/compiler/resource.cpp | 152 +++++++++++ src/codegen/compiler/resource.h | 79 ++++++ src/codegen/compiler/value.h | 49 ++++ 7 files changed, 487 insertions(+), 361 deletions(-) create mode 100644 src/codegen/compiler/context.cpp create mode 100644 src/codegen/compiler/context.h create mode 100644 src/codegen/compiler/resource.cpp create mode 100644 src/codegen/compiler/resource.h create mode 100644 src/codegen/compiler/value.h diff --git a/makefile b/makefile index 4ff3aef558..e84d022f57 100755 --- a/makefile +++ b/makefile @@ -923,7 +923,7 @@ generated-code = \ $(build)/type-name-initializations.cpp \ $(build)/type-maps.cpp -vm-depends := $(generated-code) $(wildcard $(src)/*.h) $(wildcard $(src)/codegen/*.h) +vm-depends := $(generated-code) $(wildcard $(src)/*.h) $(wildcard $(src)/codegen/*.h) $(wildcard $(src)/codegen/compiler/*.h) vm-sources = \ $(src)/$(system).cpp \ @@ -954,6 +954,8 @@ ifeq ($(process),compile) vm-sources += \ $(src)/codegen/compiler.cpp \ $(src)/codegen/regalloc.cpp \ + $(src)/codegen/compiler/context.cpp \ + $(src)/codegen/compiler/resource.cpp \ $(src)/codegen/registers.cpp \ $(src)/codegen/targets.cpp diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 768b91748d..1f27b5749e 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -16,12 +16,15 @@ #include "codegen/assembler.h" #include "codegen/regalloc.h" +#include "codegen/compiler/context.h" +#include "codegen/compiler/resource.h" +#include "codegen/compiler/value.h" + using namespace vm; -using namespace avian::codegen; -namespace { - -namespace local { +namespace avian { +namespace codegen { +namespace compiler { const bool DebugAppend = false; const bool DebugCompile = false; @@ -33,9 +36,6 @@ const bool DebugSites = false; const bool DebugMoves = false; const bool DebugBuddies = false; -const int AnyFrameIndex = -2; -const int NoFrameIndex = -1; - const unsigned StealRegisterReserveCount = 2; // this should be equal to the largest number of registers used by a @@ -48,8 +48,6 @@ const unsigned ConstantCopyCost = 3; const unsigned MemoryCopyCost = 4; const unsigned CopyPenalty = 10; -class Context; -class Value; class Stack; class Site; class ConstantSite; @@ -79,8 +77,6 @@ apply(Context* c, lir::TernaryOperation op, unsigned s2Size, Site* s2Low, Site* s2High, unsigned s3Size, Site* s3Low, Site* s3High); -inline Aborter* getAborter(Context* c); - class Cell { public: Cell(Cell* next, void* value): next(next), value(value) { } @@ -221,58 +217,6 @@ class LogicalInstruction { int index; }; -class Resource { - public: - Resource(bool reserved = false): - value(0), site(0), previousAcquired(0), nextAcquired(0), freezeCount(0), - referenceCount(0), reserved(reserved) - { } - - virtual void freeze(Context*, Value*) = 0; - - virtual void thaw(Context*, Value*) = 0; - - virtual unsigned toString(Context*, char*, unsigned) = 0; - - Value* value; - Site* site; - Resource* previousAcquired; - Resource* nextAcquired; - uint8_t freezeCount; - uint8_t referenceCount; - bool reserved; -}; - -class RegisterResource: public Resource { - public: - RegisterResource(bool reserved): - Resource(reserved) - { } - - virtual void freeze(Context*, Value*); - - virtual void thaw(Context*, Value*); - - virtual unsigned toString(Context* c, char* buffer, unsigned bufferSize) { - return vm::snprintf(buffer, bufferSize, "register %d", index(c)); - } - - virtual unsigned index(Context*); -}; - -class FrameResource: public Resource { - public: - virtual void freeze(Context*, Value*); - - virtual void thaw(Context*, Value*); - - virtual unsigned toString(Context* c, char* buffer, unsigned bufferSize) { - return vm::snprintf(buffer, bufferSize, "frame %d", index(c)); - } - - virtual unsigned index(Context*); -}; - class ConstantPoolNode { public: ConstantPoolNode(Promise* promise): promise(promise), next(0) { } @@ -321,124 +265,6 @@ intersect(const SiteMask& a, const SiteMask& b) intersectFrameIndexes(a.frameIndex, b.frameIndex)); } -class Value: public Compiler::Operand { - public: - Value(Site* site, Site* target, lir::ValueType type): - reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this), - nextWord(this), home(NoFrameIndex), type(type), wordIndex(0) - { } - - Read* reads; - Read* lastRead; - Site* sites; - Site* source; - Site* target; - Value* buddy; - Value* nextWord; - int16_t home; - lir::ValueType type; - uint8_t wordIndex; -}; - -class Context { - public: - Context(System* system, Assembler* assembler, Zone* zone, - Compiler::Client* client): - system(system), - assembler(assembler), - arch(assembler->arch()), - zone(zone), - client(client), - stack(0), - locals(0), - saved(0), - predecessor(0), - logicalCode(0), - regFile(arch->registerFile()), - regAlloc(system, arch->registerFile()), - registerResources - (static_cast - (zone->allocate(sizeof(RegisterResource) * regFile->allRegisters.limit))), - frameResources(0), - acquiredResources(0), - firstConstant(0), - lastConstant(0), - machineCode(0), - firstEvent(0), - lastEvent(0), - forkState(0), - subroutine(0), - firstBlock(0), - logicalIp(-1), - constantCount(0), - logicalCodeLength(0), - parameterFootprint(0), - localFootprint(0), - machineCodeSize(0), - alignedFrameSize(0), - availableGeneralRegisterCount(regFile->generalRegisters.limit - regFile->generalRegisters.start) - { - for (unsigned i = regFile->generalRegisters.start; i < regFile->generalRegisters.limit; ++i) { - new (registerResources + i) RegisterResource(arch->reserved(i)); - - if (registerResources[i].reserved) { - -- availableGeneralRegisterCount; - } - } - for (unsigned i = regFile->floatRegisters.start; i < regFile->floatRegisters.limit; ++i) { - new (registerResources + i) RegisterResource(arch->reserved(i)); - } - } - - System* system; - Assembler* assembler; - Assembler::Architecture* arch; - Zone* zone; - Compiler::Client* client; - Stack* stack; - Local* locals; - Cell* saved; - Event* predecessor; - LogicalInstruction** logicalCode; - const RegisterFile* regFile; - regalloc::RegisterAllocator regAlloc; - RegisterResource* registerResources; - FrameResource* frameResources; - Resource* acquiredResources; - ConstantPoolNode* firstConstant; - ConstantPoolNode* lastConstant; - uint8_t* machineCode; - Event* firstEvent; - Event* lastEvent; - ForkState* forkState; - MySubroutine* subroutine; - Block* firstBlock; - int logicalIp; - unsigned constantCount; - unsigned logicalCodeLength; - unsigned parameterFootprint; - unsigned localFootprint; - unsigned machineCodeSize; - unsigned alignedFrameSize; - unsigned availableGeneralRegisterCount; -}; - -inline Aborter* getAborter(Context* c) { - return c->system; -} - -unsigned -RegisterResource::index(Context* c) -{ - return this - c->registerResources; -} - -unsigned -FrameResource::index(Context* c) -{ - return this - c->frameResources; -} - class PoolPromise: public Promise { public: PoolPromise(Context* c, int key): c(c), key(key) { } @@ -1093,135 +919,6 @@ addBuddy(Value* original, Value* buddy) } } -void -decrementAvailableGeneralRegisterCount(Context* c) -{ - assert(c, c->availableGeneralRegisterCount); - -- c->availableGeneralRegisterCount; - - if (DebugResources) { - fprintf(stderr, "%d registers available\n", - c->availableGeneralRegisterCount); - } -} - -void -incrementAvailableGeneralRegisterCount(Context* c) -{ - ++ c->availableGeneralRegisterCount; - - if (DebugResources) { - fprintf(stderr, "%d registers available\n", - c->availableGeneralRegisterCount); - } -} - -void -increment(Context* c, RegisterResource* r) -{ - if (not r->reserved) { - if (DebugResources) { - char buffer[256]; r->toString(c, buffer, 256); - fprintf(stderr, "increment %s to %d\n", buffer, r->referenceCount + 1); - } - - ++ r->referenceCount; - - if (r->referenceCount == 1 - and ((1 << r->index(c)) & c->regFile->generalRegisters.mask)) - { - decrementAvailableGeneralRegisterCount(c); - } - } -} - -void -decrement(Context* c, RegisterResource* r) -{ - if (not r->reserved) { - if (DebugResources) { - char buffer[256]; r->toString(c, buffer, 256); - fprintf(stderr, "decrement %s to %d\n", buffer, r->referenceCount - 1); - } - - assert(c, r->referenceCount > 0); - - -- r->referenceCount; - - if (r->referenceCount == 0 - and ((1 << r->index(c)) & c->regFile->generalRegisters.mask)) - { - incrementAvailableGeneralRegisterCount(c); - } - } -} - -void -freezeResource(Context* c, Resource* r, Value* v) -{ - if (DebugResources) { - char buffer[256]; r->toString(c, buffer, 256); - fprintf(stderr, "%p freeze %s to %d\n", v, buffer, r->freezeCount + 1); - } - - ++ r->freezeCount; -} - -void -RegisterResource::freeze(Context* c, Value* v) -{ - if (not reserved) { - freezeResource(c, this, v); - - if (freezeCount == 1 - and ((1 << index(c)) & c->regFile->generalRegisters.mask)) - { - decrementAvailableGeneralRegisterCount(c); - } - } -} - -void -FrameResource::freeze(Context* c, Value* v) -{ - freezeResource(c, this, v); -} - -void -thawResource(Context* c, Resource* r, Value* v) -{ - if (not r->reserved) { - if (DebugResources) { - char buffer[256]; r->toString(c, buffer, 256); - fprintf(stderr, "%p thaw %s to %d\n", v, buffer, r->freezeCount - 1); - } - - assert(c, r->freezeCount); - - -- r->freezeCount; - } -} - -void -RegisterResource::thaw(Context* c, Value* v) -{ - if (not reserved) { - thawResource(c, this, v); - - if (freezeCount == 0 - and ((1 << index(c)) & c->regFile->generalRegisters.mask)) - { - incrementAvailableGeneralRegisterCount(c); - } - } -} - -void -FrameResource::thaw(Context* c, Value* v) -{ - thawResource(c, this, v); -} - class Target { public: static const unsigned MinimumRegisterCost = 0; @@ -1796,7 +1493,7 @@ class RegisterSite: public Site { } RegisterResource* resource = c->registerResources + target.index; - local::acquire(c, resource, v, this); + compiler::acquire(c, resource, v, this); number = target.index; } @@ -1804,7 +1501,7 @@ class RegisterSite: public Site { virtual void release(Context* c, Value* v) { assert(c, number != lir::NoRegister); - local::release(c, c->registerResources + number, v, this); + compiler::release(c, c->registerResources + number, v, this); } virtual void freeze(Context* c, Value* v) { @@ -2020,9 +1717,9 @@ class MemorySite: public Site { } virtual void acquire(Context* c, Value* v) { - increment(c, c->registerResources + base); + c->registerResources[base].increment(c); if (index != lir::NoRegister) { - increment(c, c->registerResources + index); + c->registerResources[index].increment(c); } if (base == c->arch->stack()) { @@ -2030,7 +1727,7 @@ class MemorySite: public Site { assert (c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); - local::acquire + compiler::acquire (c, c->frameResources + offsetToFrameIndex(c, offset), v, this); } @@ -2043,13 +1740,13 @@ class MemorySite: public Site { assert (c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); - local::release + compiler::release (c, c->frameResources + offsetToFrameIndex(c, offset), v, this); } - decrement(c, c->registerResources + base); + c->registerResources[base].decrement(c); if (index != lir::NoRegister) { - decrement(c, c->registerResources + index); + c->registerResources[index].decrement(c); } acquired = false; @@ -2059,9 +1756,9 @@ class MemorySite: public Site { if (base == c->arch->stack()) { c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v); } else { - increment(c, c->registerResources + base); + c->registerResources[base].increment(c); if (index != lir::NoRegister) { - increment(c, c->registerResources + index); + c->registerResources[index].increment(c); } } } @@ -2070,9 +1767,9 @@ class MemorySite: public Site { if (base == c->arch->stack()) { c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v); } else { - decrement(c, c->registerResources + base); + c->registerResources[base].decrement(c); if (index != lir::NoRegister) { - decrement(c, c->registerResources + index); + c->registerResources[index].decrement(c); } } } @@ -2245,7 +1942,7 @@ class SingleRead: public Read { { } virtual bool intersect(SiteMask* mask, unsigned) { - *mask = local::intersect(*mask, this->mask); + *mask = compiler::intersect(*mask, this->mask); return true; } @@ -3082,11 +2779,11 @@ saveLocals(Context* c, Event* e) if (local->value) { if (DebugReads) { fprintf(stderr, "local save read %p at %d of %d\n", - local->value, local::frameIndex(c, li), totalFrameSize(c)); + local->value, compiler::frameIndex(c, li), totalFrameSize(c)); } addRead(c, e, local->value, SiteMask - (1 << lir::MemoryOperand, 0, local::frameIndex(c, li))); + (1 << lir::MemoryOperand, 0, compiler::frameIndex(c, li))); } } } @@ -3266,7 +2963,7 @@ class CallEvent: public Event { while (stack) { if (stack->value) { - unsigned logicalIndex = local::frameIndex + unsigned logicalIndex = compiler::frameIndex (c, stack->index + c->localFootprint); if (DebugReads) { @@ -4376,13 +4073,13 @@ appendCombine(Context* c, lir::TernaryOperation type, unsigned stackSize = ceilingDivide(secondSize, TargetBytesPerWord) + ceilingDivide(firstSize, TargetBytesPerWord); - local::push(c, ceilingDivide(secondSize, TargetBytesPerWord), second); - local::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first); + compiler::push(c, ceilingDivide(secondSize, TargetBytesPerWord), second); + compiler::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first); if (threadParameter) { ++ stackSize; - local::push(c, 1, register_(c, c->arch->thread())); + compiler::push(c, 1, register_(c, c->arch->thread())); } Stack* argumentStack = c->stack; @@ -4499,7 +4196,7 @@ appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize, if (thunk) { Stack* oldStack = c->stack; - local::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first); + compiler::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first); Stack* argumentStack = c->stack; c->stack = oldStack; @@ -4848,8 +4545,8 @@ appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first assert(c, not threadParameter); - local::push(c, ceilingDivide(size, TargetBytesPerWord), second); - local::push(c, ceilingDivide(size, TargetBytesPerWord), first); + compiler::push(c, ceilingDivide(size, TargetBytesPerWord), second); + compiler::push(c, ceilingDivide(size, TargetBytesPerWord), first); Stack* argumentStack = c->stack; c->stack = oldStack; @@ -5209,7 +4906,7 @@ append(Context* c, Event* e) e->logicalInstruction->index); } - Link* link = local::link + Link* link = compiler::link (c, p, e->predecessors, e, p->successors, c->forkState); e->predecessors = link; p->successors = link; @@ -5840,7 +5537,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset) block->assemblerBlock = a->endBlock(e->next != 0); if (e->next) { - block = local::block(c, e->next); + block = compiler::block(c, e->next); } } } @@ -5969,12 +5666,12 @@ class Client: public Assembler::Client { int r = pickRegisterTarget(c, 0, mask, &cost); expect(c, cost < Target::Impossible); save(r); - increment(c, c->registerResources + r); + c->registerResources[r].increment(c); return r; } virtual void releaseTemporary(int r) { - decrement(c, c->registerResources + r); + c->registerResources[r].decrement(c); } virtual void save(int r) { @@ -6002,13 +5699,13 @@ class MyCompiler: public Compiler { } virtual State* saveState() { - State* s = local::saveState(&c); + State* s = compiler::saveState(&c); restoreState(s); return s; } virtual void restoreState(State* state) { - local::restoreState(&c, static_cast(state)); + compiler::restoreState(&c, static_cast(state)); } virtual Subroutine* startSubroutine() { @@ -6018,7 +5715,7 @@ class MyCompiler: public Compiler { virtual void returnFromSubroutine(Subroutine* subroutine, Operand* address) { appendSaveLocals(&c); appendJump(&c, lir::Jump, static_cast(address), false, true); - static_cast(subroutine)->forkState = local::saveState(&c); + static_cast(subroutine)->forkState = compiler::saveState(&c); } virtual void linkSubroutine(Subroutine* subroutine) { @@ -6085,7 +5782,7 @@ class MyCompiler: public Compiler { p->stackAfter = c.stack; p->localsAfter = c.locals; - Link* link = local::link + Link* link = compiler::link (&c, p, e->predecessors, e, p->successors, c.forkState); e->predecessors = link; p->successors = link; @@ -6181,12 +5878,12 @@ class MyCompiler: public Compiler { } virtual Operand* promiseConstant(Promise* value, Compiler::OperandType type) { - return local::value - (&c, valueType(&c, type), local::constantSite(&c, value)); + return compiler::value + (&c, valueType(&c, type), compiler::constantSite(&c, value)); } virtual Operand* address(Promise* address) { - return value(&c, lir::ValueGeneral, local::addressSite(&c, address)); + return value(&c, lir::ValueGeneral, compiler::addressSite(&c, address)); } virtual Operand* memory(Operand* base, @@ -6204,7 +5901,7 @@ class MyCompiler: public Compiler { } virtual Operand* register_(int number) { - return local::register_(&c, number); + return compiler::register_(&c, number); } Promise* machineIp() { @@ -6215,14 +5912,14 @@ class MyCompiler: public Compiler { assert(&c, footprint == 1); Value* v = value(&c, lir::ValueGeneral); - Stack* s = local::stack(&c, v, c.stack); + Stack* s = compiler::stack(&c, v, c.stack); v->home = frameIndex(&c, s->index + c.localFootprint); c.stack = s; } virtual void push(unsigned footprint, Operand* value) { - local::push(&c, footprint, static_cast(value)); + compiler::push(&c, footprint, static_cast(value)); } virtual void save(unsigned footprint, Operand* value) { @@ -6236,7 +5933,7 @@ class MyCompiler: public Compiler { } virtual Operand* pop(unsigned footprint) { - return local::pop(&c, footprint); + return compiler::pop(&c, footprint); } virtual void pushed() { @@ -6245,7 +5942,7 @@ class MyCompiler: public Compiler { (&c, v, frameIndex (&c, (c.stack ? c.stack->index : 0) + c.localFootprint)); - Stack* s = local::stack(&c, v, c.stack); + Stack* s = compiler::stack(&c, v, c.stack); v->home = frameIndex(&c, s->index + c.localFootprint); c.stack = s; } @@ -6340,7 +6037,7 @@ class MyCompiler: public Compiler { Stack* argumentStack = c.stack; for (int i = index - 1; i >= 0; --i) { - argumentStack = local::stack + argumentStack = compiler::stack (&c, RUNTIME_ARRAY_BODY(arguments)[i], argumentStack); } @@ -6431,11 +6128,11 @@ class MyCompiler: public Compiler { } virtual void storeLocal(unsigned footprint, Operand* src, unsigned index) { - local::storeLocal(&c, footprint, static_cast(src), index, true); + compiler::storeLocal(&c, footprint, static_cast(src), index, true); } virtual Operand* loadLocal(unsigned footprint, unsigned index) { - return local::loadLocal(&c, footprint, index); + return compiler::loadLocal(&c, footprint, index); } virtual void saveLocals() { @@ -6872,7 +6569,7 @@ class MyCompiler: public Compiler { virtual void compile(uintptr_t stackOverflowHandler, unsigned stackLimitOffset) { - local::compile(&c, stackOverflowHandler, stackLimitOffset); + compiler::compile(&c, stackOverflowHandler, stackLimitOffset); } virtual unsigned resolve(uint8_t* dst) { @@ -6934,21 +6631,16 @@ class MyCompiler: public Compiler { } Context c; - local::Client client; + compiler::Client client; }; -} // namespace local - -} // namespace - -namespace avian { -namespace codegen { +} // namespace compiler Compiler* makeCompiler(System* system, Assembler* assembler, Zone* zone, Compiler::Client* client) { - return new(zone) local::MyCompiler(system, assembler, zone, client); + return new(zone) compiler::MyCompiler(system, assembler, zone, client); } } // namespace codegen diff --git a/src/codegen/compiler/context.cpp b/src/codegen/compiler/context.cpp new file mode 100644 index 0000000000..dd1f129bad --- /dev/null +++ b/src/codegen/compiler/context.cpp @@ -0,0 +1,68 @@ +/* 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 "codegen/compiler/context.h" +#include "codegen/compiler/resource.h" + +namespace avian { +namespace codegen { +namespace compiler { + +Context::Context(vm::System* system, Assembler* assembler, vm::Zone* zone, + Compiler::Client* client): + system(system), + assembler(assembler), + arch(assembler->arch()), + zone(zone), + client(client), + stack(0), + locals(0), + saved(0), + predecessor(0), + logicalCode(0), + regFile(arch->registerFile()), + regAlloc(system, arch->registerFile()), + registerResources + (static_cast + (zone->allocate(sizeof(RegisterResource) * regFile->allRegisters.limit))), + frameResources(0), + acquiredResources(0), + firstConstant(0), + lastConstant(0), + machineCode(0), + firstEvent(0), + lastEvent(0), + forkState(0), + subroutine(0), + firstBlock(0), + logicalIp(-1), + constantCount(0), + logicalCodeLength(0), + parameterFootprint(0), + localFootprint(0), + machineCodeSize(0), + alignedFrameSize(0), + availableGeneralRegisterCount(regFile->generalRegisters.limit - regFile->generalRegisters.start) +{ + for (unsigned i = regFile->generalRegisters.start; i < regFile->generalRegisters.limit; ++i) { + new (registerResources + i) RegisterResource(arch->reserved(i)); + + if (registerResources[i].reserved) { + -- availableGeneralRegisterCount; + } + } + for (unsigned i = regFile->floatRegisters.start; i < regFile->floatRegisters.limit; ++i) { + new (registerResources + i) RegisterResource(arch->reserved(i)); + } +} + +} // namespace compiler +} // namespace codegen +} // namespace avian diff --git a/src/codegen/compiler/context.h b/src/codegen/compiler/context.h new file mode 100644 index 0000000000..df6382e68f --- /dev/null +++ b/src/codegen/compiler/context.h @@ -0,0 +1,84 @@ +/* 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_COMPILER_CONTEXT_H +#define AVIAN_CODEGEN_COMPILER_CONTEXT_H + +#include "codegen/assembler.h" +#include "codegen/regalloc.h" +#include "codegen/compiler.h" + +namespace avian { +namespace codegen { +namespace compiler { + +class Stack; +class Local; +class Cell; +class Event; +class LogicalInstruction; + +class Resource; +class RegisterResource; +class FrameResource; + +class ConstantPoolNode; + +class ForkState; +class MySubroutine; +class Block; + +class Context { + public: + Context(vm::System* system, Assembler* assembler, vm::Zone* zone, + Compiler::Client* client); + + vm::System* system; + Assembler* assembler; + Assembler::Architecture* arch; + vm::Zone* zone; + Compiler::Client* client; + Stack* stack; + Local* locals; + Cell* saved; + Event* predecessor; + LogicalInstruction** logicalCode; + const RegisterFile* regFile; + regalloc::RegisterAllocator regAlloc; + RegisterResource* registerResources; + FrameResource* frameResources; + Resource* acquiredResources; + ConstantPoolNode* firstConstant; + ConstantPoolNode* lastConstant; + uint8_t* machineCode; + Event* firstEvent; + Event* lastEvent; + ForkState* forkState; + MySubroutine* subroutine; + Block* firstBlock; + int logicalIp; + unsigned constantCount; + unsigned logicalCodeLength; + unsigned parameterFootprint; + unsigned localFootprint; + unsigned machineCodeSize; + unsigned alignedFrameSize; + unsigned availableGeneralRegisterCount; +}; + +inline Aborter* getAborter(Context* c) { + return c->system; +} + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_CONTEXT_H diff --git a/src/codegen/compiler/resource.cpp b/src/codegen/compiler/resource.cpp new file mode 100644 index 0000000000..0480c6e3d7 --- /dev/null +++ b/src/codegen/compiler/resource.cpp @@ -0,0 +1,152 @@ +/* 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 "codegen/compiler/context.h" +#include "codegen/compiler/resource.h" + +namespace avian { +namespace codegen { +namespace compiler { + +const bool DebugResources = false; + +void decrementAvailableGeneralRegisterCount(Context* c) { + assert(c, c->availableGeneralRegisterCount); + -- c->availableGeneralRegisterCount; + + if (DebugResources) { + fprintf(stderr, "%d registers available\n", + c->availableGeneralRegisterCount); + } +} + +void incrementAvailableGeneralRegisterCount(Context* c) { + ++ c->availableGeneralRegisterCount; + + if (DebugResources) { + fprintf(stderr, "%d registers available\n", + c->availableGeneralRegisterCount); + } +} + +void freezeResource(Context* c, Resource* r, Value* v) { + if (DebugResources) { + char buffer[256]; r->toString(c, buffer, 256); + fprintf(stderr, "%p freeze %s to %d\n", v, buffer, r->freezeCount + 1); + } + + ++ r->freezeCount; +} + +void thawResource(Context* c, Resource* r, Value* v) { + if (not r->reserved) { + if (DebugResources) { + char buffer[256]; r->toString(c, buffer, 256); + fprintf(stderr, "%p thaw %s to %d\n", v, buffer, r->freezeCount - 1); + } + + assert(c, r->freezeCount); + + -- r->freezeCount; + } +} + + + +void RegisterResource::freeze(Context* c, Value* v) { + if (not reserved) { + freezeResource(c, this, v); + + if (freezeCount == 1 + and ((1 << index(c)) & c->regFile->generalRegisters.mask)) + { + decrementAvailableGeneralRegisterCount(c); + } + } +} + +void RegisterResource::thaw(Context* c, Value* v) { + if (not reserved) { + thawResource(c, this, v); + + if (freezeCount == 0 + and ((1 << index(c)) & c->regFile->generalRegisters.mask)) + { + incrementAvailableGeneralRegisterCount(c); + } + } +} + +unsigned RegisterResource::toString(Context* c, char* buffer, unsigned bufferSize) { + return vm::snprintf(buffer, bufferSize, "register %d", index(c)); +} + +unsigned RegisterResource::index(Context* c) { + return this - c->registerResources; +} + +void RegisterResource::increment(Context* c) { + if (not this->reserved) { + if (DebugResources) { + char buffer[256]; this->toString(c, buffer, 256); + fprintf(stderr, "increment %s to %d\n", buffer, this->referenceCount + 1); + } + + ++ this->referenceCount; + + if (this->referenceCount == 1 + and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) + { + decrementAvailableGeneralRegisterCount(c); + } + } +} + +void RegisterResource::decrement(Context* c) { + if (not this->reserved) { + if (DebugResources) { + char buffer[256]; this->toString(c, buffer, 256); + fprintf(stderr, "decrement %s to %d\n", buffer, this->referenceCount - 1); + } + + assert(c, this->referenceCount > 0); + + -- this->referenceCount; + + if (this->referenceCount == 0 + and ((1 << this->index(c)) & c->regFile->generalRegisters.mask)) + { + incrementAvailableGeneralRegisterCount(c); + } + } +} + + + +void FrameResource::freeze(Context* c, Value* v) { + freezeResource(c, this, v); +} + +void FrameResource::thaw(Context* c, Value* v) { + thawResource(c, this, v); +} + +unsigned FrameResource::toString(Context* c, char* buffer, unsigned bufferSize) { + return vm::snprintf(buffer, bufferSize, "frame %d", index(c)); +} + +unsigned FrameResource::index(Context* c) { + return this - c->frameResources; +} + + +} // namespace compiler +} // namespace codegen +} // namespace avian \ No newline at end of file diff --git a/src/codegen/compiler/resource.h b/src/codegen/compiler/resource.h new file mode 100644 index 0000000000..b9d469bbf3 --- /dev/null +++ b/src/codegen/compiler/resource.h @@ -0,0 +1,79 @@ +/* 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_COMPILER_RESOURCE_H +#define AVIAN_CODEGEN_COMPILER_RESOURCE_H + +#include "codegen/compiler/context.h" + +namespace avian { +namespace codegen { +namespace compiler { + +class Value; +class Site; + +class Resource { + public: + Resource(bool reserved = false): + value(0), site(0), previousAcquired(0), nextAcquired(0), freezeCount(0), + referenceCount(0), reserved(reserved) + { } + + virtual void freeze(Context*, Value*) = 0; + + virtual void thaw(Context*, Value*) = 0; + + virtual unsigned toString(Context*, char*, unsigned) = 0; + + Value* value; + Site* site; + Resource* previousAcquired; + Resource* nextAcquired; + uint8_t freezeCount; + uint8_t referenceCount; + bool reserved; +}; + +class RegisterResource: public Resource { + public: + RegisterResource(bool reserved): + Resource(reserved) + { } + + virtual void freeze(Context*, Value*); + + virtual void thaw(Context*, Value*); + + virtual unsigned toString(Context* c, char* buffer, unsigned bufferSize); + + virtual unsigned index(Context*); + + void increment(Context*); + + void decrement(Context*); +}; + +class FrameResource: public Resource { + public: + virtual void freeze(Context*, Value*); + + virtual void thaw(Context*, Value*); + + virtual unsigned toString(Context* c, char* buffer, unsigned bufferSize); + + virtual unsigned index(Context*); +}; + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_RESOURCE_H diff --git a/src/codegen/compiler/value.h b/src/codegen/compiler/value.h new file mode 100644 index 0000000000..a2e8040db6 --- /dev/null +++ b/src/codegen/compiler/value.h @@ -0,0 +1,49 @@ +/* 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_COMPILER_VALUE_H +#define AVIAN_CODEGEN_COMPILER_VALUE_H + +#include "codegen/lir.h" + +namespace avian { +namespace codegen { +namespace compiler { + +class Read; +class Site; + +const int AnyFrameIndex = -2; +const int NoFrameIndex = -1; + +class Value: public Compiler::Operand { + public: + Value(Site* site, Site* target, lir::ValueType type): + reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this), + nextWord(this), home(NoFrameIndex), type(type), wordIndex(0) + { } + + Read* reads; + Read* lastRead; + Site* sites; + Site* source; + Site* target; + Value* buddy; + Value* nextWord; + int16_t home; + lir::ValueType type; + uint8_t wordIndex; +}; + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_VALUE_H \ No newline at end of file From 952cad2360d9b7e5e6e65c1c41067b7ffd9e85f5 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 12:56:56 -0700 Subject: [PATCH 06/23] move site out of compiler.cpp --- makefile | 1 + src/codegen/compiler.cpp | 244 +----------------------------- src/codegen/compiler/resource.cpp | 8 + src/codegen/compiler/resource.h | 12 +- src/codegen/compiler/site.cpp | 102 +++++++++++++ src/codegen/compiler/site.h | 190 +++++++++++++++++++++++ 6 files changed, 308 insertions(+), 249 deletions(-) create mode 100644 src/codegen/compiler/site.cpp create mode 100644 src/codegen/compiler/site.h diff --git a/makefile b/makefile index e84d022f57..a408804b29 100755 --- a/makefile +++ b/makefile @@ -956,6 +956,7 @@ ifeq ($(process),compile) $(src)/codegen/regalloc.cpp \ $(src)/codegen/compiler/context.cpp \ $(src)/codegen/compiler/resource.cpp \ + $(src)/codegen/compiler/site.cpp \ $(src)/codegen/registers.cpp \ $(src)/codegen/targets.cpp diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 1f27b5749e..d07caa4e7d 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -19,6 +19,7 @@ #include "codegen/compiler/context.h" #include "codegen/compiler/resource.h" #include "codegen/compiler/value.h" +#include "codegen/compiler/site.h" using namespace vm; @@ -42,12 +43,6 @@ const unsigned StealRegisterReserveCount = 2; // compare instruction: const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4); -const unsigned RegisterCopyCost = 1; -const unsigned AddressCopyCost = 2; -const unsigned ConstantCopyCost = 3; -const unsigned MemoryCopyCost = 4; -const unsigned CopyPenalty = 10; - class Stack; class Site; class ConstantSite; @@ -90,70 +85,6 @@ class Local { Value* value; }; -class SiteMask { - public: - SiteMask(): typeMask(~0), registerMask(~0), frameIndex(AnyFrameIndex) { } - - SiteMask(uint8_t typeMask, uint32_t registerMask, int frameIndex): - typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex) - { } - - uint8_t typeMask; - uint32_t registerMask; - int frameIndex; -}; - -class Site { - public: - Site(): next(0) { } - - virtual Site* readTarget(Context*, Read*) { return this; } - - virtual unsigned toString(Context*, char*, unsigned) = 0; - - virtual unsigned copyCost(Context*, Site*) = 0; - - virtual bool match(Context*, const SiteMask&) = 0; - - virtual bool loneMatch(Context*, const SiteMask&) = 0; - - virtual bool matchNextWord(Context*, Site*, unsigned) = 0; - - virtual void acquire(Context*, Value*) { } - - virtual void release(Context*, Value*) { } - - virtual void freeze(Context*, Value*) { } - - virtual void thaw(Context*, Value*) { } - - virtual bool frozen(Context*) { return false; } - - virtual lir::OperandType type(Context*) = 0; - - virtual void asAssemblerOperand(Context*, Site*, lir::Operand*) = 0; - - virtual Site* copy(Context*) = 0; - - virtual Site* copyLow(Context*) = 0; - - virtual Site* copyHigh(Context*) = 0; - - virtual Site* makeNextWord(Context*, unsigned) = 0; - - virtual SiteMask mask(Context*) = 0; - - virtual SiteMask nextWordMask(Context*, unsigned) = 0; - - virtual unsigned registerSize(Context*) { return TargetBytesPerWord; } - - virtual unsigned registerMask(Context*) { return 0; } - - virtual bool isVolatile(Context*) { return false; } - - Site* next; -}; - class Stack { public: Stack(unsigned index, Value* value, Stack* next): @@ -586,84 +517,6 @@ frameIndex(Context* c, FrameIterator::Element* element) return frameIndex(c, element->localIndex); } -class SiteIterator { - public: - SiteIterator(Context* c, Value* v, bool includeBuddies = true, - bool includeNextWord = true): - c(c), - originalValue(v), - currentValue(v), - includeBuddies(includeBuddies), - includeNextWord(includeNextWord), - pass(0), - next_(findNext(&(v->sites))), - previous(0) - { } - - Site** findNext(Site** p) { - while (true) { - if (*p) { - if (pass == 0 or (*p)->registerSize(c) > TargetBytesPerWord) { - return p; - } else { - p = &((*p)->next); - } - } else { - if (includeBuddies) { - Value* v = currentValue->buddy; - if (v != originalValue) { - currentValue = v; - p = &(v->sites); - continue; - } - } - - if (includeNextWord and pass == 0) { - Value* v = originalValue->nextWord; - if (v != originalValue) { - pass = 1; - originalValue = v; - currentValue = v; - p = &(v->sites); - continue; - } - } - - return 0; - } - } - } - - bool hasMore() { - if (previous) { - next_ = findNext(&((*previous)->next)); - previous = 0; - } - return next_ != 0; - } - - Site* next() { - previous = next_; - return *previous; - } - - void remove(Context* c) { - (*previous)->release(c, originalValue); - *previous = (*previous)->next; - next_ = findNext(previous); - previous = 0; - } - - Context* c; - Value* originalValue; - Value* currentValue; - bool includeBuddies; - bool includeNextWord; - uint8_t pass; - Site** next_; - Site** previous; -}; - bool hasSite(Context* c, Value* v) { @@ -1233,109 +1086,20 @@ acquire(Context* c, Resource* resource, Value* value, Site* site); void release(Context* c, Resource* resource, Value* value, Site* site); -ConstantSite* -constantSite(Context* c, Promise* value); - -ShiftMaskPromise* -shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask) -{ +Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask) { return new(c->zone) ShiftMaskPromise(base, shift, mask); } -CombinedPromise* -combinedPromise(Context* c, Promise* low, Promise* high) -{ +Promise* combinedPromise(Context* c, Promise* low, Promise* high) { return new(c->zone) CombinedPromise(low, high); } -class ConstantSite: public Site { - public: - ConstantSite(Promise* value): value(value) { } - - virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { - if (value->resolved()) { - return vm::snprintf - (buffer, bufferSize, "constant %" LLD, value->value()); - } else { - return vm::snprintf(buffer, bufferSize, "constant unresolved"); - } - } - - virtual unsigned copyCost(Context*, Site* s) { - return (s == this ? 0 : ConstantCopyCost); - } - - virtual bool match(Context*, const SiteMask& mask) { - return mask.typeMask & (1 << lir::ConstantOperand); - } - - virtual bool loneMatch(Context*, const SiteMask&) { - return true; - } - - virtual bool matchNextWord(Context* c, Site* s, unsigned) { - return s->type(c) == lir::ConstantOperand; - } - - virtual lir::OperandType type(Context*) { - return lir::ConstantOperand; - } - - virtual void asAssemblerOperand(Context* c, Site* high, - lir::Operand* result) - { - Promise* v = value; - if (high != this) { - v = combinedPromise(c, value, static_cast(high)->value); - } - new (result) lir::Constant(v); - } - - virtual Site* copy(Context* c) { - return constantSite(c, value); - } - - virtual Site* copyLow(Context* c) { - return constantSite(c, shiftMaskPromise(c, value, 0, 0xFFFFFFFF)); - } - - virtual Site* copyHigh(Context* c) { - return constantSite(c, shiftMaskPromise(c, value, 32, 0xFFFFFFFF)); - } - - virtual Site* makeNextWord(Context* c, unsigned) { - abort(c); - } - - virtual SiteMask mask(Context*) { - return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); - } - - virtual SiteMask nextWordMask(Context*, unsigned) { - return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); - } - - Promise* value; -}; - -ConstantSite* -constantSite(Context* c, Promise* value) -{ - return new(c->zone) ConstantSite(value); -} - -ResolvedPromise* +Promise* resolved(Context* c, int64_t value) { return new(c->zone) ResolvedPromise(value); } -ConstantSite* -constantSite(Context* c, int64_t value) -{ - return constantSite(c, resolved(c, value)); -} - AddressSite* addressSite(Context* c, Promise* address); diff --git a/src/codegen/compiler/resource.cpp b/src/codegen/compiler/resource.cpp index 0480c6e3d7..1b549e0197 100644 --- a/src/codegen/compiler/resource.cpp +++ b/src/codegen/compiler/resource.cpp @@ -59,6 +59,14 @@ void thawResource(Context* c, Resource* r, Value* v) { } +Resource::Resource(bool reserved): + value(0), site(0), previousAcquired(0), nextAcquired(0), freezeCount(0), + referenceCount(0), reserved(reserved) +{ } + +RegisterResource::RegisterResource(bool reserved): + Resource(reserved) +{ } void RegisterResource::freeze(Context* c, Value* v) { if (not reserved) { diff --git a/src/codegen/compiler/resource.h b/src/codegen/compiler/resource.h index b9d469bbf3..004cbc34cc 100644 --- a/src/codegen/compiler/resource.h +++ b/src/codegen/compiler/resource.h @@ -11,21 +11,17 @@ #ifndef AVIAN_CODEGEN_COMPILER_RESOURCE_H #define AVIAN_CODEGEN_COMPILER_RESOURCE_H -#include "codegen/compiler/context.h" - namespace avian { namespace codegen { namespace compiler { +class Context; class Value; class Site; class Resource { public: - Resource(bool reserved = false): - value(0), site(0), previousAcquired(0), nextAcquired(0), freezeCount(0), - referenceCount(0), reserved(reserved) - { } + Resource(bool reserved = false); virtual void freeze(Context*, Value*) = 0; @@ -44,9 +40,7 @@ class Resource { class RegisterResource: public Resource { public: - RegisterResource(bool reserved): - Resource(reserved) - { } + RegisterResource(bool reserved); virtual void freeze(Context*, Value*); diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp new file mode 100644 index 0000000000..1e3dcff448 --- /dev/null +++ b/src/codegen/compiler/site.cpp @@ -0,0 +1,102 @@ +/* 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 "target.h" + +#include "codegen/compiler/context.h" +#include "codegen/compiler/value.h" +#include "codegen/compiler/site.h" + +namespace avian { +namespace codegen { +namespace compiler { + + +ResolvedPromise* resolved(Context* c, int64_t value); + +SiteIterator::SiteIterator(Context* c, Value* v, bool includeBuddies, + bool includeNextWord): + c(c), + originalValue(v), + currentValue(v), + includeBuddies(includeBuddies), + includeNextWord(includeNextWord), + pass(0), + next_(findNext(&(v->sites))), + previous(0) +{ } + +Site** SiteIterator::findNext(Site** p) { + while (true) { + if (*p) { + if (pass == 0 or (*p)->registerSize(c) > vm::TargetBytesPerWord) { + return p; + } else { + p = &((*p)->next); + } + } else { + if (includeBuddies) { + Value* v = currentValue->buddy; + if (v != originalValue) { + currentValue = v; + p = &(v->sites); + continue; + } + } + + if (includeNextWord and pass == 0) { + Value* v = originalValue->nextWord; + if (v != originalValue) { + pass = 1; + originalValue = v; + currentValue = v; + p = &(v->sites); + continue; + } + } + + return 0; + } + } +} + +bool SiteIterator::hasMore() { + if (previous) { + next_ = findNext(&((*previous)->next)); + previous = 0; + } + return next_ != 0; +} + +Site* SiteIterator::next() { + previous = next_; + return *previous; +} + +void SiteIterator::remove(Context* c) { + (*previous)->release(c, originalValue); + *previous = (*previous)->next; + next_ = findNext(previous); + previous = 0; +} + + + +Site* constantSite(Context* c, Promise* value) { + return new(c->zone) ConstantSite(value); +} + +Site* constantSite(Context* c, int64_t value) { + return constantSite(c, resolved(c, value)); +} + +} // namespace compiler +} // namespace codegen +} // namespace avian \ No newline at end of file diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h new file mode 100644 index 0000000000..aa66243b70 --- /dev/null +++ b/src/codegen/compiler/site.h @@ -0,0 +1,190 @@ +/* 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_COMPILER_SITE_H +#define AVIAN_CODEGEN_COMPILER_SITE_H + +namespace avian { +namespace codegen { +namespace compiler { + +class Context; + +const unsigned RegisterCopyCost = 1; +const unsigned AddressCopyCost = 2; +const unsigned ConstantCopyCost = 3; +const unsigned MemoryCopyCost = 4; +const unsigned CopyPenalty = 10; + +class SiteMask { + public: + SiteMask(): typeMask(~0), registerMask(~0), frameIndex(AnyFrameIndex) { } + + SiteMask(uint8_t typeMask, uint32_t registerMask, int frameIndex): + typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex) + { } + + uint8_t typeMask; + uint32_t registerMask; + int frameIndex; +}; + +class Site { + public: + Site(): next(0) { } + + virtual Site* readTarget(Context*, Read*) { return this; } + + virtual unsigned toString(Context*, char*, unsigned) = 0; + + virtual unsigned copyCost(Context*, Site*) = 0; + + virtual bool match(Context*, const SiteMask&) = 0; + + virtual bool loneMatch(Context*, const SiteMask&) = 0; + + virtual bool matchNextWord(Context*, Site*, unsigned) = 0; + + virtual void acquire(Context*, Value*) { } + + virtual void release(Context*, Value*) { } + + virtual void freeze(Context*, Value*) { } + + virtual void thaw(Context*, Value*) { } + + virtual bool frozen(Context*) { return false; } + + virtual lir::OperandType type(Context*) = 0; + + virtual void asAssemblerOperand(Context*, Site*, lir::Operand*) = 0; + + virtual Site* copy(Context*) = 0; + + virtual Site* copyLow(Context*) = 0; + + virtual Site* copyHigh(Context*) = 0; + + virtual Site* makeNextWord(Context*, unsigned) = 0; + + virtual SiteMask mask(Context*) = 0; + + virtual SiteMask nextWordMask(Context*, unsigned) = 0; + + virtual unsigned registerSize(Context*) { return vm::TargetBytesPerWord; } + + virtual unsigned registerMask(Context*) { return 0; } + + virtual bool isVolatile(Context*) { return false; } + + Site* next; +}; + +class SiteIterator { + public: + SiteIterator(Context* c, Value* v, bool includeBuddies = true, + bool includeNextWord = true); + + Site** findNext(Site** p); + bool hasMore(); + Site* next(); + void remove(Context* c); + + Context* c; + Value* originalValue; + Value* currentValue; + bool includeBuddies; + bool includeNextWord; + uint8_t pass; + Site** next_; + Site** previous; +}; + +Site* constantSite(Context* c, Promise* value); +Site* constantSite(Context* c, int64_t value); + +Promise* combinedPromise(Context* c, Promise* low, Promise* high); +Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask); + +class ConstantSite: public Site { + public: + ConstantSite(Promise* value): value(value) { } + + virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { + if (value->resolved()) { + return vm::snprintf + (buffer, bufferSize, "constant %" LLD, value->value()); + } else { + return vm::snprintf(buffer, bufferSize, "constant unresolved"); + } + } + + virtual unsigned copyCost(Context*, Site* s) { + return (s == this ? 0 : ConstantCopyCost); + } + + virtual bool match(Context*, const SiteMask& mask) { + return mask.typeMask & (1 << lir::ConstantOperand); + } + + virtual bool loneMatch(Context*, const SiteMask&) { + return true; + } + + virtual bool matchNextWord(Context* c, Site* s, unsigned) { + return s->type(c) == lir::ConstantOperand; + } + + virtual lir::OperandType type(Context*) { + return lir::ConstantOperand; + } + + virtual void asAssemblerOperand(Context* c, Site* high, + lir::Operand* result) + { + Promise* v = value; + if (high != this) { + v = combinedPromise(c, value, static_cast(high)->value); + } + new (result) lir::Constant(v); + } + + virtual Site* copy(Context* c) { + return constantSite(c, value); + } + + virtual Site* copyLow(Context* c) { + return constantSite(c, shiftMaskPromise(c, value, 0, 0xFFFFFFFF)); + } + + virtual Site* copyHigh(Context* c) { + return constantSite(c, shiftMaskPromise(c, value, 32, 0xFFFFFFFF)); + } + + virtual Site* makeNextWord(Context* c, unsigned) { + abort(c); + } + + virtual SiteMask mask(Context*) { + return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); + } + + virtual SiteMask nextWordMask(Context*, unsigned) { + return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex); + } + + Promise* value; +}; + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_SITE_H From b0abc4e1e50b7c68768e68673e8f9634d314880a Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 16:49:46 -0700 Subject: [PATCH 07/23] further split up compiler.cpp --- makefile | 3 +- src/codegen/compiler.cpp | 705 +----------------------------- src/codegen/compiler/context.h | 5 +- src/codegen/compiler/read.h | 46 ++ src/codegen/compiler/regalloc.cpp | 301 +++++++++++++ src/codegen/compiler/regalloc.h | 106 +++++ src/codegen/compiler/resource.cpp | 66 +++ src/codegen/compiler/resource.h | 4 + src/codegen/compiler/site.cpp | 273 ++++++++++++ src/codegen/compiler/site.h | 57 +++ src/codegen/compiler/value.cpp | 43 ++ src/codegen/compiler/value.h | 13 +- src/codegen/regalloc.cpp | 24 - src/codegen/regalloc.h | 37 -- 14 files changed, 916 insertions(+), 767 deletions(-) create mode 100644 src/codegen/compiler/read.h create mode 100644 src/codegen/compiler/regalloc.cpp create mode 100644 src/codegen/compiler/regalloc.h create mode 100644 src/codegen/compiler/value.cpp delete mode 100644 src/codegen/regalloc.cpp delete mode 100644 src/codegen/regalloc.h diff --git a/makefile b/makefile index a408804b29..9f57682239 100755 --- a/makefile +++ b/makefile @@ -953,10 +953,11 @@ embed-objects = $(call cpp-objects,$(embed-sources),$(src),$(build-embed)) ifeq ($(process),compile) vm-sources += \ $(src)/codegen/compiler.cpp \ - $(src)/codegen/regalloc.cpp \ $(src)/codegen/compiler/context.cpp \ $(src)/codegen/compiler/resource.cpp \ $(src)/codegen/compiler/site.cpp \ + $(src)/codegen/compiler/regalloc.cpp \ + $(src)/codegen/compiler/value.cpp \ $(src)/codegen/registers.cpp \ $(src)/codegen/targets.cpp diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index d07caa4e7d..7b63548c42 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -14,12 +14,13 @@ #include "codegen/compiler.h" #include "codegen/assembler.h" -#include "codegen/regalloc.h" +#include "codegen/compiler/regalloc.h" #include "codegen/compiler/context.h" #include "codegen/compiler/resource.h" #include "codegen/compiler/value.h" #include "codegen/compiler/site.h" +#include "codegen/compiler/read.h" using namespace vm; @@ -156,29 +157,6 @@ class ConstantPoolNode { ConstantPoolNode* next; }; -class Read { - public: - Read(): - value(0), event(0), eventNext(0) - { } - - virtual bool intersect(SiteMask* mask, unsigned depth = 0) = 0; - - virtual Value* high(Context* c) { abort(c); } - - virtual Value* successor() = 0; - - virtual bool valid() = 0; - - virtual void append(Context* c, Read* r) = 0; - - virtual Read* next(Context* c) = 0; - - Value* value; - Event* event; - Read* eventNext; -}; - int intersectFrameIndexes(int a, int b) { @@ -524,15 +502,6 @@ hasSite(Context* c, Value* v) return it.hasMore(); } -bool -findSite(Context*, Value* v, Site* site) -{ - for (Site* s = v->sites; s; s = s->next) { - if (s == site) return true; - } - return false; -} - bool uniqueSite(Context* c, Value* v, Site* s) { @@ -561,7 +530,7 @@ uniqueSite(Context* c, Value* v, Site* s) void addSite(Context* c, Value* v, Site* s) { - if (not findSite(c, v, s)) { + if (not v->findSite(s)) { if (DebugSites) { char buffer[256]; s->toString(c, buffer, 256); fprintf(stderr, "add site %s to %p\n", buffer, v); @@ -588,7 +557,7 @@ removeSite(Context* c, Value* v, Site* s) if (DebugSites) { fprintf(stderr, "%p has more: %d\n", v, hasSite(c, v)); } - assert(c, not findSite(c, v, s)); + assert(c, not v->findSite(s)); } void @@ -745,16 +714,6 @@ popRead(Context* c, Event* e UNUSED, Value* v) } } -bool -buddies(Value* a, Value* b) -{ - if (a == b) return true; - for (Value* p = a->buddy; p != a; p = p->buddy) { - if (p == b) return true; - } - return false; -} - void addBuddy(Value* original, Value* buddy) { @@ -772,27 +731,6 @@ addBuddy(Value* original, Value* buddy) } } -class Target { - public: - static const unsigned MinimumRegisterCost = 0; - static const unsigned MinimumFrameCost = 1; - static const unsigned StealPenalty = 2; - static const unsigned StealUniquePenalty = 4; - static const unsigned IndirectMovePenalty = 4; - static const unsigned LowRegisterPenalty = 10; - static const unsigned Impossible = 20; - - Target(): cost(Impossible) { } - - Target(int index, lir::OperandType type, unsigned cost): - index(index), type(type), cost(cost) - { } - - int16_t index; - lir::OperandType type; - uint8_t cost; -}; - lir::ValueType valueType(Context* c, Compiler::OperandType type) { @@ -809,283 +747,6 @@ valueType(Context* c, Compiler::OperandType type) } } -class CostCalculator { - public: - virtual unsigned cost(Context* c, SiteMask mask) = 0; -}; - -unsigned -resourceCost(Context* c, Value* v, Resource* r, SiteMask mask, - CostCalculator* costCalculator) -{ - if (r->reserved or r->freezeCount or r->referenceCount) { - return Target::Impossible; - } else { - unsigned baseCost = - costCalculator ? costCalculator->cost(c, mask) : 0; - - if (r->value) { - assert(c, findSite(c, r->value, r->site)); - - if (v and buddies(r->value, v)) { - return baseCost; - } else if (uniqueSite(c, r->value, r->site)) { - return baseCost + Target::StealUniquePenalty; - } else { - return baseCost = Target::StealPenalty; - } - } else { - return baseCost; - } - } -} - -bool -pickRegisterTarget(Context* c, int i, Value* v, uint32_t mask, int* target, - unsigned* cost, CostCalculator* costCalculator = 0) -{ - if ((1 << i) & mask) { - RegisterResource* r = c->registerResources + i; - unsigned myCost = resourceCost - (c, v, r, SiteMask(1 << lir::RegisterOperand, 1 << i, NoFrameIndex), costCalculator) - + Target::MinimumRegisterCost; - - if ((static_cast(1) << i) == mask) { - *cost = myCost; - return true; - } else if (myCost < *cost) { - *cost = myCost; - *target = i; - } - } - return false; -} - -int -pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost, - CostCalculator* costCalculator = 0) -{ - int target = lir::NoRegister; - *cost = Target::Impossible; - - if (mask & c->regFile->generalRegisters.mask) { - for (int i = c->regFile->generalRegisters.limit - 1; - i >= c->regFile->generalRegisters.start; --i) - { - if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { - return i; - } - } - } - - if (mask & c->regFile->floatRegisters.mask) { - for (int i = c->regFile->floatRegisters.start; - i < static_cast(c->regFile->floatRegisters.limit); ++i) - { - if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { - return i; - } - } - } - - return target; -} - -Target -pickRegisterTarget(Context* c, Value* v, uint32_t mask, - CostCalculator* costCalculator = 0) -{ - unsigned cost; - int number = pickRegisterTarget(c, v, mask, &cost, costCalculator); - return Target(number, lir::RegisterOperand, cost); -} - -unsigned -frameCost(Context* c, Value* v, int frameIndex, CostCalculator* costCalculator) -{ - return resourceCost - (c, v, c->frameResources + frameIndex, SiteMask(1 << lir::MemoryOperand, 0, frameIndex), - costCalculator) - + Target::MinimumFrameCost; -} - -Target -pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator) -{ - Target best; - - Value* p = v; - do { - if (p->home >= 0) { - Target mine - (p->home, lir::MemoryOperand, frameCost(c, v, p->home, costCalculator)); - - if (mine.cost == Target::MinimumFrameCost) { - return mine; - } else if (mine.cost < best.cost) { - best = mine; - } - } - p = p->buddy; - } while (p != v); - - return best; -} - -Target -pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator) -{ - Target best; - - unsigned count = totalFrameSize(c); - for (unsigned i = 0; i < count; ++i) { - Target mine(i, lir::MemoryOperand, frameCost(c, v, i, costCalculator)); - if (mine.cost == Target::MinimumFrameCost) { - return mine; - } else if (mine.cost < best.cost) { - best = mine; - } - } - - return best; -} - -Target -pickTarget(Context* c, Value* value, const SiteMask& mask, - unsigned registerPenalty, Target best, - CostCalculator* costCalculator) -{ - if (mask.typeMask & (1 << lir::RegisterOperand)) { - Target mine = pickRegisterTarget - (c, value, mask.registerMask, costCalculator); - - mine.cost += registerPenalty; - if (mine.cost == Target::MinimumRegisterCost) { - return mine; - } else if (mine.cost < best.cost) { - best = mine; - } - } - - if (mask.typeMask & (1 << lir::MemoryOperand)) { - if (mask.frameIndex >= 0) { - Target mine(mask.frameIndex, lir::MemoryOperand, - frameCost(c, value, mask.frameIndex, costCalculator)); - if (mine.cost == Target::MinimumFrameCost) { - return mine; - } else if (mine.cost < best.cost) { - best = mine; - } - } else if (mask.frameIndex == AnyFrameIndex) { - Target mine = pickFrameTarget(c, value, costCalculator); - if (mine.cost == Target::MinimumFrameCost) { - return mine; - } else if (mine.cost < best.cost) { - best = mine; - } - } - } - - return best; -} - -Target -pickTarget(Context* c, Read* read, bool intersectRead, - unsigned registerReserveCount, CostCalculator* costCalculator) -{ - unsigned registerPenalty - = (c->availableGeneralRegisterCount > registerReserveCount - ? 0 : Target::LowRegisterPenalty); - - Value* value = read->value; - - uint32_t registerMask - = (value->type == lir::ValueFloat ? ~0 : c->regFile->generalRegisters.mask); - - SiteMask mask(~0, registerMask, AnyFrameIndex); - read->intersect(&mask); - - if (value->type == lir::ValueFloat) { - uint32_t floatMask = mask.registerMask & c->regFile->floatRegisters.mask; - if (floatMask) { - mask.registerMask = floatMask; - } - } - - Target best; - - Value* successor = read->successor(); - if (successor) { - Read* r = live(c, successor); - if (r) { - SiteMask intersection = mask; - if (r->intersect(&intersection)) { - best = pickTarget - (c, value, intersection, registerPenalty, best, costCalculator); - - if (best.cost <= Target::MinimumFrameCost) { - return best; - } - } - } - } - - best = pickTarget(c, value, mask, registerPenalty, best, costCalculator); - if (best.cost <= Target::MinimumFrameCost) { - return best; - } - - if (intersectRead) { - if (best.cost == Target::Impossible) { - fprintf(stderr, "mask type %d reg %d frame %d\n", - mask.typeMask, mask.registerMask, mask.frameIndex); - abort(c); - } - return best; - } - - { Target mine = pickRegisterTarget(c, value, registerMask, costCalculator); - - mine.cost += registerPenalty; - - if (mine.cost == Target::MinimumRegisterCost) { - return mine; - } else if (mine.cost < best.cost) { - best = mine; - } - } - - { Target mine = pickFrameTarget(c, value, costCalculator); - if (mine.cost == Target::MinimumFrameCost) { - return mine; - } else if (mine.cost < best.cost) { - best = mine; - } - } - - if (best.cost >= Target::StealUniquePenalty - and c->availableGeneralRegisterCount == 0) - { - // there are no free registers left, so moving from memory to - // memory isn't an option - try harder to find an available frame - // site: - best = pickAnyFrameTarget(c, value, costCalculator); - assert(c, best.cost <= 3); - } - - if (best.cost == Target::Impossible) { - abort(c); - } - - return best; -} - -void -acquire(Context* c, Resource* resource, Value* value, Site* site); - -void -release(Context* c, Resource* resource, Value* value, Site* site); - Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask) { return new(c->zone) ShiftMaskPromise(base, shift, mask); } @@ -1094,297 +755,10 @@ Promise* combinedPromise(Context* c, Promise* low, Promise* high) { return new(c->zone) CombinedPromise(low, high); } -Promise* -resolved(Context* c, int64_t value) -{ +Promise* resolved(Context* c, int64_t value) { return new(c->zone) ResolvedPromise(value); } -AddressSite* -addressSite(Context* c, Promise* address); - -class AddressSite: public Site { - public: - AddressSite(Promise* address): address(address) { } - - virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { - if (address->resolved()) { - return vm::snprintf - (buffer, bufferSize, "address %" LLD, address->value()); - } else { - return vm::snprintf(buffer, bufferSize, "address unresolved"); - } - } - - virtual unsigned copyCost(Context*, Site* s) { - return (s == this ? 0 : AddressCopyCost); - } - - virtual bool match(Context*, const SiteMask& mask) { - return mask.typeMask & (1 << lir::AddressOperand); - } - - virtual bool loneMatch(Context*, const SiteMask&) { - return false; - } - - virtual bool matchNextWord(Context* c, Site*, unsigned) { - abort(c); - } - - virtual lir::OperandType type(Context*) { - return lir::AddressOperand; - } - - virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, - lir::Operand* result) - { - assert(c, high == this); - - new (result) lir::Address(address); - } - - virtual Site* copy(Context* c) { - return addressSite(c, address); - } - - virtual Site* copyLow(Context* c) { - abort(c); - } - - virtual Site* copyHigh(Context* c) { - abort(c); - } - - virtual Site* makeNextWord(Context* c, unsigned) { - abort(c); - } - - virtual SiteMask mask(Context*) { - return SiteMask(1 << lir::AddressOperand, 0, NoFrameIndex); - } - - virtual SiteMask nextWordMask(Context* c, unsigned) { - abort(c); - } - - Promise* address; -}; - -AddressSite* -addressSite(Context* c, Promise* address) -{ - return new(c->zone) AddressSite(address); -} - -RegisterSite* -freeRegisterSite(Context* c, uint32_t mask); - -class RegisterSite: public Site { - public: - RegisterSite(uint32_t mask, int number): - mask_(mask), number(number) - { } - - virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { - if (number != lir::NoRegister) { - return vm::snprintf(buffer, bufferSize, "%p register %d", this, number); - } else { - return vm::snprintf(buffer, bufferSize, - "%p register unacquired (mask %d)", this, mask_); - } - } - - virtual unsigned copyCost(Context* c, Site* s) { - assert(c, number != lir::NoRegister); - - if (s and - (this == s or - (s->type(c) == lir::RegisterOperand - and (static_cast(s)->mask_ & (1 << number))))) - { - return 0; - } else { - return RegisterCopyCost; - } - } - - virtual bool match(Context* c UNUSED, const SiteMask& mask) { - assert(c, number != lir::NoRegister); - - if ((mask.typeMask & (1 << lir::RegisterOperand))) { - return ((static_cast(1) << number) & mask.registerMask); - } else { - return false; - } - } - - virtual bool loneMatch(Context* c UNUSED, const SiteMask& mask) { - assert(c, number != lir::NoRegister); - - if ((mask.typeMask & (1 << lir::RegisterOperand))) { - return ((static_cast(1) << number) == mask.registerMask); - } else { - return false; - } - } - - virtual bool matchNextWord(Context* c, Site* s, unsigned) { - assert(c, number != lir::NoRegister); - - if (s->type(c) != lir::RegisterOperand) { - return false; - } - - RegisterSite* rs = static_cast(s); - unsigned size = rs->registerSize(c); - if (size > TargetBytesPerWord) { - assert(c, number != lir::NoRegister); - return number == rs->number; - } else { - uint32_t mask = c->regFile->generalRegisters.mask; - return ((1 << number) & mask) and ((1 << rs->number) & mask); - } - } - - virtual void acquire(Context* c, Value* v) { - Target target; - if (number != lir::NoRegister) { - target = Target(number, lir::RegisterOperand, 0); - } else { - target = pickRegisterTarget(c, v, mask_); - expect(c, target.cost < Target::Impossible); - } - - RegisterResource* resource = c->registerResources + target.index; - compiler::acquire(c, resource, v, this); - - number = target.index; - } - - virtual void release(Context* c, Value* v) { - assert(c, number != lir::NoRegister); - - compiler::release(c, c->registerResources + number, v, this); - } - - virtual void freeze(Context* c, Value* v) { - assert(c, number != lir::NoRegister); - - c->registerResources[number].freeze(c, v); - } - - virtual void thaw(Context* c, Value* v) { - assert(c, number != lir::NoRegister); - - c->registerResources[number].thaw(c, v); - } - - virtual bool frozen(Context* c UNUSED) { - assert(c, number != lir::NoRegister); - - return c->registerResources[number].freezeCount != 0; - } - - virtual lir::OperandType type(Context*) { - return lir::RegisterOperand; - } - - virtual void asAssemblerOperand(Context* c UNUSED, Site* high, - lir::Operand* result) - { - assert(c, number != lir::NoRegister); - - int highNumber; - if (high != this) { - highNumber = static_cast(high)->number; - assert(c, highNumber != lir::NoRegister); - } else { - highNumber = lir::NoRegister; - } - - new (result) lir::Register(number, highNumber); - } - - virtual Site* copy(Context* c) { - uint32_t mask; - - if (number != lir::NoRegister) { - mask = 1 << number; - } else { - mask = mask_; - } - - return freeRegisterSite(c, mask); - } - - virtual Site* copyLow(Context* c) { - abort(c); - } - - virtual Site* copyHigh(Context* c) { - abort(c); - } - - virtual Site* makeNextWord(Context* c, unsigned) { - assert(c, number != lir::NoRegister); - assert(c, ((1 << number) & c->regFile->generalRegisters.mask)); - - return freeRegisterSite(c, c->regFile->generalRegisters.mask); - } - - virtual SiteMask mask(Context* c UNUSED) { - return SiteMask(1 << lir::RegisterOperand, mask_, NoFrameIndex); - } - - virtual SiteMask nextWordMask(Context* c, unsigned) { - assert(c, number != lir::NoRegister); - - if (registerSize(c) > TargetBytesPerWord) { - return SiteMask - (1 << lir::RegisterOperand, number, NoFrameIndex); - } else { - return SiteMask - (1 << lir::RegisterOperand, c->regFile->generalRegisters.mask, NoFrameIndex); - } - } - - virtual unsigned registerSize(Context* c) { - assert(c, number != lir::NoRegister); - - if ((1 << number) & c->regFile->floatRegisters.mask) { - return c->arch->floatRegisterSize(); - } else { - return TargetBytesPerWord; - } - } - - virtual unsigned registerMask(Context* c UNUSED) { - assert(c, number != lir::NoRegister); - - return 1 << number; - } - - uint32_t mask_; - int number; -}; - -RegisterSite* -registerSite(Context* c, int number) -{ - assert(c, number >= 0); - assert(c, (1 << number) & (c->regFile->generalRegisters.mask - | c->regFile->floatRegisters.mask)); - - return new(c->zone) RegisterSite(1 << number, number); -} - -RegisterSite* -freeRegisterSite(Context* c, uint32_t mask) -{ - return new(c->zone) RegisterSite(mask, lir::NoRegister); -} - MemorySite* memorySite(Context* c, int base, int offset = 0, int index = lir::NoRegister, unsigned scale = 1); @@ -1960,7 +1334,7 @@ steal(Context* c, Resource* r, Value* thief) thief, resourceBuffer, r->value, siteBuffer); } - if ((not (thief and buddies(thief, r->value)) + if ((not (thief and thief->isBuddyOf(r->value)) and uniqueSite(c, r->value, r->site))) { r->site->freeze(c, r->value); @@ -1973,71 +1347,6 @@ steal(Context* c, Resource* r, Value* thief) removeSite(c, r->value, r->site); } -void -acquire(Context* c, Resource* resource, Value* value, Site* site) -{ - assert(c, value); - assert(c, site); - - if (not resource->reserved) { - if (DebugResources) { - char buffer[256]; resource->toString(c, buffer, 256); - fprintf(stderr, "%p acquire %s\n", value, buffer); - } - - if (resource->value) { - assert(c, findSite(c, resource->value, resource->site)); - assert(c, not findSite(c, value, resource->site)); - - steal(c, resource, value); - } - - if (c->acquiredResources) { - c->acquiredResources->previousAcquired = resource; - resource->nextAcquired = c->acquiredResources; - } - c->acquiredResources = resource; - - resource->value = value; - resource->site = site; - } -} - -void -release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNUSED) -{ - if (not resource->reserved) { - if (DebugResources) { - char buffer[256]; resource->toString(c, buffer, 256); - fprintf(stderr, "%p release %s\n", resource->value, buffer); - } - - assert(c, resource->value); - assert(c, resource->site); - - assert(c, buddies(resource->value, value)); - assert(c, site == resource->site); - - Resource* next = resource->nextAcquired; - if (next) { - next->previousAcquired = resource->previousAcquired; - resource->nextAcquired = 0; - } - - Resource* previous = resource->previousAcquired; - if (previous) { - previous->nextAcquired = next; - resource->previousAcquired = 0; - } else { - assert(c, c->acquiredResources == resource); - c->acquiredResources = next; - } - - resource->value = 0; - resource->site = 0; - } -} - SiteMask generalRegisterMask(Context* c) { @@ -2319,7 +1628,7 @@ move(Context* c, Value* value, Site* src, Site* dst) srcb, dstb, value, value); } - assert(c, findSite(c, value, dst)); + assert(c, value->findSite(dst)); src->freeze(c, value); dst->freeze(c, value); diff --git a/src/codegen/compiler/context.h b/src/codegen/compiler/context.h index df6382e68f..2605aaf64d 100644 --- a/src/codegen/compiler/context.h +++ b/src/codegen/compiler/context.h @@ -12,9 +12,10 @@ #define AVIAN_CODEGEN_COMPILER_CONTEXT_H #include "codegen/assembler.h" -#include "codegen/regalloc.h" #include "codegen/compiler.h" +#include "codegen/compiler/regalloc.h" + namespace avian { namespace codegen { namespace compiler { @@ -51,7 +52,7 @@ class Context { Event* predecessor; LogicalInstruction** logicalCode; const RegisterFile* regFile; - regalloc::RegisterAllocator regAlloc; + RegisterAllocator regAlloc; RegisterResource* registerResources; FrameResource* frameResources; Resource* acquiredResources; diff --git a/src/codegen/compiler/read.h b/src/codegen/compiler/read.h new file mode 100644 index 0000000000..a0c1d5a763 --- /dev/null +++ b/src/codegen/compiler/read.h @@ -0,0 +1,46 @@ +/* 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_COMPILER_READ_H +#define AVIAN_CODEGEN_COMPILER_READ_H + +namespace avian { +namespace codegen { +namespace compiler { + +class Read { + public: + Read(): + value(0), event(0), eventNext(0) + { } + + virtual bool intersect(SiteMask* mask, unsigned depth = 0) = 0; + + virtual Value* high(Context* c) { abort(c); } + + virtual Value* successor() = 0; + + virtual bool valid() = 0; + + virtual void append(Context* c, Read* r) = 0; + + virtual Read* next(Context* c) = 0; + + Value* value; + Event* event; + Read* eventNext; +}; + + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_READ_H diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp new file mode 100644 index 0000000000..2727b569c4 --- /dev/null +++ b/src/codegen/compiler/regalloc.cpp @@ -0,0 +1,301 @@ +/* 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 "target.h" + +#include "codegen/compiler/regalloc.h" +#include "codegen/compiler/context.h" +#include "codegen/compiler/site.h" +#include "codegen/compiler/resource.h" +#include "codegen/compiler/read.h" + +namespace avian { +namespace codegen { +namespace compiler { + +RegisterAllocator::RegisterAllocator(Aborter* a, const RegisterFile* registerFile): + a(a), + registerFile(registerFile) +{ } + + +bool uniqueSite(Context* c, Value* v, Site* s); +unsigned totalFrameSize(Context* c); +Read* live(Context* c UNUSED, Value* v); + +unsigned +resourceCost(Context* c, Value* v, Resource* r, SiteMask mask, + CostCalculator* costCalculator) +{ + if (r->reserved or r->freezeCount or r->referenceCount) { + return Target::Impossible; + } else { + unsigned baseCost = + costCalculator ? costCalculator->cost(c, mask) : 0; + + if (r->value) { + assert(c, r->value->findSite(r->site)); + + if (v and r->value->isBuddyOf(v)) { + return baseCost; + } else if (uniqueSite(c, r->value, r->site)) { + return baseCost + Target::StealUniquePenalty; + } else { + return baseCost = Target::StealPenalty; + } + } else { + return baseCost; + } + } +} + +bool +pickRegisterTarget(Context* c, int i, Value* v, uint32_t mask, int* target, + unsigned* cost, CostCalculator* costCalculator) +{ + if ((1 << i) & mask) { + RegisterResource* r = c->registerResources + i; + unsigned myCost = resourceCost + (c, v, r, SiteMask(1 << lir::RegisterOperand, 1 << i, NoFrameIndex), costCalculator) + + Target::MinimumRegisterCost; + + if ((static_cast(1) << i) == mask) { + *cost = myCost; + return true; + } else if (myCost < *cost) { + *cost = myCost; + *target = i; + } + } + return false; +} + +int +pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost, + CostCalculator* costCalculator) +{ + int target = lir::NoRegister; + *cost = Target::Impossible; + + if (mask & c->regFile->generalRegisters.mask) { + for (int i = c->regFile->generalRegisters.limit - 1; + i >= c->regFile->generalRegisters.start; --i) + { + if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { + return i; + } + } + } + + if (mask & c->regFile->floatRegisters.mask) { + for (int i = c->regFile->floatRegisters.start; + i < static_cast(c->regFile->floatRegisters.limit); ++i) + { + if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { + return i; + } + } + } + + return target; +} + +Target +pickRegisterTarget(Context* c, Value* v, uint32_t mask, + CostCalculator* costCalculator) +{ + unsigned cost; + int number = pickRegisterTarget(c, v, mask, &cost, costCalculator); + return Target(number, lir::RegisterOperand, cost); +} + +unsigned +frameCost(Context* c, Value* v, int frameIndex, CostCalculator* costCalculator) +{ + return resourceCost + (c, v, c->frameResources + frameIndex, SiteMask(1 << lir::MemoryOperand, 0, frameIndex), + costCalculator) + + Target::MinimumFrameCost; +} + +Target +pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator) +{ + Target best; + + Value* p = v; + do { + if (p->home >= 0) { + Target mine + (p->home, lir::MemoryOperand, frameCost(c, v, p->home, costCalculator)); + + if (mine.cost == Target::MinimumFrameCost) { + return mine; + } else if (mine.cost < best.cost) { + best = mine; + } + } + p = p->buddy; + } while (p != v); + + return best; +} + +Target +pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator) +{ + Target best; + + unsigned count = totalFrameSize(c); + for (unsigned i = 0; i < count; ++i) { + Target mine(i, lir::MemoryOperand, frameCost(c, v, i, costCalculator)); + if (mine.cost == Target::MinimumFrameCost) { + return mine; + } else if (mine.cost < best.cost) { + best = mine; + } + } + + return best; +} + +Target +pickTarget(Context* c, Value* value, const SiteMask& mask, + unsigned registerPenalty, Target best, + CostCalculator* costCalculator) +{ + if (mask.typeMask & (1 << lir::RegisterOperand)) { + Target mine = pickRegisterTarget + (c, value, mask.registerMask, costCalculator); + + mine.cost += registerPenalty; + if (mine.cost == Target::MinimumRegisterCost) { + return mine; + } else if (mine.cost < best.cost) { + best = mine; + } + } + + if (mask.typeMask & (1 << lir::MemoryOperand)) { + if (mask.frameIndex >= 0) { + Target mine(mask.frameIndex, lir::MemoryOperand, + frameCost(c, value, mask.frameIndex, costCalculator)); + if (mine.cost == Target::MinimumFrameCost) { + return mine; + } else if (mine.cost < best.cost) { + best = mine; + } + } else if (mask.frameIndex == AnyFrameIndex) { + Target mine = pickFrameTarget(c, value, costCalculator); + if (mine.cost == Target::MinimumFrameCost) { + return mine; + } else if (mine.cost < best.cost) { + best = mine; + } + } + } + + return best; +} + +Target +pickTarget(Context* c, Read* read, bool intersectRead, + unsigned registerReserveCount, CostCalculator* costCalculator) +{ + unsigned registerPenalty + = (c->availableGeneralRegisterCount > registerReserveCount + ? 0 : Target::LowRegisterPenalty); + + Value* value = read->value; + + uint32_t registerMask + = (value->type == lir::ValueFloat ? ~0 : c->regFile->generalRegisters.mask); + + SiteMask mask(~0, registerMask, AnyFrameIndex); + read->intersect(&mask); + + if (value->type == lir::ValueFloat) { + uint32_t floatMask = mask.registerMask & c->regFile->floatRegisters.mask; + if (floatMask) { + mask.registerMask = floatMask; + } + } + + Target best; + + Value* successor = read->successor(); + if (successor) { + Read* r = live(c, successor); + if (r) { + SiteMask intersection = mask; + if (r->intersect(&intersection)) { + best = pickTarget + (c, value, intersection, registerPenalty, best, costCalculator); + + if (best.cost <= Target::MinimumFrameCost) { + return best; + } + } + } + } + + best = pickTarget(c, value, mask, registerPenalty, best, costCalculator); + if (best.cost <= Target::MinimumFrameCost) { + return best; + } + + if (intersectRead) { + if (best.cost == Target::Impossible) { + fprintf(stderr, "mask type %d reg %d frame %d\n", + mask.typeMask, mask.registerMask, mask.frameIndex); + abort(c); + } + return best; + } + + { Target mine = pickRegisterTarget(c, value, registerMask, costCalculator); + + mine.cost += registerPenalty; + + if (mine.cost == Target::MinimumRegisterCost) { + return mine; + } else if (mine.cost < best.cost) { + best = mine; + } + } + + { Target mine = pickFrameTarget(c, value, costCalculator); + if (mine.cost == Target::MinimumFrameCost) { + return mine; + } else if (mine.cost < best.cost) { + best = mine; + } + } + + if (best.cost >= Target::StealUniquePenalty + and c->availableGeneralRegisterCount == 0) + { + // there are no free registers left, so moving from memory to + // memory isn't an option - try harder to find an available frame + // site: + best = pickAnyFrameTarget(c, value, costCalculator); + assert(c, best.cost <= 3); + } + + if (best.cost == Target::Impossible) { + abort(c); + } + + return best; +} + +} // namespace regalloc +} // namespace codegen +} // namespace avian diff --git a/src/codegen/compiler/regalloc.h b/src/codegen/compiler/regalloc.h new file mode 100644 index 0000000000..cfbf154f1f --- /dev/null +++ b/src/codegen/compiler/regalloc.h @@ -0,0 +1,106 @@ +/* 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_COMPILER_REGALLOC_H +#define AVIAN_CODEGEN_COMPILER_REGALLOC_H + +#include "common.h" + +#include "codegen/lir.h" +#include "codegen/registers.h" + +class Aborter; + +namespace avian { +namespace codegen { +namespace compiler { + +class Context; +class Value; +class SiteMask; +class Resource; +class Read; + + +class RegisterAllocator { +public: + Aborter* a; + const RegisterFile* registerFile; + + RegisterAllocator(Aborter* a, const RegisterFile* registerFile); + +}; + +class Target { + public: + static const unsigned MinimumRegisterCost = 0; + static const unsigned MinimumFrameCost = 1; + static const unsigned StealPenalty = 2; + static const unsigned StealUniquePenalty = 4; + static const unsigned IndirectMovePenalty = 4; + static const unsigned LowRegisterPenalty = 10; + static const unsigned Impossible = 20; + + Target(): cost(Impossible) { } + + Target(int index, lir::OperandType type, unsigned cost): + index(index), type(type), cost(cost) + { } + + int16_t index; + lir::OperandType type; + uint8_t cost; +}; + +class CostCalculator { + public: + virtual unsigned cost(Context* c, SiteMask mask) = 0; +}; + +unsigned +resourceCost(Context* c, Value* v, Resource* r, SiteMask mask, + CostCalculator* costCalculator); + + +bool +pickRegisterTarget(Context* c, int i, Value* v, uint32_t mask, int* target, + unsigned* cost, CostCalculator* costCalculator = 0); + +int +pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost, + CostCalculator* costCalculator = 0); + +Target +pickRegisterTarget(Context* c, Value* v, uint32_t mask, + CostCalculator* costCalculator = 0); + +unsigned +frameCost(Context* c, Value* v, int frameIndex, CostCalculator* costCalculator); + +Target +pickFrameTarget(Context* c, Value* v, CostCalculator* costCalculator); + +Target +pickAnyFrameTarget(Context* c, Value* v, CostCalculator* costCalculator); + +Target +pickTarget(Context* c, Value* value, const SiteMask& mask, + unsigned registerPenalty, Target best, + CostCalculator* costCalculator); + +Target +pickTarget(Context* c, Read* read, bool intersectRead, + unsigned registerReserveCount, CostCalculator* costCalculator); + +} // namespace regalloc +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_REGALLOC_H \ No newline at end of file diff --git a/src/codegen/compiler/resource.cpp b/src/codegen/compiler/resource.cpp index 1b549e0197..af5e917762 100644 --- a/src/codegen/compiler/resource.cpp +++ b/src/codegen/compiler/resource.cpp @@ -10,6 +10,7 @@ #include "codegen/compiler/context.h" #include "codegen/compiler/resource.h" +#include "codegen/compiler/value.h" namespace avian { namespace codegen { @@ -17,6 +18,9 @@ namespace compiler { const bool DebugResources = false; + +void steal(Context* c, Resource* r, Value* thief); + void decrementAvailableGeneralRegisterCount(Context* c) { assert(c, c->availableGeneralRegisterCount); -- c->availableGeneralRegisterCount; @@ -155,6 +159,68 @@ unsigned FrameResource::index(Context* c) { } +void acquire(Context* c, Resource* resource, Value* value, Site* site) { + assert(c, value); + assert(c, site); + + if (not resource->reserved) { + if (DebugResources) { + char buffer[256]; resource->toString(c, buffer, 256); + fprintf(stderr, "%p acquire %s\n", value, buffer); + } + + if (resource->value) { + assert(c, resource->value->findSite(resource->site)); + assert(c, not value->findSite(resource->site)); + + steal(c, resource, value); + } + + if (c->acquiredResources) { + c->acquiredResources->previousAcquired = resource; + resource->nextAcquired = c->acquiredResources; + } + c->acquiredResources = resource; + + resource->value = value; + resource->site = site; + } +} + +void release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNUSED) { + if (not resource->reserved) { + if (DebugResources) { + char buffer[256]; resource->toString(c, buffer, 256); + fprintf(stderr, "%p release %s\n", resource->value, buffer); + } + + assert(c, resource->value); + assert(c, resource->site); + + assert(c, resource->value->isBuddyOf(value)); + assert(c, site == resource->site); + + Resource* next = resource->nextAcquired; + if (next) { + next->previousAcquired = resource->previousAcquired; + resource->nextAcquired = 0; + } + + Resource* previous = resource->previousAcquired; + if (previous) { + previous->nextAcquired = next; + resource->previousAcquired = 0; + } else { + assert(c, c->acquiredResources == resource); + c->acquiredResources = next; + } + + resource->value = 0; + resource->site = 0; + } +} + + } // namespace compiler } // namespace codegen } // namespace avian \ No newline at end of file diff --git a/src/codegen/compiler/resource.h b/src/codegen/compiler/resource.h index 004cbc34cc..1cc35e3445 100644 --- a/src/codegen/compiler/resource.h +++ b/src/codegen/compiler/resource.h @@ -66,6 +66,10 @@ class FrameResource: public Resource { virtual unsigned index(Context*); }; +void acquire(Context* c, Resource* resource, Value* value, Site* site); + +void release(Context* c, Resource* resource, Value* value, Site* site); + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 1e3dcff448..1534356674 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -13,6 +13,7 @@ #include "codegen/compiler/context.h" #include "codegen/compiler/value.h" #include "codegen/compiler/site.h" +#include "codegen/compiler/resource.h" namespace avian { namespace codegen { @@ -97,6 +98,278 @@ Site* constantSite(Context* c, int64_t value) { return constantSite(c, resolved(c, value)); } + + +class AddressSite: public Site { + public: + AddressSite(Promise* address): address(address) { } + + virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { + if (address->resolved()) { + return vm::snprintf + (buffer, bufferSize, "address %" LLD, address->value()); + } else { + return vm::snprintf(buffer, bufferSize, "address unresolved"); + } + } + + virtual unsigned copyCost(Context*, Site* s) { + return (s == this ? 0 : AddressCopyCost); + } + + virtual bool match(Context*, const SiteMask& mask) { + return mask.typeMask & (1 << lir::AddressOperand); + } + + virtual bool loneMatch(Context*, const SiteMask&) { + return false; + } + + virtual bool matchNextWord(Context* c, Site*, unsigned) { + abort(c); + } + + virtual lir::OperandType type(Context*) { + return lir::AddressOperand; + } + + virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, + lir::Operand* result) + { + assert(c, high == this); + + new (result) lir::Address(address); + } + + virtual Site* copy(Context* c) { + return addressSite(c, address); + } + + virtual Site* copyLow(Context* c) { + abort(c); + } + + virtual Site* copyHigh(Context* c) { + abort(c); + } + + virtual Site* makeNextWord(Context* c, unsigned) { + abort(c); + } + + virtual SiteMask mask(Context*) { + return SiteMask(1 << lir::AddressOperand, 0, NoFrameIndex); + } + + virtual SiteMask nextWordMask(Context* c, unsigned) { + abort(c); + } + + Promise* address; +}; + +Site* addressSite(Context* c, Promise* address) { + return new(c->zone) AddressSite(address); +} + + +RegisterSite::RegisterSite(uint32_t mask, int number): + mask_(mask), number(number) +{ } + +unsigned RegisterSite::toString(Context*, char* buffer, unsigned bufferSize) { + if (number != lir::NoRegister) { + return vm::snprintf(buffer, bufferSize, "%p register %d", this, number); + } else { + return vm::snprintf(buffer, bufferSize, + "%p register unacquired (mask %d)", this, mask_); + } +} + +unsigned RegisterSite::copyCost(Context* c, Site* s) { + assert(c, number != lir::NoRegister); + + if (s and + (this == s or + (s->type(c) == lir::RegisterOperand + and (static_cast(s)->mask_ & (1 << number))))) + { + return 0; + } else { + return RegisterCopyCost; + } +} + +bool RegisterSite::match(Context* c UNUSED, const SiteMask& mask) { + assert(c, number != lir::NoRegister); + + if ((mask.typeMask & (1 << lir::RegisterOperand))) { + return ((static_cast(1) << number) & mask.registerMask); + } else { + return false; + } +} + +bool RegisterSite::loneMatch(Context* c UNUSED, const SiteMask& mask) { + assert(c, number != lir::NoRegister); + + if ((mask.typeMask & (1 << lir::RegisterOperand))) { + return ((static_cast(1) << number) == mask.registerMask); + } else { + return false; + } +} + +bool RegisterSite::matchNextWord(Context* c, Site* s, unsigned) { + assert(c, number != lir::NoRegister); + + if (s->type(c) != lir::RegisterOperand) { + return false; + } + + RegisterSite* rs = static_cast(s); + unsigned size = rs->registerSize(c); + if (size > vm::TargetBytesPerWord) { + assert(c, number != lir::NoRegister); + return number == rs->number; + } else { + uint32_t mask = c->regFile->generalRegisters.mask; + return ((1 << number) & mask) and ((1 << rs->number) & mask); + } +} + +void RegisterSite::acquire(Context* c, Value* v) { + Target target; + if (number != lir::NoRegister) { + target = Target(number, lir::RegisterOperand, 0); + } else { + target = pickRegisterTarget(c, v, mask_); + expect(c, target.cost < Target::Impossible); + } + + RegisterResource* resource = c->registerResources + target.index; + compiler::acquire(c, resource, v, this); + + number = target.index; +} + +void RegisterSite::release(Context* c, Value* v) { + assert(c, number != lir::NoRegister); + + compiler::release(c, c->registerResources + number, v, this); +} + +void RegisterSite::freeze(Context* c, Value* v) { + assert(c, number != lir::NoRegister); + + c->registerResources[number].freeze(c, v); +} + +void RegisterSite::thaw(Context* c, Value* v) { + assert(c, number != lir::NoRegister); + + c->registerResources[number].thaw(c, v); +} + +bool RegisterSite::frozen(Context* c UNUSED) { + assert(c, number != lir::NoRegister); + + return c->registerResources[number].freezeCount != 0; +} + +lir::OperandType RegisterSite::type(Context*) { + return lir::RegisterOperand; +} + +void RegisterSite::asAssemblerOperand(Context* c UNUSED, Site* high, + lir::Operand* result) +{ + assert(c, number != lir::NoRegister); + + int highNumber; + if (high != this) { + highNumber = static_cast(high)->number; + assert(c, highNumber != lir::NoRegister); + } else { + highNumber = lir::NoRegister; + } + + new (result) lir::Register(number, highNumber); +} + +Site* RegisterSite::copy(Context* c) { + uint32_t mask; + + if (number != lir::NoRegister) { + mask = 1 << number; + } else { + mask = mask_; + } + + return freeRegisterSite(c, mask); +} + +Site* RegisterSite::copyLow(Context* c) { + abort(c); +} + +Site* RegisterSite::copyHigh(Context* c) { + abort(c); +} + +Site* RegisterSite::makeNextWord(Context* c, unsigned) { + assert(c, number != lir::NoRegister); + assert(c, ((1 << number) & c->regFile->generalRegisters.mask)); + + return freeRegisterSite(c, c->regFile->generalRegisters.mask); +} + +SiteMask RegisterSite::mask(Context* c UNUSED) { + return SiteMask(1 << lir::RegisterOperand, mask_, NoFrameIndex); +} + +SiteMask RegisterSite::nextWordMask(Context* c, unsigned) { + assert(c, number != lir::NoRegister); + + if (registerSize(c) > vm::TargetBytesPerWord) { + return SiteMask + (1 << lir::RegisterOperand, number, NoFrameIndex); + } else { + return SiteMask + (1 << lir::RegisterOperand, c->regFile->generalRegisters.mask, NoFrameIndex); + } +} + +unsigned RegisterSite::registerSize(Context* c) { + assert(c, number != lir::NoRegister); + + if ((1 << number) & c->regFile->floatRegisters.mask) { + return c->arch->floatRegisterSize(); + } else { + return vm::TargetBytesPerWord; + } +} + +unsigned RegisterSite::registerMask(Context* c UNUSED) { + assert(c, number != lir::NoRegister); + + return 1 << number; +} + + + +Site* registerSite(Context* c, int number) { + assert(c, number >= 0); + assert(c, (1 << number) & (c->regFile->generalRegisters.mask + | c->regFile->floatRegisters.mask)); + + return new(c->zone) RegisterSite(1 << number, number); +} + +Site* freeRegisterSite(Context* c, uint32_t mask) { + return new(c->zone) RegisterSite(mask, lir::NoRegister); +} + } // namespace compiler } // namespace codegen } // namespace avian \ No newline at end of file diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index aa66243b70..0d32b263a2 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -11,6 +11,9 @@ #ifndef AVIAN_CODEGEN_COMPILER_SITE_H #define AVIAN_CODEGEN_COMPILER_SITE_H +#include "codegen/compiler/value.h" +#include "codegen/compiler/context.h" + namespace avian { namespace codegen { namespace compiler { @@ -183,6 +186,60 @@ class ConstantSite: public Site { Promise* value; }; +Site* addressSite(Context* c, Promise* address); + +class RegisterSite: public Site { + public: + RegisterSite(uint32_t mask, int number); + + virtual unsigned toString(Context*, char* buffer, unsigned bufferSize); + + virtual unsigned copyCost(Context* c, Site* s); + + virtual bool match(Context* c UNUSED, const SiteMask& mask); + + virtual bool loneMatch(Context* c UNUSED, const SiteMask& mask); + + virtual bool matchNextWord(Context* c, Site* s, unsigned); + + virtual void acquire(Context* c, Value* v); + + virtual void release(Context* c, Value* v); + + virtual void freeze(Context* c, Value* v); + + virtual void thaw(Context* c, Value* v); + + virtual bool frozen(Context* c UNUSED); + + virtual lir::OperandType type(Context*); + + virtual void asAssemblerOperand(Context* c UNUSED, Site* high, + lir::Operand* result); + + virtual Site* copy(Context* c); + + virtual Site* copyLow(Context* c); + + virtual Site* copyHigh(Context* c); + + virtual Site* makeNextWord(Context* c, unsigned); + + virtual SiteMask mask(Context* c UNUSED); + + virtual SiteMask nextWordMask(Context* c, unsigned); + + virtual unsigned registerSize(Context* c); + + virtual unsigned registerMask(Context* c UNUSED); + + uint32_t mask_; + int number; +}; + +Site* registerSite(Context* c, int number); +Site* freeRegisterSite(Context* c, uint32_t mask); + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/value.cpp b/src/codegen/compiler/value.cpp new file mode 100644 index 0000000000..a8f88acbca --- /dev/null +++ b/src/codegen/compiler/value.cpp @@ -0,0 +1,43 @@ +/* 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 "target.h" + +#include "codegen/compiler/regalloc.h" +#include "codegen/compiler/site.h" + +namespace avian { +namespace codegen { +namespace compiler { + +Value::Value(Site* site, Site* target, lir::ValueType type): + reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this), + nextWord(this), home(NoFrameIndex), type(type), wordIndex(0) +{ } + +bool Value::findSite(Site* site) { + for (Site* s = this->sites; s; s = s->next) { + if (s == site) return true; + } + return false; +} + +bool Value::isBuddyOf(Value* b) { + Value* a = this; + if (a == b) return true; + for (Value* p = a->buddy; p != a; p = p->buddy) { + if (p == b) return true; + } + return false; +} + +} // namespace regalloc +} // namespace codegen +} // namespace avian diff --git a/src/codegen/compiler/value.h b/src/codegen/compiler/value.h index a2e8040db6..f913d89363 100644 --- a/src/codegen/compiler/value.h +++ b/src/codegen/compiler/value.h @@ -13,6 +13,8 @@ #include "codegen/lir.h" +#include "codegen/compiler.h" + namespace avian { namespace codegen { namespace compiler { @@ -25,11 +27,6 @@ const int NoFrameIndex = -1; class Value: public Compiler::Operand { public: - Value(Site* site, Site* target, lir::ValueType type): - reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this), - nextWord(this), home(NoFrameIndex), type(type), wordIndex(0) - { } - Read* reads; Read* lastRead; Site* sites; @@ -40,6 +37,12 @@ class Value: public Compiler::Operand { int16_t home; lir::ValueType type; uint8_t wordIndex; + + Value(Site* site, Site* target, lir::ValueType type); + + bool findSite(Site* site); + + bool isBuddyOf(Value* b); }; } // namespace compiler diff --git a/src/codegen/regalloc.cpp b/src/codegen/regalloc.cpp deleted file mode 100644 index bc8abf926b..0000000000 --- a/src/codegen/regalloc.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* 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 "codegen/regalloc.h" - -namespace avian { -namespace codegen { -namespace regalloc { - -RegisterAllocator::RegisterAllocator(Aborter* a, const RegisterFile* registerFile): - a(a), - registerFile(registerFile) -{ } - -} // namespace regalloc -} // namespace codegen -} // namespace avian \ No newline at end of file diff --git a/src/codegen/regalloc.h b/src/codegen/regalloc.h deleted file mode 100644 index 83fbd878f3..0000000000 --- a/src/codegen/regalloc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* 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_REGALLOC_H -#define AVIAN_CODEGEN_REGALLOC_H - -#include "common.h" - -#include "codegen/registers.h" - -class Aborter; - -namespace avian { -namespace codegen { -namespace regalloc { - -class RegisterAllocator { -public: - Aborter* a; - const RegisterFile* registerFile; - - RegisterAllocator(Aborter* a, const RegisterFile* registerFile); - -}; - -} // namespace regalloc -} // namespace codegen -} // namespace avian - -#endif // AVIAN_CODEGEN_REGALLOC_H \ No newline at end of file From 6d265374ec9338fad7db5677e920cb3e736e5f36 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 18:18:51 -0700 Subject: [PATCH 08/23] move Reads out of compile.cpp --- makefile | 1 + src/codegen/compiler.cpp | 508 +-------------------------------- src/codegen/compiler/context.h | 27 +- src/codegen/compiler/read.cpp | 183 ++++++++++++ src/codegen/compiler/read.h | 73 +++++ src/codegen/compiler/site.cpp | 253 +++++++++++++++- src/codegen/compiler/site.h | 60 ++++ 7 files changed, 609 insertions(+), 496 deletions(-) create mode 100644 src/codegen/compiler/read.cpp diff --git a/makefile b/makefile index 9f57682239..f094576f32 100755 --- a/makefile +++ b/makefile @@ -958,6 +958,7 @@ ifeq ($(process),compile) $(src)/codegen/compiler/site.cpp \ $(src)/codegen/compiler/regalloc.cpp \ $(src)/codegen/compiler/value.cpp \ + $(src)/codegen/compiler/read.cpp \ $(src)/codegen/registers.cpp \ $(src)/codegen/targets.cpp diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 7b63548c42..5e7a06b927 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -45,11 +45,6 @@ const unsigned StealRegisterReserveCount = 2; const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4); class Stack; -class Site; -class ConstantSite; -class AddressSite; -class RegisterSite; -class MemorySite; class Event; class PushEvent; class Read; @@ -73,14 +68,6 @@ apply(Context* c, lir::TernaryOperation op, unsigned s2Size, Site* s2Low, Site* s2High, unsigned s3Size, Site* s3Low, Site* s3High); -class Cell { - public: - Cell(Cell* next, void* value): next(next), value(value) { } - - Cell* next; - void* value; -}; - class Local { public: Value* value; @@ -106,7 +93,7 @@ class ForkElement { class ForkState: public Compiler::State { public: - ForkState(Stack* stack, Local* locals, Cell* saved, Event* predecessor, + ForkState(Stack* stack, Local* locals, Cell* saved, Event* predecessor, unsigned logicalIp): stack(stack), locals(locals), @@ -118,7 +105,7 @@ class ForkState: public Compiler::State { Stack* stack; Local* locals; - Cell* saved; + Cell* saved; Event* predecessor; unsigned logicalIp; unsigned readCount; @@ -157,23 +144,6 @@ class ConstantPoolNode { ConstantPoolNode* next; }; -int -intersectFrameIndexes(int a, int b) -{ - if (a == NoFrameIndex or b == NoFrameIndex) return NoFrameIndex; - if (a == AnyFrameIndex) return b; - if (b == AnyFrameIndex) return a; - if (a == b) return a; - return NoFrameIndex; -} - -SiteMask -intersect(const SiteMask& a, const SiteMask& b) -{ - return SiteMask(a.typeMask & b.typeMask, a.registerMask & b.registerMask, - intersectFrameIndexes(a.frameIndex, b.frameIndex)); -} - class PoolPromise: public Promise { public: PoolPromise(Context* c, int key): c(c), key(key) { } @@ -254,29 +224,11 @@ class IpPromise: public Promise { int logicalIp; }; -unsigned -count(Cell* c) -{ - unsigned count = 0; - while (c) { - ++ count; - c = c->next; - } - return count; -} - -Cell* -cons(Context* c, void* value, Cell* next) -{ - return new (c->zone) Cell(next, value); -} - -Cell* -reverseDestroy(Cell* cell) -{ - Cell* previous = 0; +template +Cell* reverseDestroy(Cell* cell) { + Cell* previous = 0; while (cell) { - Cell* next = cell->next; + Cell* next = cell->next; cell->next = previous; previous = cell; cell = next; @@ -377,7 +329,7 @@ class Event { Snapshot* snapshots; Link* predecessors; Link* successors; - Cell* visitLinks; + Cell* visitLinks; Block* block; LogicalInstruction* logicalInstruction; unsigned readCount; @@ -759,254 +711,6 @@ Promise* resolved(Context* c, int64_t value) { return new(c->zone) ResolvedPromise(value); } -MemorySite* -memorySite(Context* c, int base, int offset = 0, int index = lir::NoRegister, - unsigned scale = 1); - -class MemorySite: public Site { - public: - MemorySite(int base, int offset, int index, unsigned scale): - acquired(false), base(base), offset(offset), index(index), scale(scale) - { } - - virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) { - if (acquired) { - return vm::snprintf(buffer, bufferSize, "memory %d 0x%x %d %d", - base, offset, index, scale); - } else { - return vm::snprintf(buffer, bufferSize, "memory unacquired"); - } - } - - virtual unsigned copyCost(Context* c, Site* s) { - assert(c, acquired); - - if (s and - (this == s or - (s->type(c) == lir::MemoryOperand - and static_cast(s)->base == base - and static_cast(s)->offset == offset - and static_cast(s)->index == index - and static_cast(s)->scale == scale))) - { - return 0; - } else { - return MemoryCopyCost; - } - } - - bool conflicts(const SiteMask& mask) { - return (mask.typeMask & (1 << lir::RegisterOperand)) != 0 - and (((1 << base) & mask.registerMask) == 0 - or (index != lir::NoRegister - and ((1 << index) & mask.registerMask) == 0)); - } - - virtual bool match(Context* c, const SiteMask& mask) { - assert(c, acquired); - - if (mask.typeMask & (1 << lir::MemoryOperand)) { - if (mask.frameIndex >= 0) { - if (base == c->arch->stack()) { - assert(c, index == lir::NoRegister); - return static_cast(frameIndexToOffset(c, mask.frameIndex)) - == offset; - } else { - return false; - } - } else { - return true; - } - } else { - return false; - } - } - - virtual bool loneMatch(Context* c, const SiteMask& mask) { - assert(c, acquired); - - if (mask.typeMask & (1 << lir::MemoryOperand)) { - if (base == c->arch->stack()) { - assert(c, index == lir::NoRegister); - - if (mask.frameIndex == AnyFrameIndex) { - return false; - } else { - return true; - } - } - } - return false; - } - - virtual bool matchNextWord(Context* c, Site* s, unsigned index) { - if (s->type(c) == lir::MemoryOperand) { - MemorySite* ms = static_cast(s); - return ms->base == this->base - and ((index == 1 and ms->offset == static_cast - (this->offset + TargetBytesPerWord)) - or (index == 0 and this->offset == static_cast - (ms->offset + TargetBytesPerWord))) - and ms->index == this->index - and ms->scale == this->scale; - } else { - return false; - } - } - - virtual void acquire(Context* c, Value* v) { - c->registerResources[base].increment(c); - if (index != lir::NoRegister) { - c->registerResources[index].increment(c); - } - - if (base == c->arch->stack()) { - assert(c, index == lir::NoRegister); - assert - (c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); - - compiler::acquire - (c, c->frameResources + offsetToFrameIndex(c, offset), v, this); - } - - acquired = true; - } - - virtual void release(Context* c, Value* v) { - if (base == c->arch->stack()) { - assert(c, index == lir::NoRegister); - assert - (c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); - - compiler::release - (c, c->frameResources + offsetToFrameIndex(c, offset), v, this); - } - - c->registerResources[base].decrement(c); - if (index != lir::NoRegister) { - c->registerResources[index].decrement(c); - } - - acquired = false; - } - - virtual void freeze(Context* c, Value* v) { - if (base == c->arch->stack()) { - c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v); - } else { - c->registerResources[base].increment(c); - if (index != lir::NoRegister) { - c->registerResources[index].increment(c); - } - } - } - - virtual void thaw(Context* c, Value* v) { - if (base == c->arch->stack()) { - c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v); - } else { - c->registerResources[base].decrement(c); - if (index != lir::NoRegister) { - c->registerResources[index].decrement(c); - } - } - } - - virtual bool frozen(Context* c) { - return base == c->arch->stack() - and c->frameResources[offsetToFrameIndex(c, offset)].freezeCount != 0; - } - - virtual lir::OperandType type(Context*) { - return lir::MemoryOperand; - } - - virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, - lir::Operand* result) - { - // todo: endianness? - assert(c, high == this - or (static_cast(high)->base == base - and static_cast(high)->offset - == static_cast(offset + TargetBytesPerWord) - and static_cast(high)->index == index - and static_cast(high)->scale == scale)); - - assert(c, acquired); - - new (result) lir::Memory(base, offset, index, scale); - } - - virtual Site* copy(Context* c) { - return memorySite(c, base, offset, index, scale); - } - - Site* copyHalf(Context* c, bool add) { - if (add) { - return memorySite(c, base, offset + TargetBytesPerWord, index, scale); - } else { - return copy(c); - } - } - - virtual Site* copyLow(Context* c) { - return copyHalf(c, c->arch->bigEndian()); - } - - virtual Site* copyHigh(Context* c) { - return copyHalf(c, not c->arch->bigEndian()); - } - - virtual Site* makeNextWord(Context* c, unsigned index) { - return memorySite - (c, base, offset + ((index == 1) xor c->arch->bigEndian() - ? TargetBytesPerWord : -TargetBytesPerWord), - this->index, scale); - } - - virtual SiteMask mask(Context* c) { - return SiteMask(1 << lir::MemoryOperand, 0, (base == c->arch->stack()) - ? static_cast(offsetToFrameIndex(c, offset)) - : NoFrameIndex); - } - - virtual SiteMask nextWordMask(Context* c, unsigned index) { - int frameIndex; - if (base == c->arch->stack()) { - assert(c, this->index == lir::NoRegister); - frameIndex = static_cast(offsetToFrameIndex(c, offset)) - + ((index == 1) xor c->arch->bigEndian() ? 1 : -1); - } else { - frameIndex = NoFrameIndex; - } - return SiteMask(1 << lir::MemoryOperand, 0, frameIndex); - } - - virtual bool isVolatile(Context* c) { - return base != c->arch->stack(); - } - - bool acquired; - int base; - int offset; - int index; - unsigned scale; -}; - -MemorySite* -memorySite(Context* c, int base, int offset, int index, unsigned scale) -{ - return new(c->zone) MemorySite(base, offset, index, scale); -} - -MemorySite* -frameSite(Context* c, int frameIndex) -{ - assert(c, frameIndex >= 0); - return memorySite - (c, c->arch->stack(), frameIndexToOffset(c, frameIndex), lir::NoRegister, 0); -} - void move(Context* c, Value* value, Site* src, Site* dst); @@ -1073,45 +777,6 @@ pickTargetSite(Context* c, Read* read, bool intersectRead = false, } } -class SingleRead: public Read { - public: - SingleRead(const SiteMask& mask, Value* successor): - next_(0), mask(mask), high_(0), successor_(successor) - { } - - virtual bool intersect(SiteMask* mask, unsigned) { - *mask = compiler::intersect(*mask, this->mask); - - return true; - } - - virtual Value* high(Context*) { - return high_; - } - - virtual Value* successor() { - return successor_; - } - - virtual bool valid() { - return true; - } - - virtual void append(Context* c UNUSED, Read* r) { - assert(c, next_ == 0); - next_ = r; - } - - virtual Read* next(Context*) { - return next_; - } - - Read* next_; - SiteMask mask; - Value* high_; - Value* successor_; -}; - SingleRead* read(Context* c, const SiteMask& mask, Value* successor = 0) { @@ -1137,7 +802,7 @@ pickSourceSite(Context* c, Read* read, Site* target = 0, SiteMask mask; if (extraMask) { - mask = intersect(mask, *extraMask); + mask = mask.intersectionWith(*extraMask); } if (intersectRead) { @@ -1368,104 +1033,6 @@ fixedRegisterMask(int number) return SiteMask(1 << lir::RegisterOperand, 1 << number, NoFrameIndex); } -class MultiRead: public Read { - public: - MultiRead(): - reads(0), lastRead(0), firstTarget(0), lastTarget(0), visited(false) - { } - - virtual bool intersect(SiteMask* mask, unsigned depth) { - if (depth > 0) { - // short-circuit recursion to avoid poor performance in - // deeply-nested branches - return reads != 0; - } - - bool result = false; - if (not visited) { - visited = true; - for (Cell** cell = &reads; *cell;) { - Read* r = static_cast((*cell)->value); - bool valid = r->intersect(mask, depth + 1); - if (valid) { - result = true; - cell = &((*cell)->next); - } else { - *cell = (*cell)->next; - } - } - visited = false; - } - return result; - } - - virtual Value* successor() { - return 0; - } - - virtual bool valid() { - bool result = false; - if (not visited) { - visited = true; - for (Cell** cell = &reads; *cell;) { - Read* r = static_cast((*cell)->value); - if (r->valid()) { - result = true; - cell = &((*cell)->next); - } else { - *cell = (*cell)->next; - } - } - visited = false; - } - return result; - } - - virtual void append(Context* c, Read* r) { - Cell* cell = cons(c, r, 0); - if (lastRead == 0) { - reads = cell; - } else { - lastRead->next = cell; - } - lastRead = cell; - -// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this); - - lastTarget->value = r; - } - - virtual Read* next(Context* c) { - abort(c); - } - - void allocateTarget(Context* c) { - Cell* cell = cons(c, 0, 0); - -// fprintf(stderr, "allocate target for %p: %p\n", this, cell); - - if (lastTarget) { - lastTarget->next = cell; - } else { - firstTarget = cell; - } - lastTarget = cell; - } - - Read* nextTarget() { - // fprintf(stderr, "next target for %p: %p\n", this, firstTarget); - - Read* r = static_cast(firstTarget->value); - firstTarget = firstTarget->next; - return r; - } - - Cell* reads; - Cell* lastRead; - Cell* firstTarget; - Cell* lastTarget; - bool visited; -}; MultiRead* multiRead(Context* c) @@ -1473,49 +1040,6 @@ multiRead(Context* c) return new(c->zone) MultiRead; } -class StubRead: public Read { - public: - StubRead(): - next_(0), read(0), visited(false), valid_(true) - { } - - virtual bool intersect(SiteMask* mask, unsigned depth) { - if (not visited) { - visited = true; - if (read) { - bool valid = read->intersect(mask, depth); - if (not valid) { - read = 0; - } - } - visited = false; - } - return valid_; - } - - virtual Value* successor() { - return 0; - } - - virtual bool valid() { - return valid_; - } - - virtual void append(Context* c UNUSED, Read* r) { - assert(c, next_ == 0); - next_ = r; - } - - virtual Read* next(Context*) { - return next_; - } - - Read* next_; - Read* read; - bool visited; - bool valid_; -}; - StubRead* stubRead(Context* c) { @@ -2385,7 +1909,7 @@ pickMatchOrMove(Context* c, Read* r, Site* nextWord, unsigned index, } return pickSiteOrMove - (c, r->value, intersect(mask, nextWord->nextWordMask(c, index)), + (c, r->value, mask.intersectionWith(nextWord->nextWordMask(c, index)), true, true); } @@ -4257,9 +3781,8 @@ captureBranchSnapshots(Context* c, Event* e) e->snapshots = makeSnapshots(c, el.value, e->snapshots); } - for (Cell* sv = e->successors->forkState->saved; sv; sv = sv->next) { - e->snapshots = makeSnapshots - (c, static_cast(sv->value), e->snapshots); + for (Cell* sv = e->successors->forkState->saved; sv; sv = sv->next) { + e->snapshots = makeSnapshots(c, sv->value, e->snapshots); } if (DebugControl) { @@ -4577,9 +4100,8 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset) } if (e->visitLinks) { - for (Cell* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) - { - visit(c, static_cast(cell->value)); + for (Cell* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) { + visit(c, cell->value); } e->visitLinks = 0; } @@ -4666,8 +4188,8 @@ saveState(Context* c) addForkElement(c, e.value, state, count++); } - for (Cell* sv = c->saved; sv; sv = sv->next) { - addForkElement(c, static_cast(sv->value), state, count++); + for (Cell* sv = c->saved; sv; sv = sv->next) { + addForkElement(c, sv->value, state, count++); } state->readCount = count; diff --git a/src/codegen/compiler/context.h b/src/codegen/compiler/context.h index 2605aaf64d..8508086978 100644 --- a/src/codegen/compiler/context.h +++ b/src/codegen/compiler/context.h @@ -22,7 +22,6 @@ namespace compiler { class Stack; class Local; -class Cell; class Event; class LogicalInstruction; @@ -36,6 +35,25 @@ class ForkState; class MySubroutine; class Block; +template +class Cell { + public: + Cell(Cell* next, T* value): next(next), value(value) { } + + Cell* next; + T* value; +}; + +template +unsigned count(Cell* c) { + unsigned count = 0; + while (c) { + ++ count; + c = c->next; + } + return count; +} + class Context { public: Context(vm::System* system, Assembler* assembler, vm::Zone* zone, @@ -48,7 +66,7 @@ class Context { Compiler::Client* client; Stack* stack; Local* locals; - Cell* saved; + Cell* saved; Event* predecessor; LogicalInstruction** logicalCode; const RegisterFile* regFile; @@ -78,6 +96,11 @@ inline Aborter* getAborter(Context* c) { return c->system; } +template +Cell* cons(Context* c, T* value, Cell* next) { + return new (c->zone) Cell(next, value); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/read.cpp b/src/codegen/compiler/read.cpp new file mode 100644 index 0000000000..08308cfa52 --- /dev/null +++ b/src/codegen/compiler/read.cpp @@ -0,0 +1,183 @@ +/* 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 "target.h" + +#include "codegen/compiler/context.h" +#include "codegen/compiler/value.h" +#include "codegen/compiler/site.h" +#include "codegen/compiler/resource.h" +#include "codegen/compiler/read.h" + +namespace avian { +namespace codegen { +namespace compiler { + + +SingleRead::SingleRead(const SiteMask& mask, Value* successor): + next_(0), mask(mask), high_(0), successor_(successor) +{ } + +bool SingleRead::intersect(SiteMask* mask, unsigned) { + *mask = mask->intersectionWith(this->mask); + + return true; +} + +Value* SingleRead::high(Context*) { + return high_; +} + +Value* SingleRead::successor() { + return successor_; +} + +bool SingleRead::valid() { + return true; +} + +void SingleRead::append(Context* c UNUSED, Read* r) { + assert(c, next_ == 0); + next_ = r; +} + +Read* SingleRead::next(Context*) { + return next_; +} + +MultiRead::MultiRead(): + reads(0), lastRead(0), firstTarget(0), lastTarget(0), visited(false) +{ } + +bool MultiRead::intersect(SiteMask* mask, unsigned depth) { + if (depth > 0) { + // short-circuit recursion to avoid poor performance in + // deeply-nested branches + return reads != 0; + } + + bool result = false; + if (not visited) { + visited = true; + for (Cell** cell = &reads; *cell;) { + Read* r = (*cell)->value; + bool valid = r->intersect(mask, depth + 1); + if (valid) { + result = true; + cell = &((*cell)->next); + } else { + *cell = (*cell)->next; + } + } + visited = false; + } + return result; +} + +Value* MultiRead::successor() { + return 0; +} + +bool MultiRead::valid() { + bool result = false; + if (not visited) { + visited = true; + for (Cell** cell = &reads; *cell;) { + Read* r = (*cell)->value; + if (r->valid()) { + result = true; + cell = &((*cell)->next); + } else { + *cell = (*cell)->next; + } + } + visited = false; + } + return result; +} + +void MultiRead::append(Context* c, Read* r) { + Cell* cell = cons(c, r, 0); + if (lastRead == 0) { + reads = cell; + } else { + lastRead->next = cell; + } + lastRead = cell; + +// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this); + + lastTarget->value = r; +} + +Read* MultiRead::next(Context* c) { + abort(c); +} + +void MultiRead::allocateTarget(Context* c) { + Cell* cell = cons(c, 0, 0); + +// fprintf(stderr, "allocate target for %p: %p\n", this, cell); + + if (lastTarget) { + lastTarget->next = cell; + } else { + firstTarget = cell; + } + lastTarget = cell; +} + +Read* MultiRead::nextTarget() { + // fprintf(stderr, "next target for %p: %p\n", this, firstTarget); + + Read* r = firstTarget->value; + firstTarget = firstTarget->next; + return r; +} + + +StubRead::StubRead(): + next_(0), read(0), visited(false), valid_(true) +{ } + +bool StubRead::intersect(SiteMask* mask, unsigned depth) { + if (not visited) { + visited = true; + if (read) { + bool valid = read->intersect(mask, depth); + if (not valid) { + read = 0; + } + } + visited = false; + } + return valid_; +} + +Value* StubRead::successor() { + return 0; +} + +bool StubRead::valid() { + return valid_; +} + +void StubRead::append(Context* c UNUSED, Read* r) { + assert(c, next_ == 0); + next_ = r; +} + +Read* StubRead::next(Context*) { + return next_; +} + +} // namespace compiler +} // namespace codegen +} // namespace avian diff --git a/src/codegen/compiler/read.h b/src/codegen/compiler/read.h index a0c1d5a763..4e942ba75a 100644 --- a/src/codegen/compiler/read.h +++ b/src/codegen/compiler/read.h @@ -15,6 +15,11 @@ namespace avian { namespace codegen { namespace compiler { +class Context; +class SiteMask; +class Value; +class Event; + class Read { public: Read(): @@ -38,6 +43,74 @@ class Read { Read* eventNext; }; +class SingleRead: public Read { + public: + SingleRead(const SiteMask& mask, Value* successor); + + virtual bool intersect(SiteMask* mask, unsigned); + + virtual Value* high(Context*); + + virtual Value* successor(); + + virtual bool valid(); + + virtual void append(Context* c UNUSED, Read* r); + + virtual Read* next(Context*); + + Read* next_; + SiteMask mask; + Value* high_; + Value* successor_; +}; + + +class MultiRead: public Read { + public: + MultiRead(); + + virtual bool intersect(SiteMask* mask, unsigned depth); + + virtual Value* successor(); + + virtual bool valid(); + + virtual void append(Context* c, Read* r); + + virtual Read* next(Context* c); + + void allocateTarget(Context* c); + + Read* nextTarget(); + + Cell* reads; + Cell* lastRead; + Cell* firstTarget; + Cell* lastTarget; + bool visited; +}; + +class StubRead: public Read { + public: + StubRead(); + + virtual bool intersect(SiteMask* mask, unsigned depth); + + virtual Value* successor(); + + virtual bool valid(); + + virtual void append(Context* c UNUSED, Read* r); + + virtual Read* next(Context*); + + Read* next_; + Read* read; + bool visited; + bool valid_; +}; + } // namespace compiler } // namespace codegen diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 1534356674..43eb211112 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -20,8 +20,27 @@ namespace codegen { namespace compiler { +unsigned frameIndexToOffset(Context* c, unsigned frameIndex); + +unsigned offsetToFrameIndex(Context* c, unsigned offset); + ResolvedPromise* resolved(Context* c, int64_t value); + +int intersectFrameIndexes(int a, int b) { + if (a == NoFrameIndex or b == NoFrameIndex) return NoFrameIndex; + if (a == AnyFrameIndex) return b; + if (b == AnyFrameIndex) return a; + if (a == b) return a; + return NoFrameIndex; +} + + +SiteMask SiteMask::intersectionWith(const SiteMask& b) { + return SiteMask(typeMask & b.typeMask, registerMask & b.registerMask, + intersectFrameIndexes(frameIndex, b.frameIndex)); +} + SiteIterator::SiteIterator(Context* c, Value* v, bool includeBuddies, bool includeNextWord): c(c), @@ -370,6 +389,238 @@ Site* freeRegisterSite(Context* c, uint32_t mask) { return new(c->zone) RegisterSite(mask, lir::NoRegister); } +MemorySite::MemorySite(int base, int offset, int index, unsigned scale): + acquired(false), base(base), offset(offset), index(index), scale(scale) +{ } + +unsigned MemorySite::toString(Context*, char* buffer, unsigned bufferSize) { + if (acquired) { + return vm::snprintf(buffer, bufferSize, "memory %d 0x%x %d %d", + base, offset, index, scale); + } else { + return vm::snprintf(buffer, bufferSize, "memory unacquired"); + } +} + +unsigned MemorySite::copyCost(Context* c, Site* s) { + assert(c, acquired); + + if (s and + (this == s or + (s->type(c) == lir::MemoryOperand + and static_cast(s)->base == base + and static_cast(s)->offset == offset + and static_cast(s)->index == index + and static_cast(s)->scale == scale))) + { + return 0; + } else { + return MemoryCopyCost; + } +} + +bool MemorySite::conflicts(const SiteMask& mask) { + return (mask.typeMask & (1 << lir::RegisterOperand)) != 0 + and (((1 << base) & mask.registerMask) == 0 + or (index != lir::NoRegister + and ((1 << index) & mask.registerMask) == 0)); +} + +bool MemorySite::match(Context* c, const SiteMask& mask) { + assert(c, acquired); + + if (mask.typeMask & (1 << lir::MemoryOperand)) { + if (mask.frameIndex >= 0) { + if (base == c->arch->stack()) { + assert(c, index == lir::NoRegister); + return static_cast(frameIndexToOffset(c, mask.frameIndex)) + == offset; + } else { + return false; + } + } else { + return true; + } + } else { + return false; + } +} + +bool MemorySite::loneMatch(Context* c, const SiteMask& mask) { + assert(c, acquired); + + if (mask.typeMask & (1 << lir::MemoryOperand)) { + if (base == c->arch->stack()) { + assert(c, index == lir::NoRegister); + + if (mask.frameIndex == AnyFrameIndex) { + return false; + } else { + return true; + } + } + } + return false; +} + +bool MemorySite::matchNextWord(Context* c, Site* s, unsigned index) { + if (s->type(c) == lir::MemoryOperand) { + MemorySite* ms = static_cast(s); + return ms->base == this->base + and ((index == 1 and ms->offset == static_cast + (this->offset + vm::TargetBytesPerWord)) + or (index == 0 and this->offset == static_cast + (ms->offset + vm::TargetBytesPerWord))) + and ms->index == this->index + and ms->scale == this->scale; + } else { + return false; + } +} + +void MemorySite::acquire(Context* c, Value* v) { + c->registerResources[base].increment(c); + if (index != lir::NoRegister) { + c->registerResources[index].increment(c); + } + + if (base == c->arch->stack()) { + assert(c, index == lir::NoRegister); + assert + (c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); + + compiler::acquire + (c, c->frameResources + offsetToFrameIndex(c, offset), v, this); + } + + acquired = true; +} + +void MemorySite::release(Context* c, Value* v) { + if (base == c->arch->stack()) { + assert(c, index == lir::NoRegister); + assert + (c, not c->frameResources[offsetToFrameIndex(c, offset)].reserved); + + compiler::release + (c, c->frameResources + offsetToFrameIndex(c, offset), v, this); + } + + c->registerResources[base].decrement(c); + if (index != lir::NoRegister) { + c->registerResources[index].decrement(c); + } + + acquired = false; +} + +void MemorySite::freeze(Context* c, Value* v) { + if (base == c->arch->stack()) { + c->frameResources[offsetToFrameIndex(c, offset)].freeze(c, v); + } else { + c->registerResources[base].increment(c); + if (index != lir::NoRegister) { + c->registerResources[index].increment(c); + } + } +} + +void MemorySite::thaw(Context* c, Value* v) { + if (base == c->arch->stack()) { + c->frameResources[offsetToFrameIndex(c, offset)].thaw(c, v); + } else { + c->registerResources[base].decrement(c); + if (index != lir::NoRegister) { + c->registerResources[index].decrement(c); + } + } +} + +bool MemorySite::frozen(Context* c) { + return base == c->arch->stack() + and c->frameResources[offsetToFrameIndex(c, offset)].freezeCount != 0; +} + +lir::OperandType MemorySite::type(Context*) { + return lir::MemoryOperand; +} + +void MemorySite::asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, + lir::Operand* result) +{ + // todo: endianness? + assert(c, high == this + or (static_cast(high)->base == base + and static_cast(high)->offset + == static_cast(offset + vm::TargetBytesPerWord) + and static_cast(high)->index == index + and static_cast(high)->scale == scale)); + + assert(c, acquired); + + new (result) lir::Memory(base, offset, index, scale); +} + +Site* MemorySite::copy(Context* c) { + return memorySite(c, base, offset, index, scale); +} + +Site* MemorySite::copyHalf(Context* c, bool add) { + if (add) { + return memorySite(c, base, offset + vm::TargetBytesPerWord, index, scale); + } else { + return copy(c); + } +} + +Site* MemorySite::copyLow(Context* c) { + return copyHalf(c, c->arch->bigEndian()); +} + +Site* MemorySite::copyHigh(Context* c) { + return copyHalf(c, not c->arch->bigEndian()); +} + +Site* MemorySite::makeNextWord(Context* c, unsigned index) { + return memorySite + (c, base, offset + ((index == 1) xor c->arch->bigEndian() + ? vm::TargetBytesPerWord : -vm::TargetBytesPerWord), + this->index, scale); +} + +SiteMask MemorySite::mask(Context* c) { + return SiteMask(1 << lir::MemoryOperand, 0, (base == c->arch->stack()) + ? static_cast(offsetToFrameIndex(c, offset)) + : NoFrameIndex); +} + +SiteMask MemorySite::nextWordMask(Context* c, unsigned index) { + int frameIndex; + if (base == c->arch->stack()) { + assert(c, this->index == lir::NoRegister); + frameIndex = static_cast(offsetToFrameIndex(c, offset)) + + ((index == 1) xor c->arch->bigEndian() ? 1 : -1); + } else { + frameIndex = NoFrameIndex; + } + return SiteMask(1 << lir::MemoryOperand, 0, frameIndex); +} + +bool MemorySite::isVolatile(Context* c) { + return base != c->arch->stack(); +} + + +MemorySite* memorySite(Context* c, int base, int offset, int index, unsigned scale) { + return new(c->zone) MemorySite(base, offset, index, scale); +} + +MemorySite* frameSite(Context* c, int frameIndex) { + assert(c, frameIndex >= 0); + return memorySite + (c, c->arch->stack(), frameIndexToOffset(c, frameIndex), lir::NoRegister, 0); +} + } // namespace compiler } // namespace codegen -} // namespace avian \ No newline at end of file +} // namespace avian diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index 0d32b263a2..6f5508be91 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -34,6 +34,8 @@ class SiteMask { typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex) { } + SiteMask intersectionWith(const SiteMask& b); + uint8_t typeMask; uint32_t registerMask; int frameIndex; @@ -240,6 +242,64 @@ class RegisterSite: public Site { Site* registerSite(Context* c, int number); Site* freeRegisterSite(Context* c, uint32_t mask); + +class MemorySite: public Site { + public: + MemorySite(int base, int offset, int index, unsigned scale); + + virtual unsigned toString(Context*, char* buffer, unsigned bufferSize); + + virtual unsigned copyCost(Context* c, Site* s); + + bool conflicts(const SiteMask& mask); + + virtual bool match(Context* c, const SiteMask& mask); + + virtual bool loneMatch(Context* c, const SiteMask& mask); + + virtual bool matchNextWord(Context* c, Site* s, unsigned index); + + virtual void acquire(Context* c, Value* v); + + virtual void release(Context* c, Value* v); + + virtual void freeze(Context* c, Value* v); + + virtual void thaw(Context* c, Value* v); + + virtual bool frozen(Context* c); + + virtual lir::OperandType type(Context*); + + virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED, + lir::Operand* result); + + virtual Site* copy(Context* c); + + Site* copyHalf(Context* c, bool add); + + virtual Site* copyLow(Context* c); + + virtual Site* copyHigh(Context* c); + + virtual Site* makeNextWord(Context* c, unsigned index); + + virtual SiteMask mask(Context* c); + + virtual SiteMask nextWordMask(Context* c, unsigned index); + + virtual bool isVolatile(Context* c); + + bool acquired; + int base; + int offset; + int index; + unsigned scale; +}; + +MemorySite* memorySite(Context* c, int base, int offset = 0, int index = lir::NoRegister, unsigned scale = 1); +MemorySite* frameSite(Context* c, int frameIndex); + } // namespace compiler } // namespace codegen } // namespace avian From 0f6e098b6929e1701bcba80a585e73aef7e0bcb6 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 19:33:40 -0700 Subject: [PATCH 09/23] move CallEvent out of compiler.cpp --- makefile | 2 + src/codegen/compiler.cpp | 587 +++---------------------------- src/codegen/compiler/event.cpp | 446 +++++++++++++++++++++++ src/codegen/compiler/event.h | 85 +++++ src/codegen/compiler/promise.cpp | 26 ++ src/codegen/compiler/promise.h | 52 +++ src/codegen/compiler/read.cpp | 8 + src/codegen/compiler/read.h | 2 + src/codegen/compiler/site.cpp | 6 + src/codegen/compiler/site.h | 6 +- src/codegen/compiler/stack.h | 35 ++ src/codegen/compiler/value.cpp | 12 + src/codegen/compiler/value.h | 4 + 13 files changed, 732 insertions(+), 539 deletions(-) create mode 100644 src/codegen/compiler/event.cpp create mode 100644 src/codegen/compiler/event.h create mode 100644 src/codegen/compiler/promise.cpp create mode 100644 src/codegen/compiler/promise.h create mode 100644 src/codegen/compiler/stack.h diff --git a/makefile b/makefile index f094576f32..5e14ad1d7e 100755 --- a/makefile +++ b/makefile @@ -959,6 +959,8 @@ ifeq ($(process),compile) $(src)/codegen/compiler/regalloc.cpp \ $(src)/codegen/compiler/value.cpp \ $(src)/codegen/compiler/read.cpp \ + $(src)/codegen/compiler/event.cpp \ + $(src)/codegen/compiler/promise.cpp \ $(src)/codegen/registers.cpp \ $(src)/codegen/targets.cpp diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 5e7a06b927..ca6ee5ba23 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -21,6 +21,9 @@ #include "codegen/compiler/value.h" #include "codegen/compiler/site.h" #include "codegen/compiler/read.h" +#include "codegen/compiler/event.h" +#include "codegen/compiler/stack.h" +#include "codegen/compiler/promise.h" using namespace vm; @@ -33,8 +36,6 @@ const bool DebugCompile = false; const bool DebugResources = false; const bool DebugFrame = false; const bool DebugControl = false; -const bool DebugReads = false; -const bool DebugSites = false; const bool DebugMoves = false; const bool DebugBuddies = false; @@ -45,7 +46,6 @@ const unsigned StealRegisterReserveCount = 2; const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4); class Stack; -class Event; class PushEvent; class Read; class MultiRead; @@ -73,17 +73,6 @@ class Local { Value* value; }; -class Stack { - public: - Stack(unsigned index, Value* value, Stack* next): - index(index), value(value), next(next) - { } - - unsigned index; - Value* value; - Stack* next; -}; - class ForkElement { public: Value* value; @@ -166,33 +155,6 @@ class PoolPromise: public Promise { int key; }; -class CodePromise: public Promise { - public: - CodePromise(Context* c, CodePromise* next): - c(c), offset(0), next(next) - { } - - CodePromise(Context* c, Promise* offset): - c(c), offset(offset), next(0) - { } - - virtual int64_t value() { - if (resolved()) { - return reinterpret_cast(c->machineCode + offset->value()); - } - - abort(c); - } - - virtual bool resolved() { - return c->machineCode != 0 and offset and offset->resolved(); - } - - Context* c; - Promise* offset; - CodePromise* next; -}; - unsigned machineOffset(Context* c, int logicalIp) { @@ -298,43 +260,6 @@ countSuccessors(Link* link) return c; } -class Event { - public: - Event(Context* c): - next(0), stackBefore(c->stack), localsBefore(c->locals), - stackAfter(0), localsAfter(0), promises(0), reads(0), - junctionSites(0), snapshots(0), predecessors(0), successors(0), - visitLinks(0), block(0), logicalInstruction(c->logicalCode[c->logicalIp]), - readCount(0) - { } - - virtual const char* name() = 0; - - virtual void compile(Context* c) = 0; - - virtual bool isBranch() { return false; } - - virtual bool allExits() { return false; } - - virtual Local* locals() { return localsBefore; } - - Event* next; - Stack* stackBefore; - Local* localsBefore; - Stack* stackAfter; - Local* localsAfter; - CodePromise* promises; - Read* reads; - Site** junctionSites; - Snapshot* snapshots; - Link* predecessors; - Link* successors; - Cell* visitLinks; - Block* block; - LogicalInstruction* logicalInstruction; - unsigned readCount; -}; - unsigned totalFrameSize(Context* c) { @@ -479,20 +404,6 @@ uniqueSite(Context* c, Value* v, Site* s) } } -void -addSite(Context* c, Value* v, Site* s) -{ - if (not v->findSite(s)) { - if (DebugSites) { - char buffer[256]; s->toString(c, buffer, 256); - fprintf(stderr, "add site %s to %p\n", buffer, v); - } - s->acquire(c, v); - s->next = v->sites; - v->sites = s; - } -} - void removeSite(Context* c, Value* v, Site* s) { @@ -598,7 +509,7 @@ deadWord(Context* c, Value* v) if (s->registerSize(c) > TargetBytesPerWord) { it.remove(c); - addSite(c, nextWord, s); + nextWord->addSite(c, s); } } } @@ -631,7 +542,7 @@ deadBuddy(Context* c, Value* v, Read* r UNUSED) Site* s = it.next(); it.remove(c); - addSite(c, next, s); + next->addSite(c, s); } } @@ -777,14 +688,6 @@ pickTargetSite(Context* c, Read* read, bool intersectRead = false, } } -SingleRead* -read(Context* c, const SiteMask& mask, Value* successor = 0) -{ - assert(c, (mask.typeMask != 1 << lir::MemoryOperand) or mask.frameIndex >= 0); - - return new(c->zone) SingleRead(mask, successor); -} - bool acceptMatch(Context* c, Site* s, Read*, const SiteMask& mask) { @@ -919,7 +822,7 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord, src->freeze(c, value); - addSite(c, value, dst); + value->addSite(c, dst); src->thaw(c, value); @@ -934,7 +837,7 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord, Site* tmp = pickTargetSite(c, &tmpRead, true); - addSite(c, value, tmp); + value->addSite(c, tmp); move(c, value, src, tmp); @@ -1027,13 +930,6 @@ generalRegisterOrConstantMask(Context* c) c->regFile->generalRegisters.mask, NoFrameIndex); } -SiteMask -fixedRegisterMask(int number) -{ - return SiteMask(1 << lir::RegisterOperand, 1 << number, NoFrameIndex); -} - - MultiRead* multiRead(Context* c) { @@ -1093,7 +989,7 @@ pickSiteOrGrow(Context* c, Value* v, Site* s, unsigned index) } n = s->makeNextWord(c, index); - addSite(c, v, n); + v->addSite(c, n); return n; } @@ -1260,61 +1156,6 @@ apply(Context* c, lir::TernaryOperation op, OperandInfo(s3Size, s3Type, &s3Union)); } -void -addRead(Context* c, Event* e, Value* v, Read* r) -{ - if (DebugReads) { - fprintf(stderr, "add read %p to %p last %p event %p (%s)\n", - r, v, v->lastRead, e, (e ? e->name() : 0)); - } - - r->value = v; - if (e) { - r->event = e; - r->eventNext = e->reads; - e->reads = r; - ++ e->readCount; - } - - if (v->lastRead) { - // if (DebugReads) { - // fprintf(stderr, "append %p to %p for %p\n", r, v->lastRead, v); - // } - - v->lastRead->append(c, r); - } else { - v->reads = r; - } - v->lastRead = r; -} - -void -addRead(Context* c, Event* e, Value* v, const SiteMask& mask, - Value* successor = 0) -{ - addRead(c, e, v, read(c, mask, successor)); -} - -void -addReads(Context* c, Event* e, Value* v, unsigned size, - const SiteMask& lowMask, Value* lowSuccessor, - const SiteMask& highMask, Value* highSuccessor) -{ - SingleRead* r = read(c, lowMask, lowSuccessor); - addRead(c, e, v, r); - if (size > TargetBytesPerWord) { - r->high_ = v->nextWord; - addRead(c, e, v->nextWord, highMask, highSuccessor); - } -} - -void -addReads(Context* c, Event* e, Value* v, unsigned size, - const SiteMask& lowMask, const SiteMask& highMask) -{ - addReads(c, e, v, size, lowMask, 0, highMask, 0); -} - void clean(Context* c, Value* v, unsigned popIndex) { @@ -1353,18 +1194,6 @@ clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads, } } -CodePromise* -codePromise(Context* c, Event* e) -{ - return e->promises = new(c->zone) CodePromise(c, e->promises); -} - -CodePromise* -codePromise(Context* c, Promise* offset) -{ - return new (c->zone) CodePromise(c, offset); -} - void append(Context* c, Event* e); @@ -1379,333 +1208,12 @@ saveLocals(Context* c, Event* e) local->value, compiler::frameIndex(c, li), totalFrameSize(c)); } - addRead(c, e, local->value, SiteMask + e->addRead(c, local->value, SiteMask (1 << lir::MemoryOperand, 0, compiler::frameIndex(c, li))); } } } -class CallEvent: public Event { - public: - CallEvent(Context* c, Value* address, unsigned flags, - TraceHandler* traceHandler, Value* result, unsigned resultSize, - Stack* argumentStack, unsigned argumentCount, - unsigned stackArgumentFootprint): - Event(c), - address(address), - traceHandler(traceHandler), - result(result), - returnAddressSurrogate(0), - framePointerSurrogate(0), - popIndex(0), - stackArgumentIndex(0), - flags(flags), - resultSize(resultSize), - stackArgumentFootprint(stackArgumentFootprint) - { - uint32_t registerMask = c->regFile->generalRegisters.mask; - - if (argumentCount) { - assert(c, (flags & Compiler::TailJump) == 0); - assert(c, stackArgumentFootprint == 0); - - Stack* s = argumentStack; - unsigned index = 0; - unsigned argumentIndex = 0; - - while (true) { - unsigned footprint - = (argumentIndex + 1 < argumentCount - and s->value->nextWord == s->next->value) - ? 2 : 1; - - if (index % (c->arch->argumentAlignment() ? footprint : 1)) { - ++ index; - } - - SiteMask targetMask; - if (index + (c->arch->argumentRegisterAlignment() ? footprint : 1) - <= c->arch->argumentRegisterCount()) - { - int number = c->arch->argumentRegister(index); - - if (DebugReads) { - fprintf(stderr, "reg %d arg read %p\n", number, s->value); - } - - targetMask = fixedRegisterMask(number); - registerMask &= ~(1 << number); - } else { - if (index < c->arch->argumentRegisterCount()) { - index = c->arch->argumentRegisterCount(); - } - - unsigned frameIndex = index - c->arch->argumentRegisterCount(); - - if (DebugReads) { - fprintf(stderr, "stack %d arg read %p\n", frameIndex, s->value); - } - - targetMask = SiteMask(1 << lir::MemoryOperand, 0, frameIndex); - } - - addRead(c, this, s->value, targetMask); - - ++ index; - - if ((++ argumentIndex) < argumentCount) { - s = s->next; - } else { - break; - } - } - } - - if (DebugReads) { - fprintf(stderr, "address read %p\n", address); - } - - { bool thunk; - uint8_t typeMask; - uint64_t planRegisterMask; - c->arch->plan - ((flags & Compiler::Aligned) ? lir::AlignedCall : lir::Call, TargetBytesPerWord, - &typeMask, &planRegisterMask, &thunk); - - assert(c, not thunk); - - addRead(c, this, address, SiteMask - (typeMask, registerMask & planRegisterMask, AnyFrameIndex)); - } - - Stack* stack = stackBefore; - - if (stackArgumentFootprint) { - RUNTIME_ARRAY(Value*, arguments, stackArgumentFootprint); - for (int i = stackArgumentFootprint - 1; i >= 0; --i) { - Value* v = stack->value; - stack = stack->next; - - if ((TargetBytesPerWord == 8 - and (v == 0 or (i >= 1 and stack->value == 0))) - or (TargetBytesPerWord == 4 and v->nextWord != v)) - { - assert(c, TargetBytesPerWord == 8 or v->nextWord == stack->value); - - RUNTIME_ARRAY_BODY(arguments)[i--] = stack->value; - stack = stack->next; - } - RUNTIME_ARRAY_BODY(arguments)[i] = v; - } - - int returnAddressIndex; - int framePointerIndex; - int frameOffset; - - if (TailCalls and (flags & Compiler::TailJump)) { - assert(c, argumentCount == 0); - - int base = frameBase(c); - returnAddressIndex = base + c->arch->returnAddressOffset(); - if (UseFramePointer) { - framePointerIndex = base + c->arch->framePointerOffset(); - } else { - framePointerIndex = -1; - } - - frameOffset = totalFrameSize(c) - - c->arch->argumentFootprint(stackArgumentFootprint); - } else { - returnAddressIndex = -1; - framePointerIndex = -1; - frameOffset = 0; - } - - for (unsigned i = 0; i < stackArgumentFootprint; ++i) { - Value* v = RUNTIME_ARRAY_BODY(arguments)[i]; - if (v) { - int frameIndex = i + frameOffset; - - if (DebugReads) { - fprintf(stderr, "stack arg read %p at %d of %d\n", - v, frameIndex, totalFrameSize(c)); - } - - if (static_cast(frameIndex) == returnAddressIndex) { - returnAddressSurrogate = v; - addRead(c, this, v, generalRegisterMask(c)); - } else if (static_cast(frameIndex) == framePointerIndex) { - framePointerSurrogate = v; - addRead(c, this, v, generalRegisterMask(c)); - } else { - addRead(c, this, v, SiteMask(1 << lir::MemoryOperand, 0, frameIndex)); - } - } - } - } - - if ((not TailCalls) or (flags & Compiler::TailJump) == 0) { - stackArgumentIndex = c->localFootprint; - if (stackBefore) { - stackArgumentIndex += stackBefore->index + 1 - stackArgumentFootprint; - } - - popIndex - = c->alignedFrameSize - + c->parameterFootprint - - c->arch->frameFooterSize() - - stackArgumentIndex; - - assert(c, static_cast(popIndex) >= 0); - - while (stack) { - if (stack->value) { - unsigned logicalIndex = compiler::frameIndex - (c, stack->index + c->localFootprint); - - if (DebugReads) { - fprintf(stderr, "stack save read %p at %d of %d\n", - stack->value, logicalIndex, totalFrameSize(c)); - } - - addRead(c, this, stack->value, SiteMask - (1 << lir::MemoryOperand, 0, logicalIndex)); - } - - stack = stack->next; - } - - saveLocals(c, this); - } - } - - virtual const char* name() { - return "CallEvent"; - } - - virtual void compile(Context* c) { - lir::UnaryOperation op; - - if (TailCalls and (flags & Compiler::TailJump)) { - if (flags & Compiler::LongJumpOrCall) { - if (flags & Compiler::Aligned) { - op = lir::AlignedLongJump; - } else { - op = lir::LongJump; - } - } else if (flags & Compiler::Aligned) { - op = lir::AlignedJump; - } else { - op = lir::Jump; - } - - assert(c, returnAddressSurrogate == 0 - or returnAddressSurrogate->source->type(c) == lir::RegisterOperand); - assert(c, framePointerSurrogate == 0 - or framePointerSurrogate->source->type(c) == lir::RegisterOperand); - - int ras; - if (returnAddressSurrogate) { - returnAddressSurrogate->source->freeze(c, returnAddressSurrogate); - - ras = static_cast - (returnAddressSurrogate->source)->number; - } else { - ras = lir::NoRegister; - } - - int fps; - if (framePointerSurrogate) { - framePointerSurrogate->source->freeze(c, framePointerSurrogate); - - fps = static_cast - (framePointerSurrogate->source)->number; - } else { - fps = lir::NoRegister; - } - - int offset - = static_cast(c->arch->argumentFootprint(stackArgumentFootprint)) - - static_cast(c->arch->argumentFootprint(c->parameterFootprint)); - - c->assembler->popFrameForTailCall(c->alignedFrameSize, offset, ras, fps); - } else if (flags & Compiler::LongJumpOrCall) { - if (flags & Compiler::Aligned) { - op = lir::AlignedLongCall; - } else { - op = lir::LongCall; - } - } else if (flags & Compiler::Aligned) { - op = lir::AlignedCall; - } else { - op = lir::Call; - } - - apply(c, op, TargetBytesPerWord, address->source, address->source); - - if (traceHandler) { - traceHandler->handleTrace(codePromise(c, c->assembler->offset(true)), - stackArgumentIndex); - } - - if (TailCalls) { - if (flags & Compiler::TailJump) { - if (returnAddressSurrogate) { - returnAddressSurrogate->source->thaw(c, returnAddressSurrogate); - } - - if (framePointerSurrogate) { - framePointerSurrogate->source->thaw(c, framePointerSurrogate); - } - } else { - unsigned footprint = c->arch->argumentFootprint - (stackArgumentFootprint); - - if (footprint > c->arch->stackAlignmentInWords()) { - c->assembler->adjustFrame - (footprint - c->arch->stackAlignmentInWords()); - } - } - } - - clean(c, this, stackBefore, localsBefore, reads, popIndex); - - if (resultSize and live(c, result)) { - addSite(c, result, registerSite(c, c->arch->returnLow())); - if (resultSize > TargetBytesPerWord and live(c, result->nextWord)) { - addSite(c, result->nextWord, registerSite(c, c->arch->returnHigh())); - } - } - } - - virtual bool allExits() { - return (flags & Compiler::TailJump) != 0; - } - - Value* address; - TraceHandler* traceHandler; - Value* result; - Value* returnAddressSurrogate; - Value* framePointerSurrogate; - unsigned popIndex; - unsigned stackArgumentIndex; - unsigned flags; - unsigned resultSize; - unsigned stackArgumentFootprint; -}; - -void -appendCall(Context* c, Value* address, unsigned flags, - TraceHandler* traceHandler, Value* result, unsigned resultSize, - Stack* argumentStack, unsigned argumentCount, - unsigned stackArgumentFootprint) -{ - append(c, new(c->zone) - CallEvent(c, address, flags, traceHandler, result, - resultSize, argumentStack, argumentCount, - stackArgumentFootprint)); -} - bool unreachable(Event* event) { @@ -1721,8 +1229,9 @@ class ReturnEvent: public Event { Event(c), value(value) { if (value) { - addReads(c, this, value, size, fixedRegisterMask(c->arch->returnLow()), - fixedRegisterMask(c->arch->returnHigh())); + this->addReads(c, value, size, + SiteMask::fixedRegisterMask(c->arch->returnLow()), + SiteMask::fixedRegisterMask(c->arch->returnHigh())); } } @@ -1781,7 +1290,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, src->source->freeze(c, src); - addSite(c, dst, target); + dst->addSite(c, target); src->source->thaw(c, src); @@ -1835,7 +1344,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, src->source->freeze(c, src); - addSite(c, dst, tmpTarget); + dst->addSite(c, tmpTarget); tmpTarget->freeze(c, dst); @@ -1861,7 +1370,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, srcb, dstb, src, dst); } - addSite(c, dst, target); + dst->addSite(c, target); tmpTarget->freeze(c, dst); @@ -1968,8 +1477,8 @@ split(Context* c, Value* v) Site* s = it.next(); removeSite(c, v, s); - addSite(c, v, s->copyLow(c)); - addSite(c, v->nextWord, s->copyHigh(c)); + v->addSite(c, s->copyLow(c)); + v->nextWord->addSite(c, s->copyHigh(c)); } } @@ -2001,7 +1510,7 @@ class MoveEvent: public Event { maybeSplit(c, src); } - addReads(c, this, src, srcSelectSize, srcLowMask, noop ? dst : 0, + this->addReads(c, src, srcSelectSize, srcLowMask, noop ? dst : 0, srcHighMask, noop and dstSize > TargetBytesPerWord ? dst->nextWord : 0); } @@ -2081,7 +1590,7 @@ class MoveEvent: public Event { src->source->freeze(c, src); - addSite(c, dst, low); + dst->addSite(c, low); low->freeze(c, dst); @@ -2105,7 +1614,7 @@ class MoveEvent: public Event { low->freeze(c, dst); - addSite(c, dst->nextWord, high); + dst->nextWord->addSite(c, high); high->freeze(c, dst->nextWord); @@ -2203,7 +1712,7 @@ getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask) r.successor_ = result; s = pickTargetSite(c, &r, true); v = result; - addSite(c, result, s); + result->addSite(c, s); } removeSite(c, v, s); @@ -2245,7 +1754,7 @@ class CombineEvent: public Event { secondSize(secondSize), second(second), resultSize(resultSize), result(result) { - addReads(c, this, first, firstSize, firstLowMask, firstHighMask); + this->addReads(c, first, firstSize, firstLowMask, firstHighMask); if (resultSize > TargetBytesPerWord) { grow(c, result); @@ -2253,7 +1762,7 @@ class CombineEvent: public Event { bool condensed = c->arch->alwaysCondensed(type); - addReads(c, this, second, secondSize, + this->addReads(c, second, secondSize, secondLowMask, condensed ? result : 0, secondHighMask, condensed ? result->nextWord : 0); } @@ -2325,9 +1834,9 @@ class CombineEvent: public Event { } if (live(c, result)) { - addSite(c, result, low); + result->addSite(c, low); if (resultSize > lowSize and live(c, result->nextWord)) { - addSite(c, result->nextWord, high); + result->nextWord->addSite(c, high); } } } @@ -2715,7 +2224,7 @@ class TranslateEvent: public Event { grow(c, result); } - addReads(c, this, value, valueSize, valueLowMask, condensed ? result : 0, + this->addReads(c, value, valueSize, valueLowMask, condensed ? result : 0, valueHighMask, condensed ? result->nextWord : 0); } @@ -2762,9 +2271,9 @@ class TranslateEvent: public Event { } if (live(c, result)) { - addSite(c, result, low); + result->addSite(c, low); if (resultSize > lowSize and live(c, result->nextWord)) { - addSite(c, result->nextWord, high); + result->nextWord->addSite(c, high); } } } @@ -2856,9 +2365,9 @@ class MemoryEvent: public Event { Event(c), base(base), displacement(displacement), index(index), scale(scale), result(result) { - addRead(c, this, base, generalRegisterMask(c)); + this->addRead(c, base, generalRegisterMask(c)); if (index) { - addRead(c, this, index, generalRegisterOrConstantMask(c)); + this->addRead(c, index, generalRegisterOrConstantMask(c)); } } @@ -2906,14 +2415,14 @@ class MemoryEvent: public Event { low = static_cast(site->copyLow(c)); result->nextWord->target = high; - addSite(c, result->nextWord, high); + result->nextWord->addSite(c, high); moveIfConflict(c, result->nextWord, high); } else { low = site; } result->target = low; - addSite(c, result, low); + result->addSite(c, low); moveIfConflict(c, result, low); } @@ -3052,15 +2561,15 @@ class BranchEvent: public Event { Event(c), type(type), size(size), first(first), second(second), address(address) { - addReads(c, this, first, size, firstLowMask, firstHighMask); - addReads(c, this, second, size, secondLowMask, secondHighMask); + this->addReads(c, first, size, firstLowMask, firstHighMask); + this->addReads(c, second, size, secondLowMask, secondHighMask); uint8_t typeMask; uint64_t registerMask; c->arch->planDestination(type, size, 0, 0, size, 0, 0, TargetBytesPerWord, &typeMask, ®isterMask); - addRead(c, this, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); + this->addRead(c, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); } virtual const char* name() { @@ -3183,7 +2692,7 @@ class JumpEvent: public Event { assert(c, not thunk); - addRead(c, this, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); + this->addRead(c, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); } virtual const char* name() { @@ -3233,8 +2742,8 @@ class BoundsCheckEvent: public Event { Event(c), object(object), lengthOffset(lengthOffset), index(index), handler(handler) { - addRead(c, this, object, generalRegisterMask(c)); - addRead(c, this, index, generalRegisterOrConstantMask(c)); + this->addRead(c, object, generalRegisterMask(c)); + this->addRead(c, index, generalRegisterOrConstantMask(c)); } virtual const char* name() { @@ -3254,7 +2763,7 @@ class BoundsCheckEvent: public Event { OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &handlerConstant)); } } else { - outOfBoundsPromise = codePromise(c, static_cast(0)); + outOfBoundsPromise = compiler::codePromise(c, static_cast(0)); ConstantSite zero(resolved(c, 0)); ConstantSite oob(outOfBoundsPromise); @@ -3270,7 +2779,7 @@ class BoundsCheckEvent: public Event { lengthOffset, lir::NoRegister, 1); length.acquired = true; - CodePromise* nextPromise = codePromise(c, static_cast(0)); + CodePromise* nextPromise = compiler::codePromise(c, static_cast(0)); freezeSource(c, TargetBytesPerWord, index); @@ -3322,7 +2831,7 @@ class FrameSiteEvent: public Event { virtual void compile(Context* c) { if (live(c, value)) { - addSite(c, value, frameSite(c, index)); + value->addSite(c, frameSite(c, index)); } } @@ -3382,7 +2891,7 @@ class BuddyEvent: public Event { BuddyEvent(Context* c, Value* original, Value* buddy): Event(c), original(original), buddy(buddy) { - addRead(c, this, original, SiteMask(~0, ~0, AnyFrameIndex), buddy); + this->addRead(c, original, SiteMask(~0, ~0, AnyFrameIndex), buddy); } virtual const char* name() { @@ -3655,7 +3164,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen, } Value dummy(0, 0, lir::ValueGeneral); - addSite(c, &dummy, s); + dummy.addSite(c, s); removeSite(c, &dummy, s); freeze(c, frozen, s, 0); } @@ -3806,7 +3315,7 @@ setSites(Context* c, Value* v, Site* s) assert(c, live(c, v)); for (; s; s = s->next) { - addSite(c, v, s->copy(c)); + v->addSite(c, s->copy(c)); } if (DebugControl) { @@ -3924,7 +3433,8 @@ setStubRead(Context* c, StubReadPair* p, Value* v) if (DebugReads) { fprintf(stderr, "add stub read %p to %p\n", r, v); } - addRead(c, 0, v, r); + // TODO: this is rather icky looking... but despite how it looks, it will not cause an NPE + ((Event*)0)->addRead(c, v, r); p->value = v; p->read = r; @@ -4157,7 +3667,8 @@ addForkElement(Context* c, Value* v, ForkState* state, unsigned index) if (DebugReads) { fprintf(stderr, "add multi read %p to %p\n", r, v); } - addRead(c, 0, v, r); + // TODO: this is rather icky looking... but despite how it looks, it will not cause an NPE + ((Event*)0)->addRead(c, v, r); ForkElement* p = state->elements + index; p->value = v; @@ -4500,7 +4011,7 @@ class MyCompiler: public Compiler { } Promise* machineIp() { - return codePromise(&c, c.logicalCode[c.logicalIp]->lastEvent); + return c.logicalCode[c.logicalIp]->lastEvent->makeCodePromise(&c); } virtual void push(unsigned footprint UNUSED) { diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp new file mode 100644 index 0000000000..9b4fee04e1 --- /dev/null +++ b/src/codegen/compiler/event.cpp @@ -0,0 +1,446 @@ +/* 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 "target.h" +#include "util/runtime-array.h" + +#include "codegen/compiler/context.h" +#include "codegen/compiler/event.h" +#include "codegen/compiler/stack.h" +#include "codegen/compiler/site.h" +#include "codegen/compiler/read.h" +#include "codegen/compiler/value.h" +#include "codegen/compiler/promise.h" + +namespace avian { +namespace codegen { +namespace compiler { + + +unsigned frameBase(Context* c); +unsigned totalFrameSize(Context* c); +int frameIndex(Context* c, int localIndex); + +SiteMask generalRegisterMask(Context* c); +SiteMask generalRegisterOrConstantMask(Context* c); + +CodePromise* codePromise(Context* c, Promise* offset); + +void saveLocals(Context* c, Event* e); + +void +apply(Context* c, lir::UnaryOperation op, + unsigned s1Size, Site* s1Low, Site* s1High); + +void +apply(Context* c, lir::BinaryOperation op, + unsigned s1Size, Site* s1Low, Site* s1High, + unsigned s2Size, Site* s2Low, Site* s2High); + +void +apply(Context* c, lir::TernaryOperation op, + unsigned s1Size, Site* s1Low, Site* s1High, + unsigned s2Size, Site* s2Low, Site* s2High, + unsigned s3Size, Site* s3Low, Site* s3High); + + +void append(Context* c, Event* e); + + +void clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads, + unsigned popIndex); + +Read* live(Context* c UNUSED, Value* v); + +Event::Event(Context* c): + next(0), stackBefore(c->stack), localsBefore(c->locals), + stackAfter(0), localsAfter(0), promises(0), reads(0), + junctionSites(0), snapshots(0), predecessors(0), successors(0), + visitLinks(0), block(0), logicalInstruction(c->logicalCode[c->logicalIp]), + readCount(0) +{ } + +void Event::addRead(Context* c, Value* v, Read* r) { + if (DebugReads) { + fprintf(stderr, "add read %p to %p last %p event %p (%s)\n", + r, v, v->lastRead, this, (this ? this->name() : 0)); + } + + r->value = v; + if (this) { + r->event = this; + r->eventNext = this->reads; + this->reads = r; + ++ this->readCount; + } + + if (v->lastRead) { + // if (DebugReads) { + // fprintf(stderr, "append %p to %p for %p\n", r, v->lastRead, v); + // } + + v->lastRead->append(c, r); + } else { + v->reads = r; + } + v->lastRead = r; +} + +void Event::addRead(Context* c, Value* v, const SiteMask& mask, Value* successor) { + this->addRead(c, v, read(c, mask, successor)); +} + +void Event::addReads(Context* c, Value* v, unsigned size, + const SiteMask& lowMask, Value* lowSuccessor, + const SiteMask& highMask, Value* highSuccessor) +{ + SingleRead* r = read(c, lowMask, lowSuccessor); + this->addRead(c, v, r); + if (size > vm::TargetBytesPerWord) { + r->high_ = v->nextWord; + this->addRead(c, v->nextWord, highMask, highSuccessor); + } +} + +void Event::addReads(Context* c, Value* v, unsigned size, + const SiteMask& lowMask, const SiteMask& highMask) +{ + this->addReads(c, v, size, lowMask, 0, highMask, 0); +} + +CodePromise* Event::makeCodePromise(Context* c) { + return this->promises = new(c->zone) CodePromise(c, this->promises); +} + + +class CallEvent: public Event { + public: + CallEvent(Context* c, Value* address, unsigned flags, + TraceHandler* traceHandler, Value* result, unsigned resultSize, + Stack* argumentStack, unsigned argumentCount, + unsigned stackArgumentFootprint): + Event(c), + address(address), + traceHandler(traceHandler), + result(result), + returnAddressSurrogate(0), + framePointerSurrogate(0), + popIndex(0), + stackArgumentIndex(0), + flags(flags), + resultSize(resultSize), + stackArgumentFootprint(stackArgumentFootprint) + { + uint32_t registerMask = c->regFile->generalRegisters.mask; + + if (argumentCount) { + assert(c, (flags & Compiler::TailJump) == 0); + assert(c, stackArgumentFootprint == 0); + + Stack* s = argumentStack; + unsigned index = 0; + unsigned argumentIndex = 0; + + while (true) { + unsigned footprint + = (argumentIndex + 1 < argumentCount + and s->value->nextWord == s->next->value) + ? 2 : 1; + + if (index % (c->arch->argumentAlignment() ? footprint : 1)) { + ++ index; + } + + SiteMask targetMask; + if (index + (c->arch->argumentRegisterAlignment() ? footprint : 1) + <= c->arch->argumentRegisterCount()) + { + int number = c->arch->argumentRegister(index); + + if (DebugReads) { + fprintf(stderr, "reg %d arg read %p\n", number, s->value); + } + + targetMask = SiteMask::fixedRegisterMask(number); + registerMask &= ~(1 << number); + } else { + if (index < c->arch->argumentRegisterCount()) { + index = c->arch->argumentRegisterCount(); + } + + unsigned frameIndex = index - c->arch->argumentRegisterCount(); + + if (DebugReads) { + fprintf(stderr, "stack %d arg read %p\n", frameIndex, s->value); + } + + targetMask = SiteMask(1 << lir::MemoryOperand, 0, frameIndex); + } + + this->addRead(c, s->value, targetMask); + + ++ index; + + if ((++ argumentIndex) < argumentCount) { + s = s->next; + } else { + break; + } + } + } + + if (DebugReads) { + fprintf(stderr, "address read %p\n", address); + } + + { bool thunk; + uint8_t typeMask; + uint64_t planRegisterMask; + c->arch->plan + ((flags & Compiler::Aligned) ? lir::AlignedCall : lir::Call, vm::TargetBytesPerWord, + &typeMask, &planRegisterMask, &thunk); + + assert(c, not thunk); + + this->addRead(c, address, SiteMask + (typeMask, registerMask & planRegisterMask, AnyFrameIndex)); + } + + Stack* stack = stackBefore; + + if (stackArgumentFootprint) { + RUNTIME_ARRAY(Value*, arguments, stackArgumentFootprint); + for (int i = stackArgumentFootprint - 1; i >= 0; --i) { + Value* v = stack->value; + stack = stack->next; + + if ((vm::TargetBytesPerWord == 8 + and (v == 0 or (i >= 1 and stack->value == 0))) + or (vm::TargetBytesPerWord == 4 and v->nextWord != v)) + { + assert(c, vm::TargetBytesPerWord == 8 or v->nextWord == stack->value); + + RUNTIME_ARRAY_BODY(arguments)[i--] = stack->value; + stack = stack->next; + } + RUNTIME_ARRAY_BODY(arguments)[i] = v; + } + + int returnAddressIndex; + int framePointerIndex; + int frameOffset; + + if (TailCalls and (flags & Compiler::TailJump)) { + assert(c, argumentCount == 0); + + int base = frameBase(c); + returnAddressIndex = base + c->arch->returnAddressOffset(); + if (UseFramePointer) { + framePointerIndex = base + c->arch->framePointerOffset(); + } else { + framePointerIndex = -1; + } + + frameOffset = totalFrameSize(c) + - c->arch->argumentFootprint(stackArgumentFootprint); + } else { + returnAddressIndex = -1; + framePointerIndex = -1; + frameOffset = 0; + } + + for (unsigned i = 0; i < stackArgumentFootprint; ++i) { + Value* v = RUNTIME_ARRAY_BODY(arguments)[i]; + if (v) { + int frameIndex = i + frameOffset; + + if (DebugReads) { + fprintf(stderr, "stack arg read %p at %d of %d\n", + v, frameIndex, totalFrameSize(c)); + } + + if (static_cast(frameIndex) == returnAddressIndex) { + returnAddressSurrogate = v; + this->addRead(c, v, generalRegisterMask(c)); + } else if (static_cast(frameIndex) == framePointerIndex) { + framePointerSurrogate = v; + this->addRead(c, v, generalRegisterMask(c)); + } else { + this->addRead(c, v, SiteMask(1 << lir::MemoryOperand, 0, frameIndex)); + } + } + } + } + + if ((not TailCalls) or (flags & Compiler::TailJump) == 0) { + stackArgumentIndex = c->localFootprint; + if (stackBefore) { + stackArgumentIndex += stackBefore->index + 1 - stackArgumentFootprint; + } + + popIndex + = c->alignedFrameSize + + c->parameterFootprint + - c->arch->frameFooterSize() + - stackArgumentIndex; + + assert(c, static_cast(popIndex) >= 0); + + while (stack) { + if (stack->value) { + unsigned logicalIndex = compiler::frameIndex + (c, stack->index + c->localFootprint); + + if (DebugReads) { + fprintf(stderr, "stack save read %p at %d of %d\n", + stack->value, logicalIndex, totalFrameSize(c)); + } + + this->addRead(c, stack->value, SiteMask + (1 << lir::MemoryOperand, 0, logicalIndex)); + } + + stack = stack->next; + } + + saveLocals(c, this); + } + } + + virtual const char* name() { + return "CallEvent"; + } + + virtual void compile(Context* c) { + lir::UnaryOperation op; + + if (TailCalls and (flags & Compiler::TailJump)) { + if (flags & Compiler::LongJumpOrCall) { + if (flags & Compiler::Aligned) { + op = lir::AlignedLongJump; + } else { + op = lir::LongJump; + } + } else if (flags & Compiler::Aligned) { + op = lir::AlignedJump; + } else { + op = lir::Jump; + } + + assert(c, returnAddressSurrogate == 0 + or returnAddressSurrogate->source->type(c) == lir::RegisterOperand); + assert(c, framePointerSurrogate == 0 + or framePointerSurrogate->source->type(c) == lir::RegisterOperand); + + int ras; + if (returnAddressSurrogate) { + returnAddressSurrogate->source->freeze(c, returnAddressSurrogate); + + ras = static_cast + (returnAddressSurrogate->source)->number; + } else { + ras = lir::NoRegister; + } + + int fps; + if (framePointerSurrogate) { + framePointerSurrogate->source->freeze(c, framePointerSurrogate); + + fps = static_cast + (framePointerSurrogate->source)->number; + } else { + fps = lir::NoRegister; + } + + int offset + = static_cast(c->arch->argumentFootprint(stackArgumentFootprint)) + - static_cast(c->arch->argumentFootprint(c->parameterFootprint)); + + c->assembler->popFrameForTailCall(c->alignedFrameSize, offset, ras, fps); + } else if (flags & Compiler::LongJumpOrCall) { + if (flags & Compiler::Aligned) { + op = lir::AlignedLongCall; + } else { + op = lir::LongCall; + } + } else if (flags & Compiler::Aligned) { + op = lir::AlignedCall; + } else { + op = lir::Call; + } + + apply(c, op, vm::TargetBytesPerWord, address->source, address->source); + + if (traceHandler) { + traceHandler->handleTrace(codePromise(c, c->assembler->offset(true)), + stackArgumentIndex); + } + + if (TailCalls) { + if (flags & Compiler::TailJump) { + if (returnAddressSurrogate) { + returnAddressSurrogate->source->thaw(c, returnAddressSurrogate); + } + + if (framePointerSurrogate) { + framePointerSurrogate->source->thaw(c, framePointerSurrogate); + } + } else { + unsigned footprint = c->arch->argumentFootprint + (stackArgumentFootprint); + + if (footprint > c->arch->stackAlignmentInWords()) { + c->assembler->adjustFrame + (footprint - c->arch->stackAlignmentInWords()); + } + } + } + + clean(c, this, stackBefore, localsBefore, reads, popIndex); + + if (resultSize and live(c, result)) { + result->addSite(c, registerSite(c, c->arch->returnLow())); + if (resultSize > vm::TargetBytesPerWord and live(c, result->nextWord)) { + result->nextWord->addSite(c, registerSite(c, c->arch->returnHigh())); + } + } + } + + virtual bool allExits() { + return (flags & Compiler::TailJump) != 0; + } + + Value* address; + TraceHandler* traceHandler; + Value* result; + Value* returnAddressSurrogate; + Value* framePointerSurrogate; + unsigned popIndex; + unsigned stackArgumentIndex; + unsigned flags; + unsigned resultSize; + unsigned stackArgumentFootprint; +}; + +void +appendCall(Context* c, Value* address, unsigned flags, + TraceHandler* traceHandler, Value* result, unsigned resultSize, + Stack* argumentStack, unsigned argumentCount, + unsigned stackArgumentFootprint) +{ + append(c, new(c->zone) + CallEvent(c, address, flags, traceHandler, result, + resultSize, argumentStack, argumentCount, + stackArgumentFootprint)); +} + +} // namespace compiler +} // namespace codegen +} // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h new file mode 100644 index 0000000000..3308ede12a --- /dev/null +++ b/src/codegen/compiler/event.h @@ -0,0 +1,85 @@ +/* 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_COMPILER_EVENT_H +#define AVIAN_CODEGEN_COMPILER_EVENT_H + +namespace avian { +namespace codegen { +namespace compiler { + +class Context; +class CodePromise; +class Snapshot; +class Link; +class Site; + +const bool DebugReads = false; + +class Event { + public: + Event(Context* c); + + virtual const char* name() = 0; + + virtual void compile(Context* c) = 0; + + virtual bool isBranch() { return false; } + + virtual bool allExits() { return false; } + + virtual Local* locals() { return localsBefore; } + + + + void addRead(Context* c, Value* v, Read* r); + + void addRead(Context* c, Value* v, const SiteMask& mask, + Value* successor = 0); + + void addReads(Context* c, Value* v, unsigned size, + const SiteMask& lowMask, Value* lowSuccessor, + const SiteMask& highMask, Value* highSuccessor); + + void addReads(Context* c, Value* v, unsigned size, + const SiteMask& lowMask, const SiteMask& highMask); + + + + CodePromise* makeCodePromise(Context* c); + + Event* next; + Stack* stackBefore; + Local* localsBefore; + Stack* stackAfter; + Local* localsAfter; + CodePromise* promises; + Read* reads; + Site** junctionSites; + Snapshot* snapshots; + Link* predecessors; + Link* successors; + Cell* visitLinks; + Block* block; + LogicalInstruction* logicalInstruction; + unsigned readCount; +}; + +void +appendCall(Context* c, Value* address, unsigned flags, + TraceHandler* traceHandler, Value* result, unsigned resultSize, + Stack* argumentStack, unsigned argumentCount, + unsigned stackArgumentFootprint); + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_EVENT_H diff --git a/src/codegen/compiler/promise.cpp b/src/codegen/compiler/promise.cpp new file mode 100644 index 0000000000..ceb25d89e7 --- /dev/null +++ b/src/codegen/compiler/promise.cpp @@ -0,0 +1,26 @@ +/* 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 "codegen/compiler/context.h" +#include "codegen/compiler/promise.h" + +namespace avian { +namespace codegen { +namespace compiler { + +CodePromise* +codePromise(Context* c, Promise* offset) +{ + return new (c->zone) CodePromise(c, offset); +} + +} // namespace compiler +} // namespace codegen +} // namespace avian diff --git a/src/codegen/compiler/promise.h b/src/codegen/compiler/promise.h new file mode 100644 index 0000000000..2afcd49304 --- /dev/null +++ b/src/codegen/compiler/promise.h @@ -0,0 +1,52 @@ +/* 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_COMPILER_PROMISE_H +#define AVIAN_CODEGEN_COMPILER_PROMISE_H + +namespace avian { +namespace codegen { +namespace compiler { + + +class CodePromise: public Promise { + public: + CodePromise(Context* c, CodePromise* next): + c(c), offset(0), next(next) + { } + + CodePromise(Context* c, Promise* offset): + c(c), offset(offset), next(0) + { } + + virtual int64_t value() { + if (resolved()) { + return reinterpret_cast(c->machineCode + offset->value()); + } + + abort(c); + } + + virtual bool resolved() { + return c->machineCode != 0 and offset and offset->resolved(); + } + + Context* c; + Promise* offset; + CodePromise* next; +}; + +CodePromise* codePromise(Context* c, Promise* offset); + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_PROMISE_H diff --git a/src/codegen/compiler/read.cpp b/src/codegen/compiler/read.cpp index 08308cfa52..1b90878c1e 100644 --- a/src/codegen/compiler/read.cpp +++ b/src/codegen/compiler/read.cpp @@ -178,6 +178,14 @@ Read* StubRead::next(Context*) { return next_; } + + +SingleRead* read(Context* c, const SiteMask& mask, Value* successor) { + assert(c, (mask.typeMask != 1 << lir::MemoryOperand) or mask.frameIndex >= 0); + + return new(c->zone) SingleRead(mask, successor); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/read.h b/src/codegen/compiler/read.h index 4e942ba75a..52db19b0e8 100644 --- a/src/codegen/compiler/read.h +++ b/src/codegen/compiler/read.h @@ -111,6 +111,8 @@ class StubRead: public Read { bool valid_; }; +SingleRead* read(Context* c, const SiteMask& mask, Value* successor = 0); + } // namespace compiler } // namespace codegen diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index 43eb211112..d05a09cd64 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -109,6 +109,12 @@ void SiteIterator::remove(Context* c) { +unsigned Site::registerSize(Context*) { + return vm::TargetBytesPerWord; +} + + + Site* constantSite(Context* c, Promise* value) { return new(c->zone) ConstantSite(value); } diff --git a/src/codegen/compiler/site.h b/src/codegen/compiler/site.h index 6f5508be91..1360e8959f 100644 --- a/src/codegen/compiler/site.h +++ b/src/codegen/compiler/site.h @@ -36,6 +36,10 @@ class SiteMask { SiteMask intersectionWith(const SiteMask& b); + static SiteMask fixedRegisterMask(int number) { + return SiteMask(1 << lir::RegisterOperand, 1 << number, NoFrameIndex); + } + uint8_t typeMask; uint32_t registerMask; int frameIndex; @@ -83,7 +87,7 @@ class Site { virtual SiteMask nextWordMask(Context*, unsigned) = 0; - virtual unsigned registerSize(Context*) { return vm::TargetBytesPerWord; } + virtual unsigned registerSize(Context*); virtual unsigned registerMask(Context*) { return 0; } diff --git a/src/codegen/compiler/stack.h b/src/codegen/compiler/stack.h new file mode 100644 index 0000000000..7ae8c4f7c1 --- /dev/null +++ b/src/codegen/compiler/stack.h @@ -0,0 +1,35 @@ +/* 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_COMPILER_STACK_H +#define AVIAN_CODEGEN_COMPILER_STACK_H + +namespace avian { +namespace codegen { +namespace compiler { + +class Value; + +class Stack { + public: + Stack(unsigned index, Value* value, Stack* next): + index(index), value(value), next(next) + { } + + unsigned index; + Value* value; + Stack* next; +}; + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_STACK_H diff --git a/src/codegen/compiler/value.cpp b/src/codegen/compiler/value.cpp index a8f88acbca..90a4f3c100 100644 --- a/src/codegen/compiler/value.cpp +++ b/src/codegen/compiler/value.cpp @@ -38,6 +38,18 @@ bool Value::isBuddyOf(Value* b) { return false; } +void Value::addSite(Context* c, Site* s) { + if (not this->findSite(s)) { + if (DebugSites) { + char buffer[256]; s->toString(c, buffer, 256); + fprintf(stderr, "add site %s to %p\n", buffer, this); + } + s->acquire(c, this); + s->next = this->sites; + this->sites = s; + } +} + } // namespace regalloc } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/value.h b/src/codegen/compiler/value.h index f913d89363..f21bcbc062 100644 --- a/src/codegen/compiler/value.h +++ b/src/codegen/compiler/value.h @@ -25,6 +25,8 @@ class Site; const int AnyFrameIndex = -2; const int NoFrameIndex = -1; +const bool DebugSites = false; + class Value: public Compiler::Operand { public: Read* reads; @@ -43,6 +45,8 @@ class Value: public Compiler::Operand { bool findSite(Site* site); bool isBuddyOf(Value* b); + + void addSite(Context* c, Site* s); }; } // namespace compiler From 165c77d7729fe12a8be241db5a094644741f1438 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 19:43:19 -0700 Subject: [PATCH 10/23] move ReturnEvent out of compiler.cpp --- src/codegen/compiler.cpp | 91 ++-------------------------------- src/codegen/compiler/event.cpp | 52 +++++++++++++++++++ src/codegen/compiler/event.h | 43 +++++++++++++++- 3 files changed, 96 insertions(+), 90 deletions(-) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index ca6ee5ba23..5ab7eaea50 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -198,45 +198,6 @@ Cell* reverseDestroy(Cell* cell) { return previous; } -class StubReadPair { - public: - Value* value; - StubRead* read; -}; - -class JunctionState { - public: - JunctionState(unsigned frameFootprint): frameFootprint(frameFootprint) { } - - unsigned frameFootprint; - StubReadPair reads[0]; -}; - -class Link { - public: - Link(Event* predecessor, Link* nextPredecessor, Event* successor, - Link* nextSuccessor, ForkState* forkState): - predecessor(predecessor), nextPredecessor(nextPredecessor), - successor(successor), nextSuccessor(nextSuccessor), forkState(forkState), - junctionState(0) - { } - - Event* predecessor; - Link* nextPredecessor; - Event* successor; - Link* nextSuccessor; - ForkState* forkState; - JunctionState* junctionState; -}; - -Link* -link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor, - Link* nextSuccessor, ForkState* forkState) -{ - return new(c->zone) Link - (predecessor, nextPredecessor, successor, nextSuccessor, forkState); -} - unsigned countPredecessors(Link* link) { @@ -1214,52 +1175,6 @@ saveLocals(Context* c, Event* e) } } -bool -unreachable(Event* event) -{ - for (Link* p = event->predecessors; p; p = p->nextPredecessor) { - if (not p->predecessor->allExits()) return false; - } - return event->predecessors != 0; -} - -class ReturnEvent: public Event { - public: - ReturnEvent(Context* c, unsigned size, Value* value): - Event(c), value(value) - { - if (value) { - this->addReads(c, value, size, - SiteMask::fixedRegisterMask(c->arch->returnLow()), - SiteMask::fixedRegisterMask(c->arch->returnHigh())); - } - } - - virtual const char* name() { - return "ReturnEvent"; - } - - virtual void compile(Context* c) { - for (Read* r = reads; r; r = r->eventNext) { - popRead(c, this, r->value); - } - - if (not unreachable(this)) { - c->assembler->popFrameAndPopArgumentsAndReturn - (c->alignedFrameSize, - c->arch->argumentFootprint(c->parameterFootprint)); - } - } - - Value* value; -}; - -void -appendReturn(Context* c, unsigned size, Value* value) -{ - append(c, new(c->zone) ReturnEvent(c, size, value)); -} - void maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst, @@ -2580,7 +2495,7 @@ class BranchEvent: public Event { ConstantSite* firstConstant = findConstantSite(c, first); ConstantSite* secondConstant = findConstantSite(c, second); - if (not unreachable(this)) { + if (not this->isUnreachable()) { if (firstConstant and secondConstant and firstConstant->value->resolved() @@ -2700,7 +2615,7 @@ class JumpEvent: public Event { } virtual void compile(Context* c) { - if (not unreachable(this)) { + if (not this->isUnreachable()) { apply(c, type, TargetBytesPerWord, address->source, address->source); } @@ -2719,7 +2634,7 @@ class JumpEvent: public Event { virtual bool isBranch() { return true; } virtual bool allExits() { - return exit or unreachable(this); + return exit or this->isUnreachable(); } lir::UnaryOperation type; diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 9b4fee04e1..2ac259cf94 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -59,6 +59,8 @@ void clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads, Read* live(Context* c UNUSED, Value* v); +void popRead(Context* c, Event* e UNUSED, Value* v); + Event::Event(Context* c): next(0), stackBefore(c->stack), localsBefore(c->locals), stackAfter(0), localsAfter(0), promises(0), reads(0), @@ -119,6 +121,20 @@ CodePromise* Event::makeCodePromise(Context* c) { return this->promises = new(c->zone) CodePromise(c, this->promises); } +bool Event::isUnreachable() { + for (Link* p = this->predecessors; p; p = p->nextPredecessor) { + if (not p->predecessor->allExits()) return false; + } + return this->predecessors != 0; +} + +Link* link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor, + Link* nextSuccessor, ForkState* forkState) +{ + return new(c->zone) Link + (predecessor, nextPredecessor, successor, nextSuccessor, forkState); +} + class CallEvent: public Event { public: @@ -441,6 +457,42 @@ appendCall(Context* c, Value* address, unsigned flags, stackArgumentFootprint)); } + +class ReturnEvent: public Event { + public: + ReturnEvent(Context* c, unsigned size, Value* value): + Event(c), value(value) + { + if (value) { + this->addReads(c, value, size, + SiteMask::fixedRegisterMask(c->arch->returnLow()), + SiteMask::fixedRegisterMask(c->arch->returnHigh())); + } + } + + virtual const char* name() { + return "ReturnEvent"; + } + + virtual void compile(Context* c) { + for (Read* r = reads; r; r = r->eventNext) { + popRead(c, this, r->value); + } + + if (not this->isUnreachable()) { + c->assembler->popFrameAndPopArgumentsAndReturn + (c->alignedFrameSize, + c->arch->argumentFootprint(c->parameterFootprint)); + } + } + + Value* value; +}; + +void appendReturn(Context* c, unsigned size, Value* value) { + append(c, new(c->zone) ReturnEvent(c, size, value)); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index 3308ede12a..91b441353b 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -20,6 +20,7 @@ class CodePromise; class Snapshot; class Link; class Site; +class StubRead; const bool DebugReads = false; @@ -51,10 +52,10 @@ class Event { void addReads(Context* c, Value* v, unsigned size, const SiteMask& lowMask, const SiteMask& highMask); - - CodePromise* makeCodePromise(Context* c); + bool isUnreachable(); + Event* next; Stack* stackBefore; Local* localsBefore; @@ -72,12 +73,50 @@ class Event { unsigned readCount; }; +class StubReadPair { + public: + Value* value; + StubRead* read; +}; + +class JunctionState { + public: + JunctionState(unsigned frameFootprint): frameFootprint(frameFootprint) { } + + unsigned frameFootprint; + StubReadPair reads[0]; +}; + +class Link { + public: + Link(Event* predecessor, Link* nextPredecessor, Event* successor, + Link* nextSuccessor, ForkState* forkState): + predecessor(predecessor), nextPredecessor(nextPredecessor), + successor(successor), nextSuccessor(nextSuccessor), forkState(forkState), + junctionState(0) + { } + + Event* predecessor; + Link* nextPredecessor; + Event* successor; + Link* nextSuccessor; + ForkState* forkState; + JunctionState* junctionState; +}; + +Link* +link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor, + Link* nextSuccessor, ForkState* forkState); + void appendCall(Context* c, Value* address, unsigned flags, TraceHandler* traceHandler, Value* result, unsigned resultSize, Stack* argumentStack, unsigned argumentCount, unsigned stackArgumentFootprint); +void +appendReturn(Context* c, unsigned size, Value* value); + } // namespace compiler } // namespace codegen } // namespace avian From 5ad0eb86d344fb331f859142ad0fae2c26fb628c Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 20:03:37 -0700 Subject: [PATCH 11/23] move MoveEvent out of compiler.cpp --- src/codegen/compiler.cpp | 269 ++------------------------------- src/codegen/compiler/event.cpp | 186 +++++++++++++++++++++++ src/codegen/compiler/event.h | 5 + src/codegen/compiler/value.cpp | 55 +++++++ src/codegen/compiler/value.h | 13 ++ 5 files changed, 272 insertions(+), 256 deletions(-) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 5ab7eaea50..019204da74 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -36,7 +36,6 @@ const bool DebugCompile = false; const bool DebugResources = false; const bool DebugFrame = false; const bool DebugControl = false; -const bool DebugMoves = false; const bool DebugBuddies = false; const unsigned StealRegisterReserveCount = 2; @@ -333,13 +332,6 @@ frameIndex(Context* c, FrameIterator::Element* element) return frameIndex(c, element->localIndex); } -bool -hasSite(Context* c, Value* v) -{ - SiteIterator it(c, v); - return it.hasMore(); -} - bool uniqueSite(Context* c, Value* v, Site* s) { @@ -365,25 +357,6 @@ uniqueSite(Context* c, Value* v, Site* s) } } -void -removeSite(Context* c, Value* v, Site* s) -{ - for (SiteIterator it(c, v); it.hasMore();) { - if (s == it.next()) { - if (DebugSites) { - char buffer[256]; s->toString(c, buffer, 256); - fprintf(stderr, "remove site %s from %p\n", buffer, v); - } - it.remove(c); - break; - } - } - if (DebugSites) { - fprintf(stderr, "%p has more: %d\n", v, hasSite(c, v)); - } - assert(c, not v->findSite(s)); -} - void clearSites(Context* c, Value* v) { @@ -873,7 +846,7 @@ steal(Context* c, Resource* r, Value* thief) r->site->thaw(c, r->value); } - removeSite(c, r->value, r->site); + r->value->removeSite(c, r->site); } SiteMask @@ -1238,7 +1211,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, // pick a temporary register which is valid as both a // destination and a source for the moves we need to perform: - removeSite(c, dst, target); + dst->removeSite(c, target); bool thunk; uint8_t srcTypeMask; @@ -1294,7 +1267,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, tmpTarget->thaw(c, dst); if (isStore) { - removeSite(c, dst, tmpTarget); + dst->removeSite(c, tmpTarget); } } } @@ -1315,7 +1288,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, } if (isStore) { - removeSite(c, dst, target); + dst->removeSite(c, target); } } @@ -1358,7 +1331,7 @@ pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord, addBuddy(src, dst); if (src->source->isVolatile(c)) { - removeSite(c, src, src->source); + src->removeSite(c, src->source); } return s; @@ -1367,222 +1340,6 @@ pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord, } } -Value* -value(Context* c, lir::ValueType type, Site* site = 0, Site* target = 0) -{ - return new(c->zone) Value(site, target, type); -} - -void -grow(Context* c, Value* v) -{ - assert(c, v->nextWord == v); - - Value* next = value(c, v->type); - v->nextWord = next; - next->nextWord = v; - next->wordIndex = 1; -} - -void -split(Context* c, Value* v) -{ - grow(c, v); - for (SiteIterator it(c, v); it.hasMore();) { - Site* s = it.next(); - removeSite(c, v, s); - - v->addSite(c, s->copyLow(c)); - v->nextWord->addSite(c, s->copyHigh(c)); - } -} - -void -maybeSplit(Context* c, Value* v) -{ - if (v->nextWord == v) { - split(c, v); - } -} - -class MoveEvent: public Event { - public: - MoveEvent(Context* c, lir::BinaryOperation type, unsigned srcSize, - unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst, - const SiteMask& srcLowMask, const SiteMask& srcHighMask): - Event(c), type(type), srcSize(srcSize), srcSelectSize(srcSelectSize), - src(src), dstSize(dstSize), dst(dst) - { - assert(c, srcSelectSize <= srcSize); - - bool noop = srcSelectSize >= dstSize; - - if (dstSize > TargetBytesPerWord) { - grow(c, dst); - } - - if (srcSelectSize > TargetBytesPerWord) { - maybeSplit(c, src); - } - - this->addReads(c, src, srcSelectSize, srcLowMask, noop ? dst : 0, - srcHighMask, - noop and dstSize > TargetBytesPerWord ? dst->nextWord : 0); - } - - virtual const char* name() { - return "MoveEvent"; - } - - virtual void compile(Context* c) { - uint8_t dstTypeMask; - uint64_t dstRegisterMask; - - c->arch->planDestination - (type, - srcSelectSize, - 1 << src->source->type(c), - (static_cast(src->nextWord->source->registerMask(c)) << 32) - | static_cast(src->source->registerMask(c)), - dstSize, - &dstTypeMask, - &dstRegisterMask); - - SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex); - SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex); - - if (srcSelectSize >= TargetBytesPerWord - and dstSize >= TargetBytesPerWord - and srcSelectSize >= dstSize) - { - if (dst->target) { - if (dstSize > TargetBytesPerWord) { - if (src->source->registerSize(c) > TargetBytesPerWord) { - apply(c, lir::Move, srcSelectSize, src->source, src->source, - dstSize, dst->target, dst->target); - - if (live(c, dst) == 0) { - removeSite(c, dst, dst->target); - if (dstSize > TargetBytesPerWord) { - removeSite(c, dst->nextWord, dst->nextWord->target); - } - } - } else { - src->nextWord->source->freeze(c, src->nextWord); - - maybeMove(c, lir::Move, TargetBytesPerWord, TargetBytesPerWord, src, - TargetBytesPerWord, dst, dstLowMask); - - src->nextWord->source->thaw(c, src->nextWord); - - maybeMove - (c, lir::Move, TargetBytesPerWord, TargetBytesPerWord, src->nextWord, - TargetBytesPerWord, dst->nextWord, dstHighMask); - } - } else { - maybeMove(c, lir::Move, TargetBytesPerWord, TargetBytesPerWord, src, - TargetBytesPerWord, dst, dstLowMask); - } - } else { - Site* low = pickSiteOrMove(c, src, dst, 0, 0); - if (dstSize > TargetBytesPerWord) { - pickSiteOrMove(c, src->nextWord, dst->nextWord, low, 1); - } - } - } else if (srcSelectSize <= TargetBytesPerWord - and dstSize <= TargetBytesPerWord) - { - maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst, - dstLowMask); - } else { - assert(c, srcSize == TargetBytesPerWord); - assert(c, srcSelectSize == TargetBytesPerWord); - - if (dst->nextWord->target or live(c, dst->nextWord)) { - assert(c, dstLowMask.typeMask & (1 << lir::RegisterOperand)); - - Site* low = freeRegisterSite(c, dstLowMask.registerMask); - - src->source->freeze(c, src); - - dst->addSite(c, low); - - low->freeze(c, dst); - - if (DebugMoves) { - char srcb[256]; src->source->toString(c, srcb, 256); - char dstb[256]; low->toString(c, dstb, 256); - fprintf(stderr, "move %s to %s for %p\n", - srcb, dstb, src); - } - - apply(c, lir::Move, TargetBytesPerWord, src->source, src->source, - TargetBytesPerWord, low, low); - - low->thaw(c, dst); - - src->source->thaw(c, src); - - assert(c, dstHighMask.typeMask & (1 << lir::RegisterOperand)); - - Site* high = freeRegisterSite(c, dstHighMask.registerMask); - - low->freeze(c, dst); - - dst->nextWord->addSite(c, high); - - high->freeze(c, dst->nextWord); - - if (DebugMoves) { - char srcb[256]; low->toString(c, srcb, 256); - char dstb[256]; high->toString(c, dstb, 256); - fprintf(stderr, "extend %s to %s for %p %p\n", - srcb, dstb, dst, dst->nextWord); - } - - apply(c, lir::Move, TargetBytesPerWord, low, low, dstSize, low, high); - - high->thaw(c, dst->nextWord); - - low->thaw(c, dst); - } else { - pickSiteOrMove(c, src, dst, 0, 0); - } - } - - for (Read* r = reads; r; r = r->eventNext) { - popRead(c, this, r->value); - } - } - - lir::BinaryOperation type; - unsigned srcSize; - unsigned srcSelectSize; - Value* src; - unsigned dstSize; - Value* dst; -}; - -void -appendMove(Context* c, lir::BinaryOperation type, unsigned srcSize, - unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst) -{ - bool thunk; - uint8_t srcTypeMask; - uint64_t srcRegisterMask; - - c->arch->planSource - (type, srcSelectSize, &srcTypeMask, &srcRegisterMask, dstSize, &thunk); - - assert(c, not thunk); - - append(c, new(c->zone) - MoveEvent - (c, type, srcSize, srcSelectSize, src, dstSize, dst, - SiteMask(srcTypeMask, srcRegisterMask, AnyFrameIndex), - SiteMask(srcTypeMask, srcRegisterMask >> 32, AnyFrameIndex))); -} - ConstantSite* findConstantSite(Context* c, Value* v) { @@ -1630,7 +1387,7 @@ getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask) result->addSite(c, s); } - removeSite(c, v, s); + v->removeSite(c, s); s->freeze(c, v); @@ -1672,7 +1429,7 @@ class CombineEvent: public Event { this->addReads(c, first, firstSize, firstLowMask, firstHighMask); if (resultSize > TargetBytesPerWord) { - grow(c, result); + result->grow(c); } bool condensed = c->arch->alwaysCondensed(type); @@ -1896,7 +1653,7 @@ push(Context* c, unsigned footprint, Value* v) assert(c, footprint == 2); if (TargetBytesPerWord == 4) { - maybeSplit(c, low); + low->maybeSplit(c); high = pushWord(c, low->nextWord); } else { high = pushWord(c, 0); @@ -2136,7 +1893,7 @@ class TranslateEvent: public Event { bool condensed = c->arch->alwaysCondensed(type); if (resultSize > TargetBytesPerWord) { - grow(c, result); + result->grow(c); } this->addReads(c, value, valueSize, valueLowMask, condensed ? result : 0, @@ -2268,7 +2025,7 @@ moveIfConflict(Context* c, Value* v, MemorySite* s) v->reads->intersect(&mask); if (s->conflicts(mask)) { maybeMove(c, v->reads, true, false); - removeSite(c, v, s); + v->removeSite(c, s); } } } @@ -2818,7 +2575,7 @@ class BuddyEvent: public Event { fprintf(stderr, "original %p buddy %p\n", original, buddy); } - assert(c, hasSite(c, original)); + assert(c, original->hasSite(c)); assert(c, original); assert(c, buddy); @@ -2952,7 +2709,7 @@ readSource(Context* c, Read* r) fprintf(stderr, "read source for %p from %s\n", v, buffer); } - if (not hasSite(c, v)) { + if (not v->hasSite(c)) { if (DebugReads) { fprintf(stderr, "no sites found for %p\n", v); } @@ -3080,7 +2837,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen, Value dummy(0, 0, lir::ValueGeneral); dummy.addSite(c, s); - removeSite(c, &dummy, s); + dummy.removeSite(c, s); freeze(c, frozen, s, 0); } } diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 2ac259cf94..e96a7c8d08 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -61,6 +61,14 @@ Read* live(Context* c UNUSED, Value* v); void popRead(Context* c, Event* e UNUSED, Value* v); +void +maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, + unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst, + const SiteMask& dstMask); +Site* +pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord, + unsigned index); + Event::Event(Context* c): next(0), stackBefore(c->stack), localsBefore(c->locals), stackAfter(0), localsAfter(0), promises(0), reads(0), @@ -493,6 +501,184 @@ void appendReturn(Context* c, unsigned size, Value* value) { append(c, new(c->zone) ReturnEvent(c, size, value)); } +class MoveEvent: public Event { + public: + MoveEvent(Context* c, lir::BinaryOperation type, unsigned srcSize, + unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst, + const SiteMask& srcLowMask, const SiteMask& srcHighMask): + Event(c), type(type), srcSize(srcSize), srcSelectSize(srcSelectSize), + src(src), dstSize(dstSize), dst(dst) + { + assert(c, srcSelectSize <= srcSize); + + bool noop = srcSelectSize >= dstSize; + + if (dstSize > vm::TargetBytesPerWord) { + dst->grow(c); + } + + if (srcSelectSize > vm::TargetBytesPerWord) { + src->maybeSplit(c); + } + + this->addReads(c, src, srcSelectSize, srcLowMask, noop ? dst : 0, + srcHighMask, + noop and dstSize > vm::TargetBytesPerWord ? dst->nextWord : 0); + } + + virtual const char* name() { + return "MoveEvent"; + } + + virtual void compile(Context* c) { + uint8_t dstTypeMask; + uint64_t dstRegisterMask; + + c->arch->planDestination + (type, + srcSelectSize, + 1 << src->source->type(c), + (static_cast(src->nextWord->source->registerMask(c)) << 32) + | static_cast(src->source->registerMask(c)), + dstSize, + &dstTypeMask, + &dstRegisterMask); + + SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex); + SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex); + + if (srcSelectSize >= vm::TargetBytesPerWord + and dstSize >= vm::TargetBytesPerWord + and srcSelectSize >= dstSize) + { + if (dst->target) { + if (dstSize > vm::TargetBytesPerWord) { + if (src->source->registerSize(c) > vm::TargetBytesPerWord) { + apply(c, lir::Move, srcSelectSize, src->source, src->source, + dstSize, dst->target, dst->target); + + if (live(c, dst) == 0) { + dst->removeSite(c, dst->target); + if (dstSize > vm::TargetBytesPerWord) { + dst->nextWord->removeSite(c, dst->nextWord->target); + } + } + } else { + src->nextWord->source->freeze(c, src->nextWord); + + maybeMove(c, lir::Move, vm::TargetBytesPerWord, vm::TargetBytesPerWord, src, + vm::TargetBytesPerWord, dst, dstLowMask); + + src->nextWord->source->thaw(c, src->nextWord); + + maybeMove + (c, lir::Move, vm::TargetBytesPerWord, vm::TargetBytesPerWord, src->nextWord, + vm::TargetBytesPerWord, dst->nextWord, dstHighMask); + } + } else { + maybeMove(c, lir::Move, vm::TargetBytesPerWord, vm::TargetBytesPerWord, src, + vm::TargetBytesPerWord, dst, dstLowMask); + } + } else { + Site* low = pickSiteOrMove(c, src, dst, 0, 0); + if (dstSize > vm::TargetBytesPerWord) { + pickSiteOrMove(c, src->nextWord, dst->nextWord, low, 1); + } + } + } else if (srcSelectSize <= vm::TargetBytesPerWord + and dstSize <= vm::TargetBytesPerWord) + { + maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst, + dstLowMask); + } else { + assert(c, srcSize == vm::TargetBytesPerWord); + assert(c, srcSelectSize == vm::TargetBytesPerWord); + + if (dst->nextWord->target or live(c, dst->nextWord)) { + assert(c, dstLowMask.typeMask & (1 << lir::RegisterOperand)); + + Site* low = freeRegisterSite(c, dstLowMask.registerMask); + + src->source->freeze(c, src); + + dst->addSite(c, low); + + low->freeze(c, dst); + + if (DebugMoves) { + char srcb[256]; src->source->toString(c, srcb, 256); + char dstb[256]; low->toString(c, dstb, 256); + fprintf(stderr, "move %s to %s for %p\n", + srcb, dstb, src); + } + + apply(c, lir::Move, vm::TargetBytesPerWord, src->source, src->source, + vm::TargetBytesPerWord, low, low); + + low->thaw(c, dst); + + src->source->thaw(c, src); + + assert(c, dstHighMask.typeMask & (1 << lir::RegisterOperand)); + + Site* high = freeRegisterSite(c, dstHighMask.registerMask); + + low->freeze(c, dst); + + dst->nextWord->addSite(c, high); + + high->freeze(c, dst->nextWord); + + if (DebugMoves) { + char srcb[256]; low->toString(c, srcb, 256); + char dstb[256]; high->toString(c, dstb, 256); + fprintf(stderr, "extend %s to %s for %p %p\n", + srcb, dstb, dst, dst->nextWord); + } + + apply(c, lir::Move, vm::TargetBytesPerWord, low, low, dstSize, low, high); + + high->thaw(c, dst->nextWord); + + low->thaw(c, dst); + } else { + pickSiteOrMove(c, src, dst, 0, 0); + } + } + + for (Read* r = reads; r; r = r->eventNext) { + popRead(c, this, r->value); + } + } + + lir::BinaryOperation type; + unsigned srcSize; + unsigned srcSelectSize; + Value* src; + unsigned dstSize; + Value* dst; +}; + +void +appendMove(Context* c, lir::BinaryOperation type, unsigned srcSize, + unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst) +{ + bool thunk; + uint8_t srcTypeMask; + uint64_t srcRegisterMask; + + c->arch->planSource + (type, srcSelectSize, &srcTypeMask, &srcRegisterMask, dstSize, &thunk); + + assert(c, not thunk); + + append(c, new(c->zone) + MoveEvent + (c, type, srcSize, srcSelectSize, src, dstSize, dst, + SiteMask(srcTypeMask, srcRegisterMask, AnyFrameIndex), + SiteMask(srcTypeMask, srcRegisterMask >> 32, AnyFrameIndex))); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index 91b441353b..6dbbd018d4 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -23,6 +23,7 @@ class Site; class StubRead; const bool DebugReads = false; +const bool DebugMoves = false; class Event { public: @@ -117,6 +118,10 @@ appendCall(Context* c, Value* address, unsigned flags, void appendReturn(Context* c, unsigned size, Value* value); +void +appendMove(Context* c, lir::BinaryOperation type, unsigned srcSize, + unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst); + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/value.cpp b/src/codegen/compiler/value.cpp index 90a4f3c100..62fe9c86a5 100644 --- a/src/codegen/compiler/value.cpp +++ b/src/codegen/compiler/value.cpp @@ -50,6 +50,61 @@ void Value::addSite(Context* c, Site* s) { } } + +void Value::grow(Context* c) { + assert(c, this->nextWord == this); + + Value* next = value(c, this->type); + this->nextWord = next; + next->nextWord = this; + next->wordIndex = 1; +} + + +void Value::maybeSplit(Context* c) { + if (this->nextWord == this) { + this->split(c); + } +} + +void Value::split(Context* c) { + this->grow(c); + for (SiteIterator it(c, this); it.hasMore();) { + Site* s = it.next(); + this->removeSite(c, s); + + this->addSite(c, s->copyLow(c)); + this->nextWord->addSite(c, s->copyHigh(c)); + } +} + +void Value::removeSite(Context* c, Site* s) { + for (SiteIterator it(c, this); it.hasMore();) { + if (s == it.next()) { + if (DebugSites) { + char buffer[256]; s->toString(c, buffer, 256); + fprintf(stderr, "remove site %s from %p\n", buffer, this); + } + it.remove(c); + break; + } + } + if (DebugSites) { + fprintf(stderr, "%p has more: %d\n", this, this->hasSite(c)); + } + assert(c, not this->findSite(s)); +} + +bool Value::hasSite(Context* c) { + SiteIterator it(c, this); + return it.hasMore(); +} + + +Value* value(Context* c, lir::ValueType type, Site* site, Site* target) { + return new(c->zone) Value(site, target, type); +} + } // namespace regalloc } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/value.h b/src/codegen/compiler/value.h index f21bcbc062..0543ec3c74 100644 --- a/src/codegen/compiler/value.h +++ b/src/codegen/compiler/value.h @@ -47,8 +47,21 @@ class Value: public Compiler::Operand { bool isBuddyOf(Value* b); void addSite(Context* c, Site* s); + + void grow(Context* c); + + void maybeSplit(Context* c); + + void split(Context* c); + + void removeSite(Context* c, Site* s); + + bool hasSite(Context* c); }; + +Value* value(Context* c, lir::ValueType type, Site* site = 0, Site* target = 0); + } // namespace compiler } // namespace codegen } // namespace avian From 8a61b38a0196acbde01df5b590d1552be71e7201 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 20:28:29 -0700 Subject: [PATCH 12/23] move CombineEvent out of compiler.cpp --- src/codegen/compiler.cpp | 296 +----------------------------- src/codegen/compiler/event.cpp | 253 +++++++++++++++++++++++++ src/codegen/compiler/event.h | 6 + src/codegen/compiler/read.h | 4 + src/codegen/compiler/regalloc.cpp | 3 +- src/codegen/compiler/value.cpp | 44 +++++ src/codegen/compiler/value.h | 8 + 7 files changed, 321 insertions(+), 293 deletions(-) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 019204da74..9af7e73e97 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -332,31 +332,6 @@ frameIndex(Context* c, FrameIterator::Element* element) return frameIndex(c, element->localIndex); } -bool -uniqueSite(Context* c, Value* v, Site* s) -{ - SiteIterator it(c, v); - Site* p UNUSED = it.next(); - if (it.hasMore()) { - // the site is not this word's only site, but if the site is - // shared with the next word, it may be that word's only site - if (v->nextWord != v and s->registerSize(c) > TargetBytesPerWord) { - SiteIterator nit(c, v->nextWord); - Site* p = nit.next(); - if (nit.hasMore()) { - return false; - } else { - return p == s; - } - } else { - return false; - } - } else { - assert(c, p == s); - return true; - } -} - void clearSites(Context* c, Value* v) { @@ -369,39 +344,10 @@ clearSites(Context* c, Value* v) } } -bool -valid(Read* r) -{ - return r and r->valid(); -} - -#ifndef NDEBUG - -bool -hasBuddy(Context* c, Value* a, Value* b) -{ - if (a == b) { - return true; - } - - int i = 0; - for (Value* p = a->buddy; p != a; p = p->buddy) { - if (p == b) { - return true; - } - if (++i > 1000) { - abort(c); - } - } - return false; -} - -#endif // not NDEBUG - Read* live(Context* c UNUSED, Value* v) { - assert(c, hasBuddy(c, v->buddy, v)); + assert(c, v->buddy->hasBuddy(c, v)); Value* p = v; do { @@ -414,21 +360,6 @@ live(Context* c UNUSED, Value* v) return 0; } -Read* -liveNext(Context* c, Value* v) -{ - assert(c, hasBuddy(c, v->buddy, v)); - - Read* r = v->reads->next(c); - if (valid(r)) return r; - - for (Value* p = v->buddy; p != v; p = p->buddy) { - if (valid(p->reads)) return p->reads; - } - - return 0; -} - unsigned sitesToString(Context* c, Value* v, char* buffer, unsigned size); @@ -837,7 +768,7 @@ steal(Context* c, Resource* r, Value* thief) } if ((not (thief and thief->isBuddyOf(r->value)) - and uniqueSite(c, r->value, r->site))) + and r->value->uniqueSite(c, r->site))) { r->site->freeze(c, r->value); @@ -1352,175 +1283,14 @@ findConstantSite(Context* c, Value* v) return 0; } -void -preserve(Context* c, Value* v, Read* r, Site* s) -{ - s->freeze(c, v); - - maybeMove(c, r, false, true, 0); - - s->thaw(c, v); -} - Site* -getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask) -{ - Site* s; - Value* v; - Read* r = liveNext(c, value); - if (value->source->match - (c, static_cast(resultMask)) - and (r == 0 or value->source->loneMatch - (c, static_cast(resultMask)))) - { - s = value->source; - v = value; - if (r and uniqueSite(c, v, s)) { - preserve(c, v, r, s); - } - } else { - SingleRead r(resultMask, 0); - r.value = result; - r.successor_ = result; - s = pickTargetSite(c, &r, true); - v = result; - result->addSite(c, s); - } - - v->removeSite(c, s); - - s->freeze(c, v); - - return s; -} +getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask); void -freezeSource(Context* c, unsigned size, Value* v) -{ - v->source->freeze(c, v); - if (size > TargetBytesPerWord) { - v->nextWord->source->freeze(c, v->nextWord); - } -} +freezeSource(Context* c, unsigned size, Value* v); void -thawSource(Context* c, unsigned size, Value* v) -{ - v->source->thaw(c, v); - if (size > TargetBytesPerWord) { - v->nextWord->source->thaw(c, v->nextWord); - } -} - -class CombineEvent: public Event { - public: - CombineEvent(Context* c, lir::TernaryOperation type, - unsigned firstSize, Value* first, - unsigned secondSize, Value* second, - unsigned resultSize, Value* result, - const SiteMask& firstLowMask, - const SiteMask& firstHighMask, - const SiteMask& secondLowMask, - const SiteMask& secondHighMask): - Event(c), type(type), firstSize(firstSize), first(first), - secondSize(secondSize), second(second), resultSize(resultSize), - result(result) - { - this->addReads(c, first, firstSize, firstLowMask, firstHighMask); - - if (resultSize > TargetBytesPerWord) { - result->grow(c); - } - - bool condensed = c->arch->alwaysCondensed(type); - - this->addReads(c, second, secondSize, - secondLowMask, condensed ? result : 0, - secondHighMask, condensed ? result->nextWord : 0); - } - - virtual const char* name() { - return "CombineEvent"; - } - - virtual void compile(Context* c) { - assert(c, first->source->type(c) == first->nextWord->source->type(c)); - - // if (second->source->type(c) != second->nextWord->source->type(c)) { - // fprintf(stderr, "%p %p %d : %p %p %d\n", - // second, second->source, second->source->type(c), - // second->nextWord, second->nextWord->source, - // second->nextWord->source->type(c)); - // } - - assert(c, second->source->type(c) == second->nextWord->source->type(c)); - - freezeSource(c, firstSize, first); - - uint8_t cTypeMask; - uint64_t cRegisterMask; - - c->arch->planDestination - (type, - firstSize, - 1 << first->source->type(c), - (static_cast(first->nextWord->source->registerMask(c)) << 32) - | static_cast(first->source->registerMask(c)), - secondSize, - 1 << second->source->type(c), - (static_cast(second->nextWord->source->registerMask(c)) << 32) - | static_cast(second->source->registerMask(c)), - resultSize, - &cTypeMask, - &cRegisterMask); - - SiteMask resultLowMask(cTypeMask, cRegisterMask, AnyFrameIndex); - SiteMask resultHighMask(cTypeMask, cRegisterMask >> 32, AnyFrameIndex); - - Site* low = getTarget(c, second, result, resultLowMask); - unsigned lowSize = low->registerSize(c); - Site* high - = (resultSize > lowSize - ? getTarget(c, second->nextWord, result->nextWord, resultHighMask) - : low); - -// fprintf(stderr, "combine %p:%p and %p:%p into %p:%p\n", -// first, first->nextWord, -// second, second->nextWord, -// result, result->nextWord); - - apply(c, type, - firstSize, first->source, first->nextWord->source, - secondSize, second->source, second->nextWord->source, - resultSize, low, high); - - thawSource(c, firstSize, first); - - for (Read* r = reads; r; r = r->eventNext) { - popRead(c, this, r->value); - } - - low->thaw(c, second); - if (resultSize > lowSize) { - high->thaw(c, second->nextWord); - } - - if (live(c, result)) { - result->addSite(c, low); - if (resultSize > lowSize and live(c, result->nextWord)) { - result->nextWord->addSite(c, high); - } - } - } - - lir::TernaryOperation type; - unsigned firstSize; - Value* first; - unsigned secondSize; - Value* second; - unsigned resultSize; - Value* result; -}; +thawSource(Context* c, unsigned size, Value* v); void removeBuddy(Context* c, Value* v) @@ -1825,62 +1595,6 @@ register_(Context* c, int number) return value(c, type, s, s); } -void -appendCombine(Context* c, lir::TernaryOperation type, - unsigned firstSize, Value* first, - unsigned secondSize, Value* second, - unsigned resultSize, Value* result) -{ - bool thunk; - uint8_t firstTypeMask; - uint64_t firstRegisterMask; - uint8_t secondTypeMask; - uint64_t secondRegisterMask; - - c->arch->planSource(type, firstSize, &firstTypeMask, &firstRegisterMask, - secondSize, &secondTypeMask, &secondRegisterMask, - resultSize, &thunk); - - if (thunk) { - Stack* oldStack = c->stack; - - bool threadParameter; - intptr_t handler = c->client->getThunk - (type, firstSize, resultSize, &threadParameter); - - unsigned stackSize = ceilingDivide(secondSize, TargetBytesPerWord) - + ceilingDivide(firstSize, TargetBytesPerWord); - - compiler::push(c, ceilingDivide(secondSize, TargetBytesPerWord), second); - compiler::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first); - - if (threadParameter) { - ++ stackSize; - - compiler::push(c, 1, register_(c, c->arch->thread())); - } - - Stack* argumentStack = c->stack; - c->stack = oldStack; - - appendCall - (c, value(c, lir::ValueGeneral, constantSite(c, handler)), 0, 0, result, - resultSize, argumentStack, stackSize, 0); - } else { - append - (c, new(c->zone) - CombineEvent - (c, type, - firstSize, first, - secondSize, second, - resultSize, result, - SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex), - SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex), - SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex), - SiteMask(secondTypeMask, secondRegisterMask >> 32, AnyFrameIndex))); - } -} - class TranslateEvent: public Event { public: TranslateEvent(Context* c, lir::BinaryOperation type, unsigned valueSize, diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index e96a7c8d08..d238f54bd8 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -65,10 +65,27 @@ void maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize, unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst, const SiteMask& dstMask); + +Site* +maybeMove(Context* c, Value* v, const SiteMask& mask, bool intersectMask, + bool includeNextWord, unsigned registerReserveCount = 0); + +Site* +maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord, + unsigned registerReserveCount = 0); Site* pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord, unsigned index); +void push(Context* c, unsigned footprint, Value* v); + +Site* +pickTargetSite(Context* c, Read* read, bool intersectRead = false, + unsigned registerReserveCount = 0, + CostCalculator* costCalculator = 0); +Value* +register_(Context* c, int number); + Event::Event(Context* c): next(0), stackBefore(c->stack), localsBefore(c->locals), stackAfter(0), localsAfter(0), promises(0), reads(0), @@ -679,6 +696,242 @@ appendMove(Context* c, lir::BinaryOperation type, unsigned srcSize, SiteMask(srcTypeMask, srcRegisterMask >> 32, AnyFrameIndex))); } + +void +freezeSource(Context* c, unsigned size, Value* v) +{ + v->source->freeze(c, v); + if (size > vm::TargetBytesPerWord) { + v->nextWord->source->freeze(c, v->nextWord); + } +} + +void +thawSource(Context* c, unsigned size, Value* v) +{ + v->source->thaw(c, v); + if (size > vm::TargetBytesPerWord) { + v->nextWord->source->thaw(c, v->nextWord); + } +} + +Read* liveNext(Context* c, Value* v) { + assert(c, v->buddy->hasBuddy(c, v)); + + Read* r = v->reads->next(c); + if (valid(r)) return r; + + for (Value* p = v->buddy; p != v; p = p->buddy) { + if (valid(p->reads)) return p->reads; + } + + return 0; +} + +void preserve(Context* c, Value* v, Read* r, Site* s) { + s->freeze(c, v); + + maybeMove(c, r, false, true, 0); + + s->thaw(c, v); +} + +Site* getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask) { + Site* s; + Value* v; + Read* r = liveNext(c, value); + if (value->source->match + (c, static_cast(resultMask)) + and (r == 0 or value->source->loneMatch + (c, static_cast(resultMask)))) + { + s = value->source; + v = value; + if (r and v->uniqueSite(c, s)) { + preserve(c, v, r, s); + } + } else { + SingleRead r(resultMask, 0); + r.value = result; + r.successor_ = result; + s = pickTargetSite(c, &r, true); + v = result; + result->addSite(c, s); + } + + v->removeSite(c, s); + + s->freeze(c, v); + + return s; +} + +class CombineEvent: public Event { + public: + CombineEvent(Context* c, lir::TernaryOperation type, + unsigned firstSize, Value* first, + unsigned secondSize, Value* second, + unsigned resultSize, Value* result, + const SiteMask& firstLowMask, + const SiteMask& firstHighMask, + const SiteMask& secondLowMask, + const SiteMask& secondHighMask): + Event(c), type(type), firstSize(firstSize), first(first), + secondSize(secondSize), second(second), resultSize(resultSize), + result(result) + { + this->addReads(c, first, firstSize, firstLowMask, firstHighMask); + + if (resultSize > vm::TargetBytesPerWord) { + result->grow(c); + } + + bool condensed = c->arch->alwaysCondensed(type); + + this->addReads(c, second, secondSize, + secondLowMask, condensed ? result : 0, + secondHighMask, condensed ? result->nextWord : 0); + } + + virtual const char* name() { + return "CombineEvent"; + } + + virtual void compile(Context* c) { + assert(c, first->source->type(c) == first->nextWord->source->type(c)); + + // if (second->source->type(c) != second->nextWord->source->type(c)) { + // fprintf(stderr, "%p %p %d : %p %p %d\n", + // second, second->source, second->source->type(c), + // second->nextWord, second->nextWord->source, + // second->nextWord->source->type(c)); + // } + + assert(c, second->source->type(c) == second->nextWord->source->type(c)); + + freezeSource(c, firstSize, first); + + uint8_t cTypeMask; + uint64_t cRegisterMask; + + c->arch->planDestination + (type, + firstSize, + 1 << first->source->type(c), + (static_cast(first->nextWord->source->registerMask(c)) << 32) + | static_cast(first->source->registerMask(c)), + secondSize, + 1 << second->source->type(c), + (static_cast(second->nextWord->source->registerMask(c)) << 32) + | static_cast(second->source->registerMask(c)), + resultSize, + &cTypeMask, + &cRegisterMask); + + SiteMask resultLowMask(cTypeMask, cRegisterMask, AnyFrameIndex); + SiteMask resultHighMask(cTypeMask, cRegisterMask >> 32, AnyFrameIndex); + + Site* low = getTarget(c, second, result, resultLowMask); + unsigned lowSize = low->registerSize(c); + Site* high + = (resultSize > lowSize + ? getTarget(c, second->nextWord, result->nextWord, resultHighMask) + : low); + +// fprintf(stderr, "combine %p:%p and %p:%p into %p:%p\n", +// first, first->nextWord, +// second, second->nextWord, +// result, result->nextWord); + + apply(c, type, + firstSize, first->source, first->nextWord->source, + secondSize, second->source, second->nextWord->source, + resultSize, low, high); + + thawSource(c, firstSize, first); + + for (Read* r = reads; r; r = r->eventNext) { + popRead(c, this, r->value); + } + + low->thaw(c, second); + if (resultSize > lowSize) { + high->thaw(c, second->nextWord); + } + + if (live(c, result)) { + result->addSite(c, low); + if (resultSize > lowSize and live(c, result->nextWord)) { + result->nextWord->addSite(c, high); + } + } + } + + lir::TernaryOperation type; + unsigned firstSize; + Value* first; + unsigned secondSize; + Value* second; + unsigned resultSize; + Value* result; +}; + +void +appendCombine(Context* c, lir::TernaryOperation type, + unsigned firstSize, Value* first, + unsigned secondSize, Value* second, + unsigned resultSize, Value* result) +{ + bool thunk; + uint8_t firstTypeMask; + uint64_t firstRegisterMask; + uint8_t secondTypeMask; + uint64_t secondRegisterMask; + + c->arch->planSource(type, firstSize, &firstTypeMask, &firstRegisterMask, + secondSize, &secondTypeMask, &secondRegisterMask, + resultSize, &thunk); + + if (thunk) { + Stack* oldStack = c->stack; + + bool threadParameter; + intptr_t handler = c->client->getThunk + (type, firstSize, resultSize, &threadParameter); + + unsigned stackSize = vm::ceilingDivide(secondSize, vm::TargetBytesPerWord) + + vm::ceilingDivide(firstSize, vm::TargetBytesPerWord); + + compiler::push(c, vm::ceilingDivide(secondSize, vm::TargetBytesPerWord), second); + compiler::push(c, vm::ceilingDivide(firstSize, vm::TargetBytesPerWord), first); + + if (threadParameter) { + ++ stackSize; + + compiler::push(c, 1, register_(c, c->arch->thread())); + } + + Stack* argumentStack = c->stack; + c->stack = oldStack; + + appendCall + (c, value(c, lir::ValueGeneral, constantSite(c, handler)), 0, 0, result, + resultSize, argumentStack, stackSize, 0); + } else { + append + (c, new(c->zone) + CombineEvent + (c, type, + firstSize, first, + secondSize, second, + resultSize, result, + SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex), + SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex), + SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex), + SiteMask(secondTypeMask, secondRegisterMask >> 32, AnyFrameIndex))); + } +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index 6dbbd018d4..08de6e26c9 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -122,6 +122,12 @@ void appendMove(Context* c, lir::BinaryOperation type, unsigned srcSize, unsigned srcSelectSize, Value* src, unsigned dstSize, Value* dst); +void +appendCombine(Context* c, lir::TernaryOperation type, + unsigned firstSize, Value* first, + unsigned secondSize, Value* second, + unsigned resultSize, Value* result); + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/read.h b/src/codegen/compiler/read.h index 52db19b0e8..e221dfb4bb 100644 --- a/src/codegen/compiler/read.h +++ b/src/codegen/compiler/read.h @@ -43,6 +43,10 @@ class Read { Read* eventNext; }; +inline bool valid(Read* r) { + return r and r->valid(); +} + class SingleRead: public Read { public: SingleRead(const SiteMask& mask, Value* successor); diff --git a/src/codegen/compiler/regalloc.cpp b/src/codegen/compiler/regalloc.cpp index 2727b569c4..60fb2c7100 100644 --- a/src/codegen/compiler/regalloc.cpp +++ b/src/codegen/compiler/regalloc.cpp @@ -26,7 +26,6 @@ RegisterAllocator::RegisterAllocator(Aborter* a, const RegisterFile* registerFil { } -bool uniqueSite(Context* c, Value* v, Site* s); unsigned totalFrameSize(Context* c); Read* live(Context* c UNUSED, Value* v); @@ -45,7 +44,7 @@ resourceCost(Context* c, Value* v, Resource* r, SiteMask mask, if (v and r->value->isBuddyOf(v)) { return baseCost; - } else if (uniqueSite(c, r->value, r->site)) { + } else if (r->value->uniqueSite(c, r->site)) { return baseCost + Target::StealUniquePenalty; } else { return baseCost = Target::StealPenalty; diff --git a/src/codegen/compiler/value.cpp b/src/codegen/compiler/value.cpp index 62fe9c86a5..cc3ac08092 100644 --- a/src/codegen/compiler/value.cpp +++ b/src/codegen/compiler/value.cpp @@ -100,6 +100,50 @@ bool Value::hasSite(Context* c) { return it.hasMore(); } +bool Value::uniqueSite(Context* c, Site* s) { + SiteIterator it(c, this); + Site* p UNUSED = it.next(); + if (it.hasMore()) { + // the site is not this word's only site, but if the site is + // shared with the next word, it may be that word's only site + if (this->nextWord != this and s->registerSize(c) > vm::TargetBytesPerWord) { + SiteIterator nit(c, this->nextWord); + Site* p = nit.next(); + if (nit.hasMore()) { + return false; + } else { + return p == s; + } + } else { + return false; + } + } else { + assert(c, p == s); + return true; + } +} + + +#ifndef NDEBUG +bool Value::hasBuddy(Context* c, Value* b) { + Value* a = this; + if (a == b) { + return true; + } + + int i = 0; + for (Value* p = a->buddy; p != a; p = p->buddy) { + if (p == b) { + return true; + } + if (++i > 1000) { + abort(c); + } + } + return false; +} +#endif // not NDEBUG + Value* value(Context* c, lir::ValueType type, Site* site, Site* target) { return new(c->zone) Value(site, target, type); diff --git a/src/codegen/compiler/value.h b/src/codegen/compiler/value.h index 0543ec3c74..f567c86cd5 100644 --- a/src/codegen/compiler/value.h +++ b/src/codegen/compiler/value.h @@ -57,6 +57,14 @@ class Value: public Compiler::Operand { void removeSite(Context* c, Site* s); bool hasSite(Context* c); + + bool uniqueSite(Context* c, Site* s); + + +#ifndef NDEBUG + bool hasBuddy(Context* c, Value* b); +#endif // not NDEBUG + }; From 70f9209a6ed7b55915cdd76ae305be14f52d5d68 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 20:31:28 -0700 Subject: [PATCH 13/23] move TranslateEvent out of compiler.cpp --- src/codegen/compiler.cpp | 113 --------------------------------- src/codegen/compiler/event.cpp | 113 +++++++++++++++++++++++++++++++++ src/codegen/compiler/event.h | 4 ++ 3 files changed, 117 insertions(+), 113 deletions(-) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 9af7e73e97..e747e5668a 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -1595,119 +1595,6 @@ register_(Context* c, int number) return value(c, type, s, s); } -class TranslateEvent: public Event { - public: - TranslateEvent(Context* c, lir::BinaryOperation type, unsigned valueSize, - Value* value, unsigned resultSize, Value* result, - const SiteMask& valueLowMask, - const SiteMask& valueHighMask): - Event(c), type(type), valueSize(valueSize), resultSize(resultSize), - value(value), result(result) - { - bool condensed = c->arch->alwaysCondensed(type); - - if (resultSize > TargetBytesPerWord) { - result->grow(c); - } - - this->addReads(c, value, valueSize, valueLowMask, condensed ? result : 0, - valueHighMask, condensed ? result->nextWord : 0); - } - - virtual const char* name() { - return "TranslateEvent"; - } - - virtual void compile(Context* c) { - assert(c, value->source->type(c) == value->nextWord->source->type(c)); - - uint8_t bTypeMask; - uint64_t bRegisterMask; - - c->arch->planDestination - (type, - valueSize, - 1 << value->source->type(c), - (static_cast(value->nextWord->source->registerMask(c)) << 32) - | static_cast(value->source->registerMask(c)), - resultSize, - &bTypeMask, - &bRegisterMask); - - SiteMask resultLowMask(bTypeMask, bRegisterMask, AnyFrameIndex); - SiteMask resultHighMask(bTypeMask, bRegisterMask >> 32, AnyFrameIndex); - - Site* low = getTarget(c, value, result, resultLowMask); - unsigned lowSize = low->registerSize(c); - Site* high - = (resultSize > lowSize - ? getTarget(c, value->nextWord, result->nextWord, resultHighMask) - : low); - - apply(c, type, valueSize, value->source, value->nextWord->source, - resultSize, low, high); - - for (Read* r = reads; r; r = r->eventNext) { - popRead(c, this, r->value); - } - - low->thaw(c, value); - if (resultSize > lowSize) { - high->thaw(c, value->nextWord); - } - - if (live(c, result)) { - result->addSite(c, low); - if (resultSize > lowSize and live(c, result->nextWord)) { - result->nextWord->addSite(c, high); - } - } - } - - lir::BinaryOperation type; - unsigned valueSize; - unsigned resultSize; - Value* value; - Value* result; - Read* resultRead; - SiteMask resultLowMask; - SiteMask resultHighMask; -}; - -void -appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize, - Value* first, unsigned resultSize, Value* result) -{ - bool thunk; - uint8_t firstTypeMask; - uint64_t firstRegisterMask; - - c->arch->planSource(type, firstSize, &firstTypeMask, &firstRegisterMask, - resultSize, &thunk); - - if (thunk) { - Stack* oldStack = c->stack; - - compiler::push(c, ceilingDivide(firstSize, TargetBytesPerWord), first); - - Stack* argumentStack = c->stack; - c->stack = oldStack; - - appendCall - (c, value - (c, lir::ValueGeneral, constantSite - (c, c->client->getThunk(type, firstSize, resultSize))), - 0, 0, result, resultSize, argumentStack, - ceilingDivide(firstSize, TargetBytesPerWord), 0); - } else { - append(c, new(c->zone) - TranslateEvent - (c, type, firstSize, first, resultSize, result, - SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex), - SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex))); - } -} - class OperationEvent: public Event { public: OperationEvent(Context* c, lir::Operation op): diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index d238f54bd8..c98cbacbf3 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -932,6 +932,119 @@ appendCombine(Context* c, lir::TernaryOperation type, } } +class TranslateEvent: public Event { + public: + TranslateEvent(Context* c, lir::BinaryOperation type, unsigned valueSize, + Value* value, unsigned resultSize, Value* result, + const SiteMask& valueLowMask, + const SiteMask& valueHighMask): + Event(c), type(type), valueSize(valueSize), resultSize(resultSize), + value(value), result(result) + { + bool condensed = c->arch->alwaysCondensed(type); + + if (resultSize > vm::TargetBytesPerWord) { + result->grow(c); + } + + this->addReads(c, value, valueSize, valueLowMask, condensed ? result : 0, + valueHighMask, condensed ? result->nextWord : 0); + } + + virtual const char* name() { + return "TranslateEvent"; + } + + virtual void compile(Context* c) { + assert(c, value->source->type(c) == value->nextWord->source->type(c)); + + uint8_t bTypeMask; + uint64_t bRegisterMask; + + c->arch->planDestination + (type, + valueSize, + 1 << value->source->type(c), + (static_cast(value->nextWord->source->registerMask(c)) << 32) + | static_cast(value->source->registerMask(c)), + resultSize, + &bTypeMask, + &bRegisterMask); + + SiteMask resultLowMask(bTypeMask, bRegisterMask, AnyFrameIndex); + SiteMask resultHighMask(bTypeMask, bRegisterMask >> 32, AnyFrameIndex); + + Site* low = getTarget(c, value, result, resultLowMask); + unsigned lowSize = low->registerSize(c); + Site* high + = (resultSize > lowSize + ? getTarget(c, value->nextWord, result->nextWord, resultHighMask) + : low); + + apply(c, type, valueSize, value->source, value->nextWord->source, + resultSize, low, high); + + for (Read* r = reads; r; r = r->eventNext) { + popRead(c, this, r->value); + } + + low->thaw(c, value); + if (resultSize > lowSize) { + high->thaw(c, value->nextWord); + } + + if (live(c, result)) { + result->addSite(c, low); + if (resultSize > lowSize and live(c, result->nextWord)) { + result->nextWord->addSite(c, high); + } + } + } + + lir::BinaryOperation type; + unsigned valueSize; + unsigned resultSize; + Value* value; + Value* result; + Read* resultRead; + SiteMask resultLowMask; + SiteMask resultHighMask; +}; + +void +appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize, + Value* first, unsigned resultSize, Value* result) +{ + bool thunk; + uint8_t firstTypeMask; + uint64_t firstRegisterMask; + + c->arch->planSource(type, firstSize, &firstTypeMask, &firstRegisterMask, + resultSize, &thunk); + + if (thunk) { + Stack* oldStack = c->stack; + + compiler::push(c, vm::ceilingDivide(firstSize, vm::TargetBytesPerWord), first); + + Stack* argumentStack = c->stack; + c->stack = oldStack; + + appendCall + (c, value + (c, lir::ValueGeneral, constantSite + (c, c->client->getThunk(type, firstSize, resultSize))), + 0, 0, result, resultSize, argumentStack, + vm::ceilingDivide(firstSize, vm::TargetBytesPerWord), 0); + } else { + append(c, new(c->zone) + TranslateEvent + (c, type, firstSize, first, resultSize, result, + SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex), + SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex))); + } +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index 08de6e26c9..a87619e0a7 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -128,6 +128,10 @@ appendCombine(Context* c, lir::TernaryOperation type, unsigned secondSize, Value* second, unsigned resultSize, Value* result); +void +appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize, + Value* first, unsigned resultSize, Value* result); + } // namespace compiler } // namespace codegen } // namespace avian From 9c102bc1a861a19c5efd7189725d8c9f299df221 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 20:33:33 -0700 Subject: [PATCH 14/23] move OperationEvent out of compiler.cpp --- src/codegen/compiler.cpp | 23 ----------------------- src/codegen/compiler/event.cpp | 23 +++++++++++++++++++++++ src/codegen/compiler/event.h | 3 +++ 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index e747e5668a..8265fc3a58 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -1595,29 +1595,6 @@ register_(Context* c, int number) return value(c, type, s, s); } -class OperationEvent: public Event { - public: - OperationEvent(Context* c, lir::Operation op): - Event(c), op(op) - { } - - virtual const char* name() { - return "OperationEvent"; - } - - virtual void compile(Context* c) { - c->assembler->apply(op); - } - - lir::Operation op; -}; - -void -appendOperation(Context* c, lir::Operation op) -{ - append(c, new(c->zone) OperationEvent(c, op)); -} - void moveIfConflict(Context* c, Value* v, MemorySite* s) { diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index c98cbacbf3..b0ccd3a48e 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -1045,6 +1045,29 @@ appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize, } } +class OperationEvent: public Event { + public: + OperationEvent(Context* c, lir::Operation op): + Event(c), op(op) + { } + + virtual const char* name() { + return "OperationEvent"; + } + + virtual void compile(Context* c) { + c->assembler->apply(op); + } + + lir::Operation op; +}; + +void +appendOperation(Context* c, lir::Operation op) +{ + append(c, new(c->zone) OperationEvent(c, op)); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index a87619e0a7..22a812657b 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -132,6 +132,9 @@ void appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize, Value* first, unsigned resultSize, Value* result); +void +appendOperation(Context* c, lir::Operation op); + } // namespace compiler } // namespace codegen } // namespace avian From 18e6f28ff4e53513b22aa378bc0dbf3bf1351552 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 20:36:37 -0700 Subject: [PATCH 15/23] move MemoryEvent out of compiler.cpp --- src/codegen/compiler.cpp | 107 +-------------------------------- src/codegen/compiler/event.cpp | 106 ++++++++++++++++++++++++++++++++ src/codegen/compiler/event.h | 4 ++ 3 files changed, 111 insertions(+), 106 deletions(-) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 8265fc3a58..ab16fb5446 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -1272,16 +1272,7 @@ pickSiteOrMove(Context* c, Value* src, Value* dst, Site* nextWord, } ConstantSite* -findConstantSite(Context* c, Value* v) -{ - for (SiteIterator it(c, v); it.hasMore();) { - Site* s = it.next(); - if (s->type(c) == lir::ConstantOperand) { - return static_cast(s); - } - } - return 0; -} +findConstantSite(Context* c, Value* v); Site* getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask); @@ -1595,102 +1586,6 @@ register_(Context* c, int number) return value(c, type, s, s); } -void -moveIfConflict(Context* c, Value* v, MemorySite* s) -{ - if (v->reads) { - SiteMask mask(1 << lir::RegisterOperand, ~0, AnyFrameIndex); - v->reads->intersect(&mask); - if (s->conflicts(mask)) { - maybeMove(c, v->reads, true, false); - v->removeSite(c, s); - } - } -} - -class MemoryEvent: public Event { - public: - MemoryEvent(Context* c, Value* base, int displacement, Value* index, - unsigned scale, Value* result): - Event(c), base(base), displacement(displacement), index(index), - scale(scale), result(result) - { - this->addRead(c, base, generalRegisterMask(c)); - if (index) { - this->addRead(c, index, generalRegisterOrConstantMask(c)); - } - } - - virtual const char* name() { - return "MemoryEvent"; - } - - virtual void compile(Context* c) { - int indexRegister; - int displacement = this->displacement; - unsigned scale = this->scale; - if (index) { - ConstantSite* constant = findConstantSite(c, index); - - if (constant) { - indexRegister = lir::NoRegister; - displacement += (constant->value->value() * scale); - scale = 1; - } else { - assert(c, index->source->type(c) == lir::RegisterOperand); - indexRegister = static_cast(index->source)->number; - } - } else { - indexRegister = lir::NoRegister; - } - assert(c, base->source->type(c) == lir::RegisterOperand); - int baseRegister = static_cast(base->source)->number; - - popRead(c, this, base); - if (index) { - if (TargetBytesPerWord == 8 and indexRegister != lir::NoRegister) { - apply(c, lir::Move, 4, index->source, index->source, - 8, index->source, index->source); - } - - popRead(c, this, index); - } - - MemorySite* site = memorySite - (c, baseRegister, displacement, indexRegister, scale); - - MemorySite* low; - if (result->nextWord != result) { - MemorySite* high = static_cast(site->copyHigh(c)); - low = static_cast(site->copyLow(c)); - - result->nextWord->target = high; - result->nextWord->addSite(c, high); - moveIfConflict(c, result->nextWord, high); - } else { - low = site; - } - - result->target = low; - result->addSite(c, low); - moveIfConflict(c, result, low); - } - - Value* base; - int displacement; - Value* index; - unsigned scale; - Value* result; -}; - -void -appendMemory(Context* c, Value* base, int displacement, Value* index, - unsigned scale, Value* result) -{ - append(c, new(c->zone) - MemoryEvent(c, base, displacement, index, scale, result)); -} - double asFloat(unsigned size, int64_t v) { diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index b0ccd3a48e..4073bcad69 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -1068,6 +1068,112 @@ appendOperation(Context* c, lir::Operation op) append(c, new(c->zone) OperationEvent(c, op)); } +ConstantSite* findConstantSite(Context* c, Value* v) { + for (SiteIterator it(c, v); it.hasMore();) { + Site* s = it.next(); + if (s->type(c) == lir::ConstantOperand) { + return static_cast(s); + } + } + return 0; +} + +void +moveIfConflict(Context* c, Value* v, MemorySite* s) +{ + if (v->reads) { + SiteMask mask(1 << lir::RegisterOperand, ~0, AnyFrameIndex); + v->reads->intersect(&mask); + if (s->conflicts(mask)) { + maybeMove(c, v->reads, true, false); + v->removeSite(c, s); + } + } +} + +class MemoryEvent: public Event { + public: + MemoryEvent(Context* c, Value* base, int displacement, Value* index, + unsigned scale, Value* result): + Event(c), base(base), displacement(displacement), index(index), + scale(scale), result(result) + { + this->addRead(c, base, generalRegisterMask(c)); + if (index) { + this->addRead(c, index, generalRegisterOrConstantMask(c)); + } + } + + virtual const char* name() { + return "MemoryEvent"; + } + + virtual void compile(Context* c) { + int indexRegister; + int displacement = this->displacement; + unsigned scale = this->scale; + if (index) { + ConstantSite* constant = findConstantSite(c, index); + + if (constant) { + indexRegister = lir::NoRegister; + displacement += (constant->value->value() * scale); + scale = 1; + } else { + assert(c, index->source->type(c) == lir::RegisterOperand); + indexRegister = static_cast(index->source)->number; + } + } else { + indexRegister = lir::NoRegister; + } + assert(c, base->source->type(c) == lir::RegisterOperand); + int baseRegister = static_cast(base->source)->number; + + popRead(c, this, base); + if (index) { + if (vm::TargetBytesPerWord == 8 and indexRegister != lir::NoRegister) { + apply(c, lir::Move, 4, index->source, index->source, + 8, index->source, index->source); + } + + popRead(c, this, index); + } + + MemorySite* site = memorySite + (c, baseRegister, displacement, indexRegister, scale); + + MemorySite* low; + if (result->nextWord != result) { + MemorySite* high = static_cast(site->copyHigh(c)); + low = static_cast(site->copyLow(c)); + + result->nextWord->target = high; + result->nextWord->addSite(c, high); + moveIfConflict(c, result->nextWord, high); + } else { + low = site; + } + + result->target = low; + result->addSite(c, low); + moveIfConflict(c, result, low); + } + + Value* base; + int displacement; + Value* index; + unsigned scale; + Value* result; +}; + +void +appendMemory(Context* c, Value* base, int displacement, Value* index, + unsigned scale, Value* result) +{ + append(c, new(c->zone) + MemoryEvent(c, base, displacement, index, scale, result)); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index 22a812657b..89188a245b 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -135,6 +135,10 @@ appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize, void appendOperation(Context* c, lir::Operation op); +void +appendMemory(Context* c, Value* base, int displacement, Value* index, + unsigned scale, Value* result); + } // namespace compiler } // namespace codegen } // namespace avian From 65b7cf047c9c5534a32b4d32ce4c3e7987d30a8e Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 20:43:42 -0700 Subject: [PATCH 16/23] move BranchEvent out of compiler.cpp --- src/codegen/compiler.cpp | 237 --------------------------------- src/codegen/compiler/event.cpp | 235 ++++++++++++++++++++++++++++++++ src/codegen/compiler/event.h | 4 + 3 files changed, 239 insertions(+), 237 deletions(-) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index ab16fb5446..d44426b46f 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -1586,243 +1586,6 @@ register_(Context* c, int number) return value(c, type, s, s); } -double -asFloat(unsigned size, int64_t v) -{ - if (size == 4) { - return bitsToFloat(v); - } else { - return bitsToDouble(v); - } -} - -bool -unordered(double a, double b) -{ - return not (a >= b or a < b); -} - -bool -shouldJump(Context* c, lir::TernaryOperation type, unsigned size, int64_t b, - int64_t a) -{ - switch (type) { - case lir::JumpIfEqual: - return a == b; - - case lir::JumpIfNotEqual: - return a != b; - - case lir::JumpIfLess: - return a < b; - - case lir::JumpIfGreater: - return a > b; - - case lir::JumpIfLessOrEqual: - return a <= b; - - case lir::JumpIfGreaterOrEqual: - return a >= b; - - case lir::JumpIfFloatEqual: - return asFloat(size, a) == asFloat(size, b); - - case lir::JumpIfFloatNotEqual: - return asFloat(size, a) != asFloat(size, b); - - case lir::JumpIfFloatLess: - return asFloat(size, a) < asFloat(size, b); - - case lir::JumpIfFloatGreater: - return asFloat(size, a) > asFloat(size, b); - - case lir::JumpIfFloatLessOrEqual: - return asFloat(size, a) <= asFloat(size, b); - - case lir::JumpIfFloatGreaterOrEqual: - return asFloat(size, a) >= asFloat(size, b); - - case lir::JumpIfFloatLessOrUnordered: - return asFloat(size, a) < asFloat(size, b) - or unordered(asFloat(size, a), asFloat(size, b)); - - case lir::JumpIfFloatGreaterOrUnordered: - return asFloat(size, a) > asFloat(size, b) - or unordered(asFloat(size, a), asFloat(size, b)); - - case lir::JumpIfFloatLessOrEqualOrUnordered: - return asFloat(size, a) <= asFloat(size, b) - or unordered(asFloat(size, a), asFloat(size, b)); - - case lir::JumpIfFloatGreaterOrEqualOrUnordered: - return asFloat(size, a) >= asFloat(size, b) - or unordered(asFloat(size, a), asFloat(size, b)); - - default: - abort(c); - } -} - -lir::TernaryOperation -thunkBranch(Context* c, lir::TernaryOperation type) -{ - switch (type) { - case lir::JumpIfFloatEqual: - return lir::JumpIfEqual; - - case lir::JumpIfFloatNotEqual: - return lir::JumpIfNotEqual; - - case lir::JumpIfFloatLess: - case lir::JumpIfFloatLessOrUnordered: - return lir::JumpIfLess; - - case lir::JumpIfFloatGreater: - case lir::JumpIfFloatGreaterOrUnordered: - return lir::JumpIfGreater; - - case lir::JumpIfFloatLessOrEqual: - case lir::JumpIfFloatLessOrEqualOrUnordered: - return lir::JumpIfLessOrEqual; - - case lir::JumpIfFloatGreaterOrEqual: - case lir::JumpIfFloatGreaterOrEqualOrUnordered: - return lir::JumpIfGreaterOrEqual; - - default: - abort(c); - } -} - -class BranchEvent: public Event { - public: - BranchEvent(Context* c, lir::TernaryOperation type, unsigned size, - Value* first, Value* second, Value* address, - const SiteMask& firstLowMask, - const SiteMask& firstHighMask, - const SiteMask& secondLowMask, - const SiteMask& secondHighMask): - Event(c), type(type), size(size), first(first), second(second), - address(address) - { - this->addReads(c, first, size, firstLowMask, firstHighMask); - this->addReads(c, second, size, secondLowMask, secondHighMask); - - uint8_t typeMask; - uint64_t registerMask; - c->arch->planDestination(type, size, 0, 0, size, 0, 0, TargetBytesPerWord, - &typeMask, ®isterMask); - - this->addRead(c, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); - } - - virtual const char* name() { - return "BranchEvent"; - } - - virtual void compile(Context* c) { - ConstantSite* firstConstant = findConstantSite(c, first); - ConstantSite* secondConstant = findConstantSite(c, second); - - if (not this->isUnreachable()) { - if (firstConstant - and secondConstant - and firstConstant->value->resolved() - and secondConstant->value->resolved()) - { - int64_t firstValue = firstConstant->value->value(); - int64_t secondValue = secondConstant->value->value(); - - if (size > TargetBytesPerWord) { - firstValue |= findConstantSite - (c, first->nextWord)->value->value() << 32; - secondValue |= findConstantSite - (c, second->nextWord)->value->value() << 32; - } - - if (shouldJump(c, type, size, firstValue, secondValue)) { - apply(c, lir::Jump, TargetBytesPerWord, address->source, address->source); - } - } else { - freezeSource(c, size, first); - freezeSource(c, size, second); - freezeSource(c, TargetBytesPerWord, address); - - apply(c, type, size, first->source, first->nextWord->source, - size, second->source, second->nextWord->source, - TargetBytesPerWord, address->source, address->source); - - thawSource(c, TargetBytesPerWord, address); - thawSource(c, size, second); - thawSource(c, size, first); - } - } - - for (Read* r = reads; r; r = r->eventNext) { - popRead(c, this, r->value); - } - } - - virtual bool isBranch() { return true; } - - lir::TernaryOperation type; - unsigned size; - Value* first; - Value* second; - Value* address; -}; - -void -appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first, - Value* second, Value* address) -{ - bool thunk; - uint8_t firstTypeMask; - uint64_t firstRegisterMask; - uint8_t secondTypeMask; - uint64_t secondRegisterMask; - - c->arch->planSource(type, size, &firstTypeMask, &firstRegisterMask, - size, &secondTypeMask, &secondRegisterMask, - TargetBytesPerWord, &thunk); - - if (thunk) { - Stack* oldStack = c->stack; - - bool threadParameter; - intptr_t handler = c->client->getThunk - (type, size, size, &threadParameter); - - assert(c, not threadParameter); - - compiler::push(c, ceilingDivide(size, TargetBytesPerWord), second); - compiler::push(c, ceilingDivide(size, TargetBytesPerWord), first); - - Stack* argumentStack = c->stack; - c->stack = oldStack; - - Value* result = value(c, lir::ValueGeneral); - appendCall - (c, value - (c, lir::ValueGeneral, constantSite(c, handler)), 0, 0, result, 4, - argumentStack, ceilingDivide(size, TargetBytesPerWord) * 2, 0); - - appendBranch(c, thunkBranch(c, type), 4, value - (c, lir::ValueGeneral, constantSite(c, static_cast(0))), - result, address); - } else { - append - (c, new(c->zone) - BranchEvent - (c, type, size, first, second, address, - SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex), - SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex), - SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex), - SiteMask(secondTypeMask, secondRegisterMask >> 32, AnyFrameIndex))); - } -} - class JumpEvent: public Event { public: JumpEvent(Context* c, lir::UnaryOperation type, Value* address, bool exit, diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 4073bcad69..1722714df4 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -1174,6 +1174,241 @@ appendMemory(Context* c, Value* base, int displacement, Value* index, MemoryEvent(c, base, displacement, index, scale, result)); } +double asFloat(unsigned size, int64_t v) { + if (size == 4) { + return vm::bitsToFloat(v); + } else { + return vm::bitsToDouble(v); + } +} + +bool +unordered(double a, double b) +{ + return not (a >= b or a < b); +} + +bool +shouldJump(Context* c, lir::TernaryOperation type, unsigned size, int64_t b, + int64_t a) +{ + switch (type) { + case lir::JumpIfEqual: + return a == b; + + case lir::JumpIfNotEqual: + return a != b; + + case lir::JumpIfLess: + return a < b; + + case lir::JumpIfGreater: + return a > b; + + case lir::JumpIfLessOrEqual: + return a <= b; + + case lir::JumpIfGreaterOrEqual: + return a >= b; + + case lir::JumpIfFloatEqual: + return asFloat(size, a) == asFloat(size, b); + + case lir::JumpIfFloatNotEqual: + return asFloat(size, a) != asFloat(size, b); + + case lir::JumpIfFloatLess: + return asFloat(size, a) < asFloat(size, b); + + case lir::JumpIfFloatGreater: + return asFloat(size, a) > asFloat(size, b); + + case lir::JumpIfFloatLessOrEqual: + return asFloat(size, a) <= asFloat(size, b); + + case lir::JumpIfFloatGreaterOrEqual: + return asFloat(size, a) >= asFloat(size, b); + + case lir::JumpIfFloatLessOrUnordered: + return asFloat(size, a) < asFloat(size, b) + or unordered(asFloat(size, a), asFloat(size, b)); + + case lir::JumpIfFloatGreaterOrUnordered: + return asFloat(size, a) > asFloat(size, b) + or unordered(asFloat(size, a), asFloat(size, b)); + + case lir::JumpIfFloatLessOrEqualOrUnordered: + return asFloat(size, a) <= asFloat(size, b) + or unordered(asFloat(size, a), asFloat(size, b)); + + case lir::JumpIfFloatGreaterOrEqualOrUnordered: + return asFloat(size, a) >= asFloat(size, b) + or unordered(asFloat(size, a), asFloat(size, b)); + + default: + abort(c); + } +} + +lir::TernaryOperation +thunkBranch(Context* c, lir::TernaryOperation type) +{ + switch (type) { + case lir::JumpIfFloatEqual: + return lir::JumpIfEqual; + + case lir::JumpIfFloatNotEqual: + return lir::JumpIfNotEqual; + + case lir::JumpIfFloatLess: + case lir::JumpIfFloatLessOrUnordered: + return lir::JumpIfLess; + + case lir::JumpIfFloatGreater: + case lir::JumpIfFloatGreaterOrUnordered: + return lir::JumpIfGreater; + + case lir::JumpIfFloatLessOrEqual: + case lir::JumpIfFloatLessOrEqualOrUnordered: + return lir::JumpIfLessOrEqual; + + case lir::JumpIfFloatGreaterOrEqual: + case lir::JumpIfFloatGreaterOrEqualOrUnordered: + return lir::JumpIfGreaterOrEqual; + + default: + abort(c); + } +} + +class BranchEvent: public Event { + public: + BranchEvent(Context* c, lir::TernaryOperation type, unsigned size, + Value* first, Value* second, Value* address, + const SiteMask& firstLowMask, + const SiteMask& firstHighMask, + const SiteMask& secondLowMask, + const SiteMask& secondHighMask): + Event(c), type(type), size(size), first(first), second(second), + address(address) + { + this->addReads(c, first, size, firstLowMask, firstHighMask); + this->addReads(c, second, size, secondLowMask, secondHighMask); + + uint8_t typeMask; + uint64_t registerMask; + c->arch->planDestination(type, size, 0, 0, size, 0, 0, vm::TargetBytesPerWord, + &typeMask, ®isterMask); + + this->addRead(c, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); + } + + virtual const char* name() { + return "BranchEvent"; + } + + virtual void compile(Context* c) { + ConstantSite* firstConstant = findConstantSite(c, first); + ConstantSite* secondConstant = findConstantSite(c, second); + + if (not this->isUnreachable()) { + if (firstConstant + and secondConstant + and firstConstant->value->resolved() + and secondConstant->value->resolved()) + { + int64_t firstValue = firstConstant->value->value(); + int64_t secondValue = secondConstant->value->value(); + + if (size > vm::TargetBytesPerWord) { + firstValue |= findConstantSite + (c, first->nextWord)->value->value() << 32; + secondValue |= findConstantSite + (c, second->nextWord)->value->value() << 32; + } + + if (shouldJump(c, type, size, firstValue, secondValue)) { + apply(c, lir::Jump, vm::TargetBytesPerWord, address->source, address->source); + } + } else { + freezeSource(c, size, first); + freezeSource(c, size, second); + freezeSource(c, vm::TargetBytesPerWord, address); + + apply(c, type, size, first->source, first->nextWord->source, + size, second->source, second->nextWord->source, + vm::TargetBytesPerWord, address->source, address->source); + + thawSource(c, vm::TargetBytesPerWord, address); + thawSource(c, size, second); + thawSource(c, size, first); + } + } + + for (Read* r = reads; r; r = r->eventNext) { + popRead(c, this, r->value); + } + } + + virtual bool isBranch() { return true; } + + lir::TernaryOperation type; + unsigned size; + Value* first; + Value* second; + Value* address; +}; + +void +appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first, + Value* second, Value* address) +{ + bool thunk; + uint8_t firstTypeMask; + uint64_t firstRegisterMask; + uint8_t secondTypeMask; + uint64_t secondRegisterMask; + + c->arch->planSource(type, size, &firstTypeMask, &firstRegisterMask, + size, &secondTypeMask, &secondRegisterMask, + vm::TargetBytesPerWord, &thunk); + + if (thunk) { + Stack* oldStack = c->stack; + + bool threadParameter; + intptr_t handler = c->client->getThunk + (type, size, size, &threadParameter); + + assert(c, not threadParameter); + + compiler::push(c, vm::ceilingDivide(size, vm::TargetBytesPerWord), second); + compiler::push(c, vm::ceilingDivide(size, vm::TargetBytesPerWord), first); + + Stack* argumentStack = c->stack; + c->stack = oldStack; + + Value* result = value(c, lir::ValueGeneral); + appendCall + (c, value + (c, lir::ValueGeneral, constantSite(c, handler)), 0, 0, result, 4, + argumentStack, vm::ceilingDivide(size, vm::TargetBytesPerWord) * 2, 0); + + appendBranch(c, thunkBranch(c, type), 4, value + (c, lir::ValueGeneral, constantSite(c, static_cast(0))), + result, address); + } else { + append + (c, new(c->zone) + BranchEvent + (c, type, size, first, second, address, + SiteMask(firstTypeMask, firstRegisterMask, AnyFrameIndex), + SiteMask(firstTypeMask, firstRegisterMask >> 32, AnyFrameIndex), + SiteMask(secondTypeMask, secondRegisterMask, AnyFrameIndex), + SiteMask(secondTypeMask, secondRegisterMask >> 32, AnyFrameIndex))); + } +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index 89188a245b..97686c22cf 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -139,6 +139,10 @@ void appendMemory(Context* c, Value* base, int displacement, Value* index, unsigned scale, Value* result); +void +appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first, + Value* second, Value* address); + } // namespace compiler } // namespace codegen } // namespace avian From d00950458f3705993e7e0beaeb630e6973fb518f Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 21:34:59 -0700 Subject: [PATCH 17/23] move JumpEvent out of compiler.cpp --- makefile | 1 + src/codegen/compiler.cpp | 232 +-------------------------------- src/codegen/compiler/event.cpp | 97 +++++++++++++- src/codegen/compiler/event.h | 4 + src/codegen/compiler/frame.cpp | 119 +++++++++++++++++ src/codegen/compiler/frame.h | 75 +++++++++++ src/codegen/compiler/stack.h | 35 ----- 7 files changed, 297 insertions(+), 266 deletions(-) create mode 100644 src/codegen/compiler/frame.cpp create mode 100644 src/codegen/compiler/frame.h delete mode 100644 src/codegen/compiler/stack.h diff --git a/makefile b/makefile index 5e14ad1d7e..1dd25da9a6 100755 --- a/makefile +++ b/makefile @@ -961,6 +961,7 @@ ifeq ($(process),compile) $(src)/codegen/compiler/read.cpp \ $(src)/codegen/compiler/event.cpp \ $(src)/codegen/compiler/promise.cpp \ + $(src)/codegen/compiler/frame.cpp \ $(src)/codegen/registers.cpp \ $(src)/codegen/targets.cpp diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index d44426b46f..e8bba8e44f 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -22,8 +22,8 @@ #include "codegen/compiler/site.h" #include "codegen/compiler/read.h" #include "codegen/compiler/event.h" -#include "codegen/compiler/stack.h" #include "codegen/compiler/promise.h" +#include "codegen/compiler/frame.h" using namespace vm; @@ -67,11 +67,6 @@ apply(Context* c, lir::TernaryOperation op, unsigned s2Size, Site* s2Low, Site* s2High, unsigned s3Size, Site* s3Low, Site* s3High); -class Local { - public: - Value* value; -}; - class ForkElement { public: Value* value; @@ -220,118 +215,6 @@ countSuccessors(Link* link) return c; } -unsigned -totalFrameSize(Context* c) -{ - return c->alignedFrameSize - + c->arch->frameHeaderSize() - + c->arch->argumentFootprint(c->parameterFootprint); -} - -int -frameIndex(Context* c, int localIndex) -{ - assert(c, localIndex >= 0); - - int index = c->alignedFrameSize + c->parameterFootprint - localIndex - 1; - - if (localIndex < static_cast(c->parameterFootprint)) { - index += c->arch->frameHeaderSize(); - } else { - index -= c->arch->frameFooterSize(); - } - - assert(c, index >= 0); - assert(c, static_cast(index) < totalFrameSize(c)); - - return index; -} - -unsigned -frameIndexToOffset(Context* c, unsigned frameIndex) -{ - assert(c, frameIndex < totalFrameSize(c)); - - return (frameIndex + c->arch->frameFooterSize()) * TargetBytesPerWord; -} - -unsigned -offsetToFrameIndex(Context* c, unsigned offset) -{ - assert(c, static_cast - ((offset / TargetBytesPerWord) - c->arch->frameFooterSize()) >= 0); - assert(c, ((offset / TargetBytesPerWord) - c->arch->frameFooterSize()) - < totalFrameSize(c)); - - return (offset / TargetBytesPerWord) - c->arch->frameFooterSize(); -} - -unsigned -frameBase(Context* c) -{ - return c->alignedFrameSize - - c->arch->frameReturnAddressSize() - - c->arch->frameFooterSize() - + c->arch->frameHeaderSize(); -} - -class FrameIterator { - public: - class Element { - public: - Element(Value* value, unsigned localIndex): - value(value), localIndex(localIndex) - { } - - Value* const value; - const unsigned localIndex; - }; - - FrameIterator(Context* c, Stack* stack, Local* locals, - bool includeEmpty = false): - stack(stack), locals(locals), localIndex(c->localFootprint - 1), - includeEmpty(includeEmpty) - { } - - bool hasMore() { - if (not includeEmpty) { - while (stack and stack->value == 0) stack = stack->next; - - while (localIndex >= 0 and locals[localIndex].value == 0) -- localIndex; - } - - return stack != 0 or localIndex >= 0; - } - - Element next(Context* c) { - Value* v; - unsigned li; - if (stack) { - Stack* s = stack; - v = s->value; - li = s->index + c->localFootprint; - stack = stack->next; - } else { - Local* l = locals + localIndex; - v = l->value; - li = localIndex; - -- localIndex; - } - return Element(v, li); - } - - Stack* stack; - Local* locals; - int localIndex; - bool includeEmpty; -}; - -int -frameIndex(Context* c, FrameIterator::Element* element) -{ - return frameIndex(c, element->localIndex); -} - void clearSites(Context* c, Value* v) { @@ -1021,44 +904,6 @@ apply(Context* c, lir::TernaryOperation op, OperandInfo(s3Size, s3Type, &s3Union)); } -void -clean(Context* c, Value* v, unsigned popIndex) -{ - for (SiteIterator it(c, v); it.hasMore();) { - Site* s = it.next(); - if (not (s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex)) - and offsetToFrameIndex - (c, static_cast(s)->offset) - >= popIndex)) - { - if (false and - s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex))) - { - char buffer[256]; s->toString(c, buffer, 256); - fprintf(stderr, "remove %s from %p at %d pop offset 0x%x\n", - buffer, v, offsetToFrameIndex - (c, static_cast(s)->offset), - frameIndexToOffset(c, popIndex)); - } - it.remove(c); - } - } -} - -void -clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads, - unsigned popIndex) -{ - for (FrameIterator it(c, stack, locals); it.hasMore();) { - FrameIterator::Element e = it.next(c); - clean(c, e.value, popIndex); - } - - for (Read* r = reads; r; r = r->eventNext) { - popRead(c, e, r->value); - } -} - void append(Context* c, Event* e); @@ -1366,12 +1211,6 @@ makeSnapshots(Context* c, Value* value, Snapshot* next) return next; } -Stack* -stack(Context* c, Value* value, Stack* next) -{ - return new(c->zone) Stack(next ? next->index + 1 : 0, value, next); -} - Value* maybeBuddy(Context* c, Value* v); @@ -1586,63 +1425,6 @@ register_(Context* c, int number) return value(c, type, s, s); } -class JumpEvent: public Event { - public: - JumpEvent(Context* c, lir::UnaryOperation type, Value* address, bool exit, - bool cleanLocals): - Event(c), type(type), address(address), exit(exit), - cleanLocals(cleanLocals) - { - bool thunk; - uint8_t typeMask; - uint64_t registerMask; - c->arch->plan(type, TargetBytesPerWord, &typeMask, ®isterMask, &thunk); - - assert(c, not thunk); - - this->addRead(c, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); - } - - virtual const char* name() { - return "JumpEvent"; - } - - virtual void compile(Context* c) { - if (not this->isUnreachable()) { - apply(c, type, TargetBytesPerWord, address->source, address->source); - } - - for (Read* r = reads; r; r = r->eventNext) { - popRead(c, this, r->value); - } - - if (cleanLocals) { - for (FrameIterator it(c, 0, c->locals); it.hasMore();) { - FrameIterator::Element e = it.next(c); - clean(c, e.value, 0); - } - } - } - - virtual bool isBranch() { return true; } - - virtual bool allExits() { - return exit or this->isUnreachable(); - } - - lir::UnaryOperation type; - Value* address; - bool exit; - bool cleanLocals; -}; - -void -appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit = false, - bool cleanLocals = false) -{ - append(c, new(c->zone) JumpEvent(c, type, address, exit, cleanLocals)); -} - class BoundsCheckEvent: public Event { public: BoundsCheckEvent(Context* c, Value* object, unsigned lengthOffset, @@ -2053,7 +1835,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen, char buffer[256]; s->toString(c, buffer, 256); fprintf(stderr, "resolve original %s for %p local %d frame %d\n", - buffer, v, el.localIndex, frameIndex(c, &el)); + buffer, v, el.localIndex, el.frameIndex(c)); } Site* target = pickSiteOrMove @@ -2068,7 +1850,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen, char buffer[256]; s->toString(c, buffer, 256); fprintf(stderr, "freeze original %s for %p local %d frame %d\n", - buffer, v, el.localIndex, frameIndex(c, &el)); + buffer, v, el.localIndex, el.frameIndex(c)); } Value dummy(0, 0, lir::ValueGeneral); @@ -2101,7 +1883,7 @@ resolveSourceSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites) if (DebugControl) { char buffer[256]; s->toString(c, buffer, 256); fprintf(stderr, "resolve source %s from %p local %d frame %d\n", - buffer, v, el.localIndex, frameIndex(c, &el)); + buffer, v, el.localIndex, el.frameIndex(c)); } freeze(c, frozen, s, v); @@ -2142,7 +1924,7 @@ resolveTargetSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites) if (DebugControl) { char buffer[256]; sites[el.localIndex]->toString(c, buffer, 256); fprintf(stderr, "resolve target %s for %p local %d frame %d\n", - buffer, el.value, el.localIndex, frameIndex(c, &el)); + buffer, el.value, el.localIndex, el.frameIndex(c)); } } } @@ -2258,11 +2040,11 @@ setSites(Context* c, Event* e, Site** sites) } else if (DebugControl) { char buffer[256]; sitesToString(c, sites[el.localIndex], buffer, 256); fprintf(stderr, "skip sites %s for %p local %d frame %d\n", - buffer, el.value, el.localIndex, frameIndex(c, &el)); + buffer, el.value, el.localIndex, el.frameIndex(c)); } } else if (DebugControl) { fprintf(stderr, "no sites for %p local %d frame %d\n", - el.value, el.localIndex, frameIndex(c, &el)); + el.value, el.localIndex, el.frameIndex(c)); } } } diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 1722714df4..93f12c62b1 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -13,21 +13,16 @@ #include "codegen/compiler/context.h" #include "codegen/compiler/event.h" -#include "codegen/compiler/stack.h" #include "codegen/compiler/site.h" #include "codegen/compiler/read.h" #include "codegen/compiler/value.h" #include "codegen/compiler/promise.h" +#include "codegen/compiler/frame.h" namespace avian { namespace codegen { namespace compiler { - -unsigned frameBase(Context* c); -unsigned totalFrameSize(Context* c); -int frameIndex(Context* c, int localIndex); - SiteMask generalRegisterMask(Context* c); SiteMask generalRegisterOrConstantMask(Context* c); @@ -1409,6 +1404,96 @@ appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first } } +void clean(Context* c, Value* v, unsigned popIndex) { + for (SiteIterator it(c, v); it.hasMore();) { + Site* s = it.next(); + if (not (s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex)) + and offsetToFrameIndex + (c, static_cast(s)->offset) + >= popIndex)) + { + if (false and + s->match(c, SiteMask(1 << lir::MemoryOperand, 0, AnyFrameIndex))) + { + char buffer[256]; s->toString(c, buffer, 256); + fprintf(stderr, "remove %s from %p at %d pop offset 0x%x\n", + buffer, v, offsetToFrameIndex + (c, static_cast(s)->offset), + frameIndexToOffset(c, popIndex)); + } + it.remove(c); + } + } +} + +void +clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads, + unsigned popIndex) +{ + for (FrameIterator it(c, stack, locals); it.hasMore();) { + FrameIterator::Element e = it.next(c); + clean(c, e.value, popIndex); + } + + for (Read* r = reads; r; r = r->eventNext) { + popRead(c, e, r->value); + } +} + +class JumpEvent: public Event { + public: + JumpEvent(Context* c, lir::UnaryOperation type, Value* address, bool exit, + bool cleanLocals): + Event(c), type(type), address(address), exit(exit), + cleanLocals(cleanLocals) + { + bool thunk; + uint8_t typeMask; + uint64_t registerMask; + c->arch->plan(type, vm::TargetBytesPerWord, &typeMask, ®isterMask, &thunk); + + assert(c, not thunk); + + this->addRead(c, address, SiteMask(typeMask, registerMask, AnyFrameIndex)); + } + + virtual const char* name() { + return "JumpEvent"; + } + + virtual void compile(Context* c) { + if (not this->isUnreachable()) { + apply(c, type, vm::TargetBytesPerWord, address->source, address->source); + } + + for (Read* r = reads; r; r = r->eventNext) { + popRead(c, this, r->value); + } + + if (cleanLocals) { + for (FrameIterator it(c, 0, c->locals); it.hasMore();) { + FrameIterator::Element e = it.next(c); + clean(c, e.value, 0); + } + } + } + + virtual bool isBranch() { return true; } + + virtual bool allExits() { + return exit or this->isUnreachable(); + } + + lir::UnaryOperation type; + Value* address; + bool exit; + bool cleanLocals; +}; + +void appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit, bool cleanLocals) { + append(c, new(c->zone) JumpEvent(c, type, address, exit, cleanLocals)); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index 97686c22cf..d3a171baee 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -143,6 +143,10 @@ void appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first, Value* second, Value* address); +void +appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit = false, + bool cleanLocals = false); + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/frame.cpp b/src/codegen/compiler/frame.cpp new file mode 100644 index 0000000000..e879238b79 --- /dev/null +++ b/src/codegen/compiler/frame.cpp @@ -0,0 +1,119 @@ +/* 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 "target.h" + +#include "codegen/compiler/context.h" +#include "codegen/compiler/frame.h" + +namespace avian { +namespace codegen { +namespace compiler { + +unsigned totalFrameSize(Context* c) { + return c->alignedFrameSize + + c->arch->frameHeaderSize() + + c->arch->argumentFootprint(c->parameterFootprint); +} + +int frameIndex(Context* c, int localIndex) { + assert(c, localIndex >= 0); + + int index = c->alignedFrameSize + c->parameterFootprint - localIndex - 1; + + if (localIndex < static_cast(c->parameterFootprint)) { + index += c->arch->frameHeaderSize(); + } else { + index -= c->arch->frameFooterSize(); + } + + assert(c, index >= 0); + assert(c, static_cast(index) < totalFrameSize(c)); + + return index; +} + +unsigned frameIndexToOffset(Context* c, unsigned frameIndex) { + assert(c, frameIndex < totalFrameSize(c)); + + return (frameIndex + c->arch->frameFooterSize()) * vm::TargetBytesPerWord; +} + +unsigned offsetToFrameIndex(Context* c, unsigned offset) { + assert(c, static_cast + ((offset / vm::TargetBytesPerWord) - c->arch->frameFooterSize()) >= 0); + assert(c, ((offset / vm::TargetBytesPerWord) - c->arch->frameFooterSize()) + < totalFrameSize(c)); + + return (offset / vm::TargetBytesPerWord) - c->arch->frameFooterSize(); +} + +unsigned frameBase(Context* c) { + return c->alignedFrameSize + - c->arch->frameReturnAddressSize() + - c->arch->frameFooterSize() + + c->arch->frameHeaderSize(); +} + +FrameIterator::Element::Element(Value* value, unsigned localIndex): + value(value), localIndex(localIndex) +{ } + + +int FrameIterator::Element::frameIndex(Context* c) { + return compiler::frameIndex(c, this->localIndex); +} + +FrameIterator::FrameIterator(Context* c, Stack* stack, Local* locals, + bool includeEmpty): + stack(stack), locals(locals), localIndex(c->localFootprint - 1), + includeEmpty(includeEmpty) +{ } + +bool FrameIterator::hasMore() { + if (not includeEmpty) { + while (stack and stack->value == 0) { + stack = stack->next; + } + + while (localIndex >= 0 and locals[localIndex].value == 0) { + -- localIndex; + } + } + + return stack != 0 or localIndex >= 0; +} + +FrameIterator::Element FrameIterator::next(Context* c) { + Value* v; + unsigned li; + if (stack) { + Stack* s = stack; + v = s->value; + li = s->index + c->localFootprint; + stack = stack->next; + } else { + Local* l = locals + localIndex; + v = l->value; + li = localIndex; + -- localIndex; + } + return Element(v, li); +} + +Stack* stack(Context* c, Value* value, Stack* next) { + return new(c->zone) Stack(next ? next->index + 1 : 0, value, next); +} + + + +} // namespace compiler +} // namespace codegen +} // namespace avian diff --git a/src/codegen/compiler/frame.h b/src/codegen/compiler/frame.h new file mode 100644 index 0000000000..3ae47dfae9 --- /dev/null +++ b/src/codegen/compiler/frame.h @@ -0,0 +1,75 @@ +/* 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_COMPILER_FRAME_H +#define AVIAN_CODEGEN_COMPILER_FRAME_H + +namespace avian { +namespace codegen { +namespace compiler { + +unsigned totalFrameSize(Context* c); + +int frameIndex(Context* c, int localIndex); + +unsigned frameIndexToOffset(Context* c, unsigned frameIndex); + +unsigned offsetToFrameIndex(Context* c, unsigned offset); + +unsigned frameBase(Context* c); + +class FrameIterator { + public: + class Element { + public: + Element(Value* value, unsigned localIndex); + + int frameIndex(Context* c); + + Value* const value; + const unsigned localIndex; + }; + + FrameIterator(Context* c, Stack* stack, Local* locals, + bool includeEmpty = false); + + bool hasMore(); + + Element next(Context* c); + + Stack* stack; + Local* locals; + int localIndex; + bool includeEmpty; +}; + +class Local { + public: + Value* value; +}; + +class Stack { + public: + Stack(unsigned index, Value* value, Stack* next): + index(index), value(value), next(next) + { } + + unsigned index; + Value* value; + Stack* next; +}; + +Stack* stack(Context* c, Value* value, Stack* next); + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_FRAME_H diff --git a/src/codegen/compiler/stack.h b/src/codegen/compiler/stack.h deleted file mode 100644 index 7ae8c4f7c1..0000000000 --- a/src/codegen/compiler/stack.h +++ /dev/null @@ -1,35 +0,0 @@ -/* 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_COMPILER_STACK_H -#define AVIAN_CODEGEN_COMPILER_STACK_H - -namespace avian { -namespace codegen { -namespace compiler { - -class Value; - -class Stack { - public: - Stack(unsigned index, Value* value, Stack* next): - index(index), value(value), next(next) - { } - - unsigned index; - Value* value; - Stack* next; -}; - -} // namespace compiler -} // namespace codegen -} // namespace avian - -#endif // AVIAN_CODEGEN_COMPILER_STACK_H From be86d26512407b788c52c9a8422fcf534c189643 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 21:49:37 -0700 Subject: [PATCH 18/23] move BoundsCheckEvent out of compiler.cpp --- src/codegen/compiler.cpp | 101 +------------------------------ src/codegen/compiler/event.cpp | 84 +++++++++++++++++++++++++ src/codegen/compiler/event.h | 4 ++ src/codegen/compiler/promise.cpp | 36 ++++++++++- src/codegen/compiler/promise.h | 26 +++----- src/codegen/compiler/site.cpp | 10 +-- 6 files changed, 137 insertions(+), 124 deletions(-) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index e8bba8e44f..ee79e97a8f 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -14,6 +14,7 @@ #include "codegen/compiler.h" #include "codegen/assembler.h" +#include "codegen/promise.h" #include "codegen/compiler/regalloc.h" #include "codegen/compiler/context.h" @@ -358,18 +359,6 @@ valueType(Context* c, Compiler::OperandType type) } } -Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask) { - return new(c->zone) ShiftMaskPromise(base, shift, mask); -} - -Promise* combinedPromise(Context* c, Promise* low, Promise* high) { - return new(c->zone) CombinedPromise(low, high); -} - -Promise* resolved(Context* c, int64_t value) { - return new(c->zone) ResolvedPromise(value); -} - void move(Context* c, Value* value, Site* src, Site* dst); @@ -1425,90 +1414,6 @@ register_(Context* c, int number) return value(c, type, s, s); } -class BoundsCheckEvent: public Event { - public: - BoundsCheckEvent(Context* c, Value* object, unsigned lengthOffset, - Value* index, intptr_t handler): - Event(c), object(object), lengthOffset(lengthOffset), index(index), - handler(handler) - { - this->addRead(c, object, generalRegisterMask(c)); - this->addRead(c, index, generalRegisterOrConstantMask(c)); - } - - virtual const char* name() { - return "BoundsCheckEvent"; - } - - virtual void compile(Context* c) { - Assembler* a = c->assembler; - - ConstantSite* constant = findConstantSite(c, index); - CodePromise* outOfBoundsPromise = 0; - - if (constant) { - if (constant->value->value() < 0) { - lir::Constant handlerConstant(resolved(c, handler)); - a->apply(lir::Call, - OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &handlerConstant)); - } - } else { - outOfBoundsPromise = compiler::codePromise(c, static_cast(0)); - - ConstantSite zero(resolved(c, 0)); - ConstantSite oob(outOfBoundsPromise); - apply(c, lir::JumpIfLess, - 4, &zero, &zero, - 4, index->source, index->source, - TargetBytesPerWord, &oob, &oob); - } - - if (constant == 0 or constant->value->value() >= 0) { - assert(c, object->source->type(c) == lir::RegisterOperand); - MemorySite length(static_cast(object->source)->number, - lengthOffset, lir::NoRegister, 1); - length.acquired = true; - - CodePromise* nextPromise = compiler::codePromise(c, static_cast(0)); - - freezeSource(c, TargetBytesPerWord, index); - - ConstantSite next(nextPromise); - apply(c, lir::JumpIfGreater, - 4, index->source, - index->source, 4, &length, - &length, TargetBytesPerWord, &next, &next); - - thawSource(c, TargetBytesPerWord, index); - - if (constant == 0) { - outOfBoundsPromise->offset = a->offset(); - } - - lir::Constant handlerConstant(resolved(c, handler)); - a->apply(lir::Call, - OperandInfo(TargetBytesPerWord, lir::ConstantOperand, &handlerConstant)); - - nextPromise->offset = a->offset(); - } - - popRead(c, this, object); - popRead(c, this, index); - } - - Value* object; - unsigned lengthOffset; - Value* index; - intptr_t handler; -}; - -void -appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset, - Value* index, intptr_t handler) -{ - append(c, new(c->zone) BoundsCheckEvent(c, object, lengthOffset, index, handler)); -} - class FrameSiteEvent: public Event { public: FrameSiteEvent(Context* c, Value* value, int index): @@ -2650,7 +2555,7 @@ class MyCompiler: public Compiler { } virtual Promise* poolAppend(intptr_t value) { - return poolAppendPromise(resolved(&c, value)); + return poolAppendPromise(resolvedPromise(&c, value)); } virtual Promise* poolAppendPromise(Promise* value) { @@ -2670,7 +2575,7 @@ class MyCompiler: public Compiler { } virtual Operand* constant(int64_t value, Compiler::OperandType type) { - return promiseConstant(resolved(&c, value), type); + return promiseConstant(resolvedPromise(&c, value), type); } virtual Operand* promiseConstant(Promise* value, Compiler::OperandType type) { diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 93f12c62b1..abb170bb1b 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -1494,6 +1494,90 @@ void appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit, append(c, new(c->zone) JumpEvent(c, type, address, exit, cleanLocals)); } +class BoundsCheckEvent: public Event { + public: + BoundsCheckEvent(Context* c, Value* object, unsigned lengthOffset, + Value* index, intptr_t handler): + Event(c), object(object), lengthOffset(lengthOffset), index(index), + handler(handler) + { + this->addRead(c, object, generalRegisterMask(c)); + this->addRead(c, index, generalRegisterOrConstantMask(c)); + } + + virtual const char* name() { + return "BoundsCheckEvent"; + } + + virtual void compile(Context* c) { + Assembler* a = c->assembler; + + ConstantSite* constant = findConstantSite(c, index); + CodePromise* outOfBoundsPromise = 0; + + if (constant) { + if (constant->value->value() < 0) { + lir::Constant handlerConstant(resolvedPromise(c, handler)); + a->apply(lir::Call, + OperandInfo(vm::TargetBytesPerWord, lir::ConstantOperand, &handlerConstant)); + } + } else { + outOfBoundsPromise = compiler::codePromise(c, static_cast(0)); + + ConstantSite zero(resolvedPromise(c, 0)); + ConstantSite oob(outOfBoundsPromise); + apply(c, lir::JumpIfLess, + 4, &zero, &zero, + 4, index->source, index->source, + vm::TargetBytesPerWord, &oob, &oob); + } + + if (constant == 0 or constant->value->value() >= 0) { + assert(c, object->source->type(c) == lir::RegisterOperand); + MemorySite length(static_cast(object->source)->number, + lengthOffset, lir::NoRegister, 1); + length.acquired = true; + + CodePromise* nextPromise = compiler::codePromise(c, static_cast(0)); + + freezeSource(c, vm::TargetBytesPerWord, index); + + ConstantSite next(nextPromise); + apply(c, lir::JumpIfGreater, + 4, index->source, + index->source, 4, &length, + &length, vm::TargetBytesPerWord, &next, &next); + + thawSource(c, vm::TargetBytesPerWord, index); + + if (constant == 0) { + outOfBoundsPromise->offset = a->offset(); + } + + lir::Constant handlerConstant(resolvedPromise(c, handler)); + a->apply(lir::Call, + OperandInfo(vm::TargetBytesPerWord, lir::ConstantOperand, &handlerConstant)); + + nextPromise->offset = a->offset(); + } + + popRead(c, this, object); + popRead(c, this, index); + } + + Value* object; + unsigned lengthOffset; + Value* index; + intptr_t handler; +}; + +void +appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset, + Value* index, intptr_t handler) +{ + append(c, new(c->zone) BoundsCheckEvent(c, object, lengthOffset, index, handler)); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index d3a171baee..ecefcf85d6 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -147,6 +147,10 @@ void appendJump(Context* c, lir::UnaryOperation type, Value* address, bool exit = false, bool cleanLocals = false); +void +appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset, + Value* index, intptr_t handler); + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/promise.cpp b/src/codegen/compiler/promise.cpp index ceb25d89e7..e4e55edbc9 100644 --- a/src/codegen/compiler/promise.cpp +++ b/src/codegen/compiler/promise.cpp @@ -15,12 +15,42 @@ namespace avian { namespace codegen { namespace compiler { -CodePromise* -codePromise(Context* c, Promise* offset) -{ +CodePromise::CodePromise(Context* c, CodePromise* next): + c(c), offset(0), next(next) +{ } + +CodePromise::CodePromise(Context* c, Promise* offset): + c(c), offset(offset), next(0) +{ } + +int64_t CodePromise::value() { + if (resolved()) { + return reinterpret_cast(c->machineCode + offset->value()); + } + + abort(c); +} + +bool CodePromise::resolved() { + return c->machineCode != 0 and offset and offset->resolved(); +} + +CodePromise* codePromise(Context* c, Promise* offset) { return new (c->zone) CodePromise(c, offset); } +Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask) { + return new (c->zone) ShiftMaskPromise(base, shift, mask); +} + +Promise* combinedPromise(Context* c, Promise* low, Promise* high) { + return new (c->zone) CombinedPromise(low, high); +} + +Promise* resolvedPromise(Context* c, int64_t value) { + return new (c->zone) ResolvedPromise(value); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/promise.h b/src/codegen/compiler/promise.h index 2afcd49304..d7262b3724 100644 --- a/src/codegen/compiler/promise.h +++ b/src/codegen/compiler/promise.h @@ -18,25 +18,13 @@ namespace compiler { class CodePromise: public Promise { public: - CodePromise(Context* c, CodePromise* next): - c(c), offset(0), next(next) - { } + CodePromise(Context* c, CodePromise* next); - CodePromise(Context* c, Promise* offset): - c(c), offset(offset), next(0) - { } + CodePromise(Context* c, Promise* offset); - virtual int64_t value() { - if (resolved()) { - return reinterpret_cast(c->machineCode + offset->value()); - } - - abort(c); - } + virtual int64_t value(); - virtual bool resolved() { - return c->machineCode != 0 and offset and offset->resolved(); - } + virtual bool resolved(); Context* c; Promise* offset; @@ -45,6 +33,12 @@ class CodePromise: public Promise { CodePromise* codePromise(Context* c, Promise* offset); +Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask); + +Promise* combinedPromise(Context* c, Promise* low, Promise* high); + +Promise* resolvedPromise(Context* c, int64_t value); + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/site.cpp b/src/codegen/compiler/site.cpp index d05a09cd64..dc877b9e1e 100644 --- a/src/codegen/compiler/site.cpp +++ b/src/codegen/compiler/site.cpp @@ -14,18 +14,14 @@ #include "codegen/compiler/value.h" #include "codegen/compiler/site.h" #include "codegen/compiler/resource.h" +#include "codegen/compiler/frame.h" +#include "codegen/compiler/promise.h" namespace avian { namespace codegen { namespace compiler { -unsigned frameIndexToOffset(Context* c, unsigned frameIndex); - -unsigned offsetToFrameIndex(Context* c, unsigned offset); - -ResolvedPromise* resolved(Context* c, int64_t value); - int intersectFrameIndexes(int a, int b) { if (a == NoFrameIndex or b == NoFrameIndex) return NoFrameIndex; @@ -120,7 +116,7 @@ Site* constantSite(Context* c, Promise* value) { } Site* constantSite(Context* c, int64_t value) { - return constantSite(c, resolved(c, value)); + return constantSite(c, resolvedPromise(c, value)); } From 94ddb62b5fccca6a2ce9ecf060e10aadd7fdbefa Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 21:52:07 -0700 Subject: [PATCH 19/23] move FrameSiteEvent out of compiler.cpp --- src/codegen/compiler.cpp | 26 -------------------------- src/codegen/compiler/event.cpp | 27 +++++++++++++++++++++++++++ src/codegen/compiler/event.h | 3 +++ 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index ee79e97a8f..5f1f9ab431 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -1414,32 +1414,6 @@ register_(Context* c, int number) return value(c, type, s, s); } -class FrameSiteEvent: public Event { - public: - FrameSiteEvent(Context* c, Value* value, int index): - Event(c), value(value), index(index) - { } - - virtual const char* name() { - return "FrameSiteEvent"; - } - - virtual void compile(Context* c) { - if (live(c, value)) { - value->addSite(c, frameSite(c, index)); - } - } - - Value* value; - int index; -}; - -void -appendFrameSite(Context* c, Value* value, int index) -{ - append(c, new(c->zone) FrameSiteEvent(c, value, index)); -} - unsigned frameFootprint(Context* c, Stack* s) { diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index abb170bb1b..68d3bccfd6 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -1578,6 +1578,33 @@ appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset, append(c, new(c->zone) BoundsCheckEvent(c, object, lengthOffset, index, handler)); } + +class FrameSiteEvent: public Event { + public: + FrameSiteEvent(Context* c, Value* value, int index): + Event(c), value(value), index(index) + { } + + virtual const char* name() { + return "FrameSiteEvent"; + } + + virtual void compile(Context* c) { + if (live(c, value)) { + value->addSite(c, frameSite(c, index)); + } + } + + Value* value; + int index; +}; + +void +appendFrameSite(Context* c, Value* value, int index) +{ + append(c, new(c->zone) FrameSiteEvent(c, value, index)); +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index ecefcf85d6..c28fa6230b 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -151,6 +151,9 @@ void appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset, Value* index, intptr_t handler); +void +appendFrameSite(Context* c, Value* value, int index); + } // namespace compiler } // namespace codegen } // namespace avian From 64d58bdb290ecc4fdf55d46029903f6c11b5e1fb Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 13 Feb 2013 08:48:32 -0700 Subject: [PATCH 20/23] update bootimage.cpp and heapwalk.cpp to reflect function renames --- src/bootimage.cpp | 6 +++--- src/heapwalk.cpp | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/bootimage.cpp b/src/bootimage.cpp index 5a57a40e1c..111d850f97 100644 --- a/src/bootimage.cpp +++ b/src/bootimage.cpp @@ -14,7 +14,7 @@ #include "machine.h" #include "util.h" #include "stream.h" -#include "assembler.h" +#include "codegen/assembler.h" #include "target.h" #include "binaryToObject/tools.h" #include "lzma.h" @@ -31,7 +31,7 @@ namespace { const unsigned HeapCapacity = 512 * 1024 * 1024; const unsigned TargetFixieSizeInBytes = 8 + (TargetBytesPerWord * 2); -const unsigned TargetFixieSizeInWords = ceiling +const unsigned TargetFixieSizeInWords = ceilingDivide (TargetFixieSizeInBytes, TargetBytesPerWord); const unsigned TargetFixieAge = 0; const unsigned TargetFixieFlags = 2; @@ -787,7 +787,7 @@ targetSize(Thread* t, object typeMaps, object referer, unsigned refererOffset, { return (TargetBytesPerWord * 2) + pad - (ceiling + (ceilingDivide (objectMaskCount (classTypeMap(t, typeMaps, referer)), 32) * 4, TargetBytesPerWord); } else { diff --git a/src/heapwalk.cpp b/src/heapwalk.cpp index 69840abf16..8732d28497 100644 --- a/src/heapwalk.cpp +++ b/src/heapwalk.cpp @@ -228,7 +228,8 @@ inline object get(object o, unsigned offsetInWords) { return static_cast - (mask(fieldAtOffset(o, offsetInWords * BytesPerWord))); + (maskAlignedPointer + (fieldAtOffset(o, offsetInWords * BytesPerWord))); } unsigned @@ -297,7 +298,8 @@ class MyHeapWalker: public HeapWalker { Visitor(Context* c, HeapVisitor* v): c(c), v(v) { } virtual void visit(void* p) { - walk(c, v, static_cast(mask(*static_cast(p)))); + walk(c, v, static_cast + (maskAlignedPointer(*static_cast(p)))); } Context* c; From b8fd040ac15be98c74b93a6ca287db827d73bf1b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 13 Feb 2013 09:04:04 -0700 Subject: [PATCH 21/23] include util/runtime-array.h in windows.cpp to fix build --- src/windows.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/windows.cpp b/src/windows.cpp index 02ebfc72b5..5c85eb906e 100644 --- a/src/windows.cpp +++ b/src/windows.cpp @@ -25,6 +25,7 @@ #include "arch.h" #include "system.h" +#include "util/runtime-array.h" #if defined(WINAPI_FAMILY) From a7ab59f1f6caa2c765edc86439e51f5d4d905788 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 13 Feb 2013 09:09:30 -0700 Subject: [PATCH 22/23] switch clean target back to deleting all generated files --- makefile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/makefile b/makefile index 1dd25da9a6..8a3b4a7e81 100755 --- a/makefile +++ b/makefile @@ -1278,11 +1278,6 @@ clean-current: .PHONY: clean clean: - @echo "removing $(build)" - rm -rf $(build) - -.PHONY: clean-all -clean-all: @echo "removing build" rm -rf build From 2db0303e2f21a6331c6d33269d65c78e27499709 Mon Sep 17 00:00:00 2001 From: Joshua Warner Date: Wed, 13 Feb 2013 23:23:07 -0700 Subject: [PATCH 23/23] further compiler cleanup / organization --- makefile | 1 + src/codegen/compiler.cpp | 282 ++----------------------------- src/codegen/compiler/context.h | 12 ++ src/codegen/compiler/event.cpp | 88 ++++++++++ src/codegen/compiler/event.h | 10 ++ src/codegen/compiler/ir.cpp | 48 ++++++ src/codegen/compiler/ir.h | 90 ++++++++++ src/codegen/compiler/promise.cpp | 60 +++++++ src/codegen/compiler/promise.h | 4 + src/codegen/compiler/value.cpp | 10 ++ src/codegen/compiler/value.h | 1 + 11 files changed, 339 insertions(+), 267 deletions(-) create mode 100644 src/codegen/compiler/ir.cpp create mode 100644 src/codegen/compiler/ir.h diff --git a/makefile b/makefile index 8a3b4a7e81..b83d2d45a7 100755 --- a/makefile +++ b/makefile @@ -962,6 +962,7 @@ ifeq ($(process),compile) $(src)/codegen/compiler/event.cpp \ $(src)/codegen/compiler/promise.cpp \ $(src)/codegen/compiler/frame.cpp \ + $(src)/codegen/compiler/ir.cpp \ $(src)/codegen/registers.cpp \ $(src)/codegen/targets.cpp diff --git a/src/codegen/compiler.cpp b/src/codegen/compiler.cpp index 5f1f9ab431..23c62a8b5e 100644 --- a/src/codegen/compiler.cpp +++ b/src/codegen/compiler.cpp @@ -25,6 +25,7 @@ #include "codegen/compiler/event.h" #include "codegen/compiler/promise.h" #include "codegen/compiler/frame.h" +#include "codegen/compiler/ir.h" using namespace vm; @@ -45,14 +46,6 @@ const unsigned StealRegisterReserveCount = 2; // compare instruction: const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4); -class Stack; -class PushEvent; -class Read; -class MultiRead; -class StubRead; -class Block; -class Snapshot; - void apply(Context* c, lir::UnaryOperation op, unsigned s1Size, Site* s1Low, Site* s1High); @@ -68,57 +61,6 @@ apply(Context* c, lir::TernaryOperation op, unsigned s2Size, Site* s2Low, Site* s2High, unsigned s3Size, Site* s3Low, Site* s3High); -class ForkElement { - public: - Value* value; - MultiRead* read; - bool local; -}; - -class ForkState: public Compiler::State { - public: - ForkState(Stack* stack, Local* locals, Cell* saved, Event* predecessor, - unsigned logicalIp): - stack(stack), - locals(locals), - saved(saved), - predecessor(predecessor), - logicalIp(logicalIp), - readCount(0) - { } - - Stack* stack; - Local* locals; - Cell* saved; - Event* predecessor; - unsigned logicalIp; - unsigned readCount; - ForkElement elements[0]; -}; - -class MySubroutine: public Compiler::Subroutine { - public: - MySubroutine(): forkState(0) { } - - ForkState* forkState; -}; - -class LogicalInstruction { - public: - LogicalInstruction(int index, Stack* stack, Local* locals): - firstEvent(0), lastEvent(0), immediatePredecessor(0), stack(stack), - locals(locals), machineOffset(0), subroutine(0), index(index) - { } - - Event* firstEvent; - Event* lastEvent; - LogicalInstruction* immediatePredecessor; - Stack* stack; - Local* locals; - Promise* machineOffset; - MySubroutine* subroutine; - int index; -}; class ConstantPoolNode { public: @@ -128,106 +70,6 @@ class ConstantPoolNode { ConstantPoolNode* next; }; -class PoolPromise: public Promise { - public: - PoolPromise(Context* c, int key): c(c), key(key) { } - - virtual int64_t value() { - if (resolved()) { - return reinterpret_cast - (c->machineCode + pad(c->machineCodeSize, TargetBytesPerWord) - + (key * TargetBytesPerWord)); - } - - abort(c); - } - - virtual bool resolved() { - return c->machineCode != 0; - } - - Context* c; - int key; -}; - -unsigned -machineOffset(Context* c, int logicalIp) -{ - return c->logicalCode[logicalIp]->machineOffset->value(); -} - -class IpPromise: public Promise { - public: - IpPromise(Context* c, int logicalIp): - c(c), - logicalIp(logicalIp) - { } - - virtual int64_t value() { - if (resolved()) { - return reinterpret_cast - (c->machineCode + machineOffset(c, logicalIp)); - } - - abort(c); - } - - virtual bool resolved() { - return c->machineCode != 0 - and c->logicalCode[logicalIp]->machineOffset->resolved(); - } - - Context* c; - int logicalIp; -}; - -template -Cell* reverseDestroy(Cell* cell) { - Cell* previous = 0; - while (cell) { - Cell* next = cell->next; - cell->next = previous; - previous = cell; - cell = next; - } - return previous; -} - -unsigned -countPredecessors(Link* link) -{ - unsigned c = 0; - for (; link; link = link->nextPredecessor) ++ c; - return c; -} - -Link* -lastPredecessor(Link* link) -{ - while (link->nextPredecessor) link = link->nextPredecessor; - return link; -} - -unsigned -countSuccessors(Link* link) -{ - unsigned c = 0; - for (; link; link = link->nextSuccessor) ++ c; - return c; -} - -void -clearSites(Context* c, Value* v) -{ - if (DebugSites) { - fprintf(stderr, "clear sites for %p\n", v); - } - for (SiteIterator it(c, v); it.hasMore();) { - it.next(); - it.remove(c); - } -} - Read* live(Context* c UNUSED, Value* v) { @@ -321,7 +163,7 @@ popRead(Context* c, Event* e UNUSED, Value* v) if (r) { deadBuddy(c, v, r); } else { - clearSites(c, v); + v->clearSites(c); } } } @@ -1140,11 +982,11 @@ removeBuddy(Context* c, Value* v) assert(c, p->buddy); if (not live(c, next)) { - clearSites(c, next); + next->clearSites(c); } if (not live(c, v)) { - clearSites(c, v); + v->clearSites(c); } } } @@ -1437,7 +1279,7 @@ visit(Context* c, Link* link) v->reads = p->read->nextTarget(); // fprintf(stderr, "next read %p for %p from %p\n", v->reads, v, p->read); if (not live(c, v)) { - clearSites(c, v); + v->clearSites(c); } } } @@ -1492,67 +1334,6 @@ appendBuddy(Context* c, Value* original, Value* buddy) append(c, new(c->zone) BuddyEvent(c, original, buddy)); } -class SaveLocalsEvent: public Event { - public: - SaveLocalsEvent(Context* c): - Event(c) - { - saveLocals(c, this); - } - - virtual const char* name() { - return "SaveLocalsEvent"; - } - - virtual void compile(Context* c) { - for (Read* r = reads; r; r = r->eventNext) { - popRead(c, this, r->value); - } - } -}; - -void -appendSaveLocals(Context* c) -{ - append(c, new(c->zone) SaveLocalsEvent(c)); -} - -class DummyEvent: public Event { - public: - DummyEvent(Context* c, Local* locals): - Event(c), - locals_(locals) - { } - - virtual const char* name() { - return "DummyEvent"; - } - - virtual void compile(Context*) { } - - virtual Local* locals() { - return locals_; - } - - Local* locals_; -}; - -void -appendDummy(Context* c) -{ - Stack* stack = c->stack; - Local* locals = c->locals; - LogicalInstruction* i = c->logicalCode[c->logicalIp]; - - c->stack = i->stack; - c->locals = i->locals; - - append(c, new(c->zone) DummyEvent(c, locals)); - - c->stack = stack; - c->locals = locals; -} - void append(Context* c, Event* e) { @@ -1898,11 +1679,11 @@ resetFrame(Context* c, Event* e) { for (FrameIterator it(c, e->stackBefore, e->localsBefore); it.hasMore();) { FrameIterator::Element el = it.next(c); - clearSites(c, el.value); + el.value->clearSites(c); } while (c->acquiredResources) { - clearSites(c, c->acquiredResources->value); + c->acquiredResources->value->clearSites(c); } } @@ -2058,35 +1839,6 @@ updateJunctionReads(Context* c, JunctionState* state) } } -LogicalInstruction* -next(Context* c, LogicalInstruction* i) -{ - for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) { - i = c->logicalCode[n]; - if (i) return i; - } - return 0; -} - -class Block { - public: - Block(Event* head): - head(head), nextBlock(0), nextInstruction(0), assemblerBlock(0), start(0) - { } - - Event* head; - Block* nextBlock; - LogicalInstruction* nextInstruction; - Assembler::Block* assemblerBlock; - unsigned start; -}; - -Block* -block(Context* c, Event* head) -{ - return new(c->zone) Block(head); -} - void compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset) { @@ -2110,8 +1862,8 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset) fprintf(stderr, " -- compile %s at %d with %d preds %d succs %d stack\n", e->name(), e->logicalInstruction->index, - countPredecessors(e->predecessors), - countSuccessors(e->successors), + e->predecessors->countPredecessors(), + e->successors->countSuccessors(), e->stackBefore ? e->stackBefore->index + 1 : 0); } @@ -2125,7 +1877,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset) } if (e->predecessors) { - visit(c, lastPredecessor(e->predecessors)); + visit(c, e->predecessors->lastPredecessor()); Event* first = e->predecessors->predecessor; if (e->predecessors->nextPredecessor) { @@ -2191,7 +1943,7 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset) a->endEvent(); - LogicalInstruction* nextInstruction = next(c, e->logicalInstruction); + LogicalInstruction* nextInstruction = e->logicalInstruction->next(c); if (e->next == 0 or (e->next->logicalInstruction != e->logicalInstruction and (e->next->logicalInstruction != nextInstruction @@ -2433,9 +2185,7 @@ class MyCompiler: public Compiler { memset(c.locals, 0, sizeof(Local) * localFootprint); - c.logicalCode[-1] = new - (c.zone->allocate(sizeof(LogicalInstruction))) - LogicalInstruction(-1, c.stack, c.locals); + c.logicalCode[-1] = new(c.zone) LogicalInstruction(-1, c.stack, c.locals); } virtual void visitLogicalIp(unsigned logicalIp) { @@ -2494,9 +2244,7 @@ class MyCompiler: public Compiler { p->localsAfter = c.locals; } - c.logicalCode[logicalIp] = new - (c.zone->allocate(sizeof(LogicalInstruction))) - LogicalInstruction(logicalIp, c.stack, c.locals); + c.logicalCode[logicalIp] = new(c.zone) LogicalInstruction(logicalIp, c.stack, c.locals); bool startSubroutine = c.subroutine != 0; if (startSubroutine) { @@ -2525,7 +2273,7 @@ class MyCompiler: public Compiler { } virtual Promise* machineIp(unsigned logicalIp) { - return new(c.zone) IpPromise(&c, logicalIp); + return ipPromise(&c, logicalIp); } virtual Promise* poolAppend(intptr_t value) { @@ -2533,7 +2281,7 @@ class MyCompiler: public Compiler { } virtual Promise* poolAppendPromise(Promise* value) { - Promise* p = new(c.zone) PoolPromise(&c, c.constantCount); + Promise* p = poolPromise(&c, c.constantCount); ConstantPoolNode* constant = new (c.zone) ConstantPoolNode(value); diff --git a/src/codegen/compiler/context.h b/src/codegen/compiler/context.h index 8508086978..974de8e17a 100644 --- a/src/codegen/compiler/context.h +++ b/src/codegen/compiler/context.h @@ -54,6 +54,18 @@ unsigned count(Cell* c) { return count; } +template +Cell* reverseDestroy(Cell* cell) { + Cell* previous = 0; + while (cell) { + Cell* next = cell->next; + cell->next = previous; + previous = cell; + cell = next; + } + return previous; +} + class Context { public: Context(vm::System* system, Assembler* assembler, vm::Zone* zone, diff --git a/src/codegen/compiler/event.cpp b/src/codegen/compiler/event.cpp index 68d3bccfd6..ba8c0c222a 100644 --- a/src/codegen/compiler/event.cpp +++ b/src/codegen/compiler/event.cpp @@ -18,6 +18,7 @@ #include "codegen/compiler/value.h" #include "codegen/compiler/promise.h" #include "codegen/compiler/frame.h" +#include "codegen/compiler/ir.h" namespace avian { namespace codegen { @@ -148,6 +149,32 @@ bool Event::isUnreachable() { return this->predecessors != 0; } +unsigned Link::countPredecessors() { + Link* link = this; + unsigned c = 0; + for (; link; link = link->nextPredecessor) { + ++ c; + } + return c; +} + +Link* Link::lastPredecessor() { + Link* link = this; + while (link->nextPredecessor) { + link = link->nextPredecessor; + } + return link; +} + +unsigned Link::countSuccessors() { + Link* link = this; + unsigned c = 0; + for (; link; link = link->nextSuccessor) { + ++ c; + } + return c; +} + Link* link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor, Link* nextSuccessor, ForkState* forkState) { @@ -1605,6 +1632,67 @@ appendFrameSite(Context* c, Value* value, int index) append(c, new(c->zone) FrameSiteEvent(c, value, index)); } +class SaveLocalsEvent: public Event { + public: + SaveLocalsEvent(Context* c): + Event(c) + { + saveLocals(c, this); + } + + virtual const char* name() { + return "SaveLocalsEvent"; + } + + virtual void compile(Context* c) { + for (Read* r = reads; r; r = r->eventNext) { + popRead(c, this, r->value); + } + } +}; + +void +appendSaveLocals(Context* c) +{ + append(c, new(c->zone) SaveLocalsEvent(c)); +} + +class DummyEvent: public Event { + public: + DummyEvent(Context* c, Local* locals): + Event(c), + locals_(locals) + { } + + virtual const char* name() { + return "DummyEvent"; + } + + virtual void compile(Context*) { } + + virtual Local* locals() { + return locals_; + } + + Local* locals_; +}; + +void +appendDummy(Context* c) +{ + Stack* stack = c->stack; + Local* locals = c->locals; + LogicalInstruction* i = c->logicalCode[c->logicalIp]; + + c->stack = i->stack; + c->locals = i->locals; + + append(c, new(c->zone) DummyEvent(c, locals)); + + c->stack = stack; + c->locals = locals; +} + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/event.h b/src/codegen/compiler/event.h index c28fa6230b..504da33bae 100644 --- a/src/codegen/compiler/event.h +++ b/src/codegen/compiler/event.h @@ -97,6 +97,10 @@ class Link { junctionState(0) { } + unsigned countPredecessors(); + Link* lastPredecessor(); + unsigned countSuccessors(); + Event* predecessor; Link* nextPredecessor; Event* successor; @@ -154,6 +158,12 @@ appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset, void appendFrameSite(Context* c, Value* value, int index); +void +appendSaveLocals(Context* c); + +void +appendDummy(Context* c); + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/ir.cpp b/src/codegen/compiler/ir.cpp new file mode 100644 index 0000000000..671fd86df8 --- /dev/null +++ b/src/codegen/compiler/ir.cpp @@ -0,0 +1,48 @@ +/* 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 "codegen/compiler/context.h" +#include "codegen/compiler/ir.h" + +namespace avian { +namespace codegen { +namespace compiler { + +LogicalInstruction::LogicalInstruction(int index, Stack* stack, Local* locals): + firstEvent(0), lastEvent(0), immediatePredecessor(0), stack(stack), + locals(locals), machineOffset(0), subroutine(0), index(index) +{ } + +LogicalInstruction* LogicalInstruction::next(Context* c) { + LogicalInstruction* i = this; + for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) { + i = c->logicalCode[n]; + if (i) return i; + } + return 0; +} + +unsigned +machineOffset(Context* c, int logicalIp) +{ + return c->logicalCode[logicalIp]->machineOffset->value(); +} + +Block::Block(Event* head): + head(head), nextBlock(0), nextInstruction(0), assemblerBlock(0), start(0) +{ } + +Block* block(Context* c, Event* head) { + return new(c->zone) Block(head); +} + +} // namespace compiler +} // namespace codegen +} // namespace avian diff --git a/src/codegen/compiler/ir.h b/src/codegen/compiler/ir.h new file mode 100644 index 0000000000..56a0283367 --- /dev/null +++ b/src/codegen/compiler/ir.h @@ -0,0 +1,90 @@ +/* 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_COMPILER_IR_H +#define AVIAN_CODEGEN_COMPILER_IR_H + +namespace avian { +namespace codegen { +namespace compiler { + +class MultiRead; + +class ForkElement { + public: + Value* value; + MultiRead* read; + bool local; +}; + +class ForkState: public Compiler::State { + public: + ForkState(Stack* stack, Local* locals, Cell* saved, Event* predecessor, + unsigned logicalIp): + stack(stack), + locals(locals), + saved(saved), + predecessor(predecessor), + logicalIp(logicalIp), + readCount(0) + { } + + Stack* stack; + Local* locals; + Cell* saved; + Event* predecessor; + unsigned logicalIp; + unsigned readCount; + ForkElement elements[0]; +}; + +class LogicalInstruction { + public: + LogicalInstruction(int index, Stack* stack, Local* locals); + + LogicalInstruction* next(Context* c); + + Event* firstEvent; + Event* lastEvent; + LogicalInstruction* immediatePredecessor; + Stack* stack; + Local* locals; + Promise* machineOffset; + MySubroutine* subroutine; + int index; +}; + +class MySubroutine: public Compiler::Subroutine { + public: + MySubroutine(): forkState(0) { } + + ForkState* forkState; +}; + +class Block { + public: + Block(Event* head); + + Event* head; + Block* nextBlock; + LogicalInstruction* nextInstruction; + Assembler::Block* assemblerBlock; + unsigned start; +}; + +Block* block(Context* c, Event* head); + +unsigned machineOffset(Context* c, int logicalIp); + +} // namespace compiler +} // namespace codegen +} // namespace avian + +#endif // AVIAN_CODEGEN_COMPILER_IR_H diff --git a/src/codegen/compiler/promise.cpp b/src/codegen/compiler/promise.cpp index e4e55edbc9..fc5a69da63 100644 --- a/src/codegen/compiler/promise.cpp +++ b/src/codegen/compiler/promise.cpp @@ -8,8 +8,11 @@ There is NO WARRANTY for this software. See license.txt for details. */ +#include "target.h" + #include "codegen/compiler/context.h" #include "codegen/compiler/promise.h" +#include "codegen/compiler/ir.h" namespace avian { namespace codegen { @@ -51,6 +54,63 @@ Promise* resolvedPromise(Context* c, int64_t value) { return new (c->zone) ResolvedPromise(value); } +class IpPromise: public Promise { + public: + IpPromise(Context* c, int logicalIp): + c(c), + logicalIp(logicalIp) + { } + + virtual int64_t value() { + if (resolved()) { + return reinterpret_cast + (c->machineCode + machineOffset(c, logicalIp)); + } + + abort(c); + } + + virtual bool resolved() { + return c->machineCode != 0 + and c->logicalCode[logicalIp]->machineOffset->resolved(); + } + + Context* c; + int logicalIp; +}; + +Promise* ipPromise(Context* c, int logicalIp) { + return new (c->zone) IpPromise(c, logicalIp); +} + + +class PoolPromise: public Promise { + public: + PoolPromise(Context* c, int key): c(c), key(key) { } + + virtual int64_t value() { + if (resolved()) { + return reinterpret_cast + (c->machineCode + vm::pad(c->machineCodeSize, vm::TargetBytesPerWord) + + (key * vm::TargetBytesPerWord)); + } + + abort(c); + } + + virtual bool resolved() { + return c->machineCode != 0; + } + + Context* c; + int key; +}; + +Promise* poolPromise(Context* c, int key) { + return new(c->zone) PoolPromise(c, key); +} + + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/promise.h b/src/codegen/compiler/promise.h index d7262b3724..516782e0cd 100644 --- a/src/codegen/compiler/promise.h +++ b/src/codegen/compiler/promise.h @@ -39,6 +39,10 @@ Promise* combinedPromise(Context* c, Promise* low, Promise* high); Promise* resolvedPromise(Context* c, int64_t value); +Promise* ipPromise(Context* c, int logicalIp); + +Promise* poolPromise(Context* c, int key); + } // namespace compiler } // namespace codegen } // namespace avian diff --git a/src/codegen/compiler/value.cpp b/src/codegen/compiler/value.cpp index cc3ac08092..58c3f341ae 100644 --- a/src/codegen/compiler/value.cpp +++ b/src/codegen/compiler/value.cpp @@ -123,6 +123,16 @@ bool Value::uniqueSite(Context* c, Site* s) { } } +void Value::clearSites(Context* c) { + if (DebugSites) { + fprintf(stderr, "clear sites for %p\n", this); + } + for (SiteIterator it(c, this); it.hasMore();) { + it.next(); + it.remove(c); + } +} + #ifndef NDEBUG bool Value::hasBuddy(Context* c, Value* b) { diff --git a/src/codegen/compiler/value.h b/src/codegen/compiler/value.h index f567c86cd5..9cdac0bba3 100644 --- a/src/codegen/compiler/value.h +++ b/src/codegen/compiler/value.h @@ -60,6 +60,7 @@ class Value: public Compiler::Operand { bool uniqueSite(Context* c, Site* s); + void clearSites(Context* c); #ifndef NDEBUG bool hasBuddy(Context* c, Value* b);