Index: dec_base.cpp =================================================================== --- dec_base.cpp (revision 620764) +++ dec_base.cpp (working copy) @@ -56,28 +56,84 @@ 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) { Inst tmp; - //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); return 0; } - + // Load up to 4 prefixes // for each Mnemonic // for each opcodedesc @@ -154,6 +210,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; } Index: enc_tabl.cpp =================================================================== --- enc_tabl.cpp (revision 620764) +++ enc_tabl.cpp (working copy) @@ -740,6 +740,7 @@ BEGIN_MNEMONIC(FILD, MF_NONE, D_U ) BEGIN_OPCODES() {OpcodeInfo::all, {0xDF, _5}, {FP0D, m64}, D_U }, + {OpcodeInfo::all, {0xDB, _0}, {FP0S, m32}, D_U }, END_OPCODES() END_MNEMONIC() @@ -1292,6 +1293,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() @@ -1431,6 +1433,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() Index: dec_base.h =================================================================== --- dec_base.h (revision 620764) +++ dec_base.h (working copy) @@ -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); };