Index: working_vm/vm/port/src/encoder/ia32_em64t/enc_defs.h =================================================================== --- working_vm/vm/port/src/encoder/ia32_em64t/enc_defs.h £¨ÐÞ¶©°æ 699568£© +++ 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 £¨ÐÞ¶©°æ 699568£© +++ 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 £¨ÐÞ¶©°æ 699568£© +++ 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 £¨ÐÞ¶©°æ 699568£© +++ 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 £¨ÐÞ¶©°æ 699568£© +++ working_vm/vm/jitrino/src/optimizer/simplifier.cpp £¨¹¤×÷¿½±´£© @@ -1185,10 +1185,9 @@ return NULL; } - // convert multiply-by-constant to shifts if this is a late simplify pass - if (isLate) { - if (src1isConstant || src2isConstant) { - switch (type->tag) { + // reduce multiply-by-constant + if (src1isConstant || src2isConstant) { + switch (type->tag) { case Type::Int32: case Type::UInt32: if (src1isConstant) { @@ -1227,10 +1226,10 @@ default: break; - } } } + // // Inversion // @@ -1321,11 +1320,10 @@ if (src2isConstant && ConstantFolder::isConstantZero(src2)) return src2; - // convert multiply-by-constant to shifts if this is a late simplify pass - if (isLate) { - if (src1isConstant || src2isConstant) { - bool isSigned = false; - switch (type->tag) { + // reduce multiply-by-constant + if (src1isConstant || src2isConstant) { + bool isSigned = false; + switch (type->tag) { case Type::Int32: isSigned = true; case Type::UInt32: if (src1isConstant) { @@ -1373,10 +1371,9 @@ default: break; - } } } - + return NULL; } @@ -1445,7 +1442,7 @@ src2->getInst()->asConstInst(), mod.isSigned()); -#ifdef _IPF_ + const OptimizerFlags& optimizerFlags = irManager.getOptimizerFlags(); // // further ops only for integers @@ -1485,92 +1482,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); - - Opnd *mulRes; - if (optimizerFlags.use_mulhi) { - Opnd *magicOpnd = genLdConstant(magicNum)->getDst(); - mulRes = genMulHi(dstType, SignedOp, magicOpnd, - src1)->getDst(); + 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 { - 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), + // 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(); - 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 +1621,7 @@ src1->getInst()->asConstInst(), src2->getInst()->asConstInst(), mod.isSigned()); -#ifdef _IPF_ + // // don't simplify floating point further // @@ -1634,21 +1662,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 +1670,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 +1684,7 @@ return remOpnd; } } -#endif + return NULL; } //----------------------------------------------------------------------------- Index: working_vm/vm/jitrino/src/optimizer/multiplybyconstant.cpp =================================================================== --- working_vm/vm/jitrino/src/optimizer/multiplybyconstant.cpp £¨ÐÞ¶©°æ 699568£© +++ working_vm/vm/jitrino/src/optimizer/multiplybyconstant.cpp £¨¹¤×÷¿½±´£© @@ -172,7 +172,7 @@ assert(sp < stackDepth); switch (op) { case MulOp::pushc: assert(ip= 2); ::std::swap(thestack[sp-1], thestack[sp-2]); ::std::swap(when[sp-1], when[sp-2]); break; case MulOp::dup: assert(sp >= 1); thestack[sp] = thestack[sp-1]; when[sp] = when[sp-1]; sp += 1; break; case MulOp::dup2: assert(sp >= 2); thestack[sp] = thestack[sp-2]; when[sp] = when[sp-2]; sp += 1; break; @@ -255,6 +255,8 @@ int ip = 0; int sp = 0; int subnum = 0; + if (len == 0) + return; // no reduction while (ip < len) { enum MulOp::Op op = (enum MulOp::Op) data[ip]; ip += 1; @@ -351,6 +353,8 @@ thestack[0] = 0; int ip = 0; int sp = 0; + if (len == 0) + return NULL; // no reduction while (ip < len) { enum MulOp::Op op = (enum MulOp::Op) data[ip]; ip += 1; @@ -442,6 +446,14 @@ int k = width - 1; m.append(MulOp::pushy); m.append(MulOp::shiftl, k); } else { + /* ONLY DO REDUCTION FOR THE TWO CASES */ + if ((d < 32) && (d > 0)) { + planMulLookup(m, d, depth+1); + } else if (isPowerOf2(d)) { + int k = whichPowerOf2(d); + m.append(MulOp::pushy); m.append(MulOp::shiftl, k); + } + /* if (d < 0) { planMulNeg(m, d, depth); } else if (d < 32) { @@ -452,6 +464,7 @@ } else { planMulLarge(m, d, depth+1); } + */ } #ifdef TEST_OUTPUT DEBUGPRINT2("planMul(" << d << ")", res); @@ -875,50 +888,36 @@ case 0: m.append(MulOp::pushc, 0); break; case 1: m.append(MulOp::pushy); break; case 2: m.append(MulOp::pushy); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); break; - case 3: m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); break; + case 3: m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); break; case 4: m.append(MulOp::pushy); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 2); break; - case 5: m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 2); break; + case 5: m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 2); break; case 6: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); break; case 7: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); break; case 8: m.append(MulOp::pushy); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 3); break; - case 9: m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 3); break; + case 9: m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 3); break; case 10: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 2); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 2); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); break; case 11: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 2); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 2); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); break; case 12: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 2); break; case 13: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); m.append(MulOp::pushy); m.append(MulOp::shladd, 2); break; case 14: - m.append(MulOp::pushy); - if (m.SMALL_SHIFT_MAXBITS == 4) { - m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 4); - } else if (m.SMALL_SHIFT_MAXBITS == 3) { - m.append(MulOp::shiftl, 4); - } else { - assert(0); - } - m.append(MulOp::pushy); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); - m.append(MulOp::sub); break; + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); break; case 15: - m.append(MulOp::pushy); - if (m.SMALL_SHIFT_MAXBITS == 4) { - m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 4); - } else if (m.SMALL_SHIFT_MAXBITS == 3) { - m.append(MulOp::shiftl, 4); - } else { - assert(0); - } - m.append(MulOp::pushy); m.append(MulOp::sub); break; + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); + m.append(MulOp::dup); m.append(MulOp::shladd, 2); break; case 16: m.append(MulOp::pushy); if (m.SMALL_SHIFT_MAXBITS == 4) { @@ -930,70 +929,58 @@ } break; case 17: - if (m.SMALL_SHIFT_MAXBITS == 4) { - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 4); - } else if (m.SMALL_SHIFT_MAXBITS == 3) { - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shiftl, 4); m.append(MulOp::add); - } else { - assert(0); - } + m.append(MulOp::pushy); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 3); + m.append(MulOp::pushy); m.append(MulOp::shladd, 1); break; case 18: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 3); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 3); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); break; case 19: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 3); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 3); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); break; case 20: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 2); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 2); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 2); break; case 21: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 2); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 2); m.append(MulOp::pushy); m.append(MulOp::shladd, 2); break; case 22: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); - m.append(MulOp::pushy); - if (m.SMALL_SHIFT_MAXBITS == 4) { - m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 4); - } else if (m.SMALL_SHIFT_MAXBITS == 3) { - m.append(MulOp::shiftl, 4); - } else { - assert(0); - } - m.append(MulOp::shladd, 1); break; + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 2); + m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); break; case 23: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); - m.append(MulOp::pushy); m.append(MulOp::neg); - m.append(MulOp::shladd, 3); break; + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 2); + m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::shladd, 1); break; case 24: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 3); break; case 25: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); m.append(MulOp::pushy); m.append(MulOp::shladd, 3); break; case 26: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); - m.append(MulOp::pushy); m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); - m.append(MulOp::shladd, 3); break; + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::shladd, 2); + m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); break; case 27: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); m.append(MulOp::dup); m.append(MulOp::shladd, 3); break; case 28: - m.append(MulOp::pushy); m.append(MulOp::neg); - m.append(MulOp::pushy); m.append(MulOp::shiftl, 5); - m.append(MulOp::shladd, 2); break; + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 2); break; case 29: - m.append(MulOp::pushy); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); m.append(MulOp::pushy); m.append(MulOp::shladd, 1); m.append(MulOp::pushy); m.append(MulOp::shladd, 2); break; case 30: - m.append(MulOp::pushy); m.append(MulOp::neg); - m.append(MulOp::pushy); m.append(MulOp::shiftl, 5); - m.append(MulOp::shladd, 1); break; + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); + m.append(MulOp::dup); m.append(MulOp::shladd, 2); + m.append(MulOp::pushc, 0); m.append(MulOp::shladd, 1); break; case 31: - m.append(MulOp::pushy); m.append(MulOp::neg); - m.append(MulOp::pushy); m.append(MulOp::shiftl, 5); - m.append(MulOp::add); break; + m.append(MulOp::pushy); m.append(MulOp::dup); m.append(MulOp::shladd, 1); + m.append(MulOp::dup); m.append(MulOp::shladd, 2); + m.append(MulOp::pushy); m.append(MulOp::shladd, 1); break; default: assert(0); }