core/sal: refactoring BochsCPU::get/setRegisterContent

Using switch/case instead of an if cascade is more readable and has a
better chance to be optimized.

Change-Id: I41dc2cbdf8c14bd35c91520d74b476d7b522a3a4
This commit is contained in:
Horst Schirmeier
2018-11-20 18:43:27 +01:00
parent 60329bface
commit 171fe54330

View File

@ -8,165 +8,130 @@ namespace fail {
regdata_t BochsCPU::getRegisterContent(const Register* reg) const regdata_t BochsCPU::getRegisterContent(const Register* reg) const
{ {
assert(reg != NULL && "FATAL ERROR: reg-ptr cannot be NULL!"); assert(reg != NULL && "FATAL ERROR: reg-ptr cannot be NULL!");
// TODO: BX_CPU(0) *always* correct?
if (reg->getId() == RID_FLAGS) { // EFLAGS register? switch (reg->getId()) {
case RID_FLAGS: // EFLAGS/RFLAGS
return static_cast<regdata_t>(BX_CPU(m_Id)->read_eflags()); return static_cast<regdata_t>(BX_CPU(m_Id)->read_eflags());
} case RID_CR0:
// untested
// untested
if (reg->getId() == RID_CR0) { // CR0 register?
return static_cast<regdata_t>(BX_CPU(m_Id)->read_CR0()); return static_cast<regdata_t>(BX_CPU(m_Id)->read_CR0());
} case RID_CR2:
// untested
// untested
if (reg->getId() == RID_CR2) { // CR2 register?
return static_cast<regdata_t>(BX_CPU(m_Id)->cr2); return static_cast<regdata_t>(BX_CPU(m_Id)->cr2);
} case RID_CR3:
if (reg->getId() == RID_CR3) { // CR3 register?
return static_cast<regdata_t>(BX_CPU(m_Id)->cr3); return static_cast<regdata_t>(BX_CPU(m_Id)->cr3);
} case RID_CR4:
// untested
// untested
if (reg->getId() == RID_CR4) { // CR4 register?
return static_cast<regdata_t>(BX_CPU(m_Id)->read_CR4()); return static_cast<regdata_t>(BX_CPU(m_Id)->read_CR4());
} case RID_CS:
// untested
// untested
if (reg->getId() == RID_CS) { // CS register?
return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_CS].selector.value); return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_CS].selector.value);
} case RID_DS:
// untested
// untested
if (reg->getId() == RID_DS) { // DS register?
return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_DS].selector.value); return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_DS].selector.value);
} case RID_ES:
// untested
// untested
if (reg->getId() == RID_ES) { // ES register?
return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_ES].selector.value); return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_ES].selector.value);
} case RID_FS:
// untested
// untested
if (reg->getId() == RID_FS) { // FS register?
return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_FS].selector.value); return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_FS].selector.value);
} case RID_GS:
// untested
// untested
if (reg->getId() == RID_GS) { // GS register?
return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_GS].selector.value); return static_cast<regdata_t>(BX_CPU(m_Id)->sregs[BX_SEG_REG_GS].selector.value);
} case RID_SS:
// untested
// untested
if (reg->getId() == RID_SS) { // SS register?
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);
}
#ifdef SIM_SUPPORT_64 #ifdef SIM_SUPPORT_64
if (reg->getId() == 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);
else // 64 bit general purpose registers default: // 64 bit general purpose registers
return static_cast<regdata_t>(BX_CPU(m_Id)->gen_reg[reg->getId()].rrx); return static_cast<regdata_t>(BX_CPU(m_Id)->gen_reg[reg->getId()].rrx);
#else // 32 bit mode #else // 32 bit mode
if (reg->getId() == RID_PC) case RID_PC: // program counter
return static_cast<regdata_t>(BX_CPU(m_Id)->gen_reg[BX_32BIT_REG_EIP].dword.erx); return static_cast<regdata_t>(BX_CPU(m_Id)->gen_reg[BX_32BIT_REG_EIP].dword.erx);
else // 32 bit general purpose registers default: // 32 bit general purpose registers
return static_cast<regdata_t>(BX_CPU(m_Id)->gen_reg[reg->getId()].dword.erx); return static_cast<regdata_t>(BX_CPU(m_Id)->gen_reg[reg->getId()].dword.erx);
#endif // SIM_SUPPORT_64 #endif // SIM_SUPPORT_64
}
} }
void BochsCPU::setRegisterContent(const Register* reg, regdata_t value) void BochsCPU::setRegisterContent(const Register* reg, regdata_t value)
{ {
assert(reg != NULL && "FATAL ERROR: reg-ptr cannot be NULL!"); assert(reg != NULL && "FATAL ERROR: reg-ptr cannot be NULL!");
// TODO: BX_CPU(0) *always* correct?
if (reg->getId() == RID_FLAGS) { // EFLAGS register? regdata_t* pData;
switch (reg->getId()) {
case RID_FLAGS: // EFLAGS/RFLAGS
#ifdef SIM_SUPPORT_64 #ifdef SIM_SUPPORT_64
{
// We are in 64 bit mode: Just assign the lower 32 bits! // We are in 64 bit mode: Just assign the lower 32 bits!
regdata_t regdata = getRegisterContent(reg); regdata_t regdata = getRegisterContent(reg);
BX_CPU(m_Id)->writeEFlags((regdata & 0xFFFFFFFF00000000ULL) | (value & 0xFFFFFFFFULL), BX_CPU(m_Id)->writeEFlags((regdata & 0xFFFFFFFF00000000ULL) | (value & 0xFFFFFFFFULL),
0xffffffff); 0xffffffff);
}
#else #else
BX_CPU(m_Id)->writeEFlags(value, 0xffffffff); BX_CPU(m_Id)->writeEFlags(value, 0xffffffff);
#endif #endif
BX_CPU(m_Id)->force_flags(); BX_CPU(m_Id)->force_flags();
return; return;
}
#ifndef __puma #ifndef __puma
// untested case RID_CR0:
if (reg->getId() == RID_CR0) { // CR0 register? // untested
BX_CPU(m_Id)->SetCR0(value); BX_CPU(m_Id)->SetCR0(value);
return; return;
} case RID_CR2:
// untested
// untested
if (reg->getId() == RID_CR2) { // CR2 register?
BX_CPU(m_Id)->cr2 = value; BX_CPU(m_Id)->cr2 = value;
return; return;
} case RID_CR3:
if (reg->getId() == RID_CR3) { // CR3 register?
BX_CPU(m_Id)->SetCR3(value); BX_CPU(m_Id)->SetCR3(value);
return; return;
} case RID_CR4:
// untested
// untested
if (reg->getId() == RID_CR4) { // CR4 register?
BX_CPU(m_Id)->SetCR4(value); BX_CPU(m_Id)->SetCR4(value);
return; return;
} case RID_CS:
// untested
// untested
if (reg->getId() == RID_CS) { // CS register?
BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_CS], value); BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_CS], value);
return; return;
} case RID_DS:
// untested
// untested
if (reg->getId() == RID_DS) { // DS register?
BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_DS], value); BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_DS], value);
return; return;
} case RID_ES:
// untested
// untested
if (reg->getId() == RID_ES) { // ES register?
BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_ES], value); BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_ES], value);
return; return;
} case RID_FS:
// untested
// untested
if (reg->getId() == RID_FS) { // FS register?
BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_FS], value); BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_FS], value);
return; return;
} case RID_GS:
// untested
// untested
if (reg->getId() == RID_GS) { // GS register?
BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_GS], value); BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_GS], value);
return; return;
} case RID_SS:
// untested
// untested
if (reg->getId() == RID_SS) { // SS register?
BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_SS], value); BX_CPU(m_Id)->load_seg_reg(&BX_CPU(m_Id)->sregs[BX_SEG_REG_SS], value);
return; return;
}
#endif #endif
regdata_t* pData;
#ifdef SIM_SUPPORT_64 #ifdef SIM_SUPPORT_64
if (reg->getId() == RID_PC) // program counter? case RID_PC: // program counter
pData = &(BX_CPU(m_Id)->gen_reg[BX_64BIT_REG_RIP].rrx); pData = &(BX_CPU(m_Id)->gen_reg[BX_64BIT_REG_RIP].rrx);
else // 64 bit general purpose registers break;
default: // 64 bit general purpose registers
pData = &(BX_CPU(m_Id)->gen_reg[reg->getId()].rrx); pData = &(BX_CPU(m_Id)->gen_reg[reg->getId()].rrx);
break;
#else // 32 bit mode #else // 32 bit mode
if (reg->getId() == RID_PC) case RID_PC: // program counter
pData = &(BX_CPU(m_Id)->gen_reg[BX_32BIT_REG_EIP].dword.erx); pData = &(BX_CPU(m_Id)->gen_reg[BX_32BIT_REG_EIP].dword.erx);
else // 32 bit general purpose registers break;
default: // 32 bit general purpose registers
pData = &(BX_CPU(m_Id)->gen_reg[reg->getId()].dword.erx); pData = &(BX_CPU(m_Id)->gen_reg[reg->getId()].dword.erx);
break;
#endif // SIM_SUPPORT_64 #endif // SIM_SUPPORT_64
}
*pData = value; *pData = value;
} }