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()