Index: vm/port/src/encoder/ia32_em64t/enc_tabl.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (revision 599434) +++ vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (working copy) @@ -1156,6 +1156,12 @@ END_OPCODES() END_MNEMONIC() +BEGIN_MNEMONIC(PREFETCH, MF_NONE, U) +BEGIN_OPCODES() +{OpcodeInfo::all, {0x0F, 0x18, _0}, {m8}, U }, +END_OPCODES() +END_MNEMONIC() + BEGIN_MNEMONIC(NOT, MF_AFFECTS_FLAGS, DU ) BEGIN_OPCODES() {OpcodeInfo::all, {0xF6, _2}, {r_m8}, DU }, @@ -1421,6 +1427,13 @@ END_OPCODES() END_MNEMONIC() +BEGIN_MNEMONIC(STOS, MF_AFFECTS_FLAGS, DU_DU_U) +BEGIN_OPCODES() + {OpcodeInfo::all, {0xAB}, {EDI, ECX, EAX}, DU_DU_U }, + {OpcodeInfo::em64t, {REX_W, 0xAB}, {RDI, RCX, RAX}, DU_DU_U }, +END_OPCODES() +END_MNEMONIC() + /* MOVS and CMPS are the special cases. Most the code in both CG and Encoder do not expect 2 memory operands. Index: vm/port/src/encoder/ia32_em64t/enc_defs.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_defs.h (revision 599434) +++ vm/port/src/encoder/ia32_em64t/enc_defs.h (working copy) @@ -551,6 +551,7 @@ Mnemonic_NOP, // No Operation Mnemonic_NOT, // One's Complement Negation Mnemonic_OR, // Logical Inclusive OR +Mnemonic_PREFETCH, // prefetch #ifdef _HAVE_MMX_ Mnemonic_PADDQ, // Add Packed Quadword Integers Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java (revision 599434) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java (working copy) @@ -61,6 +61,10 @@ public static void monitorExit(Object obj) {fail();} + public static void memset0(Address addr, int size) {fail();} + + public static void prefetch(Address addr, int distance, int stride) {fail();} + public static void writeBarrier(Address objBase, Address objSlot, Address source) {fail();} public static Address getInterfaceVTable(Object obj, Address intfTypePtr) {fail(); return null;} Index: vm/jitrino/src/codegenerator/ia32/Ia32Inst.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Inst.h (revision 599434) +++ vm/jitrino/src/codegenerator/ia32/Ia32Inst.h (working copy) @@ -750,12 +750,14 @@ m==Mnemonic_MOVS16 || m==Mnemonic_MOVS32 || m==Mnemonic_MOVS64 || + m==Mnemonic_STOS || m==Mnemonic_STD || m==Mnemonic_CLD || m==Mnemonic_POPFD || m==Mnemonic_PUSHFD || m==Mnemonic_POP || - m==Mnemonic_PUSH ) + m==Mnemonic_PUSH || + m==Mnemonic_PREFETCH ) { return true; } Index: vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (revision 599434) +++ vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (working copy) @@ -2640,6 +2640,58 @@ { Opnd * dstOpnd=createResultOpnd(retType); switch(callId) { + case Prefetch: + { + assert (numArgs == 3); + Opnd* address = (Opnd*) args[0]; + Opnd* distance = (Opnd*) args[1]; + Opnd* stride = (Opnd*) args[2]; + + assert (distance->isPlacedIn(OpndKind_Imm) && stride->isPlacedIn(OpndKind_Imm)); + int dist = distance->getImmValue(); + int strd = stride->getImmValue(); + + for (int i=0; i< dist; i+=strd) + { + Opnd* prefAddress = irManager.newMemOpnd(typeManager.getInt8Type(), address, 0, 0, irManager.newImmOpnd(typeManager.getInt32Type(), i)); + Inst* inst = irManager.newInst(Mnemonic_PREFETCH, prefAddress); + appendInsts(inst); + } + break; + } + + case Memset0: + { + assert(numArgs == 2); + Opnd** opnds = (Opnd**)args; + Opnd *addr = opnds[0]; + Opnd *size = opnds[1]; + + RegName counterRegName = RegName_ECX; + RegName dstRegName = RegName_EDI; + RegName zeroRegName = RegName_EAX; + + // prepare counter + Type* int32Type = typeManager.getInt32Type(); + Opnd* counter = irManager.newRegOpnd(int32Type,counterRegName); + copyOpnd(counter,size); + appendInsts(irManager.newInst(Mnemonic_SHR, counter, irManager.newImmOpnd(int32Type,2))); + + // prepare dst + Opnd* dst = irManager.newRegOpnd(int32Type,dstRegName); + copyOpnd(dst, addr); + + // prepare zero + Opnd* eax = irManager.newRegOpnd(int32Type,zeroRegName); + //appendInsts(irManager.newInst(Mnemonic_XOR, eax, eax)); + Opnd* zero = irManager.newImmOpnd(int32Type,0); + appendInsts(irManager.newInst(Mnemonic_MOV, eax, zero)); + + Inst* storeInst = irManager.newInst(Mnemonic_STOS, dst, counter, eax); + storeInst->setPrefix(InstPrefix_REP); + appendInsts(storeInst); + break; + } case InitializeArray: assert(numArgs == 4); appendInsts(irManager.newInternalRuntimeHelperCallInst("initialize_array", numArgs, (Opnd**)args, dstOpnd)); Index: vm/jitrino/src/codegenerator/CodeGenIntfc.h =================================================================== --- vm/jitrino/src/codegenerator/CodeGenIntfc.h (revision 599434) +++ vm/jitrino/src/codegenerator/CodeGenIntfc.h (working copy) @@ -164,6 +164,8 @@ class JitHelperCallOp { public: enum Id { + Prefetch, + Memset0, InitializeArray, FillArrayWithConst, SaveThisState, Index: vm/jitrino/src/optimizer/escanalyzer.cpp =================================================================== --- vm/jitrino/src/optimizer/escanalyzer.cpp (revision 599434) +++ vm/jitrino/src/optimizer/escanalyzer.cpp (working copy) @@ -407,6 +407,8 @@ case Op_JitHelperCall: // calljithelper if (method_ea_level == 0) { switch(inst->asJitHelperCallInst()->getJitHelperId()) { + case Prefetch: + case Memset0: case InitializeArray: case FillArrayWithConst: case SaveThisState: @@ -615,7 +617,7 @@ case Op_TauVirtualCall: // callvirt case Op_IndirectCall: // calli - + case Op_TauStRef: case Op_TauStField: case Op_TauStElem: @@ -5880,3 +5882,4 @@ } //namespace Jitrino + Index: vm/jitrino/src/optimizer/Inst.cpp =================================================================== --- vm/jitrino/src/optimizer/Inst.cpp (revision 599434) +++ vm/jitrino/src/optimizer/Inst.cpp (working copy) @@ -464,6 +464,10 @@ switch(code) { case 'd': switch(jitHelperId) { + case Prefetch: + os << "Prefetch"; break; + case Memset0: + os << "Memset0"; break; case InitializeArray: os << "InitializeArray"; break; case SaveThisState: Index: vm/jitrino/src/optimizer/CodeSelectors.cpp =================================================================== --- vm/jitrino/src/optimizer/CodeSelectors.cpp (revision 599434) +++ vm/jitrino/src/optimizer/CodeSelectors.cpp (working copy) @@ -403,6 +403,8 @@ JitHelperCallOp::Id _BlockCodeSelector::convertJitHelperId(JitHelperCallId callId) { switch(callId) { + case Prefetch: return JitHelperCallOp::Prefetch; + case Memset0: return JitHelperCallOp::Memset0; case InitializeArray: return JitHelperCallOp::InitializeArray; case SaveThisState: return JitHelperCallOp::SaveThisState; case ReadThisState: return JitHelperCallOp::ReadThisState; Index: vm/jitrino/src/optimizer/Opcode.h =================================================================== --- vm/jitrino/src/optimizer/Opcode.h (revision 599434) +++ vm/jitrino/src/optimizer/Opcode.h (working copy) @@ -270,6 +270,8 @@ }; enum JitHelperCallId { + Prefetch, + Memset0, InitializeArray, FillArrayWithConst, SaveThisState, //todo: replace with GetTLS + offset sequence Index: vm/jitrino/src/optimizer/memoryopt.cpp =================================================================== --- vm/jitrino/src/optimizer/memoryopt.cpp (revision 599434) +++ vm/jitrino/src/optimizer/memoryopt.cpp (working copy) @@ -661,6 +661,8 @@ JitHelperCallInst *jitcalli = i->asJitHelperCallInst(); JitHelperCallId callId = jitcalli->getJitHelperId(); switch (callId) { + case Prefetch: + case Memset0: case InitializeArray: case SaveThisState: case ReadThisState: Index: vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp =================================================================== --- vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (revision 599434) +++ vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (working copy) @@ -3579,6 +3579,20 @@ return true; } + if (!strcmp(mname, "memset0")) + { + assert(numArgs == 2); + irBuilder.genJitHelperCall(Memset0, resType, numArgs, srcOpnds); + return true; + } + + if (!strcmp(mname, "prefetch")) + { + assert(numArgs == 3); + irBuilder.genJitHelperCall(Prefetch, resType, numArgs, srcOpnds); + return true; + } + if (!strcmp(mname,"getInterfaceVTable")) { assert(numArgs == 2); Opnd* res = irBuilder.genVMHelperCall(VM_RT_GET_INTERFACE_VTABLE_VER0, resType, numArgs, srcOpnds);