diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 2d14542f4..d7e2122ab 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -26,13 +26,6 @@ #include "decoder/decoder.h" -#define BX_16BIT_REG_IP (BX_GENERAL_REGISTERS) -#define BX_32BIT_REG_EIP (BX_GENERAL_REGISTERS) -#define BX_64BIT_REG_RIP (BX_GENERAL_REGISTERS) - -#define BX_TMP_REGISTER (BX_GENERAL_REGISTERS+1) -#define BX_NIL_REGISTER (BX_GENERAL_REGISTERS+2) - #if defined(NEED_CPU_REG_SHORTCUTS) /* WARNING: @@ -475,14 +468,12 @@ class BX_CPU_C; class BX_MEM_C; class bxInstruction_c; -typedef void BX_INSF_TYPE; - // #if BX_USE_CPU_SMF -typedef BX_INSF_TYPE (BX_CPP_AttrRegparmN(1) *BxExecutePtr_tR)(bxInstruction_c *); +//typedef BX_INSF_TYPE (BX_CPP_AttrRegparmN(1) *BxExecutePtr_tR)(bxInstruction_c *); typedef void (BX_CPP_AttrRegparmN(1) *BxRepIterationPtr_tR)(bxInstruction_c *); #else -typedef BX_INSF_TYPE (BX_CPU_C::*BxExecutePtr_tR)(bxInstruction_c *) BX_CPP_AttrRegparmN(1); +//typedef BX_INSF_TYPE (BX_CPU_C::*BxExecutePtr_tR)(bxInstruction_c *) BX_CPP_AttrRegparmN(1); typedef void (BX_CPU_C::*BxRepIterationPtr_tR)(bxInstruction_c *) BX_CPP_AttrRegparmN(1); #endif // diff --git a/bochs/cpu/decoder/decoder.h b/bochs/cpu/decoder/decoder.h index dafc3d33c..2a0769ee5 100644 --- a/bochs/cpu/decoder/decoder.h +++ b/bochs/cpu/decoder/decoder.h @@ -238,6 +238,13 @@ enum BxRegs64 { # define BX_GENERAL_REGISTERS 8 #endif +const unsigned BX_16BIT_REG_IP = (BX_GENERAL_REGISTERS), + BX_32BIT_REG_EIP = (BX_GENERAL_REGISTERS), + BX_64BIT_REG_RIP = (BX_GENERAL_REGISTERS); + +const unsigned BX_TMP_REGISTER = (BX_GENERAL_REGISTERS+1); +const unsigned BX_NIL_REGISTER = (BX_GENERAL_REGISTERS+2); + enum OpmaskRegs { BX_REG_OPMASK_K0, BX_REG_OPMASK_K1, @@ -249,5 +256,35 @@ enum OpmaskRegs { BX_REG_OPMASK_K7 }; +// AVX Registers +enum bx_avx_vector_length { + BX_NO_VL, + BX_VL128 = 1, + BX_VL256 = 2, + BX_VL512 = 4, +}; + +#if BX_SUPPORT_EVEX +# define BX_VLMAX BX_VL512 +#else +# if BX_SUPPORT_AVX +# define BX_VLMAX BX_VL256 +# else +# define BX_VLMAX BX_VL128 +# endif +#endif + +#if BX_SUPPORT_EVEX +# define BX_XMM_REGISTERS 32 +#else +# if BX_SUPPORT_X86_64 +# define BX_XMM_REGISTERS 16 +# else +# define BX_XMM_REGISTERS 8 +# endif +#endif + +const unsigned BX_VECTOR_TMP_REGISTER = (BX_XMM_REGISTERS); + #endif // BX_X86_DECODER_H diff --git a/bochs/cpu/decoder/disasm.cc b/bochs/cpu/decoder/disasm.cc index 000d8be94..16fa102ea 100644 --- a/bochs/cpu/decoder/disasm.cc +++ b/bochs/cpu/decoder/disasm.cc @@ -26,9 +26,9 @@ #include "fetchdecode.h" -extern int fetchDecode32(const Bit8u *fetchPtr, Bit32u fetchModeMask, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage); +extern int fetchDecode32(const Bit8u *fetchPtr, bx_bool is_32, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage); #if BX_SUPPORT_X86_64 -extern int fetchDecode64(const Bit8u *fetchPtr, Bit32u fetchModeMask, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage); +extern int fetchDecode64(const Bit8u *fetchPtr, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage); #endif // table of all Bochs opcodes @@ -603,22 +603,14 @@ char* disasm(char *disbufptr, const bxInstruction_c *i, bx_address cs_base, bx_a char* disasm(const Bit8u *opcode, bool is_32, bool is_64, char *disbufptr, bxInstruction_c *i, bx_address cs_base, bx_address rip) { - Bit32u fetchModeMask = BX_FETCH_MODE_SSE_OK | - BX_FETCH_MODE_AVX_OK | - BX_FETCH_MODE_OPMASK_OK | - BX_FETCH_MODE_EVEX_OK; - - if (is_64) fetchModeMask |= BX_FETCH_MODE_IS64_MASK; - else if (is_32) fetchModeMask |= BX_FETCH_MODE_IS32_MASK; - int ret; #if BX_SUPPORT_X86_64 if (is_64) - ret = fetchDecode64(opcode, fetchModeMask, BX_CPU(0)->is_cpu_extension_supported(BX_ISA_ALT_MOV_CR8), i, 16); + ret = fetchDecode64(opcode, BX_CPU(0)->is_cpu_extension_supported(BX_ISA_ALT_MOV_CR8), i, 16); else #endif - ret = fetchDecode32(opcode, fetchModeMask, BX_CPU(0)->is_cpu_extension_supported(BX_ISA_ALT_MOV_CR8), i, 16); + ret = fetchDecode32(opcode, is_32, BX_CPU(0)->is_cpu_extension_supported(BX_ISA_ALT_MOV_CR8), i, 16); if (ret < 0) sprintf(disbufptr, "decode failed"); diff --git a/bochs/cpu/decoder/fetchdecode32.cc b/bochs/cpu/decoder/fetchdecode32.cc index e548600e3..e2f9c4497 100644 --- a/bochs/cpu/decoder/fetchdecode32.cc +++ b/bochs/cpu/decoder/fetchdecode32.cc @@ -23,6 +23,9 @@ #include "bochs.h" #include "../cpu.h" +#include "decoder.h" +#include "instr.h" + #define LOG_THIS genlog-> /////////////////////////// @@ -67,6 +70,13 @@ struct BxOpcodeDecodeDescriptor32 { const BxOpcodeInfo_t *opcode_table; }; +// table of all Bochs opcodes +bxIAOpcodeTable BxOpcodesTable[] = { +#define bx_define_opcode(a, b, c, d, s1, s2, s3, s4, e) { b, c, { s1, s2, s3, s4 }, e }, +#include "ia_opcodes.def" +}; +#undef bx_define_opcode + // Some info on the opcodes at {0F A6} and {0F A7} // // On 386 steps A0-B0: @@ -1193,13 +1203,6 @@ static unsigned sreg_mod1or2_base32[8] = { BX_SEG_REG_DS }; -// table of all Bochs opcodes -bxIAOpcodeTable BxOpcodesTable[] = { -#define bx_define_opcode(a, b, c, d, s1, s2, s3, s4, e) { b, c, { s1, s2, s3, s4 }, e }, -#include "ia_opcodes.def" -}; -#undef bx_define_opcode - extern const Bit8u *decodeModrm32(const Bit8u *iptr, unsigned &remain, bxInstruction_c *i, unsigned mod, unsigned nnn, unsigned rm); extern const Bit8u *parseModrm32(const Bit8u *iptr, unsigned &remain, bxInstruction_c *i, struct bx_modrm *modrm); extern int decodeImmediate32(const Bit8u *iptr, unsigned &remain, bxInstruction_c *i, unsigned imm_mode, unsigned imm_mode2); @@ -2494,204 +2497,6 @@ int decoder_ud32(const Bit8u *iptr, unsigned &remain, bxInstruction_c *i, unsign return BX_IA_ERROR; } -int fetchDecode32(const Bit8u *iptr, Bit32u fetchModeMask, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage) -{ - if (remainingInPage > 15) remainingInPage = 15; - - unsigned remain = remainingInPage; // remain must be at least 1 - unsigned b1; - int ia_opcode = BX_IA_ERROR; - unsigned seg_override = BX_SEG_REG_NULL; - bx_bool is_32, os_32, lock = 0; - unsigned sse_prefix = SSE_PREFIX_NONE; - - os_32 = is_32 = fetchModeMask & BX_FETCH_MODE_IS32_MASK; - - i->init(/*os32*/ is_32, /*as32*/ is_32, - /*os64*/ 0, /*as64*/ 0); - -fetch_b1: - b1 = *iptr++; - remain--; - - switch (b1) { - case 0x0f: // 2-byte escape - if (remain != 0) { - remain--; - b1 = 0x100 | *iptr++; - break; - } - return(-1); - case 0x66: // OpSize - os_32 = !is_32; - if(!sse_prefix) sse_prefix = SSE_PREFIX_66; - i->setOs32B(os_32); - if (remain != 0) { - goto fetch_b1; - } - return(-1); - case 0x67: // AddrSize - i->setAs32B(!is_32); - if (remain != 0) { - goto fetch_b1; - } - return(-1); - case 0xf2: // REPNE/REPNZ - case 0xf3: // REP/REPE/REPZ - sse_prefix = (b1 & 3) ^ 1; - i->setLockRepUsed(b1 & 3); - if (remain != 0) { - goto fetch_b1; - } - return(-1); - case 0x26: // ES: - case 0x2e: // CS: - case 0x36: // SS: - case 0x3e: // DS: - seg_override = (b1 >> 3) & 3; - if (remain != 0) { - goto fetch_b1; - } - return(-1); - case 0x64: // FS: - case 0x65: // GS: - seg_override = (b1 & 0xf); - if (remain != 0) { - goto fetch_b1; - } - return(-1); - case 0xf0: // LOCK: - lock = 1; - if (remain != 0) { - goto fetch_b1; - } - return(-1); - default: - break; - } - -#if BX_CPU_LEVEL >= 6 - if (b1 == 0x138 || b1 == 0x13a) { - if (remain == 0) - return(-1); - if (b1 == 0x138) b1 = 0x200 | *iptr++; - else b1 = 0x300 | *iptr++; - remain--; - } -#endif - - i->setSeg(BX_SEG_REG_DS); // default segment is DS: - - i->modRMForm.Id = 0; - - BxOpcodeDecodeDescriptor32 *decode_descriptor = &decode32_descriptor[b1]; - ia_opcode = decode_descriptor->decode_method(iptr, remain, i, b1, sse_prefix, decode_descriptor->opcode_table); - if (ia_opcode < 0) - return(-1); - - i->setILen(remainingInPage - remain); - i->setIaOpcode(ia_opcode); - - // assign memory segment override - if (! BX_NULL_SEG_REG(seg_override)) - i->setSeg(seg_override); - - if (! i->modC0()) { - i->execute1 = BxOpcodesTable[ia_opcode].execute1; - i->handlers.execute2 = BxOpcodesTable[ia_opcode].execute2; - - if (ia_opcode == BX_IA_MOV_Op32_GdEd) { - if (i->seg() == BX_SEG_REG_SS) - i->execute1 = &BX_CPU_C::MOV32S_GdEdM; - } - if (ia_opcode == BX_IA_MOV_Op32_EdGd) { - if (i->seg() == BX_SEG_REG_SS) - i->execute1 = &BX_CPU_C::MOV32S_EdGdM; - } - } - else { - i->execute1 = BxOpcodesTable[ia_opcode].execute2; - i->handlers.execute2 = NULL; - } - - BX_ASSERT(i->execute1); - - Bit32u op_flags = BxOpcodesTable[ia_opcode].opflags; - - if (lock) { - i->setLock(); - // lock prefix not allowed or destination operand is not memory - if (i->modC0() || !(op_flags & BX_LOCKABLE)) { -#if BX_CPU_LEVEL >= 6 - if (handle_lock_cr0 && (ia_opcode == BX_IA_MOV_CR0Rd || ia_opcode == BX_IA_MOV_RdCR0)) { - if (ia_opcode == BX_IA_MOV_CR0Rd) - i->setSrcReg(0, 8); // extend CR0 -> CR8 - if (ia_opcode == BX_IA_MOV_RdCR0) - i->setSrcReg(1, 8); // extend CR0 -> CR8 - } - else -#endif - { - // replace execution function with undefined-opcode - i->execute1 = &BX_CPU_C::BxError; - } - } - } - - -#if BX_SUPPORT_EVEX - if ((op_flags & BX_PREPARE_EVEX) != 0 && i->getEvexb()) { - if (! i->modC0()) { - if ((op_flags & BX_PREPARE_EVEX_NO_BROADCAST) == BX_PREPARE_EVEX_NO_BROADCAST) { -// BX_DEBUG(("%s: broadcast is not supported for this instruction", i->getIaOpcodeNameShort())); - i->execute1 = &BX_CPU_C::BxError; - } - } - else { - if ((op_flags & BX_PREPARE_EVEX_NO_SAE) == BX_PREPARE_EVEX_NO_SAE) { -// BX_DEBUG(("%s: EVEX.b in reg form is not allowed for instructions which cannot cause floating point exception", i->getIaOpcodeNameShort())); - i->execute1 = &BX_CPU_C::BxError; - } - } - } -#endif -#if BX_CPU_LEVEL >= 6 - if (! (fetchModeMask & BX_FETCH_MODE_SSE_OK)) { - if (op_flags & BX_PREPARE_SSE) { - if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoSSE; - return(1); - } - } -#if BX_SUPPORT_AVX - if (! (fetchModeMask & BX_FETCH_MODE_AVX_OK)) { - if (op_flags & BX_PREPARE_AVX) { - if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoAVX; - return(1); - } - } -#if BX_SUPPORT_EVEX - if (! (fetchModeMask & BX_FETCH_MODE_OPMASK_OK)) { - if (op_flags & BX_PREPARE_OPMASK) { - if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoOpMask; - return(1); - } - } - if (! (fetchModeMask & BX_FETCH_MODE_EVEX_OK)) { - if (op_flags & BX_PREPARE_EVEX) { - if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoEVEX; - return(1); - } - } -#endif -#endif -#endif - - if ((op_flags & BX_TRACE_END) != 0 || i->execute1 == &BX_CPU_C::BxError) - return(1); - - return(0); -} - Bit16u WalkOpcodeTables(const BxExtOpcodeInfo_t *OpcodeInfoPtr, Bit16u &attr, bx_bool is_64, unsigned modrm, unsigned sse_prefix, unsigned osize, unsigned vex_vl, bx_bool vex_w) { // Parse mod-nnn-rm and related bytes @@ -2805,6 +2610,210 @@ Bit16u WalkOpcodeTables(const BxExtOpcodeInfo_t *OpcodeInfoPtr, Bit16u &attr, bx return (ia_opcode); } +int fetchDecode32(const Bit8u *iptr, bx_bool is_32, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage) +{ + if (remainingInPage > 15) remainingInPage = 15; + + unsigned remain = remainingInPage; // remain must be at least 1 + unsigned b1; + int ia_opcode = BX_IA_ERROR; + unsigned seg_override = BX_SEG_REG_NULL; + bx_bool os_32 = is_32, lock = 0; + unsigned sse_prefix = SSE_PREFIX_NONE; + + i->init(/*os32*/ is_32, /*as32*/ is_32, + /*os64*/ 0, /*as64*/ 0); + +fetch_b1: + b1 = *iptr++; + remain--; + + switch (b1) { + case 0x0f: // 2-byte escape + if (remain != 0) { + remain--; + b1 = 0x100 | *iptr++; + break; + } + return(-1); + case 0x66: // OpSize + os_32 = !is_32; + if(!sse_prefix) sse_prefix = SSE_PREFIX_66; + i->setOs32B(os_32); + if (remain != 0) { + goto fetch_b1; + } + return(-1); + case 0x67: // AddrSize + i->setAs32B(!is_32); + if (remain != 0) { + goto fetch_b1; + } + return(-1); + case 0xf2: // REPNE/REPNZ + case 0xf3: // REP/REPE/REPZ + sse_prefix = (b1 & 3) ^ 1; + i->setLockRepUsed(b1 & 3); + if (remain != 0) { + goto fetch_b1; + } + return(-1); + case 0x26: // ES: + case 0x2e: // CS: + case 0x36: // SS: + case 0x3e: // DS: + seg_override = (b1 >> 3) & 3; + if (remain != 0) { + goto fetch_b1; + } + return(-1); + case 0x64: // FS: + case 0x65: // GS: + seg_override = (b1 & 0xf); + if (remain != 0) { + goto fetch_b1; + } + return(-1); + case 0xf0: // LOCK: + lock = 1; + if (remain != 0) { + goto fetch_b1; + } + return(-1); + default: + break; + } + +#if BX_CPU_LEVEL >= 6 + if (b1 == 0x138 || b1 == 0x13a) { + if (remain == 0) + return(-1); + if (b1 == 0x138) b1 = 0x200 | *iptr++; + else b1 = 0x300 | *iptr++; + remain--; + } +#endif + + i->setSeg(BX_SEG_REG_DS); // default segment is DS: + + i->modRMForm.Id = 0; + + BxOpcodeDecodeDescriptor32 *decode_descriptor = &decode32_descriptor[b1]; + ia_opcode = decode_descriptor->decode_method(iptr, remain, i, b1, sse_prefix, decode_descriptor->opcode_table); + if (ia_opcode < 0) + return(-1); + + i->setILen(remainingInPage - remain); + i->setIaOpcode(ia_opcode); + + // assign memory segment override + if (! BX_NULL_SEG_REG(seg_override)) + i->setSeg(seg_override); + + Bit32u op_flags = BxOpcodesTable[ia_opcode].opflags; + + if (lock) { + i->setLock(); + // lock prefix not allowed or destination operand is not memory + if (i->modC0() || !(op_flags & BX_LOCKABLE)) { +#if BX_CPU_LEVEL >= 6 + if (handle_lock_cr0 && (ia_opcode == BX_IA_MOV_CR0Rd || ia_opcode == BX_IA_MOV_RdCR0)) { + if (ia_opcode == BX_IA_MOV_CR0Rd) + i->setSrcReg(0, 8); // extend CR0 -> CR8 + if (ia_opcode == BX_IA_MOV_RdCR0) + i->setSrcReg(1, 8); // extend CR0 -> CR8 + } + else +#endif + { + // replace execution function with undefined-opcode + i->setIaOpcode(BX_IA_ERROR); + } + } + } + + return(0); +} + +int assignHandler(bxInstruction_c *i, Bit32u fetchModeMask) +{ + unsigned ia_opcode = i->getIaOpcode(); + + if (! i->modC0()) { + i->execute1 = BxOpcodesTable[ia_opcode].execute1; + i->handlers.execute2 = BxOpcodesTable[ia_opcode].execute2; + + if (ia_opcode == BX_IA_MOV_Op32_GdEd) { + if (i->seg() == BX_SEG_REG_SS) + i->execute1 = &BX_CPU_C::MOV32S_GdEdM; + } + if (ia_opcode == BX_IA_MOV_Op32_EdGd) { + if (i->seg() == BX_SEG_REG_SS) + i->execute1 = &BX_CPU_C::MOV32S_EdGdM; + } + } + else { + i->execute1 = BxOpcodesTable[ia_opcode].execute2; + i->handlers.execute2 = NULL; + } + + BX_ASSERT(i->execute1); + + Bit32u op_flags = BxOpcodesTable[ia_opcode].opflags; + +#if BX_SUPPORT_EVEX + if ((op_flags & BX_PREPARE_EVEX) != 0 && i->getEvexb()) { + if (! i->modC0()) { + if ((op_flags & BX_PREPARE_EVEX_NO_BROADCAST) == BX_PREPARE_EVEX_NO_BROADCAST) { +// BX_DEBUG(("%s: broadcast is not supported for this instruction", i->getIaOpcodeNameShort())); + i->execute1 = &BX_CPU_C::BxError; + } + } + else { + if ((op_flags & BX_PREPARE_EVEX_NO_SAE) == BX_PREPARE_EVEX_NO_SAE) { +// BX_DEBUG(("%s: EVEX.b in reg form is not allowed for instructions which cannot cause floating point exception", i->getIaOpcodeNameShort())); + i->execute1 = &BX_CPU_C::BxError; + } + } + } +#endif +#if BX_CPU_LEVEL >= 6 + if (! (fetchModeMask & BX_FETCH_MODE_SSE_OK)) { + if (op_flags & BX_PREPARE_SSE) { + if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoSSE; + return(1); + } + } +#if BX_SUPPORT_AVX + if (! (fetchModeMask & BX_FETCH_MODE_AVX_OK)) { + if (op_flags & BX_PREPARE_AVX) { + if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoAVX; + return(1); + } + } +#if BX_SUPPORT_EVEX + if (! (fetchModeMask & BX_FETCH_MODE_OPMASK_OK)) { + if (op_flags & BX_PREPARE_OPMASK) { + if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoOpMask; + return(1); + } + } + if (! (fetchModeMask & BX_FETCH_MODE_EVEX_OK)) { + if (op_flags & BX_PREPARE_EVEX) { + if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoEVEX; + return(1); + } + } +#endif +#endif +#endif + + if ((op_flags & BX_TRACE_END) != 0 || i->execute1 == &BX_CPU_C::BxError) + return(1); + + return(0); +} + const char *get_bx_opcode_name(Bit16u ia_opcode) { static const char* BxOpcodeNamesTable[BX_IA_LAST] = diff --git a/bochs/cpu/decoder/fetchdecode64.cc b/bochs/cpu/decoder/fetchdecode64.cc index 779355630..4887c3e7d 100644 --- a/bochs/cpu/decoder/fetchdecode64.cc +++ b/bochs/cpu/decoder/fetchdecode64.cc @@ -21,7 +21,9 @@ ///////////////////////////////////////////////////////////////////////// #include "bochs.h" -#include "../cpu.h" + +#include "instr.h" +#include "decoder.h" #define LOG_THIS genlog-> @@ -2319,7 +2321,7 @@ int decodeImmediate64(const Bit8u *iptr, unsigned &remain, bxInstruction_c *i, u return 0; } -int fetchDecode64(const Bit8u *iptr, Bit32u fetchModeMask, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage) +int fetchDecode64(const Bit8u *iptr, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage) { if (remainingInPage > 15) remainingInPage = 15; @@ -2455,26 +2457,6 @@ fetch_b1: if (! BX_NULL_SEG_REG(seg_override)) i->setSeg(seg_override); - if (! i->modC0()) { - i->execute1 = BxOpcodesTable[ia_opcode].execute1; - i->handlers.execute2 = BxOpcodesTable[ia_opcode].execute2; - - if (ia_opcode == BX_IA_MOV_GqEq) { - if (i->seg() == BX_SEG_REG_SS) - i->execute1 = &BX_CPU_C::MOV64S_GqEqM; - } - if (ia_opcode == BX_IA_MOV_EqGq) { - if (i->seg() == BX_SEG_REG_SS) - i->execute1 = &BX_CPU_C::MOV64S_EqGqM; - } - } - else { - i->execute1 = BxOpcodesTable[ia_opcode].execute2; - i->handlers.execute2 = NULL; - } - - BX_ASSERT(i->execute1); - Bit32u op_flags = BxOpcodesTable[ia_opcode].opflags; if (lock) { @@ -2489,59 +2471,11 @@ fetch_b1: } else { // replace execution function with undefined-opcode - i->execute1 = &BX_CPU_C::BxError; + i->setIaOpcode(BX_IA_ERROR); } } } -#if BX_SUPPORT_EVEX - if ((op_flags & BX_PREPARE_EVEX) != 0 && i->getEvexb()) { - if (! i->modC0()) { - if ((op_flags & BX_PREPARE_EVEX_NO_BROADCAST) == BX_PREPARE_EVEX_NO_BROADCAST) { - BX_DEBUG(("%s: broadcast is not supported for this instruction", i->getIaOpcodeNameShort())); - i->execute1 = &BX_CPU_C::BxError; - } - } - else { - if ((op_flags & BX_PREPARE_EVEX_NO_SAE) == BX_PREPARE_EVEX_NO_SAE) { - BX_DEBUG(("%s: EVEX.b in reg form is not allowed for instructions which cannot cause floating point exception", i->getIaOpcodeNameShort())); - i->execute1 = &BX_CPU_C::BxError; - } - } - } -#endif - if (! (fetchModeMask & BX_FETCH_MODE_SSE_OK)) { - if (op_flags & BX_PREPARE_SSE) { - if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoSSE; - return(1); - } - } -#if BX_SUPPORT_AVX - if (! (fetchModeMask & BX_FETCH_MODE_AVX_OK)) { - if (op_flags & BX_PREPARE_AVX) { - if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoAVX; - return(1); - } - } -#if BX_SUPPORT_EVEX - if (! (fetchModeMask & BX_FETCH_MODE_OPMASK_OK)) { - if (op_flags & BX_PREPARE_OPMASK) { - if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoOpMask; - return(1); - } - } - if (! (fetchModeMask & BX_FETCH_MODE_EVEX_OK)) { - if (op_flags & BX_PREPARE_EVEX) { - if (i->execute1 != &BX_CPU_C::BxError) i->execute1 = &BX_CPU_C::BxNoEVEX; - return(1); - } - } -#endif -#endif - - if ((op_flags & BX_TRACE_END) != 0 || i->execute1 == &BX_CPU_C::BxError) - return(1); - return(0); } diff --git a/bochs/cpu/decoder/instr.h b/bochs/cpu/decoder/instr.h index ee7871fd2..1a2d843e2 100644 --- a/bochs/cpu/decoder/instr.h +++ b/bochs/cpu/decoder/instr.h @@ -28,6 +28,19 @@ extern bx_address bx_asize_mask[]; const char *get_bx_opcode_name(Bit16u ia_opcode); +class BX_CPU_C; +class bxInstruction_c; + +typedef void BX_INSF_TYPE; + +// +#if BX_USE_CPU_SMF +typedef BX_INSF_TYPE (BX_CPP_AttrRegparmN(1) *BxExecutePtr_tR)(bxInstruction_c *); +#else +typedef BX_INSF_TYPE (BX_CPU_C::*BxExecutePtr_tR)(bxInstruction_c *) BX_CPP_AttrRegparmN(1); +#endif +// + // class bxInstruction_c { public: diff --git a/bochs/cpu/icache.cc b/bochs/cpu/icache.cc index 24f797794..9adcacf9c 100644 --- a/bochs/cpu/icache.cc +++ b/bochs/cpu/icache.cc @@ -33,10 +33,11 @@ bxPageWriteStampTable pageWriteStampTable; -extern int fetchDecode32(const Bit8u *fetchPtr, Bit32u fetchModeMask, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage); +extern int fetchDecode32(const Bit8u *fetchPtr, bx_bool is_32, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage); #if BX_SUPPORT_X86_64 -extern int fetchDecode64(const Bit8u *fetchPtr, Bit32u fetchModeMask, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage); +extern int fetchDecode64(const Bit8u *fetchPtr, bx_bool handle_lock_cr0, bxInstruction_c *i, unsigned remainingInPage); #endif +extern int assignHandler(bxInstruction_c *i, Bit32u fetchModeMask); void flushICaches(void) { @@ -110,10 +111,10 @@ bxICacheEntry_c* BX_CPU_C::serveICacheMiss(Bit32u eipBiased, bx_phy_address pAdd { #if BX_SUPPORT_X86_64 if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) - ret = fetchDecode64(fetchPtr, BX_CPU_THIS_PTR fetchModeMask, BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_ALT_MOV_CR8), i, remainingInPage); + ret = fetchDecode64(fetchPtr, BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_ALT_MOV_CR8), i, remainingInPage); else #endif - ret = fetchDecode32(fetchPtr, BX_CPU_THIS_PTR fetchModeMask, BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_ALT_MOV_CR8), i, remainingInPage); + ret = fetchDecode32(fetchPtr, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_ALT_MOV_CR8), i, remainingInPage); if (ret < 0) { // Fetching instruction on segment/page boundary @@ -144,6 +145,8 @@ bxICacheEntry_c* BX_CPU_C::serveICacheMiss(Bit32u eipBiased, bx_phy_address pAdd return entry; } + ret = assignHandler(i, BX_CPU_THIS_PTR fetchModeMask); + // add instruction to the trace unsigned iLen = i->ilen(); entry->tlen++; @@ -262,16 +265,18 @@ void BX_CPU_C::boundaryFetch(const Bit8u *fetchPtr, unsigned remainingInPage, bx #if BX_SUPPORT_X86_64 if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) - ret = fetchDecode64(fetchBuffer, BX_CPU_THIS_PTR fetchModeMask, BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_ALT_MOV_CR8), i, remainingInPage+fetchBufferLimit); + ret = fetchDecode64(fetchBuffer, BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_ALT_MOV_CR8), i, remainingInPage+fetchBufferLimit); else #endif - ret = fetchDecode32(fetchBuffer, BX_CPU_THIS_PTR fetchModeMask, BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_ALT_MOV_CR8), i, remainingInPage+fetchBufferLimit); + ret = fetchDecode32(fetchBuffer, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, BX_CPUID_SUPPORT_ISA_EXTENSION(BX_ISA_ALT_MOV_CR8), i, remainingInPage+fetchBufferLimit); if (ret < 0) { BX_INFO(("boundaryFetch #GP(0): failed to complete instruction decoding")); exception(BX_GP_EXCEPTION, 0); } + ret = assignHandler(i, BX_CPU_THIS_PTR fetchModeMask); + // Restore EIP since we fudged it to start at the 2nd page boundary. RIP = BX_CPU_THIS_PTR prev_rip; diff --git a/bochs/cpu/xmm.h b/bochs/cpu/xmm.h index e665d64d7..d019b2def 100644 --- a/bochs/cpu/xmm.h +++ b/bochs/cpu/xmm.h @@ -2,7 +2,7 @@ // $Id$ ///////////////////////////////////////////////////////////////////////// // -// Copyright (c) 2003-2014 Stanislav Shwartsman +// Copyright (c) 2003-2017 Stanislav Shwartsman // Written by Stanislav Shwartsman [sshwarts at sourceforge net] // // This library is free software; you can redistribute it and/or @@ -65,36 +65,6 @@ union bx_xmm_reg_t { /* AVX REGISTER */ -enum bx_avx_vector_length { - BX_NO_VL, - BX_VL128 = 1, - BX_VL256 = 2, - BX_VL512 = 4, - BX_VL1024 = 8 // defined in EVEX but currently #UD in all implementations -}; - -#if BX_SUPPORT_EVEX -# define BX_VLMAX BX_VL512 -#else -# if BX_SUPPORT_AVX -# define BX_VLMAX BX_VL256 -# else -# define BX_VLMAX BX_VL128 -# endif -#endif - -#if BX_SUPPORT_EVEX -# define BX_XMM_REGISTERS 32 -#else -# if BX_SUPPORT_X86_64 -# define BX_XMM_REGISTERS 16 -# else -# define BX_XMM_REGISTERS 8 -# endif -#endif - -#define BX_VECTOR_TMP_REGISTER (BX_XMM_REGISTERS) - #if BX_SUPPORT_AVX typedef