Index: working_vm/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp £¨ÐÞ¶©°æ 699565£© +++ working_vm/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp £¨¹¤×÷¿½±´£© @@ -41,6 +41,16 @@ U_32 idx = defs.begin(); return callInst->getOpnd(idx); } + +static Opnd* getCallDstInd(CallInst* callInst, U_32 n) { + Inst::Opnds defs(callInst, Inst::OpndRole_InstLevel | Inst::OpndRole_Def | Inst::OpndRole_Explicit); + U_32 idx = defs.begin(); + for (U_32 i=0; igetOpnd(idx); +} + static Opnd* getCallSrc(CallInst* callInst, U_32 n) { Inst::Opnds uses(callInst, Inst::OpndRole_InstLevel | Inst::OpndRole_Use | Inst::OpndRole_Explicit); U_32 idx = uses.begin(); //the first use is call addr @@ -110,6 +120,8 @@ DECLARE_HELPER_INLINER(Float_floatToRawIntBits_x_F_x_I); DECLARE_HELPER_INLINER(Float_intBitsToFloat_x_I_x_F); +DECLARE_HELPER_INLINER(Multiplication_unsignedMultAddAdd); + void APIMagicsHandlerSession::runImpl() { CompilationContext* cc = getCompilationContext(); MemoryManager tmpMM("Inline API methods"); @@ -160,6 +172,10 @@ } else if (!strcmp(methodName, "intBitsToFloat") && !strcmp(signature, "(I)F")) { handlers.push_back(new (tmpMM) Float_intBitsToFloat_x_I_x_F(irm, callInst, md)); } + } else if (!strcmp(className, "java/math/Multiplication")) { + if (!strcmp(methodName, "unsignedMultAddAdd") && !strcmp(signature, "(IIII)J") ) { + handlers.push_back(new (tmpMM) Multiplication_unsignedMultAddAdd(irm, callInst, md)); + } } else if (mathAsMagic && !strcmp(className, "java/lang/Math")) { if (!strcmp(signature, "(D)D")) { if (!strcmp(methodName, "sqrt")) { @@ -418,6 +434,45 @@ #endif } +void Multiplication_unsignedMultAddAdd::run() { +#ifdef _EM64T_ + return; +#else + Type * i32Type =irm->getTypeFromTag(Type::Int32); + + Opnd* arg1 = getCallSrc(callInst, 0); + Opnd* arg2 = getCallSrc(callInst, 1); + Opnd* arg3 = getCallSrc(callInst, 2); + Opnd* arg4 = getCallSrc(callInst, 3); + + Opnd* resLo = getCallDstInd(callInst,0); + Opnd* resHi = getCallDstInd(callInst,1); + + Opnd* eax = irm->newOpnd(i32Type); + Opnd* edx = irm->newOpnd(i32Type); + + Node* node = callInst->getNode(); + + node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, eax,arg1)); + node->appendInst(irm->newInstEx(Mnemonic_MUL, 2, edx, eax, eax, arg2,0)); + + if(!(arg3->isPlacedIn(OpndKind_Imm)) || arg3->getImmValue()!=0) { + node->appendInst(irm->newInstEx(Mnemonic_ADD, 1, eax, eax, arg3)); + node->appendInst(irm->newInstEx(Mnemonic_ADC, 1, edx, edx, irm->newImmOpnd(i32Type, 0))); + } + + if(!(arg4->isPlacedIn(OpndKind_Imm)) || arg4->getImmValue()!=0) { + node->appendInst(irm->newInstEx(Mnemonic_ADD, 1, eax, eax, arg4)); + node->appendInst(irm->newInstEx(Mnemonic_ADC, 1, edx, edx, irm->newImmOpnd(i32Type, 0))); + } + + node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, resLo, eax)); + node->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, resHi, edx)); + + callInst->unlink(); +#endif +} + void Long_numberOfTrailingZeros_Handler_x_J_x_I::run() { #ifdef _EM64T_ return; Index: working_vm/vm/jitrino/src/optimizer/inliner.cpp =================================================================== --- working_vm/vm/jitrino/src/optimizer/inliner.cpp £¨ÐÞ¶©°æ 699565£© +++ working_vm/vm/jitrino/src/optimizer/inliner.cpp £¨¹¤×÷¿½±´£© @@ -147,6 +147,7 @@ _inlineSkipMethodTable->add_method_record("java/lang/Math", "log", "(D)D", des, false); _inlineSkipMethodTable->add_method_record("java/lang/Math", "log10", "(D)D", des, false); _inlineSkipMethodTable->add_method_record("java/lang/Math", "log1p", "(D)D", des, false); + _inlineSkipMethodTable->add_method_record("java/math/Multiplication", "unsignedMultAddAdd", "(IIII)J", des, false); #endif if(argSource->getBoolArg("System_arraycopy_as_magic",true)) { _inlineSkipMethodTable->add_method_record("java/lang/System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V", des, false);