reduce CPU dependencies from fetchdecode module

This commit is contained in:
Stanislav Shwartsman 2017-11-25 20:20:34 +00:00
parent 778c0c6fed
commit 596b3b6eb8
8 changed files with 287 additions and 336 deletions

View File

@ -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;
// <TAG-TYPE-EXECUTEPTR-START>
#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
// <TAG-TYPE-EXECUTEPTR-END>

View File

@ -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

View File

@ -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");

View File

@ -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] =

View File

@ -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);
}

View File

@ -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;
// <TAG-TYPE-EXECUTEPTR-START>
#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
// <TAG-TYPE-EXECUTEPTR-END>
// <TAG-CLASS-INSTRUCTION-START>
class bxInstruction_c {
public:

View File

@ -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;

View File

@ -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