summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibX86
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibX86')
-rw-r--r--Userland/Libraries/LibX86/Instruction.cpp30
-rw-r--r--Userland/Libraries/LibX86/Instruction.h69
2 files changed, 52 insertions, 47 deletions
diff --git a/Userland/Libraries/LibX86/Instruction.cpp b/Userland/Libraries/LibX86/Instruction.cpp
index 2e0fac7059..aba6379e6e 100644
--- a/Userland/Libraries/LibX86/Instruction.cpp
+++ b/Userland/Libraries/LibX86/Instruction.cpp
@@ -1037,7 +1037,7 @@ String MemoryOrRegisterReference::to_string_a16() const
String base;
bool hasDisplacement = false;
- switch (m_rm & 7) {
+ switch (rm()) {
case 0:
base = "bx+si";
break;
@@ -1060,16 +1060,16 @@ String MemoryOrRegisterReference::to_string_a16() const
base = "bx";
break;
case 6:
- if ((m_rm & 0xc0) == 0)
+ if (mod() == 0)
base = String::formatted("{:#04x}", m_displacement16);
else
base = "bp";
break;
}
- switch (m_rm & 0xc0) {
- case 0x40:
- case 0x80:
+ switch (mod()) {
+ case 0b01:
+ case 0b10:
hasDisplacement = true;
}
@@ -1178,16 +1178,16 @@ String MemoryOrRegisterReference::to_string_a32() const
return register_name(static_cast<RegisterIndex32>(m_register_index));
bool has_displacement = false;
- switch (m_rm & 0xc0) {
- case 0x40:
- case 0x80:
+ switch (mod()) {
+ case 0b01:
+ case 0b10:
has_displacement = true;
}
if (m_has_sib && (m_sib & 7) == 5)
has_displacement = true;
String base;
- switch (m_rm & 7) {
+ switch (rm()) {
case 0:
base = "eax";
break;
@@ -1207,13 +1207,13 @@ String MemoryOrRegisterReference::to_string_a32() const
base = "edi";
break;
case 5:
- if ((m_rm & 0xc0) == 0)
+ if (mod() == 0)
base = String::formatted("{:#08x}", m_displacement32);
else
base = "ebp";
break;
case 4:
- base = sib_to_string(m_rm, m_sib);
+ base = sib_to_string(m_rm_byte, m_sib);
break;
}
@@ -1766,7 +1766,7 @@ void Instruction::to_string_internal(StringBuilder& builder, u32 origin, const S
break;
case OP_reg32_CR:
append_mnemonic_space();
- builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7)));
+ builder.append(register_name(static_cast<RegisterIndex32>(modrm().rm())));
append(", ");
append_creg();
break;
@@ -1774,11 +1774,11 @@ void Instruction::to_string_internal(StringBuilder& builder, u32 origin, const S
append_mnemonic_space();
append_creg();
append(", ");
- builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7)));
+ builder.append(register_name(static_cast<RegisterIndex32>(modrm().rm())));
break;
case OP_reg32_DR:
append_mnemonic_space();
- builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7)));
+ builder.append(register_name(static_cast<RegisterIndex32>(modrm().rm())));
append(", ");
append_dreg();
break;
@@ -1786,7 +1786,7 @@ void Instruction::to_string_internal(StringBuilder& builder, u32 origin, const S
append_mnemonic_space();
append_dreg();
append(", ");
- builder.append(register_name(static_cast<RegisterIndex32>(rm() & 7)));
+ builder.append(register_name(static_cast<RegisterIndex32>(modrm().rm())));
break;
case OP_short_imm8:
append_mnemonic_space();
diff --git a/Userland/Libraries/LibX86/Instruction.h b/Userland/Libraries/LibX86/Instruction.h
index 8985f92e39..e515165cd2 100644
--- a/Userland/Libraries/LibX86/Instruction.h
+++ b/Userland/Libraries/LibX86/Instruction.h
@@ -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: