Index: vm/port/src/encoder/ia32_em64t/enc_base.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_base.cpp (revision 474682) +++ vm/port/src/encoder/ia32_em64t/enc_base.cpp (working copy) @@ -16,7 +16,7 @@ */ /** * @author Alexander V. Astapchuk - * @version $Revision: 1.1.2.3.4.4 $ + * @version $Revision$ */ #include "enc_base.h" #include Index: vm/port/src/encoder/ia32_em64t/encoder.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.cpp (revision 474682) +++ vm/port/src/encoder/ia32_em64t/encoder.cpp (working copy) @@ -16,7 +16,7 @@ */ /** * @author Alexander V. Astapchuk - * @version $Revision: 1.1.2.2.4.4 $ + * @version $Revision$ */ #include #include Index: vm/port/src/encoder/ia32_em64t/encoder.inl =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.inl (revision 474682) +++ vm/port/src/encoder/ia32_em64t/encoder.inl (working copy) @@ -129,8 +129,6 @@ EncoderBase::Operands args; add_rm(args, rm, sz); add_r(args, r, sz); - RegName implicitReg = getAliasReg(RegName_EAX, map_size(sz)); - args.add(implicitReg); return (char*)EncoderBase::encode(stream, Mnemonic_CMPXCHG, args); } @@ -252,6 +250,8 @@ // multiply instructions: mul, imul ENCODER_DECLARE_EXPORT char * mul(char * stream, const RM_Opnd & rm, Opnd_Size sz) { EncoderBase::Operands args; + args.add(RegName_EDX); + args.add(RegName_EAX); add_rm(args, rm, sz); return (char*)EncoderBase::encode(stream, Mnemonic_MUL, args); } Index: vm/port/src/encoder/ia32_em64t/enc_base.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_base.h (revision 474682) +++ vm/port/src/encoder/ia32_em64t/enc_base.h (working copy) @@ -16,7 +16,7 @@ */ /** * @author Alexander V. Astapchuk - * @version $Revision: 1.1.2.3.4.4 $ + * @version $Revision$ */ /** Index: vm/port/src/encoder/ia32_em64t/encoder.h =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.h (revision 474682) +++ vm/port/src/encoder/ia32_em64t/encoder.h (working copy) @@ -16,7 +16,7 @@ */ /** * @author Alexander V. Astapchuk - * @version $Revision: 1.1.2.2.4.5 $ + * @version $Revision$ */ /** * @file Index: vm/port/src/encoder/ia32_em64t/dec_base.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/dec_base.cpp (revision 474682) +++ vm/port/src/encoder/ia32_em64t/dec_base.cpp (working copy) @@ -16,7 +16,7 @@ */ /** * @author Alexander V. Astapchuk - * @version $Revision: $ + * @version $Revision$ */ /** Index: vm/port/src/encoder/ia32_em64t/enc_prvt.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_prvt.h (revision 474682) +++ vm/port/src/encoder/ia32_em64t/enc_prvt.h (working copy) @@ -16,7 +16,7 @@ */ /** * @author Alexander V. Astapchuk - * @version $Revision: 1.1.2.2.4.4 $ + * @version $Revision$ */ #ifndef __ENC_PRVT_H_INCLUDED__ #define __ENC_PRVT_H_INCLUDED__ Index: vm/port/src/encoder/ia32_em64t/enc_tabl.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (revision 474682) +++ vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (working copy) @@ -16,7 +16,7 @@ */ /** * @author Alexander V. Astapchuk - * @version $Revision: 1.1.2.3.4.4 $ + * @version $Revision$ */ @@ -276,20 +276,29 @@ unsigned short hash = 0; // The hash computation, uses fast way - table selection instead of if-s. if (odesc->roles.count > 0) { - hash = kind_hash[odesc->opnds[0].kind] | - size_hash[odesc->opnds[0].size]; + OpndKind kind = odesc->opnds[0].kind; + OpndSize size = odesc->opnds[0].size; + assert(kindroles.count > 1) { + OpndKind kind = odesc->opnds[1].kind; + OpndSize size = odesc->opnds[1].size; + assert(kindopnds[1].kind] | - size_hash[odesc->opnds[1].size]); + (kind_hash[kind] | size_hash[size]); } if (odesc->roles.count > 2) { + OpndKind kind = odesc->opnds[2].kind; + OpndSize size = odesc->opnds[2].size; + assert(kindopnds[2].kind] | - size_hash[odesc->opnds[2].size]); + (kind_hash[kind] | size_hash[size]); } assert(hash <= HASH_MAX); return hash; @@ -411,12 +420,12 @@ END_OPCODES() END_MNEMONIC() -BEGIN_MNEMONIC(CMPXCHG, MF_AFFECTS_FLAGS, N) +BEGIN_MNEMONIC(CMPXCHG, MF_NONE, DU_DU ) BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0xB0, _r}, {r_m8, r8, AL}, DU_DU_DU }, - {OpcodeInfo::all, {Size16, 0x0F, 0xB1, _r}, {r_m16, r16, AX}, DU_DU_DU }, - {OpcodeInfo::all, {0x0F, 0xB1, _r}, {r_m32, r32, EAX}, DU_DU_DU}, - {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB1, _r},{r_m64, r64, RAX}, DU_DU_DU }, + {OpcodeInfo::all, {0x0F, 0xB0, _r}, {r_m8, r8}, DU_DU }, + {OpcodeInfo::all, {Size16, 0x0F, 0xB1, _r}, {r_m16, r16}, DU_DU }, + {OpcodeInfo::all, {0x0F, 0xB1, _r}, {r_m32, r32}, DU_DU }, + {OpcodeInfo::em64t, {REX_W, 0x0F, 0xB1, _r},{r_m64, r64}, DU_DU }, END_OPCODES() END_MNEMONIC() @@ -436,6 +445,14 @@ END_OPCODES() END_MNEMONIC() + +BEGIN_MNEMONIC(BSR, MF_AFFECTS_FLAGS, N) +BEGIN_OPCODES() + {OpcodeInfo::all, {0x0F, 0xBD}, {r32, r_m32}, D_U}, +END_OPCODES() +END_MNEMONIC() + + BEGIN_MNEMONIC(CALL, MF_NONE, U ) BEGIN_OPCODES() {OpcodeInfo::all, {0xE8, cd}, {rel32}, U }, @@ -703,6 +720,12 @@ // ~ FPU // +BEGIN_MNEMONIC(DIV, MF_AFFECTS_FLAGS, DU_DU_U) +BEGIN_OPCODES() + {OpcodeInfo::all, {0xF7, _6}, {EDX, EAX, r_m32}, DU_DU_U }, +END_OPCODES() +END_MNEMONIC() + BEGIN_MNEMONIC(IDIV, MF_AFFECTS_FLAGS, DU_DU_U) BEGIN_OPCODES() #if !defined(_EM64T_) @@ -711,15 +734,19 @@ #endif {OpcodeInfo::all, {0xF7, _7}, {EDX, EAX, r_m32}, DU_DU_U }, {OpcodeInfo::em64t, {REX_W, 0xF7, _7}, {RDX, RAX, r_m64}, DU_DU_U }, -END_OPCODES() + END_OPCODES() END_MNEMONIC() + BEGIN_MNEMONIC(IMUL, MF_AFFECTS_FLAGS, D_DU_U) BEGIN_OPCODES() /*{OpcodeInfo::all, {0xF6, _5}, {AH, AL, r_m8}, D_DU_U }, {OpcodeInfo::all, {Size16, 0xF7, _5}, {DX, AX, r_m16}, D_DU_U }, - {OpcodeInfo::all, {0xF7, _5}, {EDX, EAX, r_m32}, D_DU_U }, - {OpcodeInfo::em64t, {REX_W, 0xF7, _5}, {RDX, RAX, r_m64}, D_DU_U },*/ + */ + // + {OpcodeInfo::all, {0xF7, _5}, {EDX, EAX, r_m32}, D_DU_U }, + {OpcodeInfo::em64t, {REX_W, 0xF7, _5}, {RDX, RAX, r_m64}, D_DU_U }, + // {OpcodeInfo::all, {Size16, 0x0F, 0xAF, _r}, {r16,r_m16}, DU_U }, {OpcodeInfo::all, {0x0F, 0xAF, _r}, {r32,r_m32}, DU_U }, {OpcodeInfo::em64t, {REX_W, 0x0F, 0xAF, _r}, {r64,r_m64}, DU_U }, @@ -737,10 +764,10 @@ BEGIN_MNEMONIC(MUL, MF_AFFECTS_FLAGS, U ) BEGIN_OPCODES() - {OpcodeInfo::all, {0xF6, _4}, {r_m8}, U }, - {OpcodeInfo::all, {Size16, 0xF7, _4}, {r_m16}, U }, - {OpcodeInfo::all, {0xF7, _4}, {r_m32}, U }, - {OpcodeInfo::em64t, {REX_W, 0xF7, _4}, {r_m64}, U }, + {OpcodeInfo::all, {0xF6, _4}, {AX, AL, r_m8}, D_DU_U }, + {OpcodeInfo::all, {Size16, 0xF7, _4}, {DX, AX, r_m16}, D_DU_U }, + {OpcodeInfo::all, {0xF7, _4}, {EDX, EAX, r_m32}, D_DU_U }, + {OpcodeInfo::em64t, {REX_W, 0xF7, _4}, {RDX, RAX, r_m64}, D_DU_U }, END_OPCODES() END_MNEMONIC() @@ -1097,8 +1124,8 @@ #undef DEFINE_SETcc_MNEMONIC -#define DEFINE_SHIFT_MNEMONIC( nam, slash_num ) \ -BEGIN_MNEMONIC(nam, MF_AFFECTS_FLAGS, DU_U) \ +#define DEFINE_SHIFT_MNEMONIC(nam, slash_num, flags) \ +BEGIN_MNEMONIC(nam, flags, DU_U) \ BEGIN_OPCODES()\ /* {OpcodeInfo::all, {0xD0, slash_num}, {r_m8, const_1}, DU_U },*/\ {OpcodeInfo::all, {0xD2, slash_num}, {r_m8, CL}, DU_U },\ @@ -1119,23 +1146,28 @@ END_OPCODES()\ END_MNEMONIC() -DEFINE_SHIFT_MNEMONIC(SAL, _4) -DEFINE_SHIFT_MNEMONIC(SAR, _7) -DEFINE_SHIFT_MNEMONIC(SHR, _5) -DEFINE_SHIFT_MNEMONIC(ROR, _1) +DEFINE_SHIFT_MNEMONIC(ROL, _0, MF_AFFECTS_FLAGS) +DEFINE_SHIFT_MNEMONIC(ROR, _1, MF_AFFECTS_FLAGS) +DEFINE_SHIFT_MNEMONIC(RCL, _2, MF_AFFECTS_FLAGS|MF_USES_FLAGS) +DEFINE_SHIFT_MNEMONIC(RCR, _3, MF_AFFECTS_FLAGS|MF_USES_FLAGS) + +DEFINE_SHIFT_MNEMONIC(SAL, _4, MF_AFFECTS_FLAGS) +DEFINE_SHIFT_MNEMONIC(SHR, _5, MF_AFFECTS_FLAGS) +DEFINE_SHIFT_MNEMONIC(SAR, _7, MF_AFFECTS_FLAGS) + #undef DEFINE_SHIFT_MNEMONIC + BEGIN_MNEMONIC(SHLD, MF_AFFECTS_FLAGS, N) -// TODO: the def/use info is worng BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0xA5}, {r_m32, r32, CL}, DU_DU_U }, + {OpcodeInfo::all, {0x0F, 0xA5}, {r_m32, r32, ECX}, DU_DU_U }, END_OPCODES() END_MNEMONIC() BEGIN_MNEMONIC(SHRD, MF_AFFECTS_FLAGS, N) // TODO: the def/use info is wrong BEGIN_OPCODES() - {OpcodeInfo::all, {0x0F, 0xAD}, {r_m32, r32, CL}, DU_DU_U }, + {OpcodeInfo::all, {0x0F, 0xAD}, {r_m32, r32, ECX}, DU_DU_U }, END_OPCODES() END_MNEMONIC() @@ -1272,6 +1304,15 @@ END_OPCODES() END_MNEMONIC() +BEGIN_MNEMONIC(MOVS, MF_NONE, DU_DU_DU) +BEGIN_OPCODES() + {OpcodeInfo::ia32, {0xA4}, {m8,m8,ECX}, DU_DU_DU }, + {OpcodeInfo::ia32, {Size16, 0xA5}, {m16,m16,ECX}, DU_DU_DU }, + {OpcodeInfo::ia32, {0xA5}, {m32,m32,ECX}, DU_DU_DU }, +END_OPCODES() +END_MNEMONIC() + + BEGIN_MNEMONIC(WAIT, MF_AFFECTS_FLAGS, N) BEGIN_OPCODES() {OpcodeInfo::all, {0x9B}, {}, N }, @@ -1353,7 +1394,7 @@ unsigned opcod = oinfo.opcode[j]; unsigned kind = opcod&OpcodeByteKind_KindMask; if (kind == OpcodeByteKind_REX_W) { - odesc.opcode[odesc.opcode_len++] = (unsigned char)0x48; + odesc.opcode[odesc.opcode_len++] = (unsigned char)0x48; continue; } else if(kind != 0 && kind != OpcodeByteKind_ZeroOpcodeByte) { @@ -1373,12 +1414,13 @@ assert((odesc.aux1 & OpcodeByteKind_KindMask) != 0); } } - else if (oinfo.roles.count==2) { + else if (oinfo.roles.count>=2) { if (((oinfo.opnds[0].kind&OpndKind_Mem) && (isRegKind(oinfo.opnds[1].kind))) || ((oinfo.opnds[1].kind&OpndKind_Mem) && (isRegKind(oinfo.opnds[0].kind)))) { // Example: MOVQ xmm1, xmm/m64 has only opcodes + // same with SHRD // Adding fake /r odesc.aux0 = _r; } @@ -1430,7 +1472,8 @@ // // check whether the operand info is a mask (i.e. r_m*). - // in this case, split the info to have separate entries for 'r' and for 'm'. + // in this case, split the info to have separate entries for 'r' + // and for 'm'. // the good news is that there can be only one such operand. // int opnd2split = -1; Index: vm/port/src/encoder/ia32_em64t/dec_base.h =================================================================== --- vm/port/src/encoder/ia32_em64t/dec_base.h (revision 474682) +++ vm/port/src/encoder/ia32_em64t/dec_base.h (working copy) @@ -16,7 +16,7 @@ */ /** * @author Alexander V. Astapchuk - * @version $Revision: $ + * @version $Revision$ */ /** Index: vm/port/src/encoder/ia32_em64t/enc_defs.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_defs.h (revision 474682) +++ vm/port/src/encoder/ia32_em64t/enc_defs.h (working copy) @@ -16,7 +16,7 @@ */ /** * @author Alexander V. Astapchuk - * @version $Revision: 1.1.2.2.4.4 $ + * @version $Revision$ */ #ifndef _ENCODER_DEFS_H_ #define _ENCODER_DEFS_H_ @@ -407,6 +407,9 @@ Mnemonic_ADDSD, // Add Scalar Double-Precision Floating-Point Values Mnemonic_ADDSS, // Add Scalar Single-Precision Floating-Point Values Mnemonic_AND, // Logical AND + +Mnemonic_BSR, // Bit scan reverse + Mnemonic_CALL, // Call Procedure Mnemonic_CWD, Mnemonic_CDQ=Mnemonic_CWD,// Convert Word to Doubleword/Convert Doubleword to Qua T dword Mnemonic_CMOVcc, // Conditional Move @@ -484,6 +487,7 @@ Mnemonic_FSTP, // Store Floating Point Value and pop the FP stack Mnemonic_XCHG, +Mnemonic_DIV, // Unsigned Divide Mnemonic_IDIV, // Signed Divide Mnemonic_MUL, // Unsigned Multiply Mnemonic_IMUL, // Signed Multiply @@ -513,8 +517,9 @@ Mnemonic_LOOPNE, Mnemonic_LOOPNZ = Mnemonic_LOOPNE, // Loop according to ECX Mnemonic_LAHF, // Load Flags into AH Mnemonic_MOV, // Move +Mnemonic_MOVD, // Move Double word Mnemonic_MOVQ, // Move Quadword -Mnemonic_MOVD, // Move Double word +Mnemonic_MOVS, // Move Data from String to String Mnemonic_MOVSD, // Move Scalar Double-Precision Floating-Point Value Mnemonic_MOVSS, // Move Scalar Single-Precision Floating-Point Values Mnemonic_MOVSX, // Move with Sign-Extension @@ -562,6 +567,9 @@ Mnemonic_SAL, Mnemonic_SHL=Mnemonic_SAL,// Shift left Mnemonic_SAR, // Unsigned shift right Mnemonic_ROR, // Rotate right +Mnemonic_RCR, // Rotate right through CARRY flag +Mnemonic_ROL, // Rotate left +Mnemonic_RCL, // Rotate left through CARRY flag Mnemonic_SHR, // Signed shift right Mnemonic_SHRD, // Double Precision Shift Right Mnemonic_SHLD, // Double Precision Shift Left