Index: vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp (working copy) @@ -537,7 +537,7 @@ // Add branch to through edge target Opnd *p0 = cfg.getOpndManager()->getP0(); NodeRef *targetNode = cfg.getOpndManager()->newNodeRef(target); - node->addInst(new(mm) Inst(mm, INST_BR, CMPLT_WH_SPTK, CMPLT_PH_FEW, p0, targetNode)); + node->addInst(new(mm) Inst(mm, INST_BR, CMPLT_WH_SPTK, CMPLT_PH_MANY, p0, targetNode)); throughEdge->setEdgeKind(EDGE_BRANCH); IPF_LOG << " branch on node" << target->getId() << " added" << endl; Index: vm/jitrino/src/codegenerator/ipf/include/IpfOpndManager.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfOpndManager.h (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/include/IpfOpndManager.h (working copy) @@ -204,7 +204,9 @@ bool areRefsCompressed() { return refsCompressed; } bool areVtablePtrsCompressed() { return vtablePtrsCompressed; } RegOpnd *getHeapBase(); + Opnd *getHeapBaseImm(); RegOpnd *getVtableBase(); + Opnd *getVtableBaseImm(); Opnd *getVtableOffset(); void initCompBases(BbNode*); @@ -234,8 +236,10 @@ RegOpnd *f8; // return value (floating point) RegOpnd *tau; // opnd ignored - RegOpnd *heapBase; // opnd containing base for references decompression - RegOpnd *vtableBase; // opnd containing base for vtable pointers decompression + RegOpnd *heapBase; // Reg opnd containing base for references decompression + Opnd *heapBaseImm; // Imm opnd containing base for references decompression + RegOpnd *vtableBase; // Reg opnd containing base for vtable pointers decompression + Opnd *vtableBaseImm; // Imm opnd containing base for vtable pointers decompression Opnd *vtableOffset; // opnd containing vtable offset inside class object bool containCall; // method contains call instruction Index: vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h (working copy) @@ -144,6 +144,8 @@ virtual int64 getValue() { return value; } bool isReg() { return IpfType::isReg(opndKind); } + bool isGReg() { return IpfType::isGReg(opndKind); } + bool isFReg() { return IpfType::isFReg(opndKind); } bool isImm() { return IpfType::isImm(opndKind); } bool isFloating() { return IpfType::isFloating(dataKind); } bool isSigned() { return IpfType::isSigned(dataKind); } @@ -151,9 +153,9 @@ bool isWritable(); bool isConstant(); bool isMem(); + + bool isFoldableImm(int16 size) { return isFoldableImm(value, size); } bool isImm(int); - - bool isFoldableImm(int16 size) { return isFoldableImm(value, size); } static bool isFoldableImm(int64 value, int16 size); protected: Index: vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h (working copy) @@ -47,19 +47,22 @@ //========================================================================================// // -// Constants that describe cache on IPF +// Constants that describe cache on Itanium2 // // // Level 1 cache // -#define L1_CACHE_LINE_SIZE 64 +#define L1I_CACHE_LINE_SIZE 64 +#define L1I_CACHE_BANK_SIZE 16384 +#define L1D_CACHE_LINE_SIZE 64 +#define L1D_CACHE_BANK_SIZE 16384 // // Level 2 cache // -#define L2_CACHE_BANK_SIZE 16 -#define NUM_L2_CACHE_BANKS 16 +#define L2_CACHE_LINE_SIZE 128 +#define L2_CACHE_BANK_SIZE 262144 #define PR(n) (opndManager->newRegOpnd(OPND_P_REG, DATA_P, n)) @@ -128,7 +131,9 @@ Inst * getSlot(int si) { return slot[si]; }; uint32 getTmplIndex() { return indxtmpl; }; - uint32 getTmpl(); + uint32 getTmpl() { return BundleDesc[indxtmpl].tmpl; }; + bool hasStop() { uint32 t = getTmpl(); + if (t%2==1 || t==0x2 || t==0xa) return true; return false; }; void emitBundleGeneral(void *); void emitBundleExtended(void *); void emitBundleBranch(void *, int *); @@ -137,6 +142,8 @@ uint64 getSlotBitsBranch(int, int); uint64 * getSlotBitsExtended(uint64 *, void *); + static const BundleDescription BundleDesc[TEMPLATES_COUNT]; + protected: uint32 indxtmpl; Inst *slot[IPF_SLOTS_COUNT]; @@ -174,6 +181,7 @@ vectorregs * rregs; BundleVector * bundles; vectorconst * consts; + bool istarget; long bsize; char * codeoff; // offset in full code block @@ -200,8 +208,7 @@ void registerDirectCall(Inst *, uint64); static InstructionType getExecUnitType(int, int); - - static const BundleDescription BundleDesc[TEMPLATES_COUNT]; + static const char Itanium2_DualIssueBundles[30][30]; protected: static void getTmpl(int, BundleDescription &, Inst *, Inst *, Inst *, bool, bool, bool); @@ -210,6 +217,7 @@ static void getReadDpndBitset(Inst *, RegistersBitset *); static bool tricking(InstVector & insts, MemoryManager& mm, Cfg& cfg); static int removeUselessInst(Cfg &, CompilationInterface &); + static int removeIgnoreTypeInst(Cfg &, CompilationInterface &); bool parsing(); bool parsing(int); bool stopping(); @@ -219,8 +227,10 @@ bool emitData(); bool emitCode(); bool fixSwitchTables(); + void checkForDualIssueBundles(); bool isBranchBundle(Bundle *, char *, char *, int *); bool isExtendedBundle(Bundle *bundle) { if (bundle->getTmpl()>=0x4 && bundle->getTmpl()<=0x5) return true; return false; }; + int getBbNodeIndex(BbNode * node); char * getBbNodeOff(BbNode * node); MemoryManager& mm; Index: vm/jitrino/src/codegenerator/ipf/include/IpfType.h =================================================================== --- vm/jitrino/src/codegenerator/ipf/include/IpfType.h (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/include/IpfType.h (working copy) @@ -109,10 +109,11 @@ #define IPF_LOG if (LOG_ON) LOG_OUT #define IPF_STAT if (STAT_ON) LOG_OUT #define IPF_ERR cerr << IPF_ERROR -#define IPF_ASSERT(condition) if (LOG_ON && !(condition)) { IPF_ERR << (#condition) << endl; } +#define IPF_ASSERT(condition) if (VERIFY_ON && !(condition)) { IPF_ERR << (#condition) << endl; } extern bool ipfLogIsOn; extern bool ipfVerifyIsOn; +extern bool ipfConstantFolding; //========================================================================================// // Enums @@ -237,6 +238,8 @@ static int16 getSize(DataKind); // opnd value size in bytes static bool isReg(OpndKind); // is opnd resides on register + static bool isGReg(OpndKind); // is opnd resides on general register + static bool isFReg(OpndKind); // is opnd resides on general register static bool isImm(OpndKind); // is opnd resides in imm static bool isSigned(DataKind); // is opnd value is signed static bool isFloating(DataKind); // is opnd value can be placed in fp reg Index: vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/IpfInstCodeSelector.cpp (working copy) @@ -28,9 +28,16 @@ namespace Jitrino { namespace IPF { -#define HEAPBASE (opndManager->getHeapBase()) -#define VTABLEBASE (opndManager->getVtableBase()) +#define HEAPBASE (opndManager->getHeapBase()) +#define HEAPBASEIMM (opndManager->getHeapBaseImm()) +#define VTABLEBASE (opndManager->getVtableBase()) +#define VTABLEBASEIMM (opndManager->getVtableBaseImm()) +#define IMM32(o) ((int32)(((Opnd *)(o))->getValue())) +#define IMM64(o) ((int64)(((Opnd *)(o))->getValue())) +#define IMM32U(o) ((uint32)(((Opnd *)(o))->getValue())) +#define IMM64U(o) ((uint64)(((Opnd *)(o))->getValue())) + //===========================================================================// // IpfInstCodeSelector //===========================================================================// @@ -63,8 +70,21 @@ IPF_LOG << " add; opType=" << opType << endl; - RegOpnd *dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); - add(dst, src1, src2); + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src1)->isImm() && ((Opnd *)src2)->isImm()) { + switch (opType) { + case ArithmeticOp::I4: + case ArithmeticOp::I: + dst = opndManager->newImm(IMM32(src1) + IMM32(src2)); break; + case ArithmeticOp::I8: + dst = opndManager->newImm(IMM64(src1) + IMM64(src2)); break; + default: + IPF_ASSERT(0); dst = NULL; break; + } + } else { + dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); + add((RegOpnd *)dst, src1, src2); + } return dst; } @@ -77,8 +97,21 @@ IPF_LOG << " sub" << endl; - RegOpnd *dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); - sub(dst, src1, src2); + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src1)->isImm() && ((Opnd *)src2)->isImm()) { + switch (opType) { + case ArithmeticOp::I4: + case ArithmeticOp::I: + dst = opndManager->newImm(IMM32(src1) - IMM32(src2)); break; + case ArithmeticOp::I8: + dst = opndManager->newImm(IMM64(src1) - IMM64(src2)); break; + default: + IPF_ASSERT(0); dst = NULL; break; + } + } else { + dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); + sub((RegOpnd *)dst, src1, src2); + } return dst; } @@ -91,24 +124,37 @@ IPF_LOG << " mul" << endl; - RegOpnd *src1 = toRegOpnd(src1_); - RegOpnd *src2 = toRegOpnd(src2_); - RegOpnd *dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType));; - RegOpnd *f0 = opndManager->getF0(); - - if (dst->isFloating()) { - Completer cmplt = CMPLT_PC_DYNAMIC; - - switch (dst->getDataKind()) { - case DATA_D: cmplt = CMPLT_PC_DOUBLE; break; - case DATA_S: cmplt = CMPLT_PC_SINGLE; break; - default: IPF_ERR << "bad data kind for float mul\n"; break; + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src1_)->isImm() && ((Opnd *)src2_)->isImm()) { + // imm is always integer + switch (opType) { + case ArithmeticOp::I4: + case ArithmeticOp::I: + dst = opndManager->newImm(IMM32(src1_) * IMM32(src2_)); break; + case ArithmeticOp::I8: + dst = opndManager->newImm(IMM64(src1_) * IMM64(src2_)); break; + default: + IPF_ASSERT(0); dst = NULL; break; } - addNewInst(INST_FMA, cmplt, p0, dst, src1, src2, f0); } else { - xma(INST_XMA_L, dst, src1, src2); + RegOpnd *src1 = toRegOpnd(src1_); + RegOpnd *src2 = toRegOpnd(src2_); + RegOpnd *f0 = opndManager->getF0(); + + dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType));; + if (dst->isFloating()) { + Completer cmplt = CMPLT_PC_DYNAMIC; + + switch (dst->getDataKind()) { + case DATA_D: cmplt = CMPLT_PC_DOUBLE; break; + case DATA_S: cmplt = CMPLT_PC_SINGLE; break; + default: IPF_ERR << "bad data kind for float mul\n"; break; + } + addNewInst(INST_FMA, cmplt, p0, dst, src1, src2, f0); + } else { + xma(INST_XMA_L, (RegOpnd *)dst, src1, src2); + } } - return dst; } @@ -120,6 +166,7 @@ CG_OpndHandle *intSrc) { IPF_LOG << " addRef" << endl; + IPF_ASSERT(((Opnd *)refSrc)->isReg()); RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); add(dst, refSrc, intSrc); @@ -134,6 +181,7 @@ CG_OpndHandle *intSrc) { IPF_LOG << " subRef" << endl; + IPF_ASSERT(((Opnd *)refSrc)->isReg()); RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); sub(dst, refSrc, intSrc); @@ -148,6 +196,8 @@ CG_OpndHandle *src2) { IPF_LOG << " diffRef" << endl; + IPF_ASSERT(((Opnd *)src1)->isReg()); + IPF_ASSERT(((Opnd *)src2)->isReg()); RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); sub(dst, src1, src2); @@ -164,6 +214,8 @@ IPF_LOG << " scaledDiffRef" << endl; IPF_ASSERT(type1->isManagedPtr() && type1==type2); + IPF_ASSERT(((Opnd *)src1_)->isReg()); + IPF_ASSERT(((Opnd *)src2_)->isReg()); Opnd *src1 = (Opnd *)src1_; Opnd *src2 = (Opnd *)src2_; @@ -196,18 +248,42 @@ CG_OpndHandle *src2, CG_OpndHandle *tau_src1NonZero) { - IPF_LOG << " tau_div" << endl; + IPF_LOG << " tau_div" + << "; opType=" << opType + << ", src1=" << IrPrinter::toString((Opnd *)src1) + << ", src2=" << IrPrinter::toString((Opnd *)src2) + << endl; - RegOpnd *dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); - - switch (opType) { - case DivOp::I4: divInt (dst, src1, src2); break; - case DivOp::I : - case DivOp::I8: divLong (dst, src1, src2); break; - case DivOp::F : - case DivOp::D : divDouble(dst, src1, src2); break; - case DivOp::S : divFloat (dst, src1, src2); break; - default : IPF_ERR << "unexpected type " << opType << endl; + Opnd *dst = NULL; + if (ipfConstantFolding && ((Opnd *)src1)->isImm() && ((Opnd *)src2)->isImm() && IMM32(src2)!=0){ + // imm is always integer + switch (opType) { + case DivOp::I4: + dst = opndManager->newImm(IMM32(src1) / IMM32(src2)); break; + case DivOp::U4: + dst = opndManager->newImm(IMM32U(src1) / IMM32U(src2)); break; + case DivOp::I: + case DivOp::I8: + dst = opndManager->newImm(IMM64(src1) / IMM64(src2)); break; + case DivOp::U: + case DivOp::U8: + dst = opndManager->newImm(IMM64U(src1) / IMM64U(src2)); break; + default: + IPF_ASSERT(0); + dst = NULL; + } + } else { + dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); + + switch (opType) { + case DivOp::I4: divInt((RegOpnd *)dst, toRegOpnd(src1), toRegOpnd(src2)); break; + case DivOp::I : + case DivOp::I8: divLong((RegOpnd *)dst, toRegOpnd(src1), toRegOpnd(src2)); break; + case DivOp::F : + case DivOp::D : divDouble((RegOpnd *)dst, src1, src2); break; + case DivOp::S : divFloat ((RegOpnd *)dst, src1, src2); break; + default : IPF_ERR << "unexpected type " << opType << endl; + } } return dst; } @@ -233,9 +309,9 @@ } } else { if (dst->getSize() > 4) { - divLong(dst, src1, src2, true); + divLong(dst, toRegOpnd(src1), toRegOpnd(src2), true); } else { - divInt (dst, src1, src2, true); + divInt (dst, toRegOpnd(src1), toRegOpnd(src2), true); } } @@ -250,13 +326,26 @@ IPF_LOG << " neg" << endl; - RegOpnd *src = toRegOpnd(src_); - RegOpnd *dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); - RegOpnd *r0 = opndManager->getR0(); - - if (dst->isFloating()) addNewInst(INST_FNEG, p0, dst, src); - else addNewInst(INST_SUB, p0, dst, r0, src); - + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src_)->isImm()) { + switch (opType) { + case NegOp::I4: + dst = opndManager->newImm((int32)0 - IMM32(src_)); break; + case NegOp::I: + case NegOp::I8: + dst = opndManager->newImm(0 - IMM64(src_)); break; + default: + IPF_ASSERT(0); + dst = NULL; + } + } else { + dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); + RegOpnd *src = toRegOpnd(src_); + RegOpnd *r0 = opndManager->getR0(); + + if (dst->isFloating()) addNewInst(INST_FNEG, p0, dst, src); + else addNewInst(INST_SUB, p0, dst, r0, src); + } return dst; } @@ -268,9 +357,23 @@ CG_OpndHandle *src2) { IPF_LOG << " min_op" << endl; - RegOpnd *dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); - - minMax(dst, src1, src2, false); + + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src1)->isImm() && ((Opnd *)src2)->isImm()) { + switch (opType) { + case NegOp::I4: + dst = opndManager->newImm(min(IMM32(src1), IMM32(src2))); break; + case NegOp::I: + case NegOp::I8: + dst = opndManager->newImm(min(IMM64(src1), IMM64(src2))); break; + default: + IPF_ASSERT(0); + dst = NULL; + } + } else { + dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); + minMax((RegOpnd *)dst, src1, src2, false); + } return dst; } @@ -282,9 +385,23 @@ CG_OpndHandle *src2) { IPF_LOG << " max_op" << endl; - RegOpnd *dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); - minMax(dst, src1, src2, true); + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src1)->isImm() && ((Opnd *)src2)->isImm()) { + switch (opType) { + case NegOp::I4: + dst = opndManager->newImm(max(IMM32(src1), IMM32(src2))); break; + case NegOp::I: + case NegOp::I8: + dst = opndManager->newImm(max(IMM64(src1), IMM64(src2))); break; + default: + IPF_ASSERT(0); + dst = NULL; + } + } else { + dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); + minMax((RegOpnd *)dst, src1, src2, true); + } return dst; } @@ -293,24 +410,41 @@ CG_OpndHandle *IpfInstCodeSelector::abs_op(NegOp::Types opType, CG_OpndHandle *src_) { - RegOpnd *src = toRegOpnd(src_); - RegOpnd *dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); - - if (dst->isFloating()) { - // TODO: check all the peculiarities of Math.min/max - addNewInst(INST_FABS, p0, dst, src); + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src_)->isImm()) { + switch (opType) { + case NegOp::I4: + dst = opndManager->newImm(abs(IMM32(src_))); break; + case NegOp::I: + case NegOp::I8: + dst = opndManager->newImm(labs(IMM64(src_))); break; + default: + IPF_ASSERT(0); + dst = NULL; + } } else { - // cmp.lt truePred, falsePred = src, 0 - // (truePred) dst = src - // (falsePred) dst = -src - RegOpnd *truePred = opndManager->newRegOpnd(OPND_P_REG, DATA_P); - RegOpnd *falsePred = opndManager->newRegOpnd(OPND_P_REG, DATA_P); - RegOpnd *r0 = opndManager->getR0(src); + RegOpnd *src = toRegOpnd(src_); + dst = opndManager->newRegOpnd(toOpndKind(opType), toDataKind(opType)); - cmp(CMPLT_CMP_CREL_LT, truePred, falsePred, src, r0); - addNewInst(INST_MOV, truePred, dst, src); - addNewInst(INST_SUB, falsePred, dst, r0, src); - } + if (dst->isFloating()) { + // TODO: check all the peculiarities of Math.min/max + addNewInst(INST_FABS, p0, dst, src); + } else { + // cmp.lt truePred, falsePred = src, 0 + // (truePred) dst = src + // (falsePred) dst = -src + RegOpnd *truePred = opndManager->newRegOpnd(OPND_P_REG, DATA_P); + RegOpnd *falsePred = opndManager->newRegOpnd(OPND_P_REG, DATA_P); + RegOpnd *r0 = opndManager->getR0(src); + + addNewInst(INST_DEF, p0, dst); + addNewInst(INST_DEF, p0, src); + + cmp(CMPLT_CMP_CREL_LT, truePred, falsePred, src, r0); + addNewInst(INST_MOV, truePred, dst, src); + addNewInst(INST_SUB, falsePred, dst, r0, src); + } + } return dst; } @@ -322,9 +456,24 @@ CG_OpndHandle *src2) { IPF_LOG << " and_ " << endl; - RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); - binOp(INST_AND, dst, src1, src2); + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src1)->isImm() && ((Opnd *)src2)->isImm()) { + switch (opType) { + case IntegerOp::I4: + dst = opndManager->newImm(IMM32(src1) & IMM32(src2)); break; + case IntegerOp::I8: + dst = opndManager->newImm(IMM64(src1) & IMM64(src2)); break; + case IntegerOp::I : + dst = opndManager->newImm(IMM64U(src1) & IMM64U(src2)); break; + default: + IPF_ASSERT(0); + dst = NULL; + } + } else { + dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); + binOp(INST_AND, (RegOpnd *)dst, src1, src2); + } return dst; } @@ -336,9 +485,24 @@ CG_OpndHandle *src2) { IPF_LOG << " or_ " << endl; - RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); - binOp(INST_OR, dst, src1, src2); + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src1)->isImm() && ((Opnd *)src2)->isImm()) { + switch (opType) { + case IntegerOp::I4: + dst = opndManager->newImm(IMM32(src1) | IMM32(src2)); break; + case IntegerOp::I8: + dst = opndManager->newImm(IMM64(src1) | IMM64(src2)); break; + case IntegerOp::I : + dst = opndManager->newImm(IMM64U(src1) | IMM64U(src2)); break; + default: + IPF_ASSERT(0); + dst = NULL; + } + } else { + dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); + binOp(INST_OR, (RegOpnd *)dst, src1, src2); + } return dst; } @@ -350,9 +514,24 @@ CG_OpndHandle *src2) { IPF_LOG << " xor_ " << endl; - RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); - binOp(INST_XOR, dst, src1, src2); + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src1)->isImm() && ((Opnd *)src2)->isImm()) { + switch (opType) { + case IntegerOp::I4: + dst = opndManager->newImm(IMM32(src1) ^ IMM32(src2)); break; + case IntegerOp::I8: + dst = opndManager->newImm(IMM64(src1) ^ IMM64(src2)); break; + case IntegerOp::I : + dst = opndManager->newImm(IMM64U(src1) ^ IMM64U(src2)); break; + default: + IPF_ASSERT(0); + dst = NULL; + } + } else { + dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); + binOp(INST_XOR, (RegOpnd *)dst, src1, src2); + } return dst; } @@ -364,14 +543,29 @@ IPF_LOG << " not_ " << endl; - uint64 val = 0; - if (opType == IntegerOp::I4) val = 0xFFFFFFFF; - else val = 0xFFFFFFFFFFFFFFFFL; - - Opnd *allOnes = opndManager->newImm(val); - RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); - - binOp(INST_XOR, dst, src, allOnes); + Opnd *dst; + if (ipfConstantFolding && ((Opnd *)src)->isImm()) { + switch (opType) { + case IntegerOp::I4: + dst = opndManager->newImm(~IMM32(src)); break; + case IntegerOp::I8: + dst = opndManager->newImm(~IMM64(src)); break; + case IntegerOp::I : + dst = opndManager->newImm(~IMM64U(src)); break; + default: + IPF_ASSERT(0); + dst = NULL; + } + } else { + uint64 val = 0; + if (opType == IntegerOp::I4) val = 0xFFFFFFFF; + else val = 0xFFFFFFFFFFFFFFFFL; + + Opnd *allOnes = opndManager->newImm(val); + dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); + + binOp(INST_XOR, (RegOpnd *)dst, src, allOnes); + } return dst; } @@ -384,6 +578,10 @@ IPF_LOG << " shl " << endl; + if (ipfConstantFolding && ((Opnd *)value)->isImm() && ((Opnd *)shiftAmount)->isImm()) { + return opndManager->newImm(((Opnd *)value)->getValue() << ((Opnd *)shiftAmount)->getValue()); + } + RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); Opnd *shiftcount = (Opnd *)shiftAmount; int bits = 5; @@ -406,6 +604,11 @@ CG_OpndHandle *shiftAmount) { IPF_LOG << " shr " << endl; + + if (ipfConstantFolding && ((Opnd *)value)->isImm() && ((Opnd *)shiftAmount)->isImm()) { + return opndManager->newImm(((Opnd *)value)->getValue() >> ((Opnd *)shiftAmount)->getValue()); + } + RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); int bits = 5; @@ -430,6 +633,15 @@ CG_OpndHandle *shiftAmount) { IPF_LOG << " shru " << endl; + + if (ipfConstantFolding && ((Opnd *)value)->isImm() && ((Opnd *)shiftAmount)->isImm()) { + if (opType==IntegerOp::I4) { + return opndManager->newImm((uint64)((uint32)((int32)(((Opnd *)value)->getValue()))) >> ((Opnd *)shiftAmount)->getValue()); + } else { + return opndManager->newImm((uint64)(((Opnd *)value)->getValue()) >> ((Opnd *)shiftAmount)->getValue()); + } + } + RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(opType)); int bits = 5; @@ -457,6 +669,10 @@ IPF_LOG << " shladd " << endl; IPF_ASSERT(imm>=1 && imm<=4); + if (ipfConstantFolding && ((Opnd *)value_)->isImm() && ((Opnd *)addto_)->isImm()) { + return opndManager->newImm((((Opnd *)value_)->getValue() << imm) + ((Opnd *)addto_)->getValue()); + } + RegOpnd *value = toRegOpnd(value_); RegOpnd *addto = toRegOpnd(addto_); Opnd *count = opndManager->newImm(imm); @@ -477,11 +693,21 @@ Type *dstType, CG_OpndHandle *src_) { - RegOpnd *src = toRegOpnd(src_); - IPF_LOG << " convToInt " << IrPrinter::toString(src); - IPF_LOG << " to " << Type::tag2str(dstType->tag) ; + IPF_LOG << " convToInt " << IrPrinter::toString((Opnd *)src_); + IPF_LOG << " to " << Type::tag2str(dstType->tag); + IPF_LOG << "; isSigned=" << isSigned; IPF_LOG << "; opType=" << opType << endl; + if (ipfConstantFolding && ((Opnd *)src_)->isImm()) { + switch (opType) { + case ConvertToIntOp::I1: break; + case ConvertToIntOp::I2: break; + case ConvertToIntOp::I4: break; + default : return src_; + } + } + + RegOpnd *src = toRegOpnd(src_); RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(dstType->tag)); if (src->isFloating()) { @@ -498,7 +724,9 @@ default : break; } - InstCode instCode = dst->isSigned() ? INST_SXT : INST_ZXT; + InstCode instCode = dst->isSigned() + ? INST_SXT + : INST_ZXT; if (cmplt == CMPLT_INVALID) addNewInst(INST_MOV, p0, dst, src); else addNewInst(instCode, cmplt, p0, dst, src); } @@ -530,7 +758,7 @@ } else { // convert from int to fp bool isSigned = (opType != ConvertToFpOp::FloatFromUnsigned); - InstCode instCode = (isSigned ? INST_FCVT_XUF : INST_FCVT_XF); + InstCode instCode = (isSigned ? INST_FCVT_XF : INST_FCVT_XUF); sxt(src, 8); addNewInst(INST_SETF_SIG, p0, dst, src); addNewInst(instCode, p0, dst, dst); @@ -544,11 +772,15 @@ CG_OpndHandle *IpfInstCodeSelector::ldc_i4(uint32 val) { - IPF_LOG << " ldc_i4" << endl; + IPF_LOG << " ldc_i4; val=" << val << endl; - RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I32); - ldc(dst, (int64)((int32)val)); - + Opnd *dst; + if (ipfConstantFolding) { + dst = opndManager->newImm((int64)((int32)val)); + } else { + dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I32); + ldc((RegOpnd *)dst, (int64)((int32)val)); + } return dst; } @@ -557,11 +789,15 @@ CG_OpndHandle *IpfInstCodeSelector::ldc_i8(uint64 val) { - IPF_LOG << " ldc_i8" << endl; + IPF_LOG << " ldc_i8; val=" << val << endl; - RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); - ldc(dst, (int64)val); - + Opnd *dst; + if (ipfConstantFolding) { + dst = opndManager->newImm((int64)val); + } else { + dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); + ldc((RegOpnd *)dst, (int64)val); + } return dst; } @@ -570,16 +806,37 @@ CG_OpndHandle *IpfInstCodeSelector::ldc_s(float val) { - IPF_LOG << " ldc_s" << endl; + IPF_LOG << " ldc_s; val=" << val << endl; - FloatConstant *fc = new(mm) FloatConstant(val); - ConstantRef *constref = opndManager->newConstantRef(fc); - RegOpnd *r3 = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); - RegOpnd *dst = opndManager->newRegOpnd(OPND_F_REG, DATA_S); - - addNewInst(INST_MOVL, p0, r3, constref); - addNewInst(INST_LDF, CMPLT_FSZ_S, p0, dst, r3); + if (val==0) { + return opndManager->getF0(); + } else if (val==1) { + return opndManager->getF1(); + } + union { + float fr; + uint32 gr; + } tmpVal; + + tmpVal.fr = val; + + RegOpnd *dst = opndManager->newRegOpnd(OPND_F_REG, DATA_S); + Opnd *immOpnd = opndManager->newImm(tmpVal.gr); + RegOpnd *r3 = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); + InstCode instCode = immOpnd->isFoldableImm(22) ? INST_MOV : INST_MOVL; + + addNewInst(instCode, p0, r3, immOpnd); + addNewInst(INST_SETF_S, p0, dst, r3); + + //FloatConstant *fc = new(mm) FloatConstant(val); + //ConstantRef *constref = opndManager->newConstantRef(fc); + //RegOpnd *r3 = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); + //RegOpnd *dst = opndManager->newRegOpnd(OPND_F_REG, DATA_S); + // + //addNewInst(INST_MOVL, p0, r3, constref); + //addNewInst(INST_LDF, CMPLT_FSZ_S, p0, dst, r3); + return dst; } @@ -588,15 +845,36 @@ CG_OpndHandle *IpfInstCodeSelector::ldc_d(double val) { - IPF_LOG << " ldc_d" << endl; + IPF_LOG << " ldc_d; val=" << val << endl; - DoubleConstant *fc = new(mm) DoubleConstant(val); - ConstantRef *constref = opndManager->newConstantRef(fc); - RegOpnd *r3 = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); - RegOpnd *dst = opndManager->newRegOpnd(OPND_F_REG, DATA_D); + if (val==0) { + return opndManager->getF0(); + } else if (val==1) { + return opndManager->getF1(); + } - addNewInst(INST_MOVL, p0, r3, constref); - addNewInst(INST_LDF, CMPLT_FSZ_D, p0, dst, r3); + union { + double fr; + uint64 gr; + } tmpVal; + + tmpVal.fr = val; + + RegOpnd *dst = opndManager->newRegOpnd(OPND_F_REG, DATA_D); + Opnd *immOpnd = opndManager->newImm(tmpVal.gr); + RegOpnd *r3 = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); + InstCode instCode = immOpnd->isFoldableImm(22) ? INST_MOV : INST_MOVL; + + addNewInst(instCode, p0, r3, immOpnd); + addNewInst(INST_SETF_D, p0, dst, r3); + + //DoubleConstant *fc = new(mm) DoubleConstant(val); + //ConstantRef *constref = opndManager->newConstantRef(fc); + //RegOpnd *r3 = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); + //RegOpnd *dst = opndManager->newRegOpnd(OPND_F_REG, DATA_D); + // + //addNewInst(INST_MOVL, p0, r3, constref); + //addNewInst(INST_LDF, CMPLT_FSZ_D, p0, dst, r3); return dst; } @@ -606,16 +884,28 @@ CG_OpndHandle *IpfInstCodeSelector::ldnull(bool compressed) { - IPF_LOG << " ldnull; compressed = " << boolalpha << compressed << endl; + IPF_LOG << " ldnull; compressed=" << boolalpha << compressed << endl; - if (opndManager->areRefsCompressed() == false) { - return opndManager->getR0(); - } - - if (compressed) { - return opndManager->getR0(); + if (false && ipfConstantFolding) { + if (opndManager->areRefsCompressed() == false) { + return opndManager->newImm(0); // return opndManager->getR0(); + } + + if (compressed) { + return opndManager->newImm(0); // return opndManager->getR0(); + } else { + return HEAPBASEIMM; // return HEAPBASE; + } } else { - return HEAPBASE; + if (opndManager->areRefsCompressed() == false) { + return opndManager->getR0(); + } + + if (compressed) { + return opndManager->getR0(); + } else { + return HEAPBASE; + } } } @@ -624,13 +914,17 @@ CG_OpndHandle *IpfInstCodeSelector::ldVar(Type *dstType, uint32 varId) { - IPF_LOG << " ldVar " << Type::tag2str(dstType->tag) << " " << varId << endl; + IPF_LOG << " ldVar; dstType=" << Type::tag2str(dstType->tag) << ", varId=" << varId << endl; if (opnds[varId] == opndManager->getTau()) { IPF_LOG << " tau operation - ignore" << endl; return opndManager->getTau(); } + if (ipfConstantFolding && opnds[varId]->isImm()) { + return opnds[varId]; + } + RegOpnd *src = toRegOpnd(opnds[varId]); RegOpnd *dst = opndManager->newRegOpnd(toOpndKind(dstType->tag), toDataKind(dstType->tag)); @@ -642,17 +936,30 @@ //----------------------------------------------------------------------------// // Store variable -void IpfInstCodeSelector::stVar(CG_OpndHandle *src, uint32 varId) { +void IpfInstCodeSelector::stVar(CG_OpndHandle *_src, uint32 varId) { - IPF_LOG << " stVar" << endl; + IPF_LOG << " stVar" + << "; varId=" << varId + << "; src=" << IrPrinter::toString((Opnd *)_src) + << endl; - if (src==opndManager->getTau() || opnds[varId]==opndManager->getTau()) { + if (_src==opndManager->getTau() || opnds[varId]==opndManager->getTau()) { IPF_LOG << " tau operation - ignore" << endl; return; } + if (ipfConstantFolding && opnds[varId]->isImm() && ((Opnd *)_src)->isImm()) { + opnds[varId]->setValue(((Opnd *)_src)->getValue()); + } + IPF_ASSERT(opnds[varId]->isReg()); - addNewInst(INST_MOV, p0, opnds[varId], src); + + Opnd *src = (Opnd *)_src; + if (src->isReg() || src->isImm(22)) { + addNewInst(INST_MOV, p0, opnds[varId], src); + } else { + addNewInst(INST_MOVL, p0, opnds[varId], src); + } } //----------------------------------------------------------------------------// @@ -675,7 +982,6 @@ RegOpnd *arg = opndManager->newRegOpnd(opndKind, dataKind, location); IPF_LOG << " defArg " << IrPrinter::toString(arg) << " " << type->getName() << endl; -// addNewInst(INST_DEF, p0, arg); // artificial def for in arg opnd if (isFp) { RegOpnd *newarg = opndManager->newRegOpnd(opndKind, dataKind); addNewInst(INST_MOV, p0, newarg, arg); // if fp arg crosses call site @@ -693,7 +999,11 @@ CG_OpndHandle *src1, CG_OpndHandle *src2) { - IPF_LOG << " cmp; opType=" << opType << endl; + IPF_LOG << " cmp" + << "; opType=" << opType + << "; src1=" << IrPrinter::toString((Opnd *)src1) + << "; src2=" << IrPrinter::toString((Opnd *)src2) + << "\n"; InstCode instCode = toInstCmp(opType); bool isFloating = (instCode == INST_FCMP); @@ -703,8 +1013,9 @@ RegOpnd *r0 = opndManager->getR0(); RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I32); + addNewInst(INST_DEF, p0, dst); + cmp(instCode, crel, truePred, falsePred, src1, src2); -// addNewInst(INST_DEF, p0, dst); addNewInst(INST_MOV, truePred, dst, opndManager->newImm(1)); addNewInst(INST_MOV, falsePred, dst, r0); @@ -717,7 +1028,9 @@ CG_OpndHandle *IpfInstCodeSelector::czero(CompareZeroOp::Types opType, CG_OpndHandle *src) { - IPF_LOG << " czero" << endl; + IPF_LOG << " czero" + << "; src=" << IrPrinter::toString((Opnd *)src) + << endl; InstCode instCode = toInstCmp(opType); Completer crel = CMPLT_CMP_CREL_EQ; @@ -726,8 +1039,9 @@ RegOpnd *r0 = opndManager->getR0(); RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I32); + addNewInst(INST_DEF, p0, dst); + cmp(instCode, crel, truePred, falsePred, src, r0); -// addNewInst(INST_DEF, p0, dst); addNewInst(INST_MOV, truePred, dst, opndManager->newImm(1)); addNewInst(INST_MOV, falsePred, dst, r0); @@ -740,7 +1054,9 @@ CG_OpndHandle *IpfInstCodeSelector::cnzero(CompareZeroOp::Types opType, CG_OpndHandle *src) { - IPF_LOG << " cnzero" << endl; + IPF_LOG << " cnzero" + << "; src=" << IrPrinter::toString((Opnd *)src) + << endl; InstCode instCode = toInstCmp(opType); Completer crel = CMPLT_CMP_CREL_NE; @@ -749,8 +1065,9 @@ RegOpnd *r0 = opndManager->getR0(); RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I32); + addNewInst(INST_DEF, p0, dst); + cmp(instCode, crel, truePred, falsePred, src, r0); -// addNewInst(INST_DEF, p0, dst); addNewInst(INST_MOV, truePred, dst, opndManager->newImm(1)); addNewInst(INST_MOV, falsePred, dst, r0); @@ -762,7 +1079,9 @@ CG_OpndHandle *IpfInstCodeSelector::copy(CG_OpndHandle *src_) { - IPF_LOG << " copy" << endl; + IPF_LOG << " copy" + << "; src_=" << IrPrinter::toString((Opnd *)src_) + << endl; if ((Opnd *)src_ == opndManager->getTau()) { IPF_LOG << " tau operation - ignore" << endl; @@ -786,6 +1105,10 @@ IPF_LOG << " tau_staticCast" << endl; + if (((Opnd *)obj)->isImm()) { + return obj; + } + RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, toDataKind(toType->tag)); addNewInst(INST_MOV, p0, dst, obj); @@ -800,16 +1123,40 @@ CG_OpndHandle *src1, CG_OpndHandle *src2) { - IPF_LOG << " branch" << endl; + IPF_LOG << " branch" + << "; src1=" << IrPrinter::toString((Opnd *)src1) + << "; src2=" << IrPrinter::toString((Opnd *)src2) + << endl; - InstCode instCode = toInstCmp(opType); - bool isFloating = (instCode == INST_FCMP); - Completer crel = toCmpltCrel(cmpOp, isFloating); - RegOpnd *truePred = opndManager->newRegOpnd(OPND_P_REG, DATA_P); - NodeRef *target = opndManager->newNodeRef(); - - cmp(instCode, crel, truePred, p0, src1, src2); - addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_DPNT, CMPLT_PH_FEW, truePred, target); + if (false // TODO: need update cfg: branch edge target and "br" instruction target are different + && ipfConstantFolding && ((Opnd *)src1)->isImm() && ((Opnd *)src2)->isImm()) { + RegOpnd *truePred = opndManager->getP0(); + NodeRef *target = opndManager->newNodeRef(); + int64 v1 = ((Opnd *)src1)->getValue(), v2 = ((Opnd *)src2)->getValue(); + bool cmpres = false; + + switch (cmpOp) { + case CompareOp::Eq : cmpres = (v1 == v2); break; + case CompareOp::Ne : cmpres = (v1 != v2); break; + case CompareOp::Gt : cmpres = (v1 > v2); break; + case CompareOp::Gtu : cmpres = ((uint64)v1 > (uint64)v2); break; + case CompareOp::Ge : cmpres = (v1 >= v2); break; + case CompareOp::Geu : cmpres = ((uint64)v1 >= (uint64)v2); break; + default : IPF_ERR << "unexpected cmpOp type " << cmpOp << endl; + } + if (cmpres) { + addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_SPTK, CMPLT_PH_MANY, truePred, target); + } + } else { + InstCode instCode = toInstCmp(opType); + bool isFloating = (instCode == INST_FCMP); + Completer crel = toCmpltCrel(cmpOp, isFloating); + RegOpnd *truePred = opndManager->newRegOpnd(OPND_P_REG, DATA_P); + NodeRef *target = opndManager->newNodeRef(); + + cmp(instCode, crel, truePred, p0, src1, src2); + addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_DPTK, CMPLT_PH_MANY, truePred, target); + } } //----------------------------------------------------------------------------// @@ -818,7 +1165,9 @@ void IpfInstCodeSelector::bzero(CompareZeroOp::Types opType, CG_OpndHandle *src) { - IPF_LOG << " bzero" << endl; + IPF_LOG << " bzero" + << "; src=" << IrPrinter::toString((Opnd *)src) + << endl; IPF_ASSERT(((Opnd *)src)->isReg()); InstCode instCode = toInstCmp(opType); @@ -833,7 +1182,7 @@ } cmp(instCode, CMPLT_CMP_CREL_EQ, truePred, p0, src, zero); - addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_DPNT, CMPLT_PH_FEW, truePred, target); + addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_DPTK, CMPLT_PH_MANY, truePred, target); } //----------------------------------------------------------------------------// @@ -842,7 +1191,9 @@ void IpfInstCodeSelector::bnzero(CompareZeroOp::Types opType, CG_OpndHandle *src) { - IPF_LOG << " bnzero" << endl; + IPF_LOG << " bnzero" + << "; src=" << IrPrinter::toString((Opnd *)src) + << endl; IPF_ASSERT(((Opnd *)src)->isReg()); InstCode instCode = toInstCmp(opType); @@ -857,7 +1208,7 @@ } cmp(instCode, CMPLT_CMP_CREL_NE, truePred, p0, src, zero); - addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_DPNT, CMPLT_PH_FEW, truePred, target); + addNewInst(INST_BR, CMPLT_BTYPE_COND, CMPLT_WH_DPTK, CMPLT_PH_MANY, truePred, target); } //----------------------------------------------------------------------------// @@ -900,6 +1251,11 @@ Opnd *tgtAddr = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); Opnd *branchTgt = opndManager->newRegOpnd(OPND_B_REG, DATA_I64); + addNewInst(INST_DEF, p0, tgt); + addNewInst(INST_DEF, p0, defTgt); + addNewInst(INST_DEF, p0, tgtAddr); + addNewInst(INST_DEF, p0, branchTgt); + // mov to maxTgtValue, defTgtValue, fallThroughTgtValue to GRs addNewInst(INST_MOV, p0, tgt, tgtValue); addNewInst(INST_MOV, p0, maxTgt, maxTgtValue); @@ -1120,7 +1476,7 @@ RegOpnd *exceptionObj = opndManager->newRegOpnd(OPND_G_REG, DATA_U64, RET_G_REG); RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, DATA_U64); - addNewInst(INST_DEF, p0, exceptionObj); + addNewInst(INST_DEF, p0, exceptionObj); // DON'T REMOVE, THIS IS NOT FOR OPTIMIZATION addNewInst(INST_MOV, p0, dst, exceptionObj); return dst; } @@ -1130,7 +1486,7 @@ CG_OpndHandle *IpfInstCodeSelector::tau_checkNull(CG_OpndHandle *base, bool checksThisForInlinedMethod) { - IPF_LOG << " tau_checkNull" << endl; + IPF_LOG << " tau_checkNull; base=" << IrPrinter::toString((Opnd *)base) << endl; IPF_ASSERT(((Opnd *)base)->isReg()); RegOpnd *truePred = opndManager->newRegOpnd(OPND_P_REG, DATA_P); @@ -1149,7 +1505,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_NullPtrException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau) } @@ -1170,7 +1526,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_ArrayBoundsException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1191,7 +1547,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_ArrayBoundsException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1212,7 +1568,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_ArrayBoundsException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1252,7 +1608,7 @@ hId = CompilationInterface::Helper_ElemTypeException; address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress2 = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress2, truePred, CMPLT_WH_SPNT); + directCall(0, NULL, NULL, helperAddress2, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau); } @@ -1262,7 +1618,7 @@ CG_OpndHandle *IpfInstCodeSelector::tau_checkZero(CG_OpndHandle *src_) { - IPF_LOG << " tau_checkZero" << endl; + IPF_LOG << " tau_checkZero; src=" << IrPrinter::toString((Opnd *)src_) << endl; // p0 cmp.eq p2, p0 = base, r0 RegOpnd *src = toRegOpnd(src_); @@ -1274,7 +1630,7 @@ CompilationInterface::RuntimeHelperId hId = CompilationInterface::Helper_DivideByZeroException; uint64 address = (uint64) compilationInterface.getRuntimeHelperAddress(hId); Opnd *helperAddress = opndManager->newImm(address); - directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_SPNT); + directCall(0, NULL, NULL, helperAddress, truePred, CMPLT_WH_DPNT); return opndManager->getTau(); // return fake value (we do not use tau) } @@ -1514,7 +1870,9 @@ FieldDesc *fieldDesc) { IPF_LOG << " ldFieldAddr " << fieldDesc->getName() - << "(" << Type::tag2str(fieldRefType->tag) << ")" << endl; + << "(" << Type::tag2str(fieldRefType->tag) << ")" + << "; base=" << IrPrinter::toString((Opnd *)base) + << endl; Opnd *fieldOffset = opndManager->newImm(fieldDesc->getOffset()); RegOpnd *fieldAddress = opndManager->newRegOpnd(OPND_G_REG, DATA_MPTR); @@ -1888,6 +2246,7 @@ } Opnd *outArg = opndManager->newRegOpnd(opndKind, dataKind, location); + addNewInst(instCode, pred, outArg, opnd); callInst->addOpnd(outArg); // add the opnd in call opnds list (for data flow analysis) } @@ -1996,18 +2355,23 @@ //----------------------------------------------------------------------------// // If opnd is imm this method generates "mov" from imm to gr - +// if imm==0 then return r0 +// RegOpnd *IpfInstCodeSelector::toRegOpnd(CG_OpndHandle *opnd_) { if(((Opnd *)opnd_)->isReg()) return (RegOpnd *)opnd_; IPF_ASSERT(((Opnd *)opnd_)->isImm()); Opnd *opnd = (Opnd *)opnd_; - RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); - InstCode instCode = opnd->isFoldableImm(22) ? INST_MOV : INST_MOVL; - - addNewInst(instCode, p0, dst, opnd); - return dst; + if (opnd->getValue()==0) { + return opndManager->getR0(); + } else { + RegOpnd *dst = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); + InstCode instCode = opnd->isFoldableImm(22) ? INST_MOV : INST_MOVL; + + addNewInst(instCode, p0, dst, opnd); + return dst; + } } //----------------------------------------------------------------------------// @@ -2084,8 +2448,7 @@ // imm opnd must be on first position if(src2->isImm()) { - Opnd *buf = src1; - src1 = src2; + Opnd *buf = src2; src2 = toRegOpnd(buf); } @@ -2121,6 +2484,8 @@ Opnd *src1 = (Opnd *)src1_; Opnd *src2 = (Opnd *)src2_; + IPF_ASSERT(src1->isReg() || src2->isReg()); + // imm opnd must be on first position if(src2->isImm()) { Opnd *buf = src1; @@ -2250,6 +2615,9 @@ CG_OpndHandle *src1, CG_OpndHandle *src2) { + IPF_ASSERT(((Opnd *)src1)->isReg()); + IPF_ASSERT(((Opnd *)src2)->isReg()); + RegOpnd *f0 = opndManager->getF0(); RegOpnd *buf1 = opndManager->newRegOpnd(OPND_F_REG, DATA_D); RegOpnd *buf2 = opndManager->newRegOpnd(OPND_F_REG, DATA_D); @@ -2323,37 +2691,73 @@ // sxt4 dst = t2 // (p1) shr.u dst = t1, 33 // (p2) shl dst = t1, 31 +// +// New code +// ldfd tf = MAXINT4 +// fcmp.lt p11,p10 = src, tf +// (p10) movl dst = 0x7fffffff +// (p10) cmp.ne p10 = r0,r0 +// +// (p11) ldfd tf = MININT4 +// (p11) fcmp.gt p11,p10 = src, tf +// (p10) movl dst = 0x80000000 +// +// (p11) fcvt.fx tf = src +// (p11) getf.sig dst = tf void IpfInstCodeSelector::saturatingConv4(RegOpnd *dst, CG_OpndHandle *src_) { + IPF_LOG << " saturatingConv4" << endl; + IPF_ASSERT(((Opnd *)src_)->isFloating()); + union { + float fr; + uint32 gr; + } fval; + union { + double fr; + uint64 gr; + } dval; + + RegOpnd *r0 = opndManager->getR0(); RegOpnd *src = (RegOpnd *)src_; - RegOpnd *p1 = opndManager->newRegOpnd(OPND_P_REG, DATA_P); - RegOpnd *p2 = opndManager->newRegOpnd(OPND_P_REG, DATA_P); - RegOpnd *t1 = opndManager->newRegOpnd(OPND_G_REG, DATA_U64); - RegOpnd *t2 = opndManager->newRegOpnd(OPND_G_REG, DATA_U64); - RegOpnd *tf1 = NULL; - RegOpnd *tf2 = NULL; - RegOpnd *tf3 = opndManager->newRegOpnd(OPND_F_REG, src->getDataKind()); + RegOpnd *p11 = opndManager->newRegOpnd(OPND_P_REG, DATA_P); + RegOpnd *p10 = opndManager->newRegOpnd(OPND_P_REG, DATA_P); + RegOpnd *tf = NULL; + RegOpnd *tr = opndManager->newRegOpnd(OPND_G_REG, DATA_I64); if (src->getDataKind() == DATA_S) { - tf1 = (RegOpnd *)ldc_s((float)0x7fffffff); - tf2 = (RegOpnd *)ldc_s((float)((int) 0x80000000)); + tf = opndManager->newRegOpnd(OPND_F_REG, DATA_S); + fval.fr = (float)0x7fffffff; + addNewInst(INST_MOVL, p0, tr, opndManager->newImm(fval.gr)); + addNewInst(INST_SETF_S, p0, tf, tr); } else { - tf1 = (RegOpnd *)ldc_d((double)0x7fffffff); - tf2 = (RegOpnd *)ldc_d((double)((int) 0x80000000)); + tf = opndManager->newRegOpnd(OPND_F_REG, DATA_D); + dval.fr = (double)0x7fffffff; + addNewInst(INST_MOVL, p0, tr, opndManager->newImm(dval.gr)); + addNewInst(INST_SETF_D, p0, tf, tr); } + addNewInst(INST_FCMP, CMPLT_CMP_CREL_LT, p0, p11, p10, src, tf); + addNewInst(INST_MOVL, p10, dst, opndManager->newImm(0x7fffffff)); + addNewInst(INST_CMP, CMPLT_CMP_CREL_NE, p10, p10, p0, r0, r0); - sxt(src, 8); // sxt src if appropriate - addNewInst(INST_MOV, p0, t1, opndManager->newImm(-1)); - addNewInst(INST_FCVT_FX_TRUNC, p0, tf3, src); - addNewInst(INST_FCMP, CMPLT_CMP_CREL_GT, p0, p1, p0, src, tf1); - addNewInst(INST_FCMP, CMPLT_CMP_CREL_LT, p0, p2, p0, src, tf2); - addNewInst(INST_GETF_SIG, p0, t2, tf3); - addNewInst(INST_SXT, CMPLT_XSZ_4, p0, dst, t2); - addNewInst(INST_SHR_U, p1, dst, t1, opndManager->newImm(33)); - addNewInst(INST_SHL, p2, dst, t1, opndManager->newImm(31)); + if (src->getDataKind() == DATA_S) { + fval.fr = (float)((int)0x80000000); + addNewInst(INST_MOVL, p11, tr, opndManager->newImm(fval.gr)); + addNewInst(INST_SETF_S, p11, tf, tr); + } else { + tf = opndManager->newRegOpnd(OPND_F_REG, DATA_D); + dval.fr = (double)((int) 0x80000000); + addNewInst(INST_MOVL, p11, tr, opndManager->newImm(dval.gr)); + addNewInst(INST_SETF_D, p11, tf, tr); + } + addNewInst(INST_FCMP, CMPLT_CMP_CREL_GT, p11, p11, p10, src, tf); + addNewInst(INST_MOVL, p10, dst, opndManager->newImm(0x80000000)); + + addNewInst(INST_FCVT_FX_TRUNC, p11, tf, src); + addNewInst(INST_GETF_SIG, p11, dst, tf); + } //----------------------------------------------------------------------------// @@ -2375,6 +2779,12 @@ sxt(src1, 8); sxt(src2, 8); + + addNewInst(INST_DEF, p0,f6 ); + addNewInst(INST_DEF, p0,f7 ); + addNewInst(INST_DEF, p0,f8 ); + addNewInst(INST_DEF, p0,f9 ); + addNewInst(INST_DEF, p0,f10); addNewInst(INST_SETF_SIG, p0, f10, src1); addNewInst(INST_SETF_SIG, p0, f9, src2); @@ -2410,9 +2820,9 @@ IPF_ASSERT(((Opnd *)src1)->isReg()); IPF_ASSERT(((Opnd *)src2)->isReg()); - RegOpnd *p6 = opndManager->newRegOpnd(OPND_P_REG, DATA_P); RegOpnd *f0 = opndManager->getF0(); RegOpnd *f1 = opndManager->getF1(); + RegOpnd *p6 = opndManager->newRegOpnd(OPND_P_REG, DATA_P); RegOpnd *f6 = opndManager->newRegOpnd(OPND_F_REG, DATA_D); RegOpnd *f7 = opndManager->newRegOpnd(OPND_F_REG, DATA_D); RegOpnd *f8 = opndManager->newRegOpnd(OPND_F_REG, DATA_D); @@ -2421,6 +2831,12 @@ sxt(src1, 8); sxt(src2, 8); + + addNewInst(INST_DEF, p0,f6 ); + addNewInst(INST_DEF, p0,f7 ); + addNewInst(INST_DEF, p0,f8 ); + addNewInst(INST_DEF, p0,f9 ); + addNewInst(INST_DEF, p0,f10); addNewInst(INST_SETF_SIG, p0, f10, src1); addNewInst(INST_SETF_SIG, p0, f9, src2); @@ -2496,6 +2912,18 @@ // Group 6 // (pX) fma.d.s0 fRes = fr,fy3,fq3 // + addNewInst(INST_DEF, p0, fe ); + addNewInst(INST_DEF, p0, fq0); + addNewInst(INST_DEF, p0, fq1); + addNewInst(INST_DEF, p0, fe2); + addNewInst(INST_DEF, p0, fy1); + addNewInst(INST_DEF, p0, fe4); + addNewInst(INST_DEF, p0, fq2); + addNewInst(INST_DEF, p0, fy2); + addNewInst(INST_DEF, p0, fq3); + addNewInst(INST_DEF, p0, fy3); + addNewInst(INST_DEF, p0, fr ); + addNewInst(INST_FRCPA, CMPLT_SF0, p0, fRes, pX, fA, fB); addNewInst(INST_FNMA, CMPLT_SF1, pX, fe, fRes, fB, f1); @@ -2542,8 +2970,8 @@ RegOpnd *f1 = opndManager->getF1(); RegOpnd *fRes = dst, *fA = (RegOpnd *)src1, *fB = (RegOpnd *)src2; - RegOpnd *pX = opndManager->newRegOpnd(OPND_P_REG, DATA_P); - RegOpnd *fe = opndManager->newRegOpnd(OPND_F_REG, DATA_F); + RegOpnd *pX = opndManager->newRegOpnd(OPND_P_REG, DATA_P); + RegOpnd *fe = opndManager->newRegOpnd(OPND_F_REG, DATA_F); RegOpnd *fq0 = opndManager->newRegOpnd(OPND_F_REG, DATA_F); RegOpnd *fq1 = opndManager->newRegOpnd(OPND_F_REG, DATA_F); RegOpnd *fe2 = opndManager->newRegOpnd(OPND_F_REG, DATA_F); @@ -2567,7 +2995,15 @@ // (pX) fma.d.s1 fq3 = fq2,fe4,fq2 // (pX) fnorm.s.s0 fRes = fq3 // - // Group 0 + + addNewInst(INST_DEF, p0, fe ); + addNewInst(INST_DEF, p0, fq0); + addNewInst(INST_DEF, p0, fq1); + addNewInst(INST_DEF, p0, fe2); + addNewInst(INST_DEF, p0, fe4); + addNewInst(INST_DEF, p0, fq2); + addNewInst(INST_DEF, p0, fq3); + addNewInst(INST_FRCPA, CMPLT_SF0, p0, fRes, pX, fA, fB); addNewInst(INST_FNMA, CMPLT_SF1, pX, fe, fRes, fB, f1); Index: vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp (working copy) @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + /** * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin * @version $Revision$ @@ -43,24 +43,24 @@ struct sigaction signal_action; struct ucontext * signal_ucontext; int saved_errno = errno; - + if (sn==SIGILL && si->si_code==ILL_BREAK && si->si_imm==INST_BREAKPOINT_IMM_VALUE) { signal_ucontext = (struct ucontext *)_sc; - + if ( (signal_ucontext->_u._mc.sc_ip & 0x03)==2 ) { signal_ucontext->_u._mc.sc_ip = (signal_ucontext->_u._mc.sc_ip & ~0x03) + 0x10; } else { signal_ucontext->_u._mc.sc_ip++; } //printf("-- sighandler() for signal %d, si_code %d, si_imm %x\n", sn, si->si_code, si->si_imm); - + signal_action.sa_flags = SA_SIGINFO; signal_action.sa_sigaction = sighandler; if (sigaction(SIGILL, &signal_action, NULL)) { printf("Sigaction returned error = %d\n", errno); } } - + errno = saved_errno; return; } @@ -71,37 +71,161 @@ namespace IPF { //============================================================================// +const BundleDescription Bundle::BundleDesc[TEMPLATES_COUNT] = { + { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_I), 0x0, 0x00 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_I), 0x4, 0x01 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_I), 0x2, 0x02 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_I), 0x6, 0x03 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_L) | IT_SLOT2(IT_X), 0x0, 0x04 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_L) | IT_SLOT2(IT_X), 0x4, 0x05 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_I), 0x0, 0x08 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_I), 0x4, 0x09 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_I), 0x1, 0x0a }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_I), 0x5, 0x0b }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_F) | IT_SLOT2(IT_I), 0x0, 0x0c }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_F) | IT_SLOT2(IT_I), 0x4, 0x0d }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_F), 0x0, 0x0e }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_F), 0x4, 0x0f }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_B), 0x0, 0x10 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_B), 0x4, 0x11 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_B) | IT_SLOT2(IT_B), 0x0, 0x12 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_B) | IT_SLOT2(IT_B), 0x4, 0x13 }, + { IT_SLOT0(IT_B) | IT_SLOT1(IT_B) | IT_SLOT2(IT_B), 0x0, 0x16 }, + { IT_SLOT0(IT_B) | IT_SLOT1(IT_B) | IT_SLOT2(IT_B), 0x4, 0x17 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_B), 0x0, 0x18 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_B), 0x4, 0x19 }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_F) | IT_SLOT2(IT_B), 0x0, 0x1c }, + { IT_SLOT0(IT_M) | IT_SLOT1(IT_F) | IT_SLOT2(IT_B), 0x4, 0x1d } +}; +//============================================================================// + +const char Emitter::Itanium2_DualIssueBundles[30][30] = { + 1, 1, 1, 1, 0, 0, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MII, 0x00 + 1, 1, 1, 1, 0, 0, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MII, 0x01 + 1, 1, 1, 1, 0, 0, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MII, 0x02 + 1, 1, 1, 1, 0, 0, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MII, 0x03 + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MLX, 0x04 + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MLX, 0x05 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MMI, 0x08 + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MMI, 0x09 + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MMI, 0x0a + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MMI, 0x0b + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MFI, 0x0c + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MFI, 0x0d + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MMF, 0x0e + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, // MMF, 0x0f + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 0, 0, 1, 1, -1, -1, 1, 1, // MIB, 0x10 + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 0, 0, 1, 1, -1, -1, 1, 1, // MIB, 0x11 + 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, // MBB, 0x12 + 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, // MBB, 0x13 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, // BBB, 0x16 + 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1, -1, 0, 0, // BBB, 0x17 + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 0, 0, 1, 1, -1, -1, 1, 1, // MMB, 0x18 + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 0, 0, 1, 1, -1, -1, 1, 1, // MMB, 0x19 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 0, 0, 1, 1, -1, -1, 1, 1, // MFB, 0x1c + 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 0, 0, 1, 1, -1, -1, 1, 1 // MFB, 0x1d +}; + +//============================================================================// + +void Emitter::checkForDualIssueBundles() { + EmitterBb *bb; + Bundle *bundle1, *bundle2; + uint32 tmpl1, tmpl2; + bool header_printed = false; + + for (int bbindex=0 ; bbindex<(int)bbs->size() ; bbindex++) { + bb = bbs->at(bbindex); + BundleVector & bundles = *(bb->bundles); + for (int bi=0, bii=bundles.size()-1 ; bigetTmpl(); + tmpl2 = bundle2->getTmpl(); + if (!bundle1->hasStop() && Itanium2_DualIssueBundles[tmpl1][tmpl2]==0) { + if (!header_printed) { + header_printed = true; + clog << "CHECK_DUAL_ISSUE: Method:" + << " bundles=" << codesize/IPF_BUNDLE_SIZE + << "; SIG=" + << compilationinterface.getMethodToCompile()->getParentType()->getName() + << "." << compilationinterface.getMethodToCompile()->getName() + << compilationinterface.getMethodToCompile()->getSignatureString() + << "\n"; + } + clog << "CHECK_DUAL_ISSUE: bbindex=" << bbindex + << ", node_id=" << bb->node->getId() + << "; bi=" << bi + << "; tmpl1=0x" << hex << tmpl1 + << "; tmpl2=0x" << tmpl2 << dec + << "\n"; + + bi += 1; + continue; + } else if (Itanium2_DualIssueBundles[tmpl1][tmpl2] == -1) { + if (!header_printed) { + header_printed = true; + clog << "Method:" + << " bundles=" << codesize/IPF_BUNDLE_SIZE + << "; SIG=" + << compilationinterface.getMethodToCompile()->getParentType()->getName() + << "." << compilationinterface.getMethodToCompile()->getName() + << compilationinterface.getMethodToCompile()->getSignatureString() + << "\n"; + } + clog << "BAD templates: " << tmpl1 << ", " << tmpl2 + << "\n"; + } + + if (bundle2->hasStop()) { + bi += 1; + continue; + } else { + bi += 2; + continue; + } + } + } + +} + +//============================================================================// + Bundle::Bundle(Cfg& cfg, uint32 itmp, Inst *i0, Inst *i1, Inst *i2) { - indxtmpl = itmp; // !!! THis is not template, but index in Emitter::BundleDesc[] !!! - + indxtmpl = itmp; // !!! THis is not template, but index in Bundle::BundleDesc[] !!! + MemoryManager& mm = cfg.getMM(); OpndManager* opndManager = cfg.getOpndManager(); - + // slot 0 if( i0==NULL ) { - slot[0] = new(mm) Inst(INST_NOP, PR(0), IMM(INST_BREAKPOINT_IMM_VALUE)); + slot[0] = new(mm) Inst(mm, INST_NOP, PR(0), IMM(INST_BREAKPOINT_IMM_VALUE)); } else { slot[0] = i0; } - + // slot 1 if( i1==NULL ) { - slot[1] = new(mm) Inst(INST_NOP, PR(0), IMM(INST_BREAKPOINT_IMM_VALUE)); + slot[1] = new(mm) Inst(mm, INST_NOP, PR(0), IMM(INST_BREAKPOINT_IMM_VALUE)); } else { slot[1] = i1; } - + // slot 2 if( i2==NULL ) { - slot[2] = new(mm) Inst(INST_NOP, PR(0), IMM(INST_BREAKPOINT_IMM_VALUE)); + slot[2] = new(mm) Inst(mm, INST_NOP, PR(0), IMM(INST_BREAKPOINT_IMM_VALUE)); } else { slot[2] = i2; } } -uint32 Bundle::getTmpl() { return Emitter::BundleDesc[indxtmpl].tmpl; }; - //============================================================================// void Bundle::emitBundleGeneral(void *whereToEmit) { uint64 * p = (uint64 *)whereToEmit; @@ -111,10 +235,10 @@ p[1] = 0; p[0] = getTmpl(); - + s = getSlotBits(0); p[0] |= s << 5; - + s = getSlotBits(1); p[0] |= s << 46; p[1] = s >> 18; @@ -132,14 +256,14 @@ p[1] = 0; p[0] = itmp; - + if (itmp==0x16 || itmp==0x17) { s = getSlotBitsBranch(0, bundletarget[0]); } else { s = getSlotBits(0); } p[0] |= s << 5; - + if (itmp>=0x12 && itmp<=0x17) { s = getSlotBitsBranch(1, bundletarget[1]); } else { @@ -165,10 +289,10 @@ p[1] = 0; p[0] = getTmpl(); - + s = getSlotBits(0); p[0] |= s << 5; - + getSlotBitsExtended(s12, whereToEmit); p[0] |= s12[0] << 46; p[1] = s12[0] >> 18; @@ -207,37 +331,9 @@ } //============================================================================// -const BundleDescription Emitter::BundleDesc[TEMPLATES_COUNT] = { - { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_I), 0x0, 0x00 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_I), 0x4, 0x01 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_I), 0x2, 0x02 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_I), 0x6, 0x03 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_L) | IT_SLOT2(IT_X), 0x0, 0x04 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_L) | IT_SLOT2(IT_X), 0x4, 0x05 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_I), 0x0, 0x08 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_I), 0x4, 0x09 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_I), 0x1, 0x0a }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_I), 0x5, 0x0b }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_F) | IT_SLOT2(IT_I), 0x0, 0x0c }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_F) | IT_SLOT2(IT_I), 0x4, 0x0d }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_F), 0x0, 0x0e }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_F), 0x4, 0x0f }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_B), 0x0, 0x10 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_I) | IT_SLOT2(IT_B), 0x4, 0x11 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_B) | IT_SLOT2(IT_B), 0x0, 0x12 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_B) | IT_SLOT2(IT_B), 0x4, 0x13 }, - { IT_SLOT0(IT_B) | IT_SLOT1(IT_B) | IT_SLOT2(IT_B), 0x0, 0x16 }, - { IT_SLOT0(IT_B) | IT_SLOT1(IT_B) | IT_SLOT2(IT_B), 0x4, 0x17 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_B), 0x0, 0x18 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_M) | IT_SLOT2(IT_B), 0x4, 0x19 }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_F) | IT_SLOT2(IT_B), 0x0, 0x1c }, - { IT_SLOT0(IT_M) | IT_SLOT1(IT_F) | IT_SLOT2(IT_B), 0x4, 0x1d } -}; - -//============================================================================// EmitterBb::EmitterBb(Cfg & cfg, CompilationInterface & compilationinterface - , BbNode * node_, bool _break4cafe, bool _nop4cafe) : - node(node_), + , BbNode * node_, bool _break4cafe, bool _nop4cafe) : + node(node_), insts(node->getInsts()) { MemoryManager& mm=cfg.getMM(); @@ -255,39 +351,39 @@ if (!_break4cafe) { if (_nop4cafe) { bundles->addBundle(0x01 - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); } } else { #ifdef SIGILL_BREAK_ACTION_HANDLER if (ipfEnableSigillBreakActionHandler) { struct sigaction signal_action; - + signal_action.sa_flags = SA_SIGINFO; signal_action.sa_sigaction = sighandler; if (sigaction(SIGILL, &signal_action, NULL)) { printf("Sigaction returned error = %d\n", errno); } - + bundles->addBundle(0x01 - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_BREAK, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_BREAK, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); } else { if (_nop4cafe) { bundles->addBundle(0x01 - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); } } #else if (_nop4cafe) { bundles->addBundle(0x01 - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) - , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); } #endif } @@ -295,28 +391,29 @@ }; //============================================================================// -Emitter::Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_) : +Emitter::Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_) : mm(cfg_.getMM()), cfg(cfg_), compilationinterface(compilationinterface_) { removeUselessInst(cfg, compilationinterface); - + removeIgnoreTypeInst(cfg, compilationinterface); + (new(mm) IpfVerifier(cfg, compilationinterface))->verifyMethod(); bbs = new(mm) vectorbb; BbNode * node = (BbNode *)cfg.getEnterNode(); EmitterBb * bbdesc; - bool break4cafe = ipfEnableSigillBreakActionHandler + bool break4cafe = ipfEnableSigillBreakActionHandler && (ipfEnableAutoSigillBreak || isIpfBreakMethod(compilationinterface.getMethodToCompile())); - bool nop4cafe = true; + bool nop4cafe = false; do { // for debugging // tricking(node->getInsts(), mm, cfg); - + if (isIpfBreakBb(node->getId())) { bbdesc = new(mm) EmitterBb(cfg, compilationinterface, node, true, nop4cafe); } else { @@ -326,7 +423,7 @@ if (!ipfSigillBreakAllBB) break4cafe = false; nop4cafe = false; } while( (node = node->getLayoutSucc()) != NULL ); - + }; //============================================================================// @@ -334,19 +431,19 @@ BbNode * node = (BbNode *)cfg.getEnterNode(); int methoduseless = 0; int methodafter = 0; - + do { InstVector &insts = node->getInsts(); int i; - - for( i=0 ; i < (int)insts.size() ; i++ ) { + + for( i=0 ; i < (int)insts.size() ; ) { Inst *inst = insts[i]; InstCode icode = inst->getInstCode(); + OpndVector &opnds = inst->getOpnds(); if (icode==INST_MOV) { if (inst->getNumOpnd()==3) { - OpndVector &opnds = inst->getOpnds(); - if (opnds[1]->isReg() && opnds[2]->isReg() + if (((opnds[1]->isGReg() && opnds[2]->isGReg()) || (opnds[1]->isFReg() && opnds[2]->isFReg())) && opnds[1]->getValue()==opnds[2]->getValue()) { IPF_LOG << "USELESS: " << IrPrinter::toString(inst) << "\n"; insts.erase(insts.begin() + i); @@ -355,10 +452,8 @@ } } } - if (icode==INST_ADD || icode==INST_ADDS || icode==INST_ADDL) { if (inst->getNumOpnd()==4) { - OpndVector &opnds = inst->getOpnds(); if (opnds[2]->getValue()==0 && opnds[1]->getValue()==opnds[3]->getValue()) { IPF_LOG << "USELESS: " << IrPrinter::toString(inst) << "\n"; @@ -368,31 +463,62 @@ } } } + + i++; } methodafter += i; } while( (node = node->getLayoutSucc()) != NULL ); - + /* statistical data */ if (0 && (methoduseless > 0)) { static int alluseless = 0; static int allafter = 0; alluseless += methoduseless; - IPF_LOG << "USELESS: method: " << methoduseless - << "(" << (((float)methoduseless)/(methoduseless + methodafter)) << "%) instructions\n"; - IPF_LOG << "USELESS: all: " << alluseless - << "(" << (((float)alluseless)/(alluseless + allafter)) << "%) instructions\n"; + allafter += methodafter; + if (methoduseless > 0) { + IPF_LOG << "USELESS: method: " << methoduseless + << "(" << (((float)methoduseless)/(methoduseless + methodafter))*100 << "%) instructions\n"; + IPF_LOG << "USELESS: all: " << alluseless + << "(" << (((float)alluseless)/(alluseless + allafter))*100 << "%) instructions\n"; + } } if (methoduseless > 0) { - IPF_LOG << "USELESS: removed " << methoduseless - << "(" << (((float)methoduseless)/(methoduseless + methodafter)) << "%) instructions\n"; + IPF_LOG << "USELESS: removed " << methoduseless + << "(" << (((float)methoduseless)/(methoduseless + methodafter) * 100) << "%) instructions\n"; } return methoduseless; } //============================================================================// +int Emitter::removeIgnoreTypeInst(Cfg & cfg, CompilationInterface & compilationinterface) { + BbNode * node = (BbNode *)cfg.getEnterNode(); + int ignoredcc = 0, i = 0; + do { + InstVector &insts = node->getInsts(); + + for( i=0 ; i < (int)insts.size() ; ) { + Inst *inst = insts[i]; + + if (Encoder::isIgnoreInst(inst)) { + IPF_LOG << "IGNORED: " << IrPrinter::toString(inst) << "\n"; + insts.erase(insts.begin() + i); + continue; + } + i++; + } + } while( (node = node->getLayoutSucc()) != NULL ); + + if (ignoredcc>0 && i>0) { + IPF_LOG << "IGNORED: removed " << ignoredcc + << "(" << (((float)ignoredcc)/(ignoredcc + i) * 100) << "%) instructions\n"; + } + return ignoredcc; +} + +//============================================================================// InstructionType Emitter::getExecUnitType(int templateindex, int slotindex) { - return (InstructionType)((Emitter::BundleDesc[templateindex].slots >> (slotindex * 8)) & 0xFF); + return (InstructionType)((Bundle::BundleDesc[templateindex].slots >> (slotindex * 8)) & 0xFF); } //============================================================================// @@ -403,14 +529,14 @@ tmp.slots = IT_SLOT0(IT_ANY); } tmp.stops = (s0 ? 1 : 0); - + if(i1!=NULL) { tmp.slots |= IT_SLOT1(Encoder::getInstType(i1)); } else { tmp.slots |= IT_SLOT1(IT_ANY); } tmp.stops |= (s1 ? 2 : 0); - + if( i2!=NULL ) { tmp.slots |= IT_SLOT2(Encoder::getInstType(i2)); } else { @@ -421,10 +547,10 @@ int Emitter::findTmpl(const BundleDescription & tmp) { for( int j=0 ; jGR.test(33)) { OpndManager * opndManager = cfg.getOpndManager(); insts.insert(insts.begin() + i - , new(mm) Inst(INST_BREAK, opndManager->getP0(), opndManager->newImm(INST_BREAKPOINT_IMM_VALUE))); + , new(mm) Inst(mm, INST_BREAK, opndManager->getP0(), opndManager->newImm(INST_BREAKPOINT_IMM_VALUE))); i++; } } @@ -517,12 +643,12 @@ //============================================================================// bool Emitter::parsing() { bool ret = true; - + datasize = 0; for (int bbindex=0, bbssize=(int)bbs->size() ; bbindexgetInstCode(); OpndVector & opnds = inst->getOpnds(); - + if (instCode==INST_BR13 || instCode==INST_BRL13) { instCode = (instCode == INST_BR13 ? INST_BR : INST_BRL); } - + + // if inst is branch and target is DATA_NODE_REF + // set istarget flag for target bb + if (instCode==INST_BR || instCode==INST_BRL) { + int is13 = (instCode==INST_BRL13 || instCode==INST_BR13 ? 1 : 0); // must be 1 or 0 + opnd = opnds[is13 + 1]; + if (opnd->getDataKind() == DATA_NODE_REF) { + int targetind = getBbNodeIndex(((NodeRef*) opnd)->getNode()); + bbs->at(targetind)->istarget=true; + } + } + // regs masks regs = new(mm) RegistersBitset(); getWriteDpndBitset(inst, regs); @@ -556,7 +693,7 @@ regs = new(mm) RegistersBitset(); getReadDpndBitset(inst, regs); rr->at(i) = regs; - + // constants dstcount=inst->getNumDst(); opndcount=inst->getNumOpnd(); @@ -576,17 +713,17 @@ } } } - + return true; } //============================================================================// bool Emitter::stopping() { bool ret = true; - + for (int bbindex=0 ; bbindex<(int)bbs->size() ; bbindex++) { ret &= stopping(bbindex); } - + return ret; } @@ -595,7 +732,7 @@ InstVector & insts = bb->insts; long sizebb = insts.size(); if (sizebb==0) return true; - + vectorbool * stops = bb->stops; vectorregs * wr = bb->wregs; vectorregs * rr = bb->rregs; @@ -617,10 +754,10 @@ } if (Encoder::isIgnoreInst(inst1)) continue; if (icode1 >= INST_ST_FIRST && icode1 <= INST_ST_LAST) continue; - + regs1w = wr->at(i); if(!regs1w->any()) continue; - + for (long j = i + 1; j < stop; j++) { inst2 = insts[j]; icode2 = inst2->getInstCode(); @@ -628,14 +765,23 @@ if (j>0) stops->at(j-1) = true; } if (Encoder::isIgnoreInst(inst2)) continue; - + regs2w = wr->at(j); regs2r = rr->at(j); if(!regs2w->any() && !regs2r->any()) continue; - - if( (regs1w->GR & (regs2w->GR | regs2r->GR)).any() - || (regs1w->FR & (regs2w->FR | regs2r->FR)).any() - || (regs1w->PR & (regs2w->PR | regs2r->PR)).any() + + if (Encoder::isBranchInst(inst2)) { + if( (Encoder::getInstType(icode1) & IT_F) + && (regs1w->PR & (regs2w->PR | regs2r->PR)).any() ) { + stop=j; + break; + } + continue; + } + + if( (regs1w->GR & (regs2w->GR | regs2r->GR)).any() + || (regs1w->FR & (regs2w->FR | regs2r->FR)).any() + || (regs1w->PR & (regs2w->PR | regs2r->PR)).any() || (regs1w->BR & (regs2w->BR | regs2r->BR)).any() ) { stop=j; break; @@ -648,14 +794,14 @@ stop=sizebb; } else if( stop==sizebb ) { start++; - } else { + } else { stops->at(stop-1) = true; start=stop; stop=sizebb; } } stops->at(stops->size()-1) = true; - + return true; } @@ -664,17 +810,36 @@ EmitterBb * bb; char * off=0; bool ret = true; - + for (int bbindex=0 ; bbindex<(int)bbs->size() ; bbindex++) { ret &= bundling(bbindex); bb = bbs->at(bbindex); bb->bsize = bb->bundles->size(); bb->codeoff = off; bb->codesize = bb->bsize * IPF_BUNDLE_SIZE; + // align bb if istarget==true + if (false && bb->istarget) { // switch off aligning + uint16 bytes4align = (bb->codesize % IPF_CODE_ALIGNMENT) == 0 + ? 0 + : IPF_CODE_ALIGNMENT - (bb->codesize % IPF_CODE_ALIGNMENT); + if (bytes4align>0 && (bytes4align%IPF_BUNDLE_SIZE)==0) { + bb->codesize += bytes4align; + uint16 bundles4align = bytes4align/IPF_BUNDLE_SIZE; + OpndManager * opndManager = cfg.getOpndManager(); + Opnd * p0 = opndManager->getP0(); + for (uint16 i=0 ; ibundles->addBundle(0x00 + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)) + , new(mm) Inst(mm, INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))); + } + + } + } off = (char *)off + bb->codesize; } codesize = (long)((char *)off); - + return ret; } bool Emitter::bundling(int bbindex) { @@ -686,13 +851,13 @@ vectorbool * stops = bb->stops; BundleVector * bundles = bb->bundles; BundleDescription tmp = {0,0,0}; - int iTmpl=-1; - Inst * inst0=NULL, * inst1=NULL, * inst2=NULL; - bool stop0=false, stop1=false, stop2=false; - bool stop0_f=false, stop1_f=false, stop2_f=false; // inst is first in group - bool stop0_l=false, stop1_l=false, stop2_l=false; // inst is last in group - int it0=0, it1=0, it2=0; // insts type - long i0, i1, i2; + int iTmpl=-1; + Inst *inst0=NULL, *inst1=NULL, *inst2=NULL, *inst3=NULL; + bool stop0=false, stop1=false, stop2=false, stop3=false; + bool stop0_f=false, stop1_f=false, stop2_f=false, stop3_f=false; // inst is first in group + bool stop0_l=false, stop1_l=false, stop2_l=false; // inst is last in group + int it0=0, it1=0, it2=0, it3=0; // insts type + long i0, i1, i2, i3; for ( i0=0 ; i0 < sizebb ; ) { inst0=Encoder::resolvePseudo(cfg, insts[i0]); @@ -714,10 +879,19 @@ break; } if ( i2 >= sizebb ) { inst2=NULL; } - + + for ( i3=i2+1 ; i3at(i3); + break; + } + if ( i3 >= sizebb ) { inst3=NULL; } + it0 = Encoder::getInstType(inst0); it1 = Encoder::getInstType(inst1); it2 = Encoder::getInstType(inst2); + it3 = Encoder::getInstType(inst3); stop0_l = (it0 & IT_GL)==IT_GL; stop1_l = (it1 & IT_GL)==IT_GL; @@ -725,10 +899,13 @@ stop0_f = (it0 & IT_GF)==IT_GF; stop1_f = (it1 & IT_GF)==IT_GF; stop2_f = (it2 & IT_GF)==IT_GF; + stop3_f = (it3 & IT_GF)==IT_GF; - // Special case for br.call - // br.ret will return to next bundle, so - // all instructions after br.call must be nop + /********************************************* + * Special case for br.call + * br.ret will return to next bundle, so + * all instructions after br.call must be nop + *********************************************/ if (inst0->getInstCode()==INST_BR || inst0->getInstCode()==INST_BR13) { CompVector & cmpls0 = inst0->getComps(); if (cmpls0.size()>0 && cmpls0[0]==CMPLT_BTYPE_CALL) { @@ -742,9 +919,47 @@ } } + /********************************************* + * Special case for inst0==LX type (brl,...) + *********************************************/ + if ( Encoder::getInstType(inst0->getInstCode()) & IT_L ) { + inst1=NULL; + inst2=NULL; + getTmpl(bbindex, tmp, NULL, inst0, NULL + , false, false, stop0 || stop0_l || stop1_f); + iTmpl=findTmpl(tmp); + if( iTmpl>=0 ) { + bundles->addBundle(iTmpl, NULL, inst0, NULL); + i0 += 1; + continue; + } + IPF_ERR << "BUNDLING ERROR: CAN'T FIND TEMPLATE !\n"; + IPF_ERR << "BUNDLING ERROR: " << IrPrinter::toString(inst0) << "\n"; + IPF_ASSERT(0); + } + + /******************************** + * Special case for inst1==LX type (brl,...) + ********************************/ + if (inst1!=NULL && (Encoder::getInstType(inst1->getInstCode()) & IT_L)) { + inst2=NULL; + getTmpl(bbindex, tmp, inst0, inst1, NULL + , stop0 || stop0_l || stop1_f, false, stop1 || stop1_l || stop2_f); + iTmpl=findTmpl(tmp); + if( iTmpl>=0 ) { + bundles->addBundle(iTmpl, inst0, inst1, NULL); + i0 = i1 + 1; + continue; + } + inst1=NULL; + } + + /******************************** + * inst1!=NULL && inst2!=NULL + ********************************/ if (inst1!=NULL && inst2!=NULL) { getTmpl(bbindex, tmp, inst0, inst1, inst2 - , stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f, stop2 || stop2_l); + , stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f, stop2 || stop2_l || stop3_f); iTmpl=findTmpl(tmp); if( iTmpl>=0 ) { bundles->addBundle(iTmpl, inst0, inst1, inst2); @@ -752,33 +967,47 @@ continue; } } - + + /******************************** + * inst2==NULL && inst1!=LX type (brl,...) + ********************************/ if (inst1!=NULL) { + getTmpl(bbindex, tmp, inst0, inst1, NULL + , stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f, false); + iTmpl=findTmpl(tmp); + if( iTmpl>=0 ) { + bundles->addBundle(iTmpl, inst0, inst1, NULL); + i0 = i1 + 1; + continue; + } + getTmpl(bbindex, tmp, inst0, inst1, NULL + , stop0 || stop0_l || stop1_f, false, stop1 || stop1_l || stop2_f); + iTmpl=findTmpl(tmp); + if( iTmpl>=0 ) { + bundles->addBundle(iTmpl, inst0, inst1, NULL); + i0 = i1 + 1; + continue; + } + getTmpl(bbindex, tmp, inst0, NULL, inst1 - , stop0 || stop0_l, stop1_f, stop1 || stop1_l || stop2_f); + , stop0 || stop0_l || stop1_f, false, stop1 || stop1_l || stop2_f); iTmpl=findTmpl(tmp); if( iTmpl>=0 ) { bundles->addBundle(iTmpl, inst0, NULL, inst1); i0 = i1 + 1; continue; } - - if ( inst1!=NULL && Encoder::getInstType(inst1->getInstCode()) & IT_L ) { - getTmpl(bbindex, tmp, inst0, inst1, NULL - , stop0 || stop0_l || stop1_f, false, stop1 || stop1_l || stop2_f); - } else { - getTmpl(bbindex, tmp, inst0, inst1, NULL - , stop0 || stop0_l || stop1_f, stop1 || stop1_l, stop2_f); - } + getTmpl(bbindex, tmp, inst0, NULL, inst1 + , false, stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f); iTmpl=findTmpl(tmp); if( iTmpl>=0 ) { - bundles->addBundle(iTmpl, inst0, inst1, NULL); + bundles->addBundle(iTmpl, inst0, NULL, inst1); i0 = i1 + 1; continue; } - + getTmpl(bbindex, tmp, NULL, inst0, inst1 - , stop0_f, stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f); + , false, stop0 || stop0_l || stop1_f, stop1 || stop1_l || stop2_f); iTmpl=findTmpl(tmp); if( iTmpl>=0 ) { bundles->addBundle(iTmpl, NULL,inst0, inst1); @@ -787,22 +1016,44 @@ } } + /******************************** + * inst1==NULL + ********************************/ getTmpl(bbindex, tmp, inst0, NULL, NULL - , stop0 || stop0_l, false, stop1_f); + , stop0 || stop0_l || stop1_f, false, false); iTmpl=findTmpl(tmp); if( iTmpl>=0 ) { bundles->addBundle(iTmpl, inst0, NULL, NULL); i0 += 1; continue; } + getTmpl(bbindex, tmp, inst0, NULL, NULL + , false, stop0 || stop0_l || stop1_f, false); + iTmpl=findTmpl(tmp); + if( iTmpl>=0 ) { + bundles->addBundle(iTmpl, inst0, NULL, NULL); + i0 += 1; + continue; + } + getTmpl(bbindex, tmp, inst0, NULL, NULL + , false, false, stop0 || stop0_l || stop1_f); + iTmpl=findTmpl(tmp); + if( iTmpl>=0 ) { + bundles->addBundle(iTmpl, inst0, NULL, NULL); + i0 += 1; + continue; + } - if ( Encoder::getInstType(inst0->getInstCode()) & IT_L ) { - getTmpl(bbindex, tmp, NULL, inst0, NULL - , false, false, stop0 || stop0_l || stop1_f); - } else { - getTmpl(bbindex, tmp, NULL, inst0, NULL - , stop0_f, stop0 || stop0_l, stop1_f); + getTmpl(bbindex, tmp, NULL, inst0, NULL + , false, stop0 || stop0_l || stop1_f, false); + iTmpl=findTmpl(tmp); + if( iTmpl>=0 ) { + bundles->addBundle(iTmpl, NULL, inst0, NULL); + i0 += 1; + continue; } + getTmpl(bbindex, tmp, NULL, inst0, NULL + , false, false, stop0 || stop0_l || stop1_f); iTmpl=findTmpl(tmp); if( iTmpl>=0 ) { bundles->addBundle(iTmpl, NULL, inst0, NULL); @@ -811,7 +1062,7 @@ } getTmpl(bbindex, tmp, NULL, NULL, inst0 - , false, stop0_f, stop0 || stop0_l || stop1_f); + , false, false, stop0 || stop0_l || stop1_f); iTmpl=findTmpl(tmp); if( iTmpl>=0 ) { bundles->addBundle(iTmpl, NULL, NULL, inst0); @@ -824,21 +1075,21 @@ i0++; } - + return true; } //============================================================================// bool Emitter::emitData() { if (datasize==0) return true; - + bool ret = true; EmitterBb * bb; char * p; Opnd * opnd; dataoff = (char *)compilationinterface.allocateDataBlock(datasize - , L2_CACHE_BANK_SIZE); + , L2_CACHE_LINE_SIZE); assert(dataoff != NULL); if ( dataoff == NULL ) return false; @@ -851,7 +1102,7 @@ if (opnd->isImm()) { if ( opnd->getDataKind() == DATA_CONST_REF) { Constant * c; - + c = ((ConstantRef *)opnd)->getConstant(); switch (c->getDataKind()) { case DATA_I64: @@ -859,12 +1110,12 @@ c->setAddress(p); p = (char *)(++((int64 *)p)); break; - case DATA_S: + case DATA_S: *((float *)p) = ((FloatConstant *)c)->getValue(); c->setAddress(p); p = (char *)(++((float *)p)); break; - case DATA_D: + case DATA_D: *((double *)p) = ((DoubleConstant *)c)->getValue(); c->setAddress(p); p = (char *)(++((double *)p)); @@ -875,7 +1126,7 @@ } } else if ( opnd->getDataKind() == DATA_SWITCH_REF) { SwitchConstant * c; - + c = (SwitchConstant *)((ConstantRef *)opnd)->getConstant(); *((uint64 *)p) = (uint64)opnd; // need to fill with actual // values of node's addresses @@ -889,7 +1140,7 @@ } } } - + return ret; } @@ -897,7 +1148,7 @@ bool Emitter::fixSwitchTables() { if ( datasize==0 ) return true; if ( dataoff == NULL ) return true; - + bool ret = true; EmitterBb * bb; void * p; @@ -922,7 +1173,7 @@ } } } - + return ret; } @@ -954,7 +1205,7 @@ inst = bundle->getSlot(si); inst->setAddr((uint32)(off - bboff) + si); } - + if ( isBranchBundle(bundle, codeoff, off, target) ) { // bundle contains B type inst bundle->emitBundleBranch(off, target); @@ -982,7 +1233,7 @@ } } IPF_LOG << "END code emitting: " - << compilationinterface.getMethodToCompile()->getParentType()->getName() + << compilationinterface.getMethodToCompile()->getParentType()->getName() << "." << compilationinterface.getMethodToCompile()->getName() << compilationinterface.getMethodToCompile()->getSignatureString() << endl; @@ -1000,8 +1251,8 @@ Opnd * opnd; InstCode icode; unsigned int is13; // must be 1 or 0 - - for (int i=0 ; i<3 ; i++ ) { + + for (int i=0 ; igetSlot(i); if(Encoder::isBranchInst(inst)) { @@ -1027,17 +1278,26 @@ return (char *)-1; } +int Emitter::getBbNodeIndex(BbNode * node) { + for (int i=0 ; i<(int)bbs->size() ; i++) { + if (bbs->at(i)->node == node) { + return i; + } + } + return -1; +} + bool Emitter::emit() { bool ret = true; - // 0 pass: parsing insts - // - clear ignored insts - // - define registers read/write masks + // 0 pass: parsing insts + // - clear ignored insts + // - define registers read/write masks // - create vector of constants // - create vector of brunches ret &= parsing(); if (!ret) { IPF_ERR << "Bad results for parsing\n"; return ret; } - + // 1 pass: emit data ret &= emitData(); if (!ret) { IPF_ERR << "Bad results for emitData\n"; return ret; } @@ -1058,10 +1318,12 @@ ret = fixSwitchTables(); if (!ret) { IPF_ERR << "Bad results for fixSwitchTables\n"; return ret; } + // checkForDualIssueBundles(); + if (LOG_ON) { -// printInsts(" Result of stopping() "); -// printBundles(" Result of bundling() "); - //printCodeBlock(" Result of emitting() "); + printInsts(" Result of stopping() "); + printBundles(" Result of bundling() "); + printCodeBlock(" Result of emitting() "); printDisasm(" Result of emitting(disasm) "); } @@ -1082,12 +1344,12 @@ BundleVector * bundles = bbs->at(bbindex)->bundles; Bundle * bndl; - IPF_LOG << ".L" << bbs->at(bbindex)->node->getId() + IPF_LOG << ".L" << bbs->at(bbindex)->node->getId() << " (0x" << hex << bbs->at(bbindex)->node->getAddress() << dec << ")\n"; for (long i = 0, ii=bundles->size() ; i < ii ; i++) { bndl = bundles->at(i); if( bndl==NULL ) { - IPF_LOG << i; + IPF_LOG << i; IPF_LOG << " \tNULL\n" << " \tNULL\n" << " \tNULL\n"; @@ -1130,7 +1392,7 @@ char printbuf[256]; char * off = codeoff; uint64 * p, tmpl, i0, i1, i2; - + IPF_LOG << "\n-----------" << cap << "-----------------------------\n"; sprintf(printbuf, "%-11.11s %-11.11s %-11.11s %-8.8s\n", "slot2", "slot1", "slot0", "template"); IPF_LOG << printbuf; @@ -1141,7 +1403,7 @@ i0 = (p[0] & 0x3FFFFFFFFFE0) >> 5; i1 = (((p[0] & ~0x1F) & ~0x3FFFFFFFFFE0) >> 46) | ((p[1] & 0x7FFFFF) << 18); i2 = (p[1] & ~0x7FFFFF) >> 23; - + sprintf(printbuf, "%11.11llx %11.11llx %11.11llx %2.2x \n", i2, i1, i0, (unsigned)tmpl); IPF_LOG << printbuf; off += IPF_BUNDLE_SIZE; @@ -1153,8 +1415,8 @@ { InstCode icode = inst->getInstCode(); unsigned int is13 = (icode==INST_BRL13 ? 1 : 0); // must be 1 or 0 - - assert((icode==INST_BRL || icode==INST_BRL13) + + assert((icode==INST_BRL || icode==INST_BRL13) && (inst->getComps())[0]==CMPLT_BTYPE_CALL); Opnd * target = (inst->getOpnds())[is13 + 2]; assert(target->isImm() && target->getDataKind()==DATA_METHOD_REF); @@ -1162,8 +1424,8 @@ compilationinterface.setNotifyWhenMethodIsRecompiled(method, (void *)data); if (LOG_ON) { - IPF_LOG << "Registered call to " << method->getParentType()->getName() - << "." << method->getName() + IPF_LOG << "Registered call to " << method->getParentType()->getName() + << "." << method->getName() << " : data=0x" << hex << data << dec << " for recompiled method event" << endl; } @@ -1171,7 +1433,7 @@ #include #include - + void Emitter::printDisasm(char * cap) { static bool load_done = false; static unsigned (*disasm)(const char *, char *, unsigned) = NULL; @@ -1182,7 +1444,7 @@ // Resolve full path to module string sz(""); int len = 0; - + len = readlink("/proc/self/exe", buf, sizeof(buf)); if (len < 0) { buf[0]='.'; @@ -1206,7 +1468,7 @@ disasm = (unsigned (*)(const char *, char *, unsigned)) (handle == NULL ? NULL : dlsym(handle, "disasm")); load_done = true; - + if (disasm==NULL) { std::cout << "CAN'T LOAD" << std::endl; return; @@ -1217,21 +1479,21 @@ if (disasm==NULL) { return; } - + string str(""); char buf[100]; char * off = codeoff; - + for (unsigned i=0 ; isize() ; bbindex++) { EmitterBb *bb = bbs->at(bbindex); char * bboff = (char *)bb->node->getAddress(); - + if (bboff==off) { char bbid[64]; - + sprintf(bbid, "%i (%p)", (int)bb->node->getId(), bboff); str.append("\n.L"); str.append(bbid); @@ -1251,7 +1513,7 @@ } i += l; } - + IPF_LOG << endl << "-----------" << cap << "-----------------------" << endl; IPF_LOG << str; } Index: vm/jitrino/src/codegenerator/ipf/IpfVerifier.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfVerifier.cpp (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/IpfVerifier.cpp (working copy) @@ -144,6 +144,9 @@ << (res->empty() ? "" : " : ") << *res << "\n"; ret = false; +#ifndef NDEBUG + verifyInst(res, inst); // verify again for debugger +#endif } } Index: vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp (working copy) @@ -169,6 +169,7 @@ *ofs << " fontpath=\"c:\\winnt\\fonts\";" << ::std::endl; *ofs << " node [shape=record,fontname=\"Courier\",fontsize=9];" << ::std::endl; *ofs << " edge [fontname=\"Courier\",fontsize=9];" << ::std::endl; + } //----------------------------------------------------------------------------------------// Index: vm/jitrino/src/codegenerator/ipf/IpfEncoder.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfEncoder.cpp (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/IpfEncoder.cpp (working copy) @@ -539,21 +539,21 @@ if (opndsize == 3) { if (okind1 == OPND_G_REG && opnds[2]->isImm(22)) { - newinst = new(mm) Inst(INST_ADDL, opnds[0], opnds[1], opnds[2] + newinst = new(mm) Inst(mm, INST_ADDL, opnds[0], opnds[1], opnds[2] , cfg.getOpndManager()->getR0()); } else if (okind1 == OPND_G_REG && opnds[2]->isImm(64)) { - newinst = new(mm) Inst(INST_MOVL, opnds[0], opnds[1], opnds[2]); + newinst = new(mm) Inst(mm, INST_MOVL, opnds[0], opnds[1], opnds[2]); } else if (okind1 == OPND_G_REG && okind2 == OPND_G_REG && cmpls.size()==0) { - newinst = new(mm) Inst(INST_ADDS, opnds[0], opnds[1] + newinst = new(mm) Inst(mm, INST_ADDS, opnds[0], opnds[1] , opndManager->newImm(0), opnds[2]); } else if (okind1 == OPND_F_REG && okind2 == OPND_F_REG) { - newinst = new(mm) Inst(INST_FMERGE_S, opnds[0], opnds[1], opnds[2], opnds[2]); + newinst = new(mm) Inst(mm, INST_FMERGE_S, opnds[0], opnds[1], opnds[2], opnds[2]); } else if (okind1 == OPND_B_REG && okind2 == OPND_G_REG) { - newinst = new(mm) Inst(INST_MOV, opnds[0], opnds[1], opnds[2] + newinst = new(mm) Inst(mm, INST_MOV, opnds[0], opnds[1], opnds[2] , opndManager->newImm(0)); } else if (okind1 == OPND_G_REG && okind2 == OPND_A_REG) { - newinst = new(mm) Inst(INST_MOV_M, opnds[0], opnds[1], opnds[2]); + newinst = new(mm) Inst(mm, INST_MOV_M, opnds[0], opnds[1], opnds[2]); } else if (okind1 == OPND_G_REG && okind2 == OPND_B_REG) { break; } else if (okind1 == OPND_A_REG @@ -680,11 +680,11 @@ default: assert(0); break; } - if (opnds[2]->isImm(14)) { + if (opnds[2]->isImm(8)) { x4 += 0x8; + return A3(x4, x2b, opnds[3]->getValue(), opnds[2]->getValue(), opnds[1]->getValue(), qp); + } else { return A1(x4, x2b, opnds[3]->getValue(), opnds[2]->getValue(), opnds[1]->getValue(), qp); - } else { - return A3(x4, x2b, opnds[3]->getValue(), opnds[2]->getValue(), opnds[1]->getValue(), qp); } } case INST_CMP: Index: vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/IpfCodeGenerator.cpp (working copy) @@ -33,7 +33,7 @@ #include "IpfPrologEpilogGenerator.h" #include "IpfRuntimeSupport.h" #include "IpfCfgVerifier.h" -#include "IpfInstrumentator.h" +//#include "IpfInstrumentator.h" namespace Jitrino { namespace IPF { Index: vm/jitrino/src/codegenerator/ipf/IpfType.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfType.cpp (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/IpfType.cpp (working copy) @@ -27,6 +27,7 @@ bool ipfLogIsOn = false; bool ipfVerifyIsOn = true; +bool ipfConstantFolding = true; //============================================================================// // IpfType @@ -84,6 +85,46 @@ //----------------------------------------------------------------------------------------// +bool IpfType::isGReg(OpndKind opndKind) { + + switch(opndKind) { + case OPND_G_REG : return true; + case OPND_F_REG : + case OPND_P_REG : + case OPND_B_REG : + case OPND_A_REG : + case OPND_IP_REG : + case OPND_UM_REG : + case OPND_IMM : return false; + case OPND_INVALID : break; + } + + IPF_ERR << " unexpected opndKind " << opndKind << endl; + return 0; +} + +//----------------------------------------------------------------------------------------// + +bool IpfType::isFReg(OpndKind opndKind) { + + switch(opndKind) { + case OPND_G_REG : return false; + case OPND_F_REG : return true; + case OPND_P_REG : + case OPND_B_REG : + case OPND_A_REG : + case OPND_IP_REG : + case OPND_UM_REG : + case OPND_IMM : return false; + case OPND_INVALID : break; + } + + IPF_ERR << " unexpected opndKind " << opndKind << endl; + return 0; +} + +//----------------------------------------------------------------------------------------// + bool IpfType::isImm(OpndKind opndKind) { switch(opndKind) { Index: vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp =================================================================== --- vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp (revision 474732) +++ vm/jitrino/src/codegenerator/ipf/IpfOpndManager.cpp (working copy) @@ -249,7 +249,9 @@ refsCompressed = compilationInterface.areReferencesCompressed(); vtablePtrsCompressed = compilationInterface.areVTablePtrsCompressed(); heapBase = NULL; + heapBaseImm = NULL; vtableBase = NULL; + vtableBaseImm = NULL; vtableOffset = NULL; } @@ -309,6 +311,11 @@ return heapBase; } +Opnd *OpndManager::getHeapBaseImm() { + if (heapBaseImm == NULL) heapBaseImm = newImm(0x7777777777777777); + return heapBaseImm; +} + //----------------------------------------------------------------------------------------// RegOpnd *OpndManager::getVtableBase() { @@ -316,6 +323,11 @@ return vtableBase; } +Opnd *OpndManager::getVtableBaseImm() { + if (vtableBaseImm == NULL) vtableBaseImm = newImm(0x7777777777777777); + return vtableBaseImm; +} + //----------------------------------------------------------------------------------------// Opnd *OpndManager::getVtableOffset() { @@ -338,19 +350,27 @@ if (heapBase != NULL) { baseValue = (uint64) compilationInterface.getHeapBase(); + baseImm = newImm(baseValue); Inst *inst = new(mm) Inst(mm, INST_MOVL, p0, heapBase, baseImm); insts.insert(insts.begin(), inst); IPF_LOG << " HeapBase initialization code inserted" << endl; } - + if (heapBaseImm != NULL) { + heapBaseImm->setValue((uint64)compilationInterface.getHeapBase()); + } + if (vtableBase != NULL) { baseValue = (uint64) compilationInterface.getVTableBase(); + baseImm = newImm(baseValue); Inst *inst = new(mm) Inst(mm, INST_MOVL, p0, vtableBase, baseImm); insts.insert(insts.begin(), inst); IPF_LOG << " VtableBase initialization code inserted" << endl; } + if (vtableBaseImm != NULL) { + vtableBaseImm->setValue((uint64)compilationInterface.getVTableBase()); + } } //----------------------------------------------------------------------------------------//