diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index bee8f331f..f3c2982b1 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -4470,7 +4470,6 @@ public: // for now... #if BX_SUPPORT_EVEX BX_SMF unsigned evex_displ8_compression(bxInstruction_c *i, unsigned ia_opcode, unsigned type, unsigned vex_w); #endif - BX_SMF Bit16u WalkOpcodeTables(const BxOpcodeInfo_t *op, Bit16u &attr, unsigned modrm, unsigned sse_prefix, unsigned osize, unsigned vex_vl, bx_bool vex_w); BX_SMF char* disasm(const Bit8u *opcode, bool is_32, bool is_64, char *disbufptr, bxInstruction_c *i, bx_address cs_base = 0, bx_address rip = 0); BX_SMF bxICacheEntry_c *serveICacheMiss(Bit32u eipBiased, bx_phy_address pAddr); @@ -5735,90 +5734,4 @@ enum { }; #endif -// - -// -// For decoding... -// - -// If the BxImmediate mask is set, the lowest 4 bits of the attribute -// specify which kinds of immediate data required by instruction. - -#define BxImmediate 0x000f // bits 3..0: any immediate -#define BxImmediate_I1 0x0001 // imm8 = 1 -#define BxImmediate_Ib 0x0002 // 8 bit -#define BxImmediate_Ib_SE 0x0003 // sign extend to operand size -#define BxImmediate_Iw 0x0004 // 16 bit -#define BxImmediate_Id 0x0005 // 32 bit -#define BxImmediate_O 0x0006 // MOV_ALOd, mov_OdAL, mov_eAXOv, mov_OveAX -#if BX_SUPPORT_X86_64 -#define BxImmediate_Iq 0x0007 // 64 bit override -#endif -#define BxImmediate_BrOff8 0x0008 // Relative branch offset byte -#define BxImmediate_BrOff16 BxImmediate_Iw // Relative branch offset word, not encodable in 64-bit mode -#define BxImmediate_BrOff32 BxImmediate_Id // Relative branch offset dword - -#define BxImmediate_Ib4 BxImmediate_Ib // Register encoded in Ib[7:4] -#define BxImmediate_Ib5 BxImmediate_Ib - -// Lookup for opcode and attributes in another opcode tables -// Totally 15 opcode groups supported -#define BxGroupX 0x00f0 // bits 7..4: opcode groups definition -#define BxPrefixSSE66 0x0010 // Group encoding: 0001, SSE_PREFIX_66 only -#define BxPrefixSSEF3 0x0020 // Group encoding: 0010, SSE_PREFIX_F3 only -#define BxPrefixSSEF2 0x0030 // Group encoding: 0011, SSE_PREFIX_F2 only -#define BxPrefixSSE 0x0040 // Group encoding: 0100 -#define BxPrefixSSE2 0x0050 // Group encoding: 0101, do not allow SSE_PREFIX_F2 or SSE_PREFIX_F3 -#define BxPrefixSSE4 0x0060 // Group encoding: 0110 -#define BxPrefixSSEF2F3 0x0070 // Group encoding: 0111, ignore SSE_PREFIX_66 -#define BxGroupN 0x0080 // Group encoding: 1000 -#define BxSplitGroupN 0x0090 // Group encoding: 1001 -#define BxFPEscape 0x00A0 // Group encoding: 1010 -#define BxOSizeGrp 0x00B0 // Group encoding: 1011 -#define BxSplitMod11B 0x00C0 // Group encoding: 1100 -#define BxSplitVexVL 0x00D0 // Group encoding: 1101 - -// The BxImmediate2 mask specifies kind of second immediate data -// required by instruction. -#define BxImmediate2 0x0300 // bits 8.9: any immediate -#define BxImmediate_Ib2 0x0100 -#define BxImmediate_Iw2 0x0200 -#define BxImmediate_Id2 0x0300 - -#define BxVexL0 0x0100 // bit 8 (aliased with imm2) -#define BxVexL1 0x0200 // bit 9 (aliased with imm2) -#define BxVexW0 0x0400 // bit 10 -#define BxVexW1 0x0800 // bit 11 - -#define BxAlias 0x3000 // bits 12..13 -#define BxAliasSSE 0x1000 // Encoding 01: form final opcode using SSE prefix and current opcode -#define BxAliasVexW 0x2000 // Encoding 10: form final opcode using VEX.W and current opcode -#define BxAliasVexW64 0x3000 // Encoding 11: form final opcode using VEX.W and current opcode in 64-bit mode only - -#define BxLockable 0x4000 // bit 14 - -#define BxGroup1 BxGroupN -#define BxGroup1A BxGroupN -#define BxGroup2 BxGroupN -#define BxGroup3 BxGroupN -#define BxGroup4 BxGroupN -#define BxGroup5 BxGroupN -#define BxGroup6 BxGroupN -#define BxGroup7 BxFPEscape -#define BxGroup8 BxGroupN -#define BxGroup9 BxSplitGroupN - -#define BxGroup11 BxGroupN -#define BxGroup12 BxGroupN -#define BxGroup13 BxGroupN -#define BxGroup14 BxGroupN -#define BxGroup15 BxSplitGroupN -#define BxGroup16 BxGroupN -#define BxGroup17 BxGroupN -#define BxGroup17A BxGroupN - -#define BxGroupFP BxSplitGroupN - -// - #endif // #ifndef BX_CPU_H diff --git a/bochs/cpu/fetchdecode.cc b/bochs/cpu/fetchdecode.cc index ba598a4f6..6a88e12f8 100644 --- a/bochs/cpu/fetchdecode.cc +++ b/bochs/cpu/fetchdecode.cc @@ -170,6 +170,8 @@ bxIAOpcodeTable BxOpcodesTable[] = { }; #undef bx_define_opcode +extern Bit16u WalkOpcodeTables(const BxOpcodeInfo_t *OpcodeInfoPtr, Bit16u &attr, Bit32u fetchModeMask, unsigned modrm, unsigned sse_prefix, unsigned osize, unsigned vex_vl, bx_bool vex_w); + /* ************************** */ /* 512 entries for 16bit mode */ /* 512 entries for 32bit mode */ @@ -1688,7 +1690,7 @@ modrm_done: } #endif - ia_opcode = WalkOpcodeTables(OpcodeInfoPtr, attr, b2, sse_prefix, os_32, i->getVL(), vex_w); + ia_opcode = WalkOpcodeTables(OpcodeInfoPtr, attr, fetchModeMask, b2, sse_prefix, os_32, i->getVL(), vex_w); } else { // Opcode does not require a MODRM byte. @@ -2091,7 +2093,7 @@ unsigned BX_CPU_C::evex_displ8_compression(bxInstruction_c *i, unsigned ia_opcod } #endif -Bit16u BX_CPU_C::WalkOpcodeTables(const BxOpcodeInfo_t *OpcodeInfoPtr, Bit16u &attr, unsigned modrm, unsigned sse_prefix, unsigned osize, unsigned vex_vl, bx_bool vex_w) +Bit16u WalkOpcodeTables(const BxOpcodeInfo_t *OpcodeInfoPtr, Bit16u &attr, Bit32u fetchModeMask, unsigned modrm, unsigned sse_prefix, unsigned osize, unsigned vex_vl, bx_bool vex_w) { // Parse mod-nnn-rm and related bytes unsigned mod_mem = (modrm & 0xc0) != 0xc0; @@ -2191,7 +2193,7 @@ Bit16u BX_CPU_C::WalkOpcodeTables(const BxOpcodeInfo_t *OpcodeInfoPtr, Bit16u &a #if BX_SUPPORT_AVX else { // VexW64 is ignored in 32-bit mode - if (has_alias == BxAliasVexW || long64_mode()) { + if (has_alias == BxAliasVexW || (fetchModeMask & BX_FETCH_MODE_IS64_MASK) != 0) { alias = vex_w; } } diff --git a/bochs/cpu/fetchdecode.h b/bochs/cpu/fetchdecode.h index 02959028b..6f6c9a9d8 100644 --- a/bochs/cpu/fetchdecode.h +++ b/bochs/cpu/fetchdecode.h @@ -24,6 +24,88 @@ #ifndef BX_COMMON_FETCHDECODE_TABLES_H #define BX_COMMON_FETCHDECODE_TABLES_H +// +// Matadata for decoder... +// + +// If the BxImmediate mask is set, the lowest 4 bits of the attribute +// specify which kinds of immediate data required by instruction. + +#define BxImmediate 0x000f // bits 3..0: any immediate +#define BxImmediate_I1 0x0001 // imm8 = 1 +#define BxImmediate_Ib 0x0002 // 8 bit +#define BxImmediate_Ib_SE 0x0003 // sign extend to operand size +#define BxImmediate_Iw 0x0004 // 16 bit +#define BxImmediate_Id 0x0005 // 32 bit +#define BxImmediate_O 0x0006 // MOV_ALOd, mov_OdAL, mov_eAXOv, mov_OveAX +#if BX_SUPPORT_X86_64 +#define BxImmediate_Iq 0x0007 // 64 bit override +#endif +#define BxImmediate_BrOff8 0x0008 // Relative branch offset byte +#define BxImmediate_BrOff16 BxImmediate_Iw // Relative branch offset word, not encodable in 64-bit mode +#define BxImmediate_BrOff32 BxImmediate_Id // Relative branch offset dword + +#define BxImmediate_Ib4 BxImmediate_Ib // Register encoded in Ib[7:4] +#define BxImmediate_Ib5 BxImmediate_Ib + +// Lookup for opcode and attributes in another opcode tables +// Totally 15 opcode groups supported +#define BxGroupX 0x00f0 // bits 7..4: opcode groups definition +#define BxPrefixSSE66 0x0010 // Group encoding: 0001, SSE_PREFIX_66 only +#define BxPrefixSSEF3 0x0020 // Group encoding: 0010, SSE_PREFIX_F3 only +#define BxPrefixSSEF2 0x0030 // Group encoding: 0011, SSE_PREFIX_F2 only +#define BxPrefixSSE 0x0040 // Group encoding: 0100 +#define BxPrefixSSE2 0x0050 // Group encoding: 0101, do not allow SSE_PREFIX_F2 or SSE_PREFIX_F3 +#define BxPrefixSSE4 0x0060 // Group encoding: 0110 +#define BxPrefixSSEF2F3 0x0070 // Group encoding: 0111, ignore SSE_PREFIX_66 +#define BxGroupN 0x0080 // Group encoding: 1000 +#define BxSplitGroupN 0x0090 // Group encoding: 1001 +#define BxFPEscape 0x00A0 // Group encoding: 1010 +#define BxOSizeGrp 0x00B0 // Group encoding: 1011 +#define BxSplitMod11B 0x00C0 // Group encoding: 1100 +#define BxSplitVexVL 0x00D0 // Group encoding: 1101 + +// The BxImmediate2 mask specifies kind of second immediate data +// required by instruction. +#define BxImmediate2 0x0300 // bits 8.9: any immediate +#define BxImmediate_Ib2 0x0100 +#define BxImmediate_Iw2 0x0200 +#define BxImmediate_Id2 0x0300 + +#define BxVexL0 0x0100 // bit 8 (aliased with imm2) +#define BxVexL1 0x0200 // bit 9 (aliased with imm2) +#define BxVexW0 0x0400 // bit 10 +#define BxVexW1 0x0800 // bit 11 + +#define BxAlias 0x3000 // bits 12..13 +#define BxAliasSSE 0x1000 // Encoding 01: form final opcode using SSE prefix and current opcode +#define BxAliasVexW 0x2000 // Encoding 10: form final opcode using VEX.W and current opcode +#define BxAliasVexW64 0x3000 // Encoding 11: form final opcode using VEX.W and current opcode in 64-bit mode only + +#define BxLockable 0x4000 // bit 14 + +#define BxGroup1 BxGroupN +#define BxGroup1A BxGroupN +#define BxGroup2 BxGroupN +#define BxGroup3 BxGroupN +#define BxGroup4 BxGroupN +#define BxGroup5 BxGroupN +#define BxGroup6 BxGroupN +#define BxGroup7 BxFPEscape +#define BxGroup8 BxGroupN +#define BxGroup9 BxSplitGroupN + +#define BxGroup11 BxGroupN +#define BxGroup12 BxGroupN +#define BxGroup13 BxGroupN +#define BxGroup14 BxGroupN +#define BxGroup15 BxSplitGroupN +#define BxGroup16 BxGroupN +#define BxGroup17 BxGroupN +#define BxGroup17A BxGroupN + +#define BxGroupFP BxSplitGroupN + enum { BX_ILLEGAL_OPCODE, BX_ILLEGAL_LOCK_PREFIX, diff --git a/bochs/cpu/fetchdecode64.cc b/bochs/cpu/fetchdecode64.cc index 48c6dbd12..75086556f 100644 --- a/bochs/cpu/fetchdecode64.cc +++ b/bochs/cpu/fetchdecode64.cc @@ -133,6 +133,8 @@ static unsigned sreg_mod1or2_base32[16] = { // table of all Bochs opcodes extern struct bxIAOpcodeTable BxOpcodesTable[]; +extern Bit16u WalkOpcodeTables(const BxOpcodeInfo_t *OpcodeInfoPtr, Bit16u &attr, Bit32u fetchModeMask, unsigned modrm, unsigned sse_prefix, unsigned osize, unsigned vex_vl, bx_bool vex_w); + // 512 entries for 16bit operand size // 512 entries for 32bit operand size // 512 entries for 64bit operand size @@ -2125,7 +2127,7 @@ modrm_done: } #endif - ia_opcode = WalkOpcodeTables(OpcodeInfoPtr, attr, b2, sse_prefix, offset >> 9, i->getVL(), vex_w); + ia_opcode = WalkOpcodeTables(OpcodeInfoPtr, attr, fetchModeMask, b2, sse_prefix, offset >> 9, i->getVL(), vex_w); } else { // Opcode does not require a MODRM byte.