Index: working_vm/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp £¨ÐÞ¶©°æ 703965£© +++ working_vm/vm/jitrino/src/codegenerator/ia32/Ia32PeepHole.cpp £¨¹¤×÷¿½±´£© @@ -637,19 +637,33 @@ PeepHoleOpt::Changed PeepHoleOpt::handleInst_MUL(Inst* inst) { - assert(inst->getMnemonic()==Mnemonic_IMUL || inst->getMnemonic()==Mnemonic_MUL); + assert((inst->getMnemonic() == Mnemonic_IMUL) || (inst->getMnemonic() == Mnemonic_MUL)); + if (inst->getForm() == Inst::Form_Native) { return Changed_Nothing; } + Inst::Opnds defs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def); - Opnd* dst = inst->getOpnd(defs.begin()); - if (defs.next(defs.begin())!=defs.end()) { + Opnd* dst1 = inst->getOpnd(defs.begin()); + Opnd* lastDst = dst1; + Opnd* dst2 = NULL; + if ((inst->getMnemonic() == Mnemonic_IMUL) && (defs.next(defs.begin()) != defs.end())){ return Changed_Nothing; } + else { //inst->getMnemonic() == Mnemonic_MUL + dst2 = inst->getOpnd(defs.next(defs.begin())); + if (defs.next(defs.next(defs.begin()))!=defs.end()) + return Changed_Nothing; + } + Inst::Opnds uses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use); Opnd* src1= inst->getOpnd(uses.begin()); Opnd* src2= inst->getOpnd(uses.next(uses.begin())); - assert(src1!=NULL && src2!=NULL && dst!=NULL); + if (inst->getMnemonic() == Mnemonic_IMUL) + assert(src1!=NULL && src2!=NULL && dst1!=NULL); + else //inst->getMnemonic() == Mnemonic_MUL + assert(src1!=NULL && src2!=NULL && dst1!=NULL && dst2!=NULL); + if (isImm(src1)) { Opnd* tmp = src1; src1 = src2; src2 = tmp; } @@ -657,31 +671,46 @@ int immVal = (int)src2->getImmValue(); if (immVal == 0) { if (Log::isEnabled()) Log::out()<<"I"<getId()<<" -> MUL with 0"<newCopyPseudoInst(Mnemonic_MOV, dst, src2)->insertAfter(inst); + if (inst->getMnemonic() == Mnemonic_IMUL) + irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, src2)->insertAfter(inst); + else { //inst->getMnemonic() == Mnemonic_MUL + irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, src2)->insertAfter(inst); + irManager->newCopyPseudoInst(Mnemonic_MOV, dst2, src2)->insertAfter(inst); + } inst->unlink(); return Changed_Inst; } else if (immVal == 1) { if (Log::isEnabled()) Log::out()<<"I"<getId()<<" -> MUL with 1"<newCopyPseudoInst(Mnemonic_MOV, dst, src1)->insertAfter(inst); + if (inst->getMnemonic() == Mnemonic_IMUL) + irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, src1)->insertAfter(inst); + else { //inst->getMnemonic() == Mnemonic_MUL + irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, + irManager->newImmOpnd(irManager->getTypeManager().getUInt8Type(), 0))->insertAfter(inst); + irManager->newCopyPseudoInst(Mnemonic_MOV, dst2, src1)->insertAfter(inst); + } inst->unlink(); return Changed_Inst; } else if (immVal == 2) { - if (Log::isEnabled()) Log::out()<<"I"<getId()<<" -> MUL with 2"<newInstEx(Mnemonic_ADD, 1, dst, src1, src1)->insertAfter(inst); - inst->unlink(); - return Changed_Inst; - } else { - int minBit=getMinBit(immVal); - int maxBit=getMaxBit(immVal); - if (minBit == maxBit) { - assert(minBit>=2); - if (Log::isEnabled()) Log::out()<<"I"<getId()<<" -> MUL with 2^"<getTypeManager().getUInt8Type(); - irManager->newCopyPseudoInst(Mnemonic_MOV, dst, src1)->insertBefore(inst); - irManager->newInst(Mnemonic_SHL, dst, irManager->newImmOpnd(immType, minBit))->insertBefore(inst); + if (inst->getMnemonic() == Mnemonic_IMUL) { + if (Log::isEnabled()) Log::out()<<"I"<getId()<<" -> MUL with 2"<newInstEx(Mnemonic_ADD, 1, dst1, src1, src1)->insertAfter(inst); inst->unlink(); return Changed_Inst; } + } else { + if (inst->getMnemonic() == Mnemonic_IMUL) { + int minBit=getMinBit(immVal); + int maxBit=getMaxBit(immVal); + if (minBit == maxBit) { + assert(minBit>=2); + if (Log::isEnabled()) Log::out()<<"I"<getId()<<" -> MUL with 2^"<getTypeManager().getUInt8Type(); + irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, src1)->insertBefore(inst); + irManager->newInst(Mnemonic_SHL, dst1, irManager->newImmOpnd(immType, minBit))->insertBefore(inst); + inst->unlink(); + return Changed_Inst; + } + } } } return Changed_Nothing;