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/31 17:39:55 UTC

svn commit: r643030 - in /harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t: dec_base.cpp dec_base.h enc_tabl.cpp

Author: mfursov
Date: Mon Mar 31 08:39:54 2008
New Revision: 643030

URL: http://svn.apache.org/viewvc?rev=643030&view=rev
Log:
Fix for HARMONY-5494 [drlvm][encoder] Improvements in prefixes recognition

Modified:
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.h
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp?rev=643030&r1=643029&r2=643030&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.cpp Mon Mar 31 08:39:54 2008
@@ -56,6 +56,71 @@
     return false;
 }
 
+unsigned int DecoderBase::fill_prefs(const unsigned char * bytes, Inst * pinst)
+{
+    const unsigned char * my_bytes = bytes;
+
+    while( 1 )
+    {
+        unsigned char by1 = *my_bytes;
+        unsigned char by2 = *(my_bytes + 1);
+        Inst::PrefGroups where;
+
+        switch( by1 )
+        {
+        case InstPrefix_REPNE:
+        case InstPrefix_REP:
+        {
+            if( 0x0F == by2)
+            {
+                return pinst->prefc;
+            }
+        }
+        case InstPrefix_LOCK:
+        {
+            where = Inst::Group1;
+            break;
+        }
+        case InstPrefix_CS:
+        case InstPrefix_SS:
+        case InstPrefix_DS:
+        case InstPrefix_ES:
+        case InstPrefix_FS:
+        case InstPrefix_GS:
+//      case InstPrefix_HintTaken: the same as CS override
+//      case InstPrefix_HintNotTaken: the same as DS override
+        {
+            where = Inst::Group2;
+            break;
+        }
+        case InstPrefix_OpndSize:
+        {
+            if( 0x0F == by2)
+            {
+                return pinst->prefc;
+            }
+            where = Inst::Group3;
+            break;
+        }
+        case InstPrefix_AddrSize:
+        {
+            where = Inst::Group4;
+            break;
+        }
+        default:
+        {
+            return pinst->prefc;
+        }
+        }
+        assert( InstPrefix_Null == pinst->pref[where] ); //only one prefix in each group 
+        pinst->pref[where] = (InstPrefix)by1;
+        assert( pinst->prefc < 4 ); //no more than 4 prefixes
+        pinst->prefc++;
+        ++my_bytes;
+    }
+}
+
+
 
 unsigned DecoderBase::decode(const void * addr, Inst * pinst)
 {
@@ -64,14 +129,8 @@
     //assert( *(unsigned char*)addr != 0x66);
     
     const unsigned char * bytes = (unsigned char*)addr;
-    // Check prefix first
-    for (unsigned i=0; i<4; i++) {
-        if (!is_prefix(bytes)) {
-            break;
-        }
-        ++bytes;
-    }
 
+    bytes += fill_prefs(bytes, &tmp); 
     if (is_prefix(bytes)) {
         // More than 4 prefixes together ?
 //        assert(false);
@@ -154,6 +213,30 @@
             if (regid>7) {
                 return false;
             }
+            OpndSize opnd_size;
+            switch(kind)
+            {
+            case OpcodeByteKind_rb:
+            {
+                opnd_size = OpndSize_8;
+                break;
+            }
+            case OpcodeByteKind_rw:
+            {
+                opnd_size = OpndSize_16;
+                break;
+            }
+            case OpcodeByteKind_rd:
+            {
+                opnd_size = OpndSize_32;
+                break;
+            }
+            default:
+                assert( false );
+            }
+            opnd = EncoderBase::Operand( getRegName(OpndKind_GPReg, opnd_size, regid) );
+
+            ++pinst->argc;
             ++*pbuf;
             return true;
         }
@@ -347,7 +430,7 @@
         *pbuf += 1;
         scale = sib.scale == 0 ? 0 : (1<<sib.scale);
         if (sib.index != 4) {
-			index = getRegName(OpndKind_GPReg, opndDesc.size, EXTEND_REG(sib.index, x));
+            index = getRegName(OpndKind_GPReg, opndDesc.size, EXTEND_REG(sib.index, x));
         } else {
             // (sib.index == 4) => no index
         }

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.h?rev=643030&r1=643029&r2=643030&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/dec_base.h Mon Mar 31 08:39:54 2008
@@ -44,17 +44,40 @@
 struct Inst {
     Inst() {
         mn = Mnemonic_Null;
+        prefc = 0;
         size = 0;
         flags = 0;
         //offset = 0;
         //direct_addr = NULL;
         argc = 0;
+        for(int i = 0; i < 4; ++i)
+        {
+            pref[i] = InstPrefix_Null;
+        }
     }
     /**
      * Mnemonic of the instruction.s
      */
     Mnemonic mn;
     /**
+     * Enumerating of indexes in the pref array.
+     */
+    enum PrefGroups
+    {
+        Group1 = 0,
+        Group2,
+        Group3,
+        Group4
+    };
+    /**
+     * Number of prefixes (1 byte each).
+     */
+    unsigned int prefc;
+    /**
+     * Instruction prefixes. Prefix should be placed here according to its group.
+     */
+    InstPrefix pref[4];
+    /**
      * Size, in bytes, of the instruction.
      */
     unsigned size;
@@ -98,7 +121,7 @@
         unsigned aux, const unsigned char ** pbuf, 
         Inst * pinst, const Rex *rex);
     static bool try_mn(Mnemonic mn, const unsigned char ** pbuf, Inst * pinst);
-
+    static unsigned int fill_prefs( const unsigned char * bytes, Inst * pinst);
     static bool is_prefix(const unsigned char * bytes);
 };
 

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=643030&r1=643029&r2=643030&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 Mon Mar 31 08:39:54 2008
@@ -741,6 +741,7 @@
 BEGIN_OPCODES()
     {OpcodeInfo::all, {0xDB, _0}, {FP0S, m32},    D_U },
     {OpcodeInfo::all, {0xDF, _5}, {FP0D, m64},    D_U },
+    {OpcodeInfo::all, {0xDB, _0}, {FP0S, m32},    D_U },
 END_OPCODES()
 END_MNEMONIC()
 
@@ -1301,6 +1302,7 @@
 BEGIN_MNEMONIC(SHLD, MF_AFFECTS_FLAGS, N)
 BEGIN_OPCODES()
     {OpcodeInfo::all,     {0x0F, 0xA5},   {r_m32, r32, ECX}, DU_DU_U },
+    {OpcodeInfo::all,     {0x0F, 0xA4},   {r_m32, r32, imm8}, DU_DU_U },
 END_OPCODES()
 END_MNEMONIC()
 
@@ -1440,6 +1442,7 @@
 BEGIN_MNEMONIC(STOS, MF_AFFECTS_FLAGS, DU_DU_U)
 BEGIN_OPCODES()
     {OpcodeInfo::all,   {0xAB},         {EDI, ECX, EAX},   DU_DU_U },
+    {OpcodeInfo::all,   {0xAA},         {EDI, ECX, AL},    DU_DU_U },
     {OpcodeInfo::em64t, {REX_W, 0xAB},  {RDI, RCX, RAX},   DU_DU_U },
 END_OPCODES()
 END_MNEMONIC()