mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 09:57:36 +00:00
LibX86: Use names closer to the spec for the Modrm
This gets rid of a lot of magic number shifts and ands.
This commit is contained in:
parent
68193c365f
commit
efa42c4d45
3 changed files with 58 additions and 53 deletions
|
@ -374,6 +374,11 @@ public:
|
|||
RegisterIndex8 reg8() const { return static_cast<RegisterIndex8>(register_index()); }
|
||||
FpuRegisterIndex reg_fpu() const { return static_cast<FpuRegisterIndex>(register_index()); }
|
||||
|
||||
// helpers to get the parts by name as in the spec
|
||||
u8 mod() const { return m_rm_byte >> 6; }
|
||||
u8 reg() const { return m_rm_byte >> 3 & 0b111; }
|
||||
u8 rm() const { return m_rm_byte & 0b111; }
|
||||
|
||||
template<typename CPU, typename T>
|
||||
void write8(CPU&, const Instruction&, T);
|
||||
template<typename CPU, typename T>
|
||||
|
@ -429,7 +434,7 @@ private:
|
|||
u16 m_displacement16;
|
||||
};
|
||||
|
||||
u8 m_rm { 0 };
|
||||
u8 m_rm_byte { 0 };
|
||||
u8 m_sib { 0 };
|
||||
u8 m_displacement_bytes { 0 };
|
||||
u8 m_register_index : 7 { 0x7f };
|
||||
|
@ -467,8 +472,8 @@ public:
|
|||
String mnemonic() const;
|
||||
|
||||
u8 op() const { return m_op; }
|
||||
u8 rm() const { return m_modrm.m_rm; }
|
||||
u8 slash() const { return (rm() >> 3) & 7; }
|
||||
u8 modrm_byte() const { return m_modrm.m_rm_byte; }
|
||||
u8 slash() const { return (modrm_byte() >> 3) & 7; }
|
||||
|
||||
u8 imm8() const { return m_imm1; }
|
||||
u16 imm16() const { return m_imm1; }
|
||||
|
@ -535,7 +540,7 @@ ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve16(const CPU& cpu
|
|||
auto default_segment = SegmentRegister::DS;
|
||||
u16 offset = 0;
|
||||
|
||||
switch (m_rm & 7) {
|
||||
switch (rm()) {
|
||||
case 0:
|
||||
offset = cpu.bx().value() + cpu.si().value() + m_displacement16;
|
||||
break;
|
||||
|
@ -557,7 +562,7 @@ ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve16(const CPU& cpu
|
|||
offset = cpu.di().value() + m_displacement16;
|
||||
break;
|
||||
case 6:
|
||||
if ((m_rm & 0xc0) == 0)
|
||||
if (mod() == 0)
|
||||
offset = m_displacement16;
|
||||
else {
|
||||
default_segment = SegmentRegister::SS;
|
||||
|
@ -579,16 +584,16 @@ ALWAYS_INLINE LogicalAddress MemoryOrRegisterReference::resolve32(const CPU& cpu
|
|||
auto default_segment = SegmentRegister::DS;
|
||||
u32 offset = 0;
|
||||
|
||||
switch (m_rm & 0x07) {
|
||||
switch (rm()) {
|
||||
case 0 ... 3:
|
||||
case 6 ... 7:
|
||||
offset = cpu.const_gpr32((RegisterIndex32)(m_rm & 0x07)).value() + m_displacement32;
|
||||
offset = cpu.const_gpr32((RegisterIndex32)(rm())).value() + m_displacement32;
|
||||
break;
|
||||
case 4:
|
||||
offset = evaluate_sib(cpu, default_segment);
|
||||
break;
|
||||
default: // 5
|
||||
if ((m_rm & 0xc0) == 0x00) {
|
||||
if (mod() == 0) {
|
||||
offset = m_displacement32;
|
||||
break;
|
||||
} else {
|
||||
|
@ -628,7 +633,7 @@ ALWAYS_INLINE u32 MemoryOrRegisterReference::evaluate_sib(const CPU& cpu, Segmen
|
|||
base += cpu.esp().value();
|
||||
break;
|
||||
default: // 5
|
||||
switch ((m_rm >> 6) & 3) {
|
||||
switch (mod()) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
|
@ -846,7 +851,7 @@ ALWAYS_INLINE Instruction::Instruction(InstructionStreamType& stream, bool o32,
|
|||
if (m_descriptor->has_rm) {
|
||||
// Consume ModR/M (may include SIB and displacement.)
|
||||
m_modrm.decode(stream, m_a32);
|
||||
m_register_index = (m_modrm.m_rm >> 3) & 7;
|
||||
m_register_index = m_modrm.reg();
|
||||
} else {
|
||||
if (has_sub_op())
|
||||
m_register_index = m_sub_op & 7;
|
||||
|
@ -857,8 +862,8 @@ ALWAYS_INLINE Instruction::Instruction(InstructionStreamType& stream, bool o32,
|
|||
bool has_slash = m_descriptor->format == MultibyteWithSlash;
|
||||
if (has_slash) {
|
||||
m_descriptor = &m_descriptor->slashes[slash()];
|
||||
if ((rm() & 0xc0) == 0xc0 && m_descriptor->slashes)
|
||||
m_descriptor = &m_descriptor->slashes[rm() & 7];
|
||||
if ((modrm_byte() & 0xc0) == 0xc0 && m_descriptor->slashes)
|
||||
m_descriptor = &m_descriptor->slashes[modrm_byte() & 7];
|
||||
}
|
||||
|
||||
if (!m_descriptor->mnemonic) {
|
||||
|
@ -924,7 +929,7 @@ ALWAYS_INLINE Instruction::Instruction(InstructionStreamType& stream, bool o32,
|
|||
template<typename InstructionStreamType>
|
||||
ALWAYS_INLINE void MemoryOrRegisterReference::decode(InstructionStreamType& stream, bool a32)
|
||||
{
|
||||
m_rm = stream.read8();
|
||||
m_rm_byte = stream.read8();
|
||||
|
||||
if (a32) {
|
||||
decode32(stream);
|
||||
|
@ -962,21 +967,21 @@ ALWAYS_INLINE void MemoryOrRegisterReference::decode(InstructionStreamType& stre
|
|||
template<typename InstructionStreamType>
|
||||
ALWAYS_INLINE void MemoryOrRegisterReference::decode16(InstructionStreamType&)
|
||||
{
|
||||
switch (m_rm & 0xc0) {
|
||||
case 0:
|
||||
if ((m_rm & 0x07) == 6)
|
||||
switch (mod()) {
|
||||
case 0b00:
|
||||
if (rm() == 6)
|
||||
m_displacement_bytes = 2;
|
||||
else
|
||||
VERIFY(m_displacement_bytes == 0);
|
||||
break;
|
||||
case 0x40:
|
||||
case 0b01:
|
||||
m_displacement_bytes = 1;
|
||||
break;
|
||||
case 0x80:
|
||||
case 0b10:
|
||||
m_displacement_bytes = 2;
|
||||
break;
|
||||
case 0xc0:
|
||||
m_register_index = m_rm & 7;
|
||||
case 0b11:
|
||||
m_register_index = rm();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -984,34 +989,34 @@ ALWAYS_INLINE void MemoryOrRegisterReference::decode16(InstructionStreamType&)
|
|||
template<typename InstructionStreamType>
|
||||
ALWAYS_INLINE void MemoryOrRegisterReference::decode32(InstructionStreamType& stream)
|
||||
{
|
||||
switch (m_rm & 0xc0) {
|
||||
case 0:
|
||||
if ((m_rm & 0x07) == 5)
|
||||
switch (mod()) {
|
||||
case 0b00:
|
||||
if (rm() == 5)
|
||||
m_displacement_bytes = 4;
|
||||
break;
|
||||
case 0x40:
|
||||
case 0b01:
|
||||
m_displacement_bytes = 1;
|
||||
break;
|
||||
case 0x80:
|
||||
case 0b10:
|
||||
m_displacement_bytes = 4;
|
||||
break;
|
||||
case 0xc0:
|
||||
m_register_index = m_rm & 7;
|
||||
case 0b11:
|
||||
m_register_index = rm();
|
||||
return;
|
||||
}
|
||||
|
||||
m_has_sib = (m_rm & 0x07) == 4;
|
||||
m_has_sib = rm() == 4;
|
||||
if (m_has_sib) {
|
||||
m_sib = stream.read8();
|
||||
if ((m_sib & 0x07) == 5) {
|
||||
switch ((m_rm >> 6) & 0x03) {
|
||||
case 0:
|
||||
switch (mod()) {
|
||||
case 0b00:
|
||||
m_displacement_bytes = 4;
|
||||
break;
|
||||
case 1:
|
||||
case 0b01:
|
||||
m_displacement_bytes = 1;
|
||||
break;
|
||||
case 2:
|
||||
case 0b10:
|
||||
m_displacement_bytes = 4;
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue