You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2007/10/19 13:08:35 UTC
svn commit: r586378 - in
/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t: dec_base.cpp
dec_base.h enc_defs.h
Author: gshimansky
Date: Fri Oct 19 04:08:33 2007
New Revision: 586378
URL: http://svn.apache.org/viewvc?rev=586378&view=rev
Log:
Impelemented REX prefixes parsing for x86_64 instructions
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_defs.h
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=586378&r1=586377&r2=586378&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 Fri Oct 19 04:08:33 2007
@@ -25,6 +25,7 @@
*/
#include "dec_base.h"
+#include "open/common.h"
bool DecoderBase::is_prefix(const unsigned char * bytes)
{
@@ -105,8 +106,15 @@
return tmp.size;
}
+#ifdef _EM64T_
+#define EXTEND_REG(reg, flag) \
+ ((NULL == rex || 0 == rex->flag) ? reg : (reg + 8))
+#else
+#define EXTEND_REG(reg, flag) (reg)
+#endif
+
bool DecoderBase::decode_aux(const EncoderBase::OpcodeDesc& odesc, unsigned aux,
- const unsigned char ** pbuf, Inst * pinst)
+ const unsigned char ** pbuf, Inst * pinst, const Rex UNREF *rex)
{
OpcodeByteKind kind = (OpcodeByteKind)(aux & OpcodeByteKind_KindMask);
unsigned byte = (aux & OpcodeByteKind_OpcodeMask);
@@ -120,15 +128,15 @@
{
const ModRM& modrm = *(ModRM*)*pbuf;
unsigned regIndex = odesc.opnds[0].kind == OpndKind_GPReg ? 0 : 1;
- RegName reg = getRegName(OpndKind_GPReg, opndDesc.size, modrm.reg);
+ RegName reg = getRegName(OpndKind_GPReg, opndDesc.size, EXTEND_REG(modrm.reg, r));
EncoderBase::Operand& regOpnd = pinst->operands[regIndex];
if (regIndex == 0) {
regOpnd = EncoderBase::Operand(reg);
++pinst->argc;
- decodeModRM(odesc, pbuf, pinst);
+ decodeModRM(odesc, pbuf, pinst, rex);
}
else {
- decodeModRM(odesc, pbuf, pinst);
+ decodeModRM(odesc, pbuf, pinst, rex);
++pinst->argc;
regOpnd = EncoderBase::Operand(reg);
}
@@ -139,6 +147,9 @@
case OpcodeByteKind_rw:
case OpcodeByteKind_rd:
{
+ // Gregory -
+ // Here we don't parse register because for current needs
+ // disassembler doesn't require to parse all operands
unsigned regid = data_byte - byte;
if (regid>7) {
return false;
@@ -172,7 +183,7 @@
if (modrm.reg != byte) {
return false;
}
- decodeModRM(odesc, pbuf, pinst);
+ decodeModRM(odesc, pbuf, pinst, rex);
++pinst->argc;
}
return true;
@@ -238,6 +249,10 @@
const EncoderBase::OpcodeDesc& odesc = opcodes[i];
char *opcode_ptr = const_cast<char *>(odesc.opcode);
int opcode_len = odesc.opcode_len;
+ Rex *prex = NULL;
+#ifdef _EM64T_
+ Rex rex;
+#endif
*pbuf = save_pbuf;
if (opcode_len != 0) {
@@ -245,6 +260,8 @@
// Match REX prefixes
if (((*pbuf)[0] & 0xf0) == 0x40 && opcode_ptr[0] == 0x48)
{
+ rex = *(Rex *)*pbuf;
+ prex = &rex;
(*pbuf)++;
opcode_ptr++;
opcode_len--;
@@ -258,11 +275,11 @@
}
if (odesc.aux0 != 0) {
- if (!decode_aux(odesc, odesc.aux0, pbuf, pinst)) {
+ if (!decode_aux(odesc, odesc.aux0, pbuf, pinst, prex)) {
continue;
}
if (odesc.aux1 != 0) {
- if (!decode_aux(odesc, odesc.aux1, pbuf, pinst)) {
+ if (!decode_aux(odesc, odesc.aux1, pbuf, pinst, prex)) {
continue;
}
}
@@ -279,14 +296,8 @@
return false;
}
-#ifdef _IA32_
-#define DISASM_REG_SIZE OpndSize_32
-#else
-#define DISASM_REG_SIZE OpndSize_64
-#endif
-
bool DecoderBase::decodeModRM(const EncoderBase::OpcodeDesc& odesc,
- const unsigned char ** pbuf, Inst * pinst)
+ const unsigned char ** pbuf, Inst * pinst, const Rex *rex)
{
EncoderBase::Operand& opnd = pinst->operands[pinst->argc];
const EncoderBase::OpndDesc& opndDesc = odesc.opnds[pinst->argc];
@@ -300,13 +311,17 @@
RegName index = RegName_Null;
int disp = 0;
unsigned scale = 0;
- //XXX
- scale=scale; base = base; index = index; disp = disp; reg = reg;
+ OpndSize reg_size = OpndSize_32;
+
+#ifdef _EM64T_
+ if (NULL != rex && 0 != rex->w)
+ reg_size = OpndSize_64;
+#endif
- reg = getRegName(OpndKind_GPReg, DISASM_REG_SIZE, modrm.reg);
+ reg = getRegName(OpndKind_GPReg, reg_size, EXTEND_REG(modrm.reg, r));
if (modrm.mod == 3) {
// we have only modrm. no sib, no disp.
- reg = getRegName(OpndKind_GPReg, opndDesc.size, modrm.rm);
+ reg = getRegName(OpndKind_GPReg, opndDesc.size, EXTEND_REG(modrm.rm, b));
opnd = EncoderBase::Operand(reg);
return true;
}
@@ -320,13 +335,13 @@
// no index
}
else {
- index = getRegName(OpndKind_GPReg, DISASM_REG_SIZE, sib.index);
+ index = getRegName(OpndKind_GPReg, reg_size, EXTEND_REG(sib.index, x));
}
- base = getRegName(OpndKind_GPReg, DISASM_REG_SIZE, sib.base);
+ base = getRegName(OpndKind_GPReg, reg_size, EXTEND_REG(sib.base, b));
}
else {
if (modrm.mod != 0 || modrm.rm != 5) {
- base = getRegName(OpndKind_GPReg, DISASM_REG_SIZE, modrm.rm);
+ base = getRegName(OpndKind_GPReg, reg_size, EXTEND_REG(modrm.rm, b));
}
else {
// mod=0 && rm == 5 => only disp32
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=586378&r1=586377&r2=586378&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 Fri Oct 19 04:08:33 2007
@@ -93,10 +93,10 @@
static unsigned decode(const void * addr, Inst * pinst);
private:
static bool decodeModRM(const EncoderBase::OpcodeDesc& odesc,
- const unsigned char ** pbuf, Inst * pinst);
+ const unsigned char ** pbuf, Inst * pinst, const Rex *rex);
static bool decode_aux(const EncoderBase::OpcodeDesc& odesc,
- unsigned aux, const unsigned char ** pbuf,
- Inst * pinst);
+ unsigned aux, const unsigned char ** pbuf,
+ Inst * pinst, const Rex *rex);
static bool try_mn(Mnemonic mn, const unsigned char ** pbuf, Inst * pinst);
static bool is_prefix(const unsigned char * bytes);
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=586378&r1=586377&r2=586378&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 Fri Oct 19 04:08:33 2007
@@ -158,6 +158,11 @@
#define REGNAME(k,s,i) ( ((k & OpndKind_Any)<<24) | ((s & OpndSize_Any)<<16) | (i&0xFF) )
+// Gregory -
+// It is critical that all register indexes (3rd number) inside of the
+// following table go in ascending order. That is R8 goes after
+// RDI. It is necessary for decoder when extending registers from RAX-DRI
+// to R8-R15 by simply adding 8 to the index on EM64T architecture
enum RegName {
RegName_Null = 0,
@@ -207,16 +212,6 @@
RegName_R13D = REGNAME(OpndKind_GPReg,OpndSize_32,13),
RegName_R14D = REGNAME(OpndKind_GPReg,OpndSize_32,14),
RegName_R15D = REGNAME(OpndKind_GPReg,OpndSize_32,15),
-
- RegName_R8S = REGNAME(OpndKind_GPReg,OpndSize_16,8),
- RegName_R9S = REGNAME(OpndKind_GPReg,OpndSize_16,9),
- RegName_R10S = REGNAME(OpndKind_GPReg,OpndSize_16,10),
- RegName_R11S = REGNAME(OpndKind_GPReg,OpndSize_16,11),
- RegName_R12S = REGNAME(OpndKind_GPReg,OpndSize_16,12),
- RegName_R13S = REGNAME(OpndKind_GPReg,OpndSize_16,13),
- RegName_R14S = REGNAME(OpndKind_GPReg,OpndSize_16,14),
- RegName_R15S = REGNAME(OpndKind_GPReg,OpndSize_16,15),
-
#endif //~_EM64T_
RegName_AX=REGNAME(OpndKind_GPReg,OpndSize_16,0),
@@ -227,12 +222,25 @@
RegName_BP=REGNAME(OpndKind_GPReg,OpndSize_16,5),
RegName_SI=REGNAME(OpndKind_GPReg,OpndSize_16,6),
RegName_DI=REGNAME(OpndKind_GPReg,OpndSize_16,7),
+
+#ifdef _EM64T_
+ RegName_R8S = REGNAME(OpndKind_GPReg,OpndSize_16,8),
+ RegName_R9S = REGNAME(OpndKind_GPReg,OpndSize_16,9),
+ RegName_R10S = REGNAME(OpndKind_GPReg,OpndSize_16,10),
+ RegName_R11S = REGNAME(OpndKind_GPReg,OpndSize_16,11),
+ RegName_R12S = REGNAME(OpndKind_GPReg,OpndSize_16,12),
+ RegName_R13S = REGNAME(OpndKind_GPReg,OpndSize_16,13),
+ RegName_R14S = REGNAME(OpndKind_GPReg,OpndSize_16,14),
+ RegName_R15S = REGNAME(OpndKind_GPReg,OpndSize_16,15),
+#endif //~_EM64T_
RegName_AL=REGNAME(OpndKind_GPReg,OpndSize_8,0),
RegName_CL=REGNAME(OpndKind_GPReg,OpndSize_8,1),
RegName_DL=REGNAME(OpndKind_GPReg,OpndSize_8,2),
RegName_BL=REGNAME(OpndKind_GPReg,OpndSize_8,3),
- // Used in enc_tabl.cpp
+ // FIXME: Used in enc_tabl.cpp
+ // AH is not accessible on EM64T, instead encoded register is SPL, so decoded
+ // register will return incorrect enum
RegName_AH=REGNAME(OpndKind_GPReg,OpndSize_8,4),
#if !defined(_EM64T_)
RegName_CH=REGNAME(OpndKind_GPReg,OpndSize_8,5),