You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by mf...@apache.org on 2008/03/15 11:35:52 UTC

svn commit: r637385 - in /harmony/enhanced/drlvm/trunk/vm: jitrino/src/codegenerator/ia32/Ia32IRManager.cpp jitrino/src/codegenerator/ia32/Ia32i586InstsExpansion.cpp port/src/encoder/ia32_em64t/enc_defs.h port/src/encoder/ia32_em64t/enc_tabl.cpp

Author: mfursov
Date: Sat Mar 15 03:35:46 2008
New Revision: 637385

URL: http://svn.apache.org/viewvc?rev=637385&view=rev
Log:
fix for HARMONY-5599 [drlvm][jit][performance] new MOVAPD instruction for register2register copying


Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32i586InstsExpansion.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp

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?rev=637385&r1=637384&r2=637385&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp Sat Mar 15 03:35:46 2008
@@ -1153,7 +1153,12 @@
         if (sourceByteSize==4){
             return newInst(Mnemonic_MOVSS,targetOpnd, sourceOpnd);
         }else if (sourceByteSize==8){
-            return newInst(Mnemonic_MOVSD,targetOpnd, sourceOpnd);
+            bool regsOnly = targetKind==OpndKind_XMMReg && sourceKind==OpndKind_XMMReg;
+            if (regsOnly && CPUID::isSSE2Supported()) {
+                return newInst(Mnemonic_MOVAPD, targetOpnd, sourceOpnd);
+            } else  {
+                return newInst(Mnemonic_MOVSD, targetOpnd, sourceOpnd);
+            }
         }
     }else if (targetKind==OpndKind_FPReg && sourceKind==OpndKind_Mem){
         sourceOpnd->setMemOpndAlignment(Opnd::MemOpndAlignment_16);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32i586InstsExpansion.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32i586InstsExpansion.cpp?rev=637385&r1=637384&r2=637385&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32i586InstsExpansion.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32i586InstsExpansion.cpp Sat Mar 15 03:35:46 2008
@@ -43,8 +43,9 @@
 
     void runImpl();
 
-    //return true if instruction is SSE, assign corresponding mnemonics if arithmetic operation
-    bool isSSE(Mnemonic mn, Mnemonic &fMnem1, Mnemonic &fMnem2);
+
+    void lowerToX87();
+    void lowerToSSE();
 
     uint32 getNeedInfo()const{ return 0; }
     uint32 getSideEffects()const{ return hasSideEffects ? SideEffect_InvalidatesLivenessInfo: 0; }
@@ -59,28 +60,31 @@
 
 static ActionFactory<I586InstsExpansion> _i586("i586");
 
-bool I586InstsExpansion::isSSE(Mnemonic mn, Mnemonic &fMnem1, Mnemonic &fMnem2) {
+
+
+
+//NOTE: today the following methods contains info only for mnemonics used in CG. 
+//TODO: update them to have all mnemonics from Architecture Manual or add this info to Encoder
+static bool isSSE2OrNewer(Mnemonic mn) {
+    switch (mn) {
+        case Mnemonic_MOVAPD:
+            return true;
+        default:
+            return false;
+    }
+}
+
+//return true if instruction is SSE or newer
+static bool isSSEOrNewer(Mnemonic mn) {
     switch (mn) {
         case Mnemonic_ADDSS:
         case Mnemonic_ADDSD:
-            fMnem1 = Mnemonic_FADDP;
-            fMnem2 = Mnemonic_FADD;
-            return true;
         case Mnemonic_SUBSS:
         case Mnemonic_SUBSD:
-            fMnem1 = Mnemonic_FSUBP;
-            fMnem2 = Mnemonic_FSUB;
-            return true;
         case Mnemonic_MULSS:
         case Mnemonic_MULSD:
-            fMnem1 = Mnemonic_FMULP;
-            fMnem2 = Mnemonic_FMUL;
-            return true;
         case Mnemonic_DIVSS:
         case Mnemonic_DIVSD:
-            fMnem1 = Mnemonic_FDIVP;
-            fMnem2 = Mnemonic_FDIV;
-            return true;
         case Mnemonic_XORPD:
         case Mnemonic_XORPS:
         case Mnemonic_PXOR:
@@ -96,20 +100,94 @@
         case Mnemonic_CVTSI2SD:
             return true;
         default:
-            return false;
+            return isSSE2OrNewer(mn);
     }
 }
 
+static void mapToX87(Mnemonic mn, Mnemonic &fMnem1, Mnemonic &fMnem2) {
+    switch (mn) {
+        case Mnemonic_ADDSS:
+        case Mnemonic_ADDSD:
+            fMnem1 = Mnemonic_FADDP;
+            fMnem2 = Mnemonic_FADD;
+            return;
+        case Mnemonic_SUBSS:
+        case Mnemonic_SUBSD:
+            fMnem1 = Mnemonic_FSUBP;
+            fMnem2 = Mnemonic_FSUB;
+            return;
+        case Mnemonic_MULSS:
+        case Mnemonic_MULSD:
+            fMnem1 = Mnemonic_FMULP;
+            fMnem2 = Mnemonic_FMUL;
+            return;
+        case Mnemonic_DIVSS:
+        case Mnemonic_DIVSD:
+            fMnem1 = Mnemonic_FDIVP;
+            fMnem2 = Mnemonic_FDIV;
+            return;
+        default:
+            return;
+    }
+}
+
+enum FPUMode {
+    FPUMode_X87     = 1,
+    FPUMode_SSE     = 2,
+    FPUMode_SSE2    = 3
+};
+
 void I586InstsExpansion::runImpl() {
-    bool hasSSE2 = CPUID::isSSE2Supported();
-    bool force = getBoolArg("force", false);
-    bool skip = hasSSE2 && !force;
+    FPUMode mode = CPUID::isSSE2Supported() ? FPUMode_SSE2 : FPUMode_SSE;
+
+    const char* modeStr = getArg("mode");
+    if (modeStr!=NULL && !strcmp(modeStr, "sse")) {
+        mode = FPUMode_SSE;
+    } else if (modeStr!=NULL && !strcmp(modeStr, "x87")) {
+        mode = FPUMode_X87;
+    }
+
     if (Log::isEnabled()) {
-        Log::out()<<"hasSSE2:"<<hasSSE2<<" force:"<<force<<" skipping:"<<skip<<std::endl; 
+        Log::out()<<"has sse2:" << CPUID::isSSE2Supported() << " mode:"<<(int)mode<<std::endl; 
     }
-    if (skip) {
-        return;
+
+    switch(mode) {
+        case FPUMode_X87:
+            lowerToX87();
+            return;
+        case FPUMode_SSE:
+            lowerToSSE();
+            return;
+        case FPUMode_SSE2:
+            //do nothing;
+            break;
+        default: assert(0);
     }
+}
+
+void I586InstsExpansion::lowerToSSE() {
+    const Nodes& nodes = irManager->getFlowGraph()->getNodes();
+    for (Nodes::const_iterator cit = nodes.begin(); cit != nodes.end(); ++cit) {
+        Node* node = *cit;
+        if (!node->isBlockNode()) {
+            continue;
+        }
+        for(Inst * inst = (Inst *)node->getFirstInst(); inst != NULL; ) {
+            Mnemonic mn = inst->getMnemonic();
+            if (!isSSE2OrNewer(mn)) {
+                continue;
+            }
+            //Mode is not implemented for a SSE2 and newer systems.
+            //Must never hit for SSE-only hardware.
+            assert(0); 
+
+        }
+    }
+}
+
+
+void I586InstsExpansion::lowerToX87() {
+    //check if to use FPU mode. Otherwise SSE1 insts will be allowed
     irManager->updateLivenessInfo();
     hasSideEffects = true;
 
@@ -141,9 +219,9 @@
         for(Inst * inst = (Inst *)node->getFirstInst(); inst != NULL; ) {
             Inst * tmpInst = inst->getNextInst();
             Mnemonic mn = inst->getMnemonic();
+            
             Mnemonic fMnem1 = Mnemonic_NULL, fMnem2 = Mnemonic_NULL;
-
-            if (!isSSE(mn, fMnem1, fMnem2)) {
+            if (!isSSEOrNewer(mn)) {
                 //check all other instruction for XMM registers operands
                 Inst::Opnds xmms(inst, Inst::OpndRole_Explicit|Inst::OpndRole_UseDef);
                 for (Inst::Opnds::iterator it = xmms.begin(); it != xmms.end(); it = xmms.next(it)) {
@@ -156,7 +234,10 @@
                 inst = tmpInst;
                 continue;
             }
-            
+
+            mapToX87(mn, fMnem1, fMnem2);
+
+
             Opnd * fp0;
             Opnd * fp1;
 

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h?rev=637385&r1=637384&r2=637385&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h Sat Mar 15 03:35:46 2008
@@ -541,6 +541,7 @@
 // MOVS is a special case: see encoding table for more details,
 Mnemonic_MOVS8, Mnemonic_MOVS16, Mnemonic_MOVS32, Mnemonic_MOVS64,
 //
+Mnemonic_MOVAPD,                         // Move Scalar Double-Precision Floating-Point Value
 Mnemonic_MOVSD,                         // Move Scalar Double-Precision Floating-Point Value
 Mnemonic_MOVSS,                         // Move Scalar Single-Precision Floating-Point Values
 Mnemonic_MOVSX,                         // Move with Sign-Extension

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?rev=637385&r1=637384&r2=637385&view=diff
==============================================================================
--- 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 Sat Mar 15 03:35:46 2008
@@ -1094,6 +1094,14 @@
 END_MNEMONIC()
 
 
+BEGIN_MNEMONIC(MOVAPD, MF_NONE, D_U )
+BEGIN_OPCODES()
+    {OpcodeInfo::all, {0x66, 0x0F, 0x28, _r},   {xmm64, xmm_m64},   D_U },
+    {OpcodeInfo::all, {0x66, 0x0F, 0x29, _r},   {xmm_m64, xmm64},   D_U },
+END_OPCODES()
+END_MNEMONIC()
+
+
 BEGIN_MNEMONIC(MOVSD, MF_NONE, D_U )
 BEGIN_OPCODES()
     {OpcodeInfo::all, {0xF2, 0x0F, 0x10, _r},   {xmm64, xmm_m64},   D_U },