x86+bochs: add IDs and accessors for FPU and SSE registers
Change-Id: I33146929255337f679ff80152ed4d83106621ffb
This commit is contained in:
@ -21,7 +21,8 @@ namespace fail {
|
|||||||
enum RegisterType {
|
enum RegisterType {
|
||||||
RT_NONE, //!< no classification
|
RT_NONE, //!< no classification
|
||||||
RT_GP, //!< general purpose
|
RT_GP, //!< general purpose
|
||||||
RT_FP, //!< floating point register
|
RT_FPU, //!< FPU register
|
||||||
|
RT_VECTOR, //!< vector-unit register
|
||||||
RT_IP, //!< program counter / instruction pointer
|
RT_IP, //!< program counter / instruction pointer
|
||||||
RT_ST, //!< status register
|
RT_ST, //!< status register
|
||||||
RT_CONTROL, //!< control registers
|
RT_CONTROL, //!< control registers
|
||||||
|
|||||||
@ -41,6 +41,75 @@ regdata_t BochsCPU::getRegisterContent(const Register* reg) const
|
|||||||
case RID_SS:
|
case RID_SS:
|
||||||
// untested
|
// untested
|
||||||
return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_SS].selector.value);
|
return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_SS].selector.value);
|
||||||
|
|
||||||
|
// FPU
|
||||||
|
case RID_FSW:
|
||||||
|
return BX_CPU(m_Id)->the_i387.swd;
|
||||||
|
case RID_FCW:
|
||||||
|
return BX_CPU(m_Id)->the_i387.cwd;
|
||||||
|
case RID_FTW:
|
||||||
|
return BX_CPU(m_Id)->the_i387.twd;
|
||||||
|
case RID_FPR0_LO:
|
||||||
|
case RID_FPR1_LO:
|
||||||
|
case RID_FPR2_LO:
|
||||||
|
case RID_FPR3_LO:
|
||||||
|
case RID_FPR4_LO:
|
||||||
|
case RID_FPR5_LO:
|
||||||
|
case RID_FPR6_LO:
|
||||||
|
case RID_FPR7_LO:
|
||||||
|
return BX_CPU(m_Id)->the_i387.st_space[(reg->getId() - RID_FPR0_LO) / 2].fraction;
|
||||||
|
case RID_FPR0_HI:
|
||||||
|
case RID_FPR1_HI:
|
||||||
|
case RID_FPR2_HI:
|
||||||
|
case RID_FPR3_HI:
|
||||||
|
case RID_FPR4_HI:
|
||||||
|
case RID_FPR5_HI:
|
||||||
|
case RID_FPR6_HI:
|
||||||
|
case RID_FPR7_HI:
|
||||||
|
return BX_CPU(m_Id)->the_i387.st_space[(reg->getId() - RID_FPR0_HI) / 2].exp;
|
||||||
|
|
||||||
|
// vector units
|
||||||
|
case RID_XMM0_LO:
|
||||||
|
case RID_XMM1_LO:
|
||||||
|
case RID_XMM2_LO:
|
||||||
|
case RID_XMM3_LO:
|
||||||
|
case RID_XMM4_LO:
|
||||||
|
case RID_XMM5_LO:
|
||||||
|
case RID_XMM6_LO:
|
||||||
|
case RID_XMM7_LO:
|
||||||
|
#ifdef SIM_SUPPORT_64
|
||||||
|
case RID_XMM8_LO:
|
||||||
|
case RID_XMM9_LO:
|
||||||
|
case RID_XMM10_LO:
|
||||||
|
case RID_XMM11_LO:
|
||||||
|
case RID_XMM12_LO:
|
||||||
|
case RID_XMM13_LO:
|
||||||
|
case RID_XMM14_LO:
|
||||||
|
case RID_XMM15_LO:
|
||||||
|
#endif
|
||||||
|
return BX_CPU(m_Id)->xmm[(reg->getId() - RID_XMM0_LO) / 2].xmm_s64[0];
|
||||||
|
case RID_XMM0_HI:
|
||||||
|
case RID_XMM1_HI:
|
||||||
|
case RID_XMM2_HI:
|
||||||
|
case RID_XMM3_HI:
|
||||||
|
case RID_XMM4_HI:
|
||||||
|
case RID_XMM5_HI:
|
||||||
|
case RID_XMM6_HI:
|
||||||
|
case RID_XMM7_HI:
|
||||||
|
#ifdef SIM_SUPPORT_64
|
||||||
|
case RID_XMM8_HI:
|
||||||
|
case RID_XMM9_HI:
|
||||||
|
case RID_XMM10_HI:
|
||||||
|
case RID_XMM11_HI:
|
||||||
|
case RID_XMM12_HI:
|
||||||
|
case RID_XMM13_HI:
|
||||||
|
case RID_XMM14_HI:
|
||||||
|
case RID_XMM15_HI:
|
||||||
|
#endif
|
||||||
|
return BX_CPU(m_Id)->xmm[(reg->getId() - RID_XMM0_HI) / 2].xmm_s64[1];
|
||||||
|
case RID_MXCSR:
|
||||||
|
return BX_CPU(m_Id)->mxcsr.mxcsr;
|
||||||
|
|
||||||
#ifdef SIM_SUPPORT_64
|
#ifdef SIM_SUPPORT_64
|
||||||
case RID_PC: // program counter
|
case RID_PC: // program counter
|
||||||
return static_cast<regdata_t>(BX_CPU(m_Id)->gen_reg[BX_64BIT_REG_RIP].rrx);
|
return static_cast<regdata_t>(BX_CPU(m_Id)->gen_reg[BX_64BIT_REG_RIP].rrx);
|
||||||
@ -115,6 +184,82 @@ void BochsCPU::setRegisterContent(const Register* reg, regdata_t value)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// FPU
|
||||||
|
case RID_FSW:
|
||||||
|
BX_CPU(m_Id)->the_i387.swd = value;
|
||||||
|
break;
|
||||||
|
case RID_FCW:
|
||||||
|
BX_CPU(m_Id)->the_i387.cwd = value;
|
||||||
|
break;
|
||||||
|
case RID_FTW:
|
||||||
|
BX_CPU(m_Id)->the_i387.twd = value;
|
||||||
|
break;
|
||||||
|
case RID_FPR0_LO:
|
||||||
|
case RID_FPR1_LO:
|
||||||
|
case RID_FPR2_LO:
|
||||||
|
case RID_FPR3_LO:
|
||||||
|
case RID_FPR4_LO:
|
||||||
|
case RID_FPR5_LO:
|
||||||
|
case RID_FPR6_LO:
|
||||||
|
case RID_FPR7_LO:
|
||||||
|
BX_CPU(m_Id)->the_i387.st_space[(reg->getId() - RID_FPR0_LO) / 2].fraction = value;
|
||||||
|
break;
|
||||||
|
case RID_FPR0_HI:
|
||||||
|
case RID_FPR1_HI:
|
||||||
|
case RID_FPR2_HI:
|
||||||
|
case RID_FPR3_HI:
|
||||||
|
case RID_FPR4_HI:
|
||||||
|
case RID_FPR5_HI:
|
||||||
|
case RID_FPR6_HI:
|
||||||
|
case RID_FPR7_HI:
|
||||||
|
BX_CPU(m_Id)->the_i387.st_space[(reg->getId() - RID_FPR0_HI) / 2].exp = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// vector units
|
||||||
|
case RID_XMM0_LO:
|
||||||
|
case RID_XMM1_LO:
|
||||||
|
case RID_XMM2_LO:
|
||||||
|
case RID_XMM3_LO:
|
||||||
|
case RID_XMM4_LO:
|
||||||
|
case RID_XMM5_LO:
|
||||||
|
case RID_XMM6_LO:
|
||||||
|
case RID_XMM7_LO:
|
||||||
|
#ifdef SIM_SUPPORT_64
|
||||||
|
case RID_XMM8_LO:
|
||||||
|
case RID_XMM9_LO:
|
||||||
|
case RID_XMM10_LO:
|
||||||
|
case RID_XMM11_LO:
|
||||||
|
case RID_XMM12_LO:
|
||||||
|
case RID_XMM13_LO:
|
||||||
|
case RID_XMM14_LO:
|
||||||
|
case RID_XMM15_LO:
|
||||||
|
#endif
|
||||||
|
BX_CPU(m_Id)->xmm[(reg->getId() - RID_XMM0_LO) / 2].xmm_s64[0] = value;
|
||||||
|
break;
|
||||||
|
case RID_XMM0_HI:
|
||||||
|
case RID_XMM1_HI:
|
||||||
|
case RID_XMM2_HI:
|
||||||
|
case RID_XMM3_HI:
|
||||||
|
case RID_XMM4_HI:
|
||||||
|
case RID_XMM5_HI:
|
||||||
|
case RID_XMM6_HI:
|
||||||
|
case RID_XMM7_HI:
|
||||||
|
#ifdef SIM_SUPPORT_64
|
||||||
|
case RID_XMM8_HI:
|
||||||
|
case RID_XMM9_HI:
|
||||||
|
case RID_XMM10_HI:
|
||||||
|
case RID_XMM11_HI:
|
||||||
|
case RID_XMM12_HI:
|
||||||
|
case RID_XMM13_HI:
|
||||||
|
case RID_XMM14_HI:
|
||||||
|
case RID_XMM15_HI:
|
||||||
|
#endif
|
||||||
|
BX_CPU(m_Id)->xmm[(reg->getId() - RID_XMM0_HI) / 2].xmm_s64[1] = value;
|
||||||
|
break;
|
||||||
|
case RID_MXCSR:
|
||||||
|
BX_CPU(m_Id)->mxcsr.mxcsr = value;
|
||||||
|
break;
|
||||||
|
|
||||||
#ifdef SIM_SUPPORT_64
|
#ifdef SIM_SUPPORT_64
|
||||||
case RID_PC: // program counter
|
case RID_PC: // program counter
|
||||||
BX_CPU(m_Id)->gen_reg[BX_64BIT_REG_RIP].rrx = value;
|
BX_CPU(m_Id)->gen_reg[BX_64BIT_REG_RIP].rrx = value;
|
||||||
|
|||||||
@ -14,11 +14,9 @@ namespace fail {
|
|||||||
|
|
||||||
typedef bx_address guest_address_t; //!< the guest memory address type
|
typedef bx_address guest_address_t; //!< the guest memory address type
|
||||||
typedef Bit8u* host_address_t; //!< the host memory address type
|
typedef Bit8u* host_address_t; //!< the host memory address type
|
||||||
#if BX_SUPPORT_X86_64
|
//! register data type (64 bit, regardless of BX_SUPPORT_X86_64: FPU and vector
|
||||||
typedef Bit64u register_data_t; //!< register data type (64 bit)
|
//! registers are that size or larger also for 32-bit machines)
|
||||||
#else
|
typedef Bit64u register_data_t;
|
||||||
typedef Bit32u register_data_t; //!< register data type (32 bit)
|
|
||||||
#endif
|
|
||||||
typedef int timer_t; //!< type of timer IDs
|
typedef int timer_t; //!< type of timer IDs
|
||||||
|
|
||||||
// 'Publish' 64 bit ability (if enabled in Bochs):
|
// 'Publish' 64 bit ability (if enabled in Bochs):
|
||||||
|
|||||||
@ -84,6 +84,54 @@ X86Architecture::X86Architecture()
|
|||||||
pSSReg->setName("SS");
|
pSSReg->setName("SS");
|
||||||
m_addRegister(pSSReg, RT_SEGMENT);
|
m_addRegister(pSSReg, RT_SEGMENT);
|
||||||
|
|
||||||
|
// FPU registers
|
||||||
|
Register *fpureg;
|
||||||
|
fpureg = new Register(RID_FSW, 16);
|
||||||
|
fpureg->setName("FSW");
|
||||||
|
m_addRegister(fpureg, RT_FPU);
|
||||||
|
fpureg = new Register(RID_FCW, 16);
|
||||||
|
fpureg->setName("FCW");
|
||||||
|
m_addRegister(fpureg, RT_FPU);
|
||||||
|
fpureg = new Register(RID_FTW, 16);
|
||||||
|
fpureg->setName("FTW");
|
||||||
|
m_addRegister(fpureg, RT_FPU);
|
||||||
|
std::stringstream ss;
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
fpureg = new Register(RID_FPR0_LO + i * 2, 64);
|
||||||
|
ss.str("");
|
||||||
|
ss << "FPR" << i << "_LO";
|
||||||
|
fpureg->setName(ss.str());
|
||||||
|
m_addRegister(fpureg, RT_FPU);
|
||||||
|
|
||||||
|
fpureg = new Register(RID_FPR0_HI + i * 2, 16);
|
||||||
|
ss.str("");
|
||||||
|
ss << "FPR" << i << "_HI";
|
||||||
|
fpureg->setName(ss.str());
|
||||||
|
m_addRegister(fpureg, RT_FPU);
|
||||||
|
}
|
||||||
|
|
||||||
|
// XMM registers (SSE)
|
||||||
|
fpureg = new Register(RID_MXCSR, 16); // in fact MXCSR has 32 bits, but only 0-15 are defined as of SSE3
|
||||||
|
fpureg->setName("MXCSR");
|
||||||
|
m_addRegister(fpureg, RT_VECTOR);
|
||||||
|
#ifdef SIM_SUPPORT_64
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
#else
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
#endif
|
||||||
|
fpureg = new Register(RID_XMM0_LO + i * 2, 64);
|
||||||
|
ss.str("");
|
||||||
|
ss << "XMM" << i << "_LO";
|
||||||
|
fpureg->setName(ss.str());
|
||||||
|
m_addRegister(fpureg, RT_VECTOR);
|
||||||
|
|
||||||
|
fpureg = new Register(RID_XMM0_HI + i * 2, 64);
|
||||||
|
ss.str("");
|
||||||
|
ss << "XMM" << i << "_HI";
|
||||||
|
fpureg->setName(ss.str());
|
||||||
|
m_addRegister(fpureg, RT_VECTOR);
|
||||||
|
}
|
||||||
|
|
||||||
// Registers used for extended tracing:
|
// Registers used for extended tracing:
|
||||||
size_t ids[] = {RID_CAX, RID_CBX, RID_CCX, RID_CDX, RID_CSI, RID_CDI, RID_CSP, RID_CBP, RID_FLAGS};
|
size_t ids[] = {RID_CAX, RID_CBX, RID_CCX, RID_CDX, RID_CSI, RID_CDI, RID_CSP, RID_CBP, RID_FLAGS};
|
||||||
for (size_t i = 0; i < sizeof(ids)/sizeof(*ids); ++i) {
|
for (size_t i = 0; i < sizeof(ids)/sizeof(*ids); ++i) {
|
||||||
|
|||||||
@ -67,9 +67,39 @@ enum SegmentRegisterId { RID_CS = RID_LAST_FLAGS_ID, RID_DS, RID_ES, RID_FS,
|
|||||||
* \enum ControlRegisterId
|
* \enum ControlRegisterId
|
||||||
* Symbolic identifier to access the control register.
|
* Symbolic identifier to access the control register.
|
||||||
*/
|
*/
|
||||||
enum ControlRegisterId { RID_CR0 = RID_LAST_SEGMENT_ID, RID_CR1, RID_CR2, RID_CR3, RID_CR4 };
|
enum ControlRegisterId { RID_CR0 = RID_LAST_SEGMENT_ID, RID_CR1, RID_CR2, RID_CR3, RID_CR4, RID_LAST_CR_ID };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \enum FPURegisterId
|
||||||
|
* Symbolic identifier to access FPU registers.
|
||||||
|
*/
|
||||||
|
enum FPURegisterId {
|
||||||
|
RID_FSW = RID_LAST_CR_ID, RID_FCW, RID_FTW,
|
||||||
|
/* FPRi_LO is fraction (64 bit), FPRi_HI is exponent (16 bit), total 80 bits */
|
||||||
|
RID_FPR0_LO, RID_FPR0_HI, RID_FPR1_LO, RID_FPR1_HI, RID_FPR2_LO, RID_FPR2_HI, RID_FPR3_LO, RID_FPR3_HI,
|
||||||
|
RID_FPR4_LO, RID_FPR4_HI, RID_FPR5_LO, RID_FPR5_HI, RID_FPR6_LO, RID_FPR6_HI, RID_FPR7_LO, RID_FPR7_HI,
|
||||||
|
/* MMXi = RID_FPRi_LO */
|
||||||
|
RID_MMX0 = RID_FPR0_LO, RID_MMX1 = RID_FPR1_LO, RID_MMX2 = RID_FPR2_LO, RID_MMX3 = RID_FPR3_LO,
|
||||||
|
RID_MMX4 = RID_FPR4_LO, RID_MMX5 = RID_FPR5_LO, RID_MMX6 = RID_FPR6_LO, RID_MMX7 = RID_FPR7_LO,
|
||||||
|
RID_MMXDUMMY = RID_FPR7_HI, RID_LAST_FP_ID
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \enum VectorRegisterId
|
||||||
|
* Symbolic identifier to access vector-unit registers (SSE, AVX, ...).
|
||||||
|
*/
|
||||||
|
enum VectorRegisterId {
|
||||||
|
/* low / high 64 bits */
|
||||||
|
RID_XMM0_LO = RID_LAST_FP_ID, RID_XMM0_HI, RID_XMM1_LO, RID_XMM1_HI, RID_XMM2_LO, RID_XMM2_HI, RID_XMM3_LO, RID_XMM3_HI,
|
||||||
|
RID_XMM4_LO, RID_XMM4_HI, RID_XMM5_LO, RID_XMM5_HI, RID_XMM6_LO, RID_XMM6_HI, RID_XMM7_LO, RID_XMM7_HI,
|
||||||
|
#ifdef SIM_SUPPORT_64
|
||||||
|
RID_XMM8_LO, RID_XMM8_HI, RID_XMM9_LO, RID_XMM9_HI, RID_XMM10_LO, RID_XMM10_HI, RID_XMM11_LO, RID_XMM11_HI,
|
||||||
|
RID_XMM12_LO, RID_XMM12_HI, RID_XMM13_LO, RID_XMM13_HI, RID_XMM14_LO, RID_XMM14_HI, RID_XMM15_LO, RID_XMM15_HI,
|
||||||
|
#endif
|
||||||
|
RID_MXCSR, /* MXCSR_MASK? */
|
||||||
|
RID_LAST_VECTOR_ID
|
||||||
|
};
|
||||||
|
|
||||||
// TODO FPU stuff (FSW, FCW, FTW; FPR0-7; MMX0-7; XMM0-15; MXCSR)
|
|
||||||
// TODO GDTR, LDTR, IDTR, TR6+7, DR0-7, TR, MSR*
|
// TODO GDTR, LDTR, IDTR, TR6+7, DR0-7, TR, MSR*
|
||||||
|
|
||||||
} // end-of-namespace: fail
|
} // end-of-namespace: fail
|
||||||
|
|||||||
Reference in New Issue
Block a user