You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/03/12 14:18:51 UTC

svn commit: r517206 - in /harmony/enhanced/drlvm/trunk/vm: jitrino/src/codegenerator/ia32/ jitrino/src/jet/ port/src/encoder/ia32_em64t/

Author: varlax
Date: Mon Mar 12 06:18:50 2007
New Revision: 517206

URL: http://svn.apache.org/viewvc?view=rev&rev=517206
Log:
Applied HARMONY-3329 [drlvm][winx64][jit] Jitrino WIN64 enabling fixes
Tested on SLES10@ia32, SLES9@x64, WinXP@ia32, IPF build.

Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeLayout.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32ComplexAddrFormLoader.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CallingConvention.cpp Mon Mar 12 06:18:50 2007
@@ -57,17 +57,26 @@
 //========================================================================================
 
 #ifdef _EM64T_
+#ifdef _WIN64
+const RegName fastCallGPRegs[4] = {RegName_RCX, RegName_RDX, RegName_R8, RegName_R9} ;
+const RegName fastCallFPRegs[4] = {RegName_XMM0,RegName_XMM1,RegName_XMM2,RegName_XMM3};
+#else 
 const RegName fastCallGPRegs[6] = {RegName_RDI, RegName_RSI, RegName_RDX, RegName_RCX, RegName_R8, RegName_R9} ;
 const RegName fastCallFPRegs[8] = {RegName_XMM0,RegName_XMM1,RegName_XMM2,RegName_XMM3,RegName_XMM4,RegName_XMM5,RegName_XMM6,RegName_XMM7};
 #endif
+#endif
 
 //______________________________________________________________________________________
 void    STDCALLCallingConvention::getOpndInfo(ArgKind kind, uint32 count, OpndInfo * infos)const
 {
     if (kind==ArgKind_InArg){
 #ifdef _EM64T_
-            uint32 gpreg = 0;
-            uint32 fpreg = 0;
+        uint32 gpreg = 0;
+#ifdef _WIN64
+#define fpreg gpreg
+#else
+        uint32 fpreg = 0;
+#endif
 #endif
         for (uint32 i=0; i<count; i++){
     

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp Mon Mar 12 06:18:50 2007
@@ -530,9 +530,9 @@
 
                     uint8* blockStartIp = (uint8*)bb->getCodeStartAddr();
                     uint8* ip = movInst->emit(instCodeStartAddr);
-                    movInst->setCodeOffset(instCodeStartAddr - blockStartIp);
+                    movInst->setCodeOffset((uint32)(instCodeStartAddr - blockStartIp));
                     inst->emit(ip);
-                    inst->setCodeOffset(ip - blockStartIp);
+                    inst->setCodeOffset((uint32)(ip - blockStartIp));
 
                     if (bcOffset != ILLEGAL_VALUE) {
                         bcMap->setEntry((uint64)(POINTER_SIZE_INT)instCodeStartAddr, bcOffset); // MOV

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeLayout.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeLayout.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeLayout.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeLayout.cpp Mon Mar 12 06:18:50 2007
@@ -65,7 +65,9 @@
 
 /**  Fix branches to work with the code layout */
 void Linearizer::fixBranches() {
-    const Nodes& nodes = irManager->getFlowGraph()->getNodes();
+    MemoryManager tmpMM(1024, "Linearizer::fixBranches");
+    Nodes nodes(tmpMM);
+    irManager->getFlowGraph()->getNodes(nodes);
     for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it)  {
         Node* node = *it;
         if (node->isBlockNode()) {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeSelector.cpp Mon Mar 12 06:18:50 2007
@@ -396,8 +396,10 @@
 
 void CfgCodeSelector::fixNodeInfo() 
 {
+    MemoryManager tmpMM(1024, "Ia32CS:fixNodeInfoMM");
     ControlFlowGraph* fg = irManager.getFlowGraph();
-    const Nodes& nodes = fg->getNodes();
+    Nodes nodes(tmpMM);
+    fg->getNodes(nodes); //copy nodes -> loop creates new ones, so we can't use reference to cfg->getNodes()
     for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
         Node* node = *it;
         // connect throw nodes added during inst code selection to corresponding dispatch or unwind nodes

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32ComplexAddrFormLoader.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32ComplexAddrFormLoader.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32ComplexAddrFormLoader.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32ComplexAddrFormLoader.cpp Mon Mar 12 06:18:50 2007
@@ -172,7 +172,7 @@
             table.baseOp = table.suspOp;
             table.baseCand1 = NULL;
             table.baseCand2 = NULL;
-            table.dispOp = NULL;
+//            table.dispOp = NULL;
         }
         return;
     } 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp Mon Mar 12 06:18:50 2007
@@ -2289,7 +2289,7 @@
 
     if (isLogEnabled(LogStream::IRDUMP)) {
         irManager->updateLoopInfo();
-        irManager->fixLivenessInfo();
+        irManager->updateLivenessInfo();
         dumpIR(subKind, "opnds");
         dumpIR(subKind, "liveness");
         dumpIR(subKind);
@@ -2297,7 +2297,7 @@
 
     if (isLogEnabled(LogStream::DOTDUMP)) {
         irManager->updateLoopInfo();
-        irManager->fixLivenessInfo();
+        irManager->updateLivenessInfo();
         printDot(subKind);
         printDot(subKind, "liveness");
     }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.cpp Mon Mar 12 06:18:50 2007
@@ -799,7 +799,7 @@
 {
     assert(callingConvention!=NULL);
     StlVector<CallingConvention::OpndInfo> & infos = getInfos(role);
-    callingConvention->getOpndInfo(argKind, (uint32)infos.size(), &infos.front());
+    callingConvention->getOpndInfo(argKind, (uint32)infos.size(), infos.empty()?(CallingConvention::OpndInfo*)NULL:&infos.front());
     bool lastToFirst=callingConvention->pushLastToFirst();
     uint32 slotNumber=0;
     for (

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Mon Mar 12 06:18:50 2007
@@ -1937,7 +1937,8 @@
         appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, dst, irManager.newImmOpnd(typeManager.getInt64Type(),0)));
         appendInsts(irManager.newCopyPseudoInst(Mnemonic_MOV, tmp, opnd));
         copyOpnd(dst, tmp);
-        dst = simpleOp_I8(Mnemonic_ADD, dstType, dst, irManager.newImmOpnd(dstType, (POINTER_SIZE_INT)compilationInterface.getHeapBase()));
+        Type* unmanagedPtrType = typeManager.getUnmanagedPtrType(typeManager.getInt8Type());
+        dst = simpleOp_I8(Mnemonic_ADD, dstType, dst, irManager.newImmOpnd(unmanagedPtrType, (POINTER_SIZE_INT)compilationInterface.getHeapBase()));
         return dst;
     } else {
         Opnd * opnd = irManager.newMemOpndAutoKind(irManager.getTypeFromTag(memType), addr);
@@ -2440,8 +2441,8 @@
     int64 heapBase = (int64) compilationInterface.getVTableBase();
     Opnd * acc =  simpleOp_I8(Mnemonic_ADD, dstType, (Opnd *)base, irManager.newImmOpnd(dstType, Opnd::RuntimeInfo::Kind_VTableAddrOffset));
     Opnd * sourceVTableAddr=irManager.newMemOpnd(typeManager.getInt32Type(), acc, 0, 0, irManager.newImmOpnd(typeManager.getUInt32Type(), 0));
-    acc=irManager.newOpnd(typeManager.getInt64Type());
-    copyOpnd(acc, sourceVTableAddr);
+    acc=irManager.newOpnd(dstType);
+    appendInsts(irManager.newInstEx(Mnemonic_MOVZX, 1, acc, sourceVTableAddr));
     vtableAddr =  simpleOp_I8(Mnemonic_ADD, dstType, acc,  irManager.newImmOpnd(dstType, heapBase));
     return vtableAddr;
 #endif

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32SpillGen.cpp Mon Mar 12 06:18:50 2007
@@ -254,7 +254,7 @@
 #endif //#ifdef _MSC_VER
 #include "Ia32SpillGenDbgHead.h"
 #else
-#define DBGOUT(s) 
+#define DBGOUT(s)
 #endif //#ifdef _DEBUG_SPILLGEN
 
 
@@ -513,6 +513,7 @@
 void SpillGen::Opline::forw ()
 {
     assert(op != 0);
+    assert(!ops->empty());
     if (op == &ops->front())
     {
         op = 0;
@@ -532,6 +533,7 @@
 {
     if (op == 0)
     {
+        assert(!ops->empty());
         op = &ops->front();
         instx = op->instx;
     }
@@ -650,7 +652,6 @@
 
     static Counter<size_t> count_emits("ia32:spillgen:emits", 0);
     count_emits += emitted;
-
 #ifdef _DEBUG_SPILLGEN
     log(LogStream::DBG) << endl << "Emitted movs :" << emitted << endl;
 
@@ -867,8 +868,8 @@
     }
 
     assert(instxp == instxs.begin());
-
     return actives.size();
+
 }
 
 
@@ -934,13 +935,12 @@
 
     //  Process instructions that are using the operand
 
-        while (opline.go())
+        while (opline.go()) {
             if (opline.isProc())
             {
                 Constraint c(opline.opnd->getConstraint(Opnd::ConstraintKind_Initial));
                 update(opline.instx->inst, opline.opnd, c);
                 opline.idx = registers.getIndex(c);
-
                 if (!tryRegister(opline, c, prefreg))
                     if (!tryMemory(opline, c))
                         if (!tryEvict(opline, c))
@@ -966,15 +966,14 @@
             {
                 opline.forw();
             }
+        }
 
     //  End-block processing
 
         assert(opline.instx == opline.ops->front().instx);
-
         if (opline.at_exit)
             loadOpndMem(opline);
     }
-
     return fails;
 }
 
@@ -1013,7 +1012,6 @@
     Constraint cr((OpndKind)cx.getKind(), c.getSize(), cx.getMask());
 
 //  handle first instruction of the interval
-
     RegMask mk = cr.getMask() & ~usedRegs(opline.instx, opline.idx, opline.isUse());
     if (mk == 0)
     {
@@ -1027,6 +1025,7 @@
 
 //  handle second and all others instructions
 
+
     Instx* begx = opline.instx;
     Instx* endx = begx;
     int count = 0;
@@ -1060,7 +1059,6 @@
         mkpost = callRegs(opline.instx, opline.idx);
         count += cnt;
     }
-
     DBGOUT("   -reg [" << (const Inst*)begx->inst << " - " << (const Inst*)endx->inst 
         << "] avail:" << RegMasks(cx, mk) << " count:" << count << endl;)
 
@@ -1075,7 +1073,6 @@
             return true;
         }
     }
-
     if ((mk & prefreg) != 0)
     {
         mk &= prefreg;
@@ -1387,7 +1384,6 @@
            << " - " << *endx->inst << "] to " << *opline.opnd_mem << endl;)
 
     loadOpnd(opline, begx, opline.opnd_mem);
-
     if (opline.opnd != opline.opnd_mem)
         for (; begx <= endx; ++begx)
         {
@@ -1576,10 +1572,10 @@
     Constraint c = registers[idx];
     usable &= c.getMask();  // search only from available registers
 
-    Instx* begx = &*instxs.begin(); ++begx;
-    Instx* endx = &*instxs.end();
+    Instx* begx = instxs.empty()? (Instx*)NULL:&*instxs.begin(); 
+    Instx* endx = begx + instxs.size() ;
+    ++begx;
     Instx* ptrx;
-
     size_t xbest = INT_MAX,
            xbest_free  = INT_MAX,
            xlgth_free  = 0,
@@ -1588,7 +1584,7 @@
 
     size_t x, found;
     RegMask msk;
-    for (x = 0, found = 0, msk = 1; usable != 0; ++x, msk <<= 1)
+    for (x = 0, found = 0, msk = 1; usable != 0; ++x, msk <<= 1) {
         if ((usable & msk) != 0)
         {
             usable ^= msk, ++found;
@@ -1606,13 +1602,11 @@
                 ++lgth;
                 press |= (ptrx->regpress[idx] & msk) != 0;
             }
-
             for (ptrx = instx+1; ptrx <  endx && (ptrx->regusage[idx] & msk) == 0; ++ptrx)
             {
                 ++lgth;
                 press |= (ptrx->regpress[idx] & msk) != 0;
             }
-
             if (press)
             {
                 if (xbest_press == INT_MAX || xlgth_press >= lgth)
@@ -1626,9 +1620,10 @@
                     xlgth_free = lgth;
             }
         }
-
-    if (xbest == INT_MAX)
+    }
+    if (xbest == INT_MAX) {
         xbest = xbest_free != INT_MAX ? xbest_free : xbest_press;
+    }
 
     return xbest == INT_MAX ? 
             RegName_Null : 
@@ -1790,8 +1785,9 @@
 
 SpillGen::Evict* SpillGen::pickEvict (Evicts& evicts)
 {
-    Instx* begx = &*instxs.begin(); ++begx;
-    Instx* endx = &*instxs.end();
+    Instx* begx = instxs.empty()? (Instx*)NULL:&*instxs.begin(); 
+    Instx* endx = begx + instxs.size();
+    ++begx;
     Instx* ptrx;
 
     DBGOUT("Evicts" << endl;)
@@ -1810,7 +1806,7 @@
         DBGOUT(" evict " << *evict.opnd << " [" << *evict.begx->inst 
                << " - " << *evict.endx->inst << "] w:" << evict.weight << endl;)
     }
-
+    assert(!evicts.empty());
     return &*max_element(evicts.begin(), evicts.end());
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/csig.cpp Mon Mar 12 06:18:50 2007
@@ -53,12 +53,12 @@
     
     for (unsigned i=0; i<num; i++) {
         jtype jt = m_args[i];
-        if (regs && is_f(jt) && get_cconv_fr(fps) != fr_x) {
-            m_data[i] = get_cconv_fr(fps);
+        if (regs && is_f(jt) && get_cconv_fr(fps, i) != fr_x) {
+            m_data[i] = get_cconv_fr(fps, i);
             ++fps;
         }
-        else if (regs && !is_f(jt) && get_cconv_gr(gps) != gr_x) {
-            m_data[i] = get_cconv_gr(gps);
+        else if (regs && !is_f(jt) && get_cconv_gr(gps, i) != gr_x) {
+            m_data[i] = get_cconv_gr(gps, i);
             ++gps;
         }
         else {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h Mon Mar 12 06:18:50 2007
@@ -486,13 +486,13 @@
  * registers (i.e. fastcall6 & fastcall4) then this presumption need to 
  * be revisited.
  */
-AR get_cconv_fr(unsigned i);
+AR get_cconv_fr(unsigned i, unsigned pos_in_args);
 /**
  * @brief Returns i-th general-purpose register for register-based calling 
  *        conventions.
  * @see get_cconv_fr
  */
-AR get_cconv_gr(unsigned i);
+AR get_cconv_gr(unsigned i, unsigned pos_in_args);
 
 /**
  * @brief Kind of operand.

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp Mon Mar 12 06:18:50 2007
@@ -197,31 +197,49 @@
     }
 }
 
-AR get_cconv_fr(unsigned i) {
+AR get_cconv_fr(unsigned i, unsigned pos_in_args) {
 #ifdef _EM64T_
+#ifdef _WIN64
+    bool compact = false;
+#else
+    bool compact = true;
+#endif
     static const AR frs[] = {
         virt(RegName_XMM0), virt(RegName_XMM1), 
         virt(RegName_XMM2), virt(RegName_XMM3), 
+#ifndef _WIN64
         virt(RegName_XMM4), virt(RegName_XMM5), 
         virt(RegName_XMM6), virt(RegName_XMM7), 
+#endif
     };
     const unsigned  count = COUNTOF(frs);
-    return (i<count) ? frs[i] : fr_x;
+    unsigned pos = compact ? i : pos_in_args;
+    return (pos<count) ? frs[pos] : fr_x;
 #else
     assert(false);
     return gr_x;
 #endif
 }
 
-AR get_cconv_gr(unsigned i) {
+AR get_cconv_gr(unsigned i, unsigned pos_in_args) {
 #ifdef _EM64T_
+#ifdef _WIN64
+    bool compact = false;
+	static const AR grs[] = {
+		virt(RegName_RCX),  virt(RegName_RDX), 
+		virt(RegName_R8),  virt(RegName_R9), 
+	};
+#else
+    bool compact = true;
     static const AR grs[] = {
         virt(RegName_RDI),  virt(RegName_RSI), 
         virt(RegName_RDX),  virt(RegName_RCX), 
         virt(RegName_R8),   virt(RegName_R9), 
     };
+#endif
     const unsigned count = COUNTOF(grs);
-    return (i<count) ? grs[i] : gr_x;
+    unsigned pos = compact ? i : pos_in_args;
+    return (pos<count) ? grs[pos] : gr_x;
 #else
     assert(false);
     return gr_x;

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp?view=diff&rev=517206&r1=517205&r2=517206
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp Mon Mar 12 06:18:50 2007
@@ -1003,7 +1003,7 @@
 BEGIN_OPCODES()
     {OpcodeInfo::all,     {Size16, 0x0F, 0xBE, _r}, {r16, r_m8},    D_U },
     {OpcodeInfo::all,     {0x0F, 0xBE, _r},         {r32, r_m8},    D_U },
-    {OpcodeInfo::all,     {REX_W, 0x0F, 0xBE, _r},  {r64, r_m8},    D_U },
+    {OpcodeInfo::em64t,   {REX_W, 0x0F, 0xBE, _r},  {r64, r_m8},    D_U },
     
     {OpcodeInfo::all,     {0x0F, 0xBF, _r},         {r32, r_m16},   D_U },
     {OpcodeInfo::em64t,   {REX_W, 0x0F, 0xBF, _r},  {r64, r_m16},   D_U },
@@ -1016,8 +1016,11 @@
 BEGIN_OPCODES()
     {OpcodeInfo::all,     {Size16, 0x0F, 0xB6, _r}, {r16, r_m8},    D_U },
     {OpcodeInfo::all,     {0x0F, 0xB6, _r},         {r32, r_m8},    D_U },
-    {OpcodeInfo::all,     {REX_W, 0x0F, 0xB6, _r},  {r64, r_m8},    D_U },
+    {OpcodeInfo::em64t,   {REX_W, 0x0F, 0xB6, _r},  {r64, r_m8},    D_U },
     {OpcodeInfo::all,     {0x0F, 0xB7, _r},         {r32, r_m16},   D_U },
+    //workaround to get r/rm32->r64 ZX mov functionality:
+    //simple 32bit reg copying zeros high bits in 64bit reg
+    {OpcodeInfo::em64t,   {0x8B, _r},  {r64, r_m32},   D_U },
 END_OPCODES()
 END_MNEMONIC()