Browse Source

LibX86: Add CMPXCHG8B, RDRAND and RDSEED

With this we can run following script with no errors:
```sh
for /usr/lib/*.so {
    disasm "$it" > /dev/zero
}
```
Hendiadyoin1 3 năm trước cách đây
mục cha
commit
7ba2e5e3e7

+ 4 - 0
Userland/DevTools/UserspaceEmulator/SoftCPU.cpp

@@ -2902,6 +2902,10 @@ FPU_INSTRUCTION(MOVD_rm32_mm2);
 FPU_INSTRUCTION(MOVQ_rm64_mm2); // long mode
 FPU_INSTRUCTION(EMMS);
 
+void SoftCPU::CMPXCHG8B_m64(X86::Instruction const&) { TODO_INSN(); }
+void SoftCPU::RDRAND_reg(X86::Instruction const&) { TODO_INSN(); }
+void SoftCPU::RDSEED_reg(X86::Instruction const&) { TODO_INSN(); }
+
 VPU_INSTRUCTION(PREFETCHTNTA);
 VPU_INSTRUCTION(PREFETCHT0);
 VPU_INSTRUCTION(PREFETCHT1);

+ 4 - 0
Userland/DevTools/UserspaceEmulator/SoftCPU.h

@@ -1109,6 +1109,10 @@ private:
     virtual void MOVQ_rm64_mm2(const X86::Instruction&) override; // long mode
     virtual void EMMS(const X86::Instruction&) override;
 
+    virtual void CMPXCHG8B_m64(X86::Instruction const&) override;
+    virtual void RDRAND_reg(X86::Instruction const&) override;
+    virtual void RDSEED_reg(X86::Instruction const&) override;
+
     virtual void PREFETCHTNTA(X86::Instruction const&) override;
     virtual void PREFETCHT0(X86::Instruction const&) override;
     virtual void PREFETCHT1(X86::Instruction const&) override;

+ 23 - 0
Userland/Libraries/LibX86/Instruction.cpp

@@ -153,6 +153,8 @@ static void build(InstructionDescriptor* table, u8 op, char const* mnemonic, Ins
     case OP_CR_reg32:
     case OP_reg16_RM8:
     case OP_reg32_RM8:
+    case OP_reg:
+    case OP_m64:
     case OP_mm1_rm32:
     case OP_rm32_mm2:
     case OP_mm1_mm2m64:
@@ -1121,6 +1123,16 @@ static void build_sse_66_slash(u8 op, u8 slash, char const* mnemonic, Instructio
     build_sse_np(0xC6, "SHUFPS", OP_xmm1_xmm2m128_imm8, &Interpreter::SHUFPS_xmm1_xmm2m128_imm8);
     build_sse_66(0xC6, "SHUFPD", OP_xmm1_xmm2m128_imm8, &Interpreter::SHUFPD_xmm1_xmm2m128_imm8);
 
+    build_0f_slash(0xC7, 1, "CMPXCHG8B", OP_m64, &Interpreter::CMPXCHG8B_m64);
+    // FIXME: NP 0f c7 /2 XRSTORS[64] mem
+    // FIXME: NP 0F C7 / 4 XSAVEC mem
+    // FIXME: NP 0F C7 /5 XSAVES mem
+    // FIXME: VMPTRLD, VMPTRST, VMCLR, VMXON
+    // This is technically NFx prefixed
+    // FIXME: f3 0f c7 /7 RDPID
+    build_0f_slash(0xC7, 6, "RDRAND", OP_reg, &Interpreter::RDRAND_reg);
+    build_0f_slash(0xC7, 7, "RDSEED", OP_reg, &Interpreter::RDSEED_reg);
+
     for (u8 i = 0xc8; i <= 0xcf; ++i)
         build_0f(i, "BSWAP", OP_reg32, &Interpreter::BSWAP_reg32);
 
@@ -2131,6 +2143,17 @@ void Instruction::to_string_internal(StringBuilder& builder, u32 origin, SymbolP
         append_reg32();
         append(", cl");
         break;
+    case OP_reg:
+        append_mnemonic_space();
+        if (m_o32)
+            append_reg32();
+        else
+            append_reg16();
+        break;
+    case OP_m64:
+        append_mnemonic_space();
+        append_rm64();
+        break;
     case OP_mm1_imm8:
         append_mnemonic_space();
         append_mm_or_xmm();

+ 2 - 0
Userland/Libraries/LibX86/Instruction.h

@@ -104,6 +104,8 @@ enum InstructionFormat {
     OP_RM32_reg32_imm8,
     OP_RM16_reg16_CL,
     OP_RM32_reg32_CL,
+    OP_reg,
+    OP_m64,
     // SSE instructions mutate on some prefixes, so we have to mark them
     // for further parsing
     __SSE,

+ 7 - 1
Userland/Libraries/LibX86/Interpreter.h

@@ -657,7 +657,13 @@ public:
     virtual void wrap_0xD3_16(Instruction const&) = 0;
     virtual void wrap_0xD3_32(Instruction const&) = 0;
 
-    virtual void PREFETCHTNTA(Instruction const&) = 0;
+    virtual void CMPXCHG8B_m64(Instruction const&) = 0;
+    virtual void RDRAND_reg(Instruction const&) = 0;
+    virtual void RDSEED_reg(Instruction const&) = 0;
+
+    virtual void
+    PREFETCHTNTA(Instruction const&)
+        = 0;
     virtual void PREFETCHT0(Instruction const&) = 0;
     virtual void PREFETCHT1(Instruction const&) = 0;
     virtual void PREFETCHT2(Instruction const&) = 0;