Index: working_vm/vm/port/src/encoder/ia32_em64t/enc_defs.h =================================================================== --- working_vm/vm/port/src/encoder/ia32_em64t/enc_defs.h £¨ÐÞ¶©°æ 696583£© +++ working_vm/vm/port/src/encoder/ia32_em64t/enc_defs.h £¨¹¤×÷¿½±´£© @@ -617,12 +617,12 @@ CCM(SET,NLE), CCM(SET,G), Mnemonic_SAL, Mnemonic_SHL=Mnemonic_SAL,// Shift left -Mnemonic_SAR, // Unsigned shift right +Mnemonic_SAR, // Shift right Mnemonic_ROR, // Rotate right Mnemonic_RCR, // Rotate right through CARRY flag Mnemonic_ROL, // Rotate left Mnemonic_RCL, // Rotate left through CARRY flag -Mnemonic_SHR, // Signed shift right +Mnemonic_SHR, // Unsigned shift right Mnemonic_SHRD, // Double Precision Shift Right Mnemonic_SHLD, // Double Precision Shift Left Index: working_vm/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h £¨ÐÞ¶©°æ 696583£© +++ working_vm/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h £¨¹¤×÷¿½±´£© @@ -343,7 +343,7 @@ */ bool isSubjectForLivenessAnalysis()const { - return (memOpndKind&(MemOpndKind_StackManualLayout|MemOpndKind_ConstantArea|MemOpndKind_Heap))==0 && !isPlacedIn(OpndKind_Imm); + return (memOpndKind&(MemOpndKind_StackManualLayout|MemOpndKind_ConstantArea|MemOpndKind_Heap|MemOpndKind_LEA))==0 && !isPlacedIn(OpndKind_Imm); } /** Returns the segment register used with the operand (memory). */ Index: working_vm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp £¨ÐÞ¶©°æ 696583£© +++ working_vm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp £¨¹¤×÷¿½±´£© @@ -1219,12 +1219,32 @@ //_______________________________________________________________________________________________________________ // Shift left and add - +#define LEA_EXP_LIMIT 3 CG_OpndHandle* InstCodeSelector::shladd(IntegerOp::Types opType, CG_OpndHandle* value, U_32 imm, CG_OpndHandle* addto) { + if ((opType == IntegerOp::I4) && (imm <= LEA_EXP_LIMIT)) { + Type * dstType = irManager.getTypeFromTag(Type::Int32); + bool addtoIsImm = false; + if (((Opnd*)addto)->isPlacedIn(OpndKind_Imm)) + addtoIsImm = true; + Opnd *res; + if (addtoIsImm) { + res = irManager.newMemOpnd(dstType, NULL, (Opnd*)value, + irManager.newImmOpnd(typeManager.getInt32Type(), 1<setMemOpndKind(MemOpndKind_LEA); + Opnd *dst = irManager.newOpnd(dstType); + Inst *newInst = irManager.newInstEx(Mnemonic_LEA, 1, dst, res); + appendInsts(newInst); + return dst; + } + Opnd * shiftDest = (Opnd *)shl(opType, value, irManager.newImmOpnd(typeManager.getUInt8Type(), imm)); ArithmeticOp::Types atype; switch (opType) { Index: working_vm/vm/jitrino/src/codegenerator/ia32/Ia32IRConstants.h =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ia32/Ia32IRConstants.h £¨ÐÞ¶©°æ 696583£© +++ working_vm/vm/jitrino/src/codegenerator/ia32/Ia32IRConstants.h £¨¹¤×÷¿½±´£© @@ -64,6 +64,7 @@ MemOpndKind_Stack=0x1f, MemOpndKind_Heap=0x20, MemOpndKind_ConstantArea=0x40, + MemOpndKind_LEA=0x80, MemOpndKind_Any=0xff, }; Index: working_vm/vm/jitrino/src/optimizer/simplifier.cpp =================================================================== --- working_vm/vm/jitrino/src/optimizer/simplifier.cpp £¨ÐÞ¶©°æ 696583£© +++ working_vm/vm/jitrino/src/optimizer/simplifier.cpp £¨¹¤×÷¿½±´£© @@ -1445,7 +1445,7 @@ src2->getInst()->asConstInst(), mod.isSigned()); -#ifdef _IPF_ + const OptimizerFlags& optimizerFlags = irManager.getOptimizerFlags(); // // further ops only for integers @@ -1485,92 +1485,123 @@ return opnd; // convert other cases to MulHi and shift if lower_divconst set - if (optimizerFlags.lower_divconst && - (dstType->tag == Type::Int32) && - mod.isSigned()) { - - I_32 denom = value2.i4; - // note that 0 and 1 were handled above - if (denom == -1) { - // convert to neg - Opnd *res = genNeg(dstType, src1)->getDst(); - return res; - } else if (isPowerOf2(denom)) { - // convert to shift and such - I_32 absdenom = (denom < 0) ? -denom : denom; - int k = whichPowerOf2(absdenom); - Opnd *kminus1 = genLdConstant((I_32)(k - 1))->getDst(); - // make k-1 copies of the sign bit - Opnd *shiftTheSign = genShr(dstType, - Modifier(SignedOp)|Modifier(ShiftMask_None), - src1, kminus1)->getDst(); - // we 32-k zeros in on left to put copies of sign on right - Opnd *t32minusk = genLdConstant((I_32)(32-k))->getDst(); - // if (n<0), this is 2^k-1, else 0 - Opnd *kminus1ones = genShr(dstType, - Modifier(UnsignedOp)|Modifier(ShiftMask_None), - shiftTheSign, t32minusk)->getDst(); - Opnd *added = genAdd(dstType, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), - src1, kminus1ones)->getDst(); - Opnd *kOpnd = genLdConstant((I_32)k)->getDst(); - Opnd *res = genShr(dstType, Modifier(SignedOp)|Modifier(ShiftMask_None), - added, kOpnd)->getDst(); - if (denom != absdenom) { // ((denom < 0) && (k < 31)) - res = genNeg(dstType, res)->getDst(); - } - return res; - } else { - // convert to MulHi and such - I_32 magicNum, shiftBy; - getMagic(denom, &magicNum, &shiftBy); + if (optimizerFlags.lower_divconst && mod.isSigned()) { + if (dstType->tag == Type::Int32) { + I_32 denom = value2.i4; + // note that 0 and 1 were handled above + if (denom == -1) { + // convert to neg + Opnd *res = genNeg(dstType, src1)->getDst(); + return res; + } else if (isPowerOf2(denom)) { + // convert to shift and such + I_32 absdenom = (denom < 0) ? -denom : denom; + int k = whichPowerOf2(absdenom); + Opnd *kminus1 = genLdConstant((I_32)(k - 1))->getDst(); + // make k-1 copies of the sign bit + Opnd *shiftTheSign = genShr(dstType, + Modifier(SignedOp)|Modifier(ShiftMask_None), + src1, kminus1)->getDst(); + // we 32-k zeros in on left to put copies of sign on right + Opnd *t32minusk = genLdConstant((I_32)(32-k))->getDst(); + // if (n<0), this is 2^k-1, else 0 + Opnd *kminus1ones = genShr(dstType, + Modifier(UnsignedOp)|Modifier(ShiftMask_None), + shiftTheSign, t32minusk)->getDst(); + Opnd *added = genAdd(dstType, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), + src1, kminus1ones)->getDst(); + Opnd *kOpnd = genLdConstant((I_32)k)->getDst(); + Opnd *res = genShr(dstType, Modifier(SignedOp)|Modifier(ShiftMask_None), + added, kOpnd)->getDst(); + if (denom != absdenom) { // ((denom < 0) && (k < 31)) + res = genNeg(dstType, res)->getDst(); + } + return res; + } else { + // convert to MulHi and such + I_32 magicNum, shiftBy; + getMagic(denom, &magicNum, &shiftBy); - Opnd *mulRes; - if (optimizerFlags.use_mulhi) { - Opnd *magicOpnd = genLdConstant(magicNum)->getDst(); - mulRes = genMulHi(dstType, SignedOp, magicOpnd, - src1)->getDst(); - } else { - Opnd *magicOpnd = genLdConstant((int64)magicNum)->getDst(); - TypeManager &tm = irManager.getTypeManager(); - Type *dstType64 = tm.getInt64Type(); - Opnd *src64 = genConv(dstType64, Type::Int64, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), + Opnd *mulRes; + if (optimizerFlags.use_mulhi) { + Opnd *magicOpnd = genLdConstant(magicNum)->getDst(); + mulRes = genMulHi(dstType, SignedOp, magicOpnd, src1)->getDst(); - Opnd *mulRes64 = genMul(dstType64, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), magicOpnd, - src64)->getDst(); - Opnd *constant32 = genLdConstant((I_32)32)->getDst(); - Opnd *mulRes64h = genShr(dstType64, - Modifier(SignedOp)|Modifier(ShiftMask_None), - mulRes64, - constant32)->getDst(); - mulRes = genConv(dstType, Type::Int32, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), - mulRes64h)->getDst(); + } else { + Opnd *magicOpnd = genLdConstant((int64)magicNum)->getDst(); + TypeManager &tm = irManager.getTypeManager(); + Type *dstType64 = tm.getInt64Type(); + Opnd *src64 = genConv(dstType64, Type::Int64, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), + src1)->getDst(); + Opnd *mulRes64 = genMul(dstType64, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), magicOpnd, + src64)->getDst(); + Opnd *constant32 = genLdConstant((I_32)32)->getDst(); + Opnd *mulRes64h = genShr(dstType64, + Modifier(SignedOp)|Modifier(ShiftMask_None), + mulRes64, + constant32)->getDst(); + mulRes = genConv(dstType, Type::Int32, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), + mulRes64h)->getDst(); + } + // need to adjust for overflow in magicNum + // this is indicated by sign which differs from + // the denom. + if ((denom > 0) && (magicNum < 0)) { + mulRes = genAdd(dstType, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), + mulRes, src1)->getDst(); + } else if ((denom < 0) && (magicNum > 0)) { + mulRes = genSub(dstType, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), + mulRes, src1)->getDst(); + } + Opnd *shiftByOpnd = genLdConstant(shiftBy)->getDst(); + mulRes = genShr(dstType, Modifier(SignedOp)|Modifier(ShiftMask_None), + mulRes, shiftByOpnd)->getDst(); + Opnd *thirtyOne = genLdConstant((I_32)31)->getDst(); + Opnd *oneIfNegative = genShr(dstType, + Modifier(UnsignedOp)|Modifier(ShiftMask_None), + ((denom < 0) + ? mulRes + : src1), + thirtyOne)->getDst(); + Opnd *res = genAdd(dstType, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), mulRes, oneIfNegative)->getDst(); + return res; } - // need to adjust for overflow in magicNum - // this is indicated by sign which differs from - // the denom. - if ((denom > 0) && (magicNum < 0)) { - mulRes = genAdd(dstType, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), - mulRes, src1)->getDst(); - } else if ((denom < 0) && (magicNum > 0)) { - mulRes = genSub(dstType, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), - mulRes, src1)->getDst(); + } else if (dstType->tag == Type::Int64) { + I_64 denom = value2.i8; + // note that 0 and 1 were handled above + if (denom == -1) { + // convert to neg + Opnd *res = genNeg(dstType, src1)->getDst(); + return res; + } else if (isPowerOf2(denom)) { + // convert to shift and such + I_64 absdenom = (denom < 0) ? -denom : denom; + int k = whichPowerOf2(absdenom); + Opnd *kminus1 = genLdConstant((I_64)(k - 1))->getDst(); + // make k-1 copies of the sign bit + Opnd *shiftTheSign = genShr(dstType, + Modifier(SignedOp)|Modifier(ShiftMask_None), + src1, kminus1)->getDst(); + // we 64-k zeros in on left to put copies of sign on right + Opnd *t64minusk = genLdConstant((I_64)(64-k))->getDst(); + // if (n<0), this is 2^k-1, else 0 + Opnd *kminus1ones = genShr(dstType, + Modifier(UnsignedOp)|Modifier(ShiftMask_None), + shiftTheSign, t64minusk)->getDst(); + Opnd *added = genAdd(dstType, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), + src1, kminus1ones)->getDst(); + Opnd *kOpnd = genLdConstant((I_64)k)->getDst(); + Opnd *res = genShr(dstType, Modifier(SignedOp)|Modifier(ShiftMask_None), + added, kOpnd)->getDst(); + if (denom != absdenom) { // ((denom < 0) && (k < 63)) + res = genNeg(dstType, res)->getDst(); + } + return res; } - Opnd *shiftByOpnd = genLdConstant(shiftBy)->getDst(); - mulRes = genShr(dstType, Modifier(SignedOp)|Modifier(ShiftMask_None), - mulRes, shiftByOpnd)->getDst(); - Opnd *thirtyOne = genLdConstant((I_32)31)->getDst(); - Opnd *oneIfNegative = genShr(dstType, - Modifier(UnsignedOp)|Modifier(ShiftMask_None), - ((denom < 0) - ? mulRes - : src1), - thirtyOne)->getDst(); - Opnd *res = genAdd(dstType, Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No), mulRes, oneIfNegative)->getDst(); - return res; } } } -#endif + return NULL; } @@ -1593,7 +1624,7 @@ src1->getInst()->asConstInst(), src2->getInst()->asConstInst(), mod.isSigned()); -#ifdef _IPF_ + // // don't simplify floating point further // @@ -1634,21 +1665,6 @@ // return genLdConstant((I_32)0)->getDst(); } - if (isPowerOf2(denom)) { - int k = whichPowerOf2(denom); - I_32 maskInt = (((I_32)0x1)<getDst(); - Opnd *maskedOpnd = genAnd(src1->getType(), - src1, maskOpnd)->getDst(); - Opnd *res = maskedOpnd; - if (denom < 0) { - I_32 signInt = ((I_32)-1) ^ maskInt; - Opnd *extendedSign - = genLdConstant(signInt)->getDst(); - res = genOr(src1->getType(), res, extendedSign)->getDst(); - } - return res; - } } else if (ConstantFolder::isConstant(src2inst, cv.i8)) { int64 denom = cv.i8; if ((denom == -1) || (denom == 1)) { @@ -1657,21 +1673,6 @@ // return genLdConstant((int64)0)->getDst(); } - if (isPowerOf2(denom)) { - int k = whichPowerOf2(denom); - int64 maskInt = (((int64)0x1)<getDst(); - Opnd *maskedOpnd = genAnd(src1->getType(), - src1, maskOpnd)->getDst(); - Opnd *res = maskedOpnd; - if (denom < 0) { - int64 signInt = ((int64)-1) ^ maskInt; - Opnd *extendedSign - = genLdConstant(signInt)->getDst(); - res = genOr(src1->getType(), res, extendedSign)->getDst(); - } - return res; - } } // convert other cases to MulHi and shift, and Mul @@ -1686,7 +1687,7 @@ return remOpnd; } } -#endif + return NULL; } //-----------------------------------------------------------------------------