x86+bochs: add IDs and accessors for FPU and SSE registers

Change-Id: I33146929255337f679ff80152ed4d83106621ffb
This commit is contained in:
Horst Schirmeier
2018-11-24 00:53:06 +03:00
parent 9625587fc4
commit 67f30a171e
5 changed files with 230 additions and 8 deletions

View File

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

View File

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

View File

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

View File

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

View File

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