diff options
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/DevTools/UserspaceEmulator/SoftCPU.cpp | 74 | ||||
-rw-r--r-- | Userland/DevTools/UserspaceEmulator/SoftCPU.h | 74 | ||||
-rw-r--r-- | Userland/Libraries/LibX86/Instruction.cpp | 219 | ||||
-rw-r--r-- | Userland/Libraries/LibX86/Instruction.h | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibX86/Interpreter.h | 74 |
5 files changed, 414 insertions, 35 deletions
diff --git a/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp b/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp index 2b9a565045..4f8eb02acc 100644 --- a/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/Userland/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -2981,6 +2981,80 @@ VPU_INSTRUCTION(PSADBB_mm1_mm2m64); VPU_INSTRUCTION(PSADBB_xmm1_xmm2m128); VPU_INSTRUCTION(MASKMOVQ_mm1_mm2m64); +void SoftCPU::MOVUPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVSD_xmm1_xmm2m32(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVUPD_xmm1m128_xmm2(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVSD_xmm1m32_xmm2(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVLPD_xmm1_m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVLPD_m64_xmm2(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::UNPCKLPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::UNPCKHPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVHPD_xmm1_xmm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVAPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVAPD_xmm1m128_xmm2(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTPI2PD_xmm1_mm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTSI2SD_xmm1_rm32(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTTPD2PI_mm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTTSS2SI_r32_xmm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTPD2PI_xmm1_mm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTSD2SI_xmm1_rm64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::UCOMISD_xmm1_xmm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::COMISD_xmm1_xmm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVMSKPD_reg_xmm(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::SQRTPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::SQRTSD_xmm1_xmm2m32(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::ANDPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::ANDNPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::ORPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::XORPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::ADDPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::ADDSD_xmm1_xmm2m32(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MULPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MULSD_xmm1_xmm2m32(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTPS2PD_xmm1_xmm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTPD2PS_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTSS2SD_xmm1_xmm2m32(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTSD2SS_xmm1_xmm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTDQ2PS_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTPS2DQ_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTTPS2DQ_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::SUBPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); }; +void SoftCPU::SUBSD_xmm1_xmm2m32(X86::Instruction const&) { TODO_INSN(); }; +void SoftCPU::MINPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MINSD_xmm1_xmm2m32(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::DIVPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::DIVSD_xmm1_xmm2m32(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MAXPD_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MAXSD_xmm1_xmm2m32(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PUNPCKLQDQ_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PUNPCKHQDQ_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVDQA_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVDQU_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PSHUFD_xmm1_xmm2m128_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PSHUFHW_xmm1_xmm2m128_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PSHUFLW_xmm1_xmm2m128_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PSRLQ_xmm1_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PSRLDQ_xmm1_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PSLLQ_xmm1_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PSLLDQ_xmm1_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVD_rm32_xmm2(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVQ_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVDQA_xmm1m128_xmm2(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVDQU_xmm1m128_xmm2(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CMPPD_xmm1_xmm2m128_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CMPSD_xmm1_xmm2m32_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::SHUFPD_xmm1_xmm2m128_imm8(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PADDQ_mm1_mm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVQ_xmm1m128_xmm2(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVQ2DQ_xmm_mm(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::MOVDQ2Q_mm_xmm(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTTPD2DQ_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTPD2DQ_xmm1_xmm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::CVTDQ2PD_xmm1_xmm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PMULUDQ_mm1_mm2m64(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PMULUDQ_mm1_mm2m128(X86::Instruction const&) { TODO_INSN(); } +void SoftCPU::PSUBQ_mm1_mm2m64(X86::Instruction const&) { TODO_INSN(); } + void SoftCPU::wrap_0xC0(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::wrap_0xC1_16(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::wrap_0xC1_32(const X86::Instruction&) { TODO_INSN(); } diff --git a/Userland/DevTools/UserspaceEmulator/SoftCPU.h b/Userland/DevTools/UserspaceEmulator/SoftCPU.h index c8831a047a..e8540cdae3 100644 --- a/Userland/DevTools/UserspaceEmulator/SoftCPU.h +++ b/Userland/DevTools/UserspaceEmulator/SoftCPU.h @@ -1188,6 +1188,80 @@ private: virtual void PSADBB_xmm1_xmm2m128(X86::Instruction const&) override; virtual void MASKMOVQ_mm1_mm2m64(X86::Instruction const&) override; + virtual void MOVUPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void MOVSD_xmm1_xmm2m32(X86::Instruction const&) override; + virtual void MOVUPD_xmm1m128_xmm2(X86::Instruction const&) override; + virtual void MOVSD_xmm1m32_xmm2(X86::Instruction const&) override; + virtual void MOVLPD_xmm1_m64(X86::Instruction const&) override; + virtual void MOVLPD_m64_xmm2(X86::Instruction const&) override; + virtual void UNPCKLPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void UNPCKHPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void MOVHPD_xmm1_xmm2m64(X86::Instruction const&) override; + virtual void MOVAPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void MOVAPD_xmm1m128_xmm2(X86::Instruction const&) override; + virtual void CVTPI2PD_xmm1_mm2m64(X86::Instruction const&) override; + virtual void CVTSI2SD_xmm1_rm32(X86::Instruction const&) override; + virtual void CVTTPD2PI_mm1_xmm2m128(X86::Instruction const&) override; + virtual void CVTTSS2SI_r32_xmm2m64(X86::Instruction const&) override; + virtual void CVTPD2PI_xmm1_mm2m128(X86::Instruction const&) override; + virtual void CVTSD2SI_xmm1_rm64(X86::Instruction const&) override; + virtual void UCOMISD_xmm1_xmm2m64(X86::Instruction const&) override; + virtual void COMISD_xmm1_xmm2m64(X86::Instruction const&) override; + virtual void MOVMSKPD_reg_xmm(X86::Instruction const&) override; + virtual void SQRTPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void SQRTSD_xmm1_xmm2m32(X86::Instruction const&) override; + virtual void ANDPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void ANDNPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void ORPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void XORPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void ADDPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void ADDSD_xmm1_xmm2m32(X86::Instruction const&) override; + virtual void MULPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void MULSD_xmm1_xmm2m32(X86::Instruction const&) override; + virtual void CVTPS2PD_xmm1_xmm2m64(X86::Instruction const&) override; + virtual void CVTPD2PS_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void CVTSS2SD_xmm1_xmm2m32(X86::Instruction const&) override; + virtual void CVTSD2SS_xmm1_xmm2m64(X86::Instruction const&) override; + virtual void CVTDQ2PS_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void CVTPS2DQ_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void CVTTPS2DQ_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void SUBPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void SUBSD_xmm1_xmm2m32(X86::Instruction const&) override; + virtual void MINPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void MINSD_xmm1_xmm2m32(X86::Instruction const&) override; + virtual void DIVPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void DIVSD_xmm1_xmm2m32(X86::Instruction const&) override; + virtual void MAXPD_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void MAXSD_xmm1_xmm2m32(X86::Instruction const&) override; + virtual void PUNPCKLQDQ_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void PUNPCKHQDQ_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void MOVDQA_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void MOVDQU_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void PSHUFD_xmm1_xmm2m128_imm8(X86::Instruction const&) override; + virtual void PSHUFHW_xmm1_xmm2m128_imm8(X86::Instruction const&) override; + virtual void PSHUFLW_xmm1_xmm2m128_imm8(X86::Instruction const&) override; + virtual void PSRLQ_xmm1_imm8(X86::Instruction const&) override; + virtual void PSRLDQ_xmm1_imm8(X86::Instruction const&) override; + virtual void PSLLQ_xmm1_imm8(X86::Instruction const&) override; + virtual void PSLLDQ_xmm1_imm8(X86::Instruction const&) override; + virtual void MOVD_rm32_xmm2(X86::Instruction const&) override; + virtual void MOVQ_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void MOVDQA_xmm1m128_xmm2(X86::Instruction const&) override; + virtual void MOVDQU_xmm1m128_xmm2(X86::Instruction const&) override; + virtual void CMPPD_xmm1_xmm2m128_imm8(X86::Instruction const&) override; + virtual void CMPSD_xmm1_xmm2m32_imm8(X86::Instruction const&) override; + virtual void SHUFPD_xmm1_xmm2m128_imm8(X86::Instruction const&) override; + virtual void PADDQ_mm1_mm2m64(X86::Instruction const&) override; + virtual void MOVQ_xmm1m128_xmm2(X86::Instruction const&) override; + virtual void MOVQ2DQ_xmm_mm(X86::Instruction const&) override; + virtual void MOVDQ2Q_mm_xmm(X86::Instruction const&) override; + virtual void CVTTPD2DQ_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void CVTPD2DQ_xmm1_xmm2m128(X86::Instruction const&) override; + virtual void CVTDQ2PD_xmm1_xmm2m64(X86::Instruction const&) override; + virtual void PMULUDQ_mm1_mm2m64(X86::Instruction const&) override; + virtual void PMULUDQ_mm1_mm2m128(X86::Instruction const&) override; + virtual void PSUBQ_mm1_mm2m64(X86::Instruction const&) override; + virtual void wrap_0xC0(const X86::Instruction&) override; virtual void wrap_0xC1_16(const X86::Instruction&) override; virtual void wrap_0xC1_32(const X86::Instruction&) override; diff --git a/Userland/Libraries/LibX86/Instruction.cpp b/Userland/Libraries/LibX86/Instruction.cpp index eb82da9a74..34d12d12be 100644 --- a/Userland/Libraries/LibX86/Instruction.cpp +++ b/Userland/Libraries/LibX86/Instruction.cpp @@ -21,6 +21,7 @@ InstructionDescriptor s_0f_table32[256]; InstructionDescriptor s_sse_table_np[256]; InstructionDescriptor s_sse_table_66[256]; InstructionDescriptor s_sse_table_f3[256]; +InstructionDescriptor s_sse_table_f2[256]; static bool opcode_has_register_index(u8 op) { @@ -68,6 +69,7 @@ static void build(InstructionDescriptor* table, u8 op, char const* mnemonic, Ins case OP_mm1_mm2m64_imm8: case OP_reg_mm1_imm8: case OP_mm1_r32m16_imm8: + case OP_xmm1_imm8: case OP_xmm1_xmm2m32_imm8: case OP_xmm1_xmm2m128_imm8: case OP_reg_xmm1_imm8: @@ -169,9 +171,14 @@ static void build(InstructionDescriptor* table, u8 op, char const* mnemonic, Ins case OP_xmm1_m64: case OP_m64_xmm2: case OP_rm8_xmm2m32: + case OP_r32_xmm2m64: + case OP_rm32_xmm2: case OP_xmm1_mm2m64: + case OP_xmm_mm: + case OP_mm_xmm: case OP_mm1m64_xmm2: case OP_mm1_xmm2m64: + case OP_mm1_xmm2m128: case OP_r32_xmm2m32: case __EndFormatsWithRMByte: case OP_CS: @@ -309,15 +316,12 @@ static void build_slash_reg(u8 op, u8 slash, char const* mnemonic, InstructionFo static void build_sse_np(u8 op, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed) { - if (s_0f_table32[op].format == InvalidFormat) { - build_0f(op, mnemonic, format, impl, lock_prefix_allowed); - build(s_sse_table_np, op, mnemonic, format, impl, lock_prefix_allowed); - return; - } if (s_0f_table32[op].format != __SSE) build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed); VERIFY(s_0f_table32[op].format == __SSE); + VERIFY(s_sse_table_np[op].format == InvalidFormat); + build(s_sse_table_np, op, mnemonic, format, impl, lock_prefix_allowed); } @@ -326,6 +330,8 @@ static void build_sse_66(u8 op, char const* mnemonic, InstructionFormat format, if (s_0f_table32[op].format != __SSE) build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed); VERIFY(s_0f_table32[op].format == __SSE); + VERIFY(s_sse_table_66[op].format == InvalidFormat); + build(s_sse_table_66, op, mnemonic, format, impl, lock_prefix_allowed); } @@ -334,9 +340,38 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, if (s_0f_table32[op].format != __SSE) build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed); VERIFY(s_0f_table32[op].format == __SSE); + VERIFY(s_sse_table_f3[op].format == InvalidFormat); + build(s_sse_table_f3, op, mnemonic, format, impl, lock_prefix_allowed); } +static void build_sse_f2(u8 op, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed) +{ + if (s_0f_table32[op].format != __SSE) + build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed); + VERIFY(s_0f_table32[op].format == __SSE); + VERIFY(s_sse_table_f2[op].format == InvalidFormat); + + build(s_sse_table_f2, op, mnemonic, format, impl, lock_prefix_allowed); +} + +static void build_sse_np_slash(u8 op, u8 slash, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed) +{ + if (s_0f_table32[op].format != __SSE) + build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed); + + VERIFY(s_0f_table32[op].format == __SSE); + build_slash(s_sse_table_np, op, slash, mnemonic, format, impl, lock_prefix_allowed); +} + +static void build_sse_66_slash(u8 op, u8 slash, char const* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed) +{ + if (s_0f_table32[op].format != __SSE) + build_0f(op, "__SSE_temp", __SSE, nullptr, lock_prefix_allowed); + VERIFY(s_0f_table32[op].format == __SSE); + build_slash(s_sse_table_66, op, slash, mnemonic, format, impl, lock_prefix_allowed); +} + [[gnu::constructor]] static void build_opcode_tables() { build(0x00, "ADD", OP_RM8_reg8, &Interpreter::ADD_RM8_reg8, LockPrefixAllowed); @@ -845,14 +880,23 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, build_0f(0x0B, "UD2", OP, &Interpreter::UD2); build_sse_np(0x10, "MOVUPS", OP_xmm1_xmm2m128, &Interpreter::MOVUPS_xmm1_xmm2m128); + build_sse_66(0x10, "MOVUPD", OP_xmm1_xmm2m128, &Interpreter::MOVUPD_xmm1_xmm2m128); build_sse_f3(0x10, "MOVSS", OP_xmm1_xmm2m32, &Interpreter::MOVSS_xmm1_xmm2m32); + build_sse_f2(0x10, "MOVSD", OP_xmm1_xmm2m32, &Interpreter::MOVSD_xmm1_xmm2m32); build_sse_np(0x11, "MOVUPS", OP_xmm1m128_xmm2, &Interpreter::MOVUPS_xmm1m128_xmm2); + build_sse_66(0x11, "MOVUPD", OP_xmm1m128_xmm2, &Interpreter::MOVUPD_xmm1m128_xmm2); build_sse_f3(0x11, "MOVSS", OP_xmm1m32_xmm2, &Interpreter::MOVSS_xmm1m32_xmm2); + build_sse_f2(0x11, "MOVSD", OP_xmm1m32_xmm2, &Interpreter::MOVSD_xmm1m32_xmm2); build_sse_np(0x12, "MOVLPS", OP_xmm1_xmm2m64, &Interpreter::MOVLPS_xmm1_xmm2m64); // FIXME: This mnemonic is MOVHLPS when providing xmm2 + build_sse_66(0x12, "MOVLPD", OP_xmm1_m64, &Interpreter::MOVLPD_xmm1_m64); build_sse_np(0x13, "MOVLPS", OP_m64_xmm2, &Interpreter::MOVLPS_m64_xmm2); - build_sse_np(0x14, "UNPCKLS", OP_xmm1_xmm2m128, &Interpreter::UNPCKLPS_xmm1_xmm2m128); - build_sse_np(0x15, "UNPCKHS", OP_xmm1_xmm2m128, &Interpreter::UNPCKHPS_xmm1_xmm2m128); + build_sse_66(0x13, "MOVLPD", OP_m64_xmm2, &Interpreter::MOVLPD_m64_xmm2); + build_sse_np(0x14, "UNPCKLPS", OP_xmm1_xmm2m128, &Interpreter::UNPCKLPS_xmm1_xmm2m128); + build_sse_66(0x14, "UNPCKLPD", OP_xmm1_xmm2m128, &Interpreter::UNPCKLPD_xmm1_xmm2m128); + build_sse_np(0x15, "UNPCKHPS", OP_xmm1_xmm2m128, &Interpreter::UNPCKHPS_xmm1_xmm2m128); + build_sse_66(0x15, "UNPCKHPD", OP_xmm1_xmm2m128, &Interpreter::UNPCKHPD_xmm1_xmm2m128); build_sse_np(0x16, "MOVHPS", OP_xmm1_xmm2m64, &Interpreter::MOVHPS_xmm1_xmm2m64); // FIXME: This mnemonic is MOVLHPS when providing xmm2 + build_sse_66(0x16, "MOVHPD", OP_xmm1_xmm2m64, &Interpreter::MOVHPD_xmm1_xmm2m64); // FIXME: This mnemonic is MOVLHPS when providing xmm2 build_sse_np(0x17, "MOVHPS", OP_m64_xmm2, &Interpreter::MOVHPS_m64_xmm2); build_0f(0x20, "MOV", OP_reg32_CR, &Interpreter::MOV_reg32_CR); @@ -861,17 +905,27 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, build_0f(0x23, "MOV", OP_DR_reg32, &Interpreter::MOV_DR_reg32); build_sse_np(0x28, "MOVAPS", OP_xmm1_xmm2m128, &Interpreter::MOVAPS_xmm1_xmm2m128); + build_sse_66(0x28, "MOVAPD", OP_xmm1_xmm2m128, &Interpreter::MOVAPD_xmm1_xmm2m128); build_sse_np(0x29, "MOVAPS", OP_xmm1m128_xmm2, &Interpreter::MOVAPS_xmm1m128_xmm2); + build_sse_66(0x29, "MOVAPD", OP_xmm1m128_xmm2, &Interpreter::MOVAPD_xmm1m128_xmm2); build_sse_np(0x2A, "CVTPI2PS", OP_xmm1_mm2m64, &Interpreter::CVTPI2PS_xmm1_mm2m64); + build_sse_66(0x2A, "CVTPI2PD", OP_xmm1_mm2m64, &Interpreter::CVTPI2PD_xmm1_mm2m64); build_sse_f3(0x2A, "CVTSI2SS", OP_xmm1_rm32, &Interpreter::CVTSI2SS_xmm1_rm32); + build_sse_f2(0x2A, "CVTSI2SD", OP_xmm1_rm32, &Interpreter::CVTSI2SD_xmm1_rm32); build_sse_np(0x2B, "MOVNTPS", OP_xmm1m128_xmm2, &Interpreter::MOVNTPS_xmm1m128_xmm2); build_sse_np(0x2C, "CVTTPS2PI", OP_mm1_xmm2m64, &Interpreter::CVTTPS2PI_mm1_xmm2m64); + build_sse_66(0x2C, "CVTTPD2PI", OP_mm1_xmm2m128, &Interpreter::CVTTPD2PI_mm1_xmm2m128); build_sse_f3(0x2C, "CVTTSS2SI", OP_r32_xmm2m32, &Interpreter::CVTTSS2SI_r32_xmm2m32); + build_sse_f2(0x2C, "CVTTSD2SI", OP_r32_xmm2m64, &Interpreter::CVTTSS2SI_r32_xmm2m64); build_sse_np(0x2D, "CVTPS2PI", OP_mm1_xmm2m64, &Interpreter::CVTPS2PI_xmm1_mm2m64); + build_sse_66(0x2D, "CVTPD2PI", OP_mm1_xmm2m128, &Interpreter::CVTPD2PI_xmm1_mm2m128); build_sse_f3(0x2D, "CVTSS2SI", OP_r32_xmm2m32, &Interpreter::CVTSS2SI_r32_xmm2m32); + build_sse_f2(0x2D, "CVTSD2SI", OP_r32_xmm2m64, &Interpreter::CVTSD2SI_xmm1_rm64); build_sse_np(0x2E, "UCOMISS", OP_xmm1_xmm2m32, &Interpreter::UCOMISS_xmm1_xmm2m32); + build_sse_66(0x2E, "UCOMISD", OP_xmm1_xmm2m64, &Interpreter::UCOMISD_xmm1_xmm2m64); build_sse_np(0x2F, "COMISS", OP_xmm1_xmm2m32, &Interpreter::COMISS_xmm1_xmm2m32); + build_sse_66(0x2F, "COMISD", OP_xmm1_xmm2m64, &Interpreter::COMISD_xmm1_xmm2m64); build_0f(0x31, "RDTSC", OP, &Interpreter::RDTSC); @@ -893,30 +947,56 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, build_0f(0x4F, "CMOVG", OP_reg16_RM16, &Interpreter::CMOVcc_reg16_RM16, OP_reg32_RM32, &Interpreter::CMOVcc_reg32_RM32); build_sse_np(0x50, "MOVMSKPS", OP_reg_xmm1, &Interpreter::MOVMSKPS_reg_xmm); + build_sse_66(0x50, "MOVMSKPD", OP_reg_xmm1, &Interpreter::MOVMSKPD_reg_xmm); build_sse_np(0x51, "SQRTPS", OP_xmm1_xmm2m128, &Interpreter::SQRTPS_xmm1_xmm2m128); + build_sse_66(0x51, "SQRTPD", OP_xmm1_xmm2m128, &Interpreter::SQRTPD_xmm1_xmm2m128); build_sse_f3(0x51, "SQRTSS", OP_xmm1_xmm2m32, &Interpreter::SQRTSS_xmm1_xmm2m32); + build_sse_f2(0x51, "SQRTSD", OP_xmm1_xmm2m32, &Interpreter::SQRTSD_xmm1_xmm2m32); build_sse_np(0x52, "RSQRTPS", OP_xmm1_xmm2m128, &Interpreter::RSQRTPS_xmm1_xmm2m128); build_sse_f3(0x52, "RSQRTSS", OP_xmm1_xmm2m32, &Interpreter::RSQRTSS_xmm1_xmm2m32); build_sse_np(0x53, "RCPPS", OP_xmm1_xmm2m128, &Interpreter::RCPPS_xmm1_xmm2m128); build_sse_f3(0x53, "RCPSS", OP_xmm1_xmm2m32, &Interpreter::RCPSS_xmm1_xmm2m32); build_sse_np(0x54, "ANDPS", OP_xmm1_xmm2m128, &Interpreter::ANDPS_xmm1_xmm2m128); + build_sse_66(0x54, "ANDPD", OP_xmm1_xmm2m128, &Interpreter::ANDPD_xmm1_xmm2m128); build_sse_np(0x55, "ANDNPS", OP_xmm1_xmm2m128, &Interpreter::ANDNPS_xmm1_xmm2m128); + build_sse_66(0x55, "ANDNPD", OP_xmm1_xmm2m128, &Interpreter::ANDNPD_xmm1_xmm2m128); build_sse_np(0x56, "ORPS", OP_xmm1_xmm2m128, &Interpreter::ORPS_xmm1_xmm2m128); + build_sse_66(0x56, "ORPD", OP_xmm1_xmm2m128, &Interpreter::ORPD_xmm1_xmm2m128); build_sse_np(0x57, "XORPS", OP_xmm1_xmm2m128, &Interpreter::XORPS_xmm1_xmm2m128); + build_sse_66(0x57, "XORPD", OP_xmm1_xmm2m128, &Interpreter::XORPD_xmm1_xmm2m128); build_sse_np(0x58, "ADDPS", OP_xmm1_xmm2m128, &Interpreter::ADDPS_xmm1_xmm2m128); + build_sse_66(0x58, "ADDPD", OP_xmm1_xmm2m128, &Interpreter::ADDPD_xmm1_xmm2m128); build_sse_f3(0x58, "ADDSS", OP_xmm1_xmm2m32, &Interpreter::ADDSS_xmm1_xmm2m32); + build_sse_f2(0x58, "ADDSD", OP_xmm1_xmm2m32, &Interpreter::ADDSD_xmm1_xmm2m32); build_sse_np(0x59, "MULPS", OP_xmm1_xmm2m128, &Interpreter::MULPS_xmm1_xmm2m128); + build_sse_66(0x59, "MULPD", OP_xmm1_xmm2m128, &Interpreter::MULPD_xmm1_xmm2m128); build_sse_f3(0x59, "MULSS", OP_xmm1_xmm2m32, &Interpreter::MULSS_xmm1_xmm2m32); + build_sse_f2(0x59, "MULSD", OP_xmm1_xmm2m32, &Interpreter::MULSD_xmm1_xmm2m32); + build_sse_np(0x5A, "CVTPS2PD", OP_xmm1_xmm2m64, &Interpreter::CVTPS2PD_xmm1_xmm2m64); + build_sse_66(0x5A, "CVTPD2PS", OP_xmm1_xmm2m128, &Interpreter::CVTPD2PS_xmm1_xmm2m128); + build_sse_f3(0x5A, "CVTSS2SD", OP_xmm1_xmm2m32, &Interpreter::CVTSS2SD_xmm1_xmm2m32); + build_sse_f2(0x5A, "CVTSD2SS", OP_xmm1_xmm2m64, &Interpreter::CVTSD2SS_xmm1_xmm2m64); + build_sse_np(0x5B, "CVTDQ2PS", OP_xmm1_xmm2m128, &Interpreter::CVTDQ2PS_xmm1_xmm2m128); + build_sse_66(0x5B, "CVTPS2DQ", OP_xmm1_xmm2m128, &Interpreter::CVTPS2DQ_xmm1_xmm2m128); + build_sse_f3(0x5B, "CVTTPS2DQ", OP_xmm1_xmm2m128, &Interpreter::CVTTPS2DQ_xmm1_xmm2m128); build_sse_np(0x5C, "SUBPS", OP_xmm1_xmm2m128, &Interpreter::SUBPS_xmm1_xmm2m128); + build_sse_66(0x5C, "SUBPD", OP_xmm1_xmm2m128, &Interpreter::SUBPD_xmm1_xmm2m128); build_sse_f3(0x5C, "SUBSS", OP_xmm1_xmm2m32, &Interpreter::SUBSS_xmm1_xmm2m32); + build_sse_f2(0x5C, "SUBSD", OP_xmm1_xmm2m32, &Interpreter::SUBSD_xmm1_xmm2m32); build_sse_np(0x5D, "MINPS", OP_xmm1_xmm2m128, &Interpreter::MINPS_xmm1_xmm2m128); + build_sse_66(0x5D, "MINPD", OP_xmm1_xmm2m128, &Interpreter::MINPD_xmm1_xmm2m128); build_sse_f3(0x5D, "MINSS", OP_xmm1_xmm2m32, &Interpreter::MINSS_xmm1_xmm2m32); + build_sse_f2(0x5D, "MINSD", OP_xmm1_xmm2m32, &Interpreter::MINSD_xmm1_xmm2m32); build_sse_np(0x5E, "DIVPS", OP_xmm1_xmm2m128, &Interpreter::DIVPS_xmm1_xmm2m128); + build_sse_66(0x5E, "DIVPD", OP_xmm1_xmm2m128, &Interpreter::DIVPD_xmm1_xmm2m128); build_sse_f3(0x5E, "DIVSS", OP_xmm1_xmm2m32, &Interpreter::DIVSS_xmm1_xmm2m32); + build_sse_f2(0x5E, "DIVSD", OP_xmm1_xmm2m32, &Interpreter::DIVSD_xmm1_xmm2m32); build_sse_np(0x5F, "MAXPS", OP_xmm1_xmm2m128, &Interpreter::MAXPS_xmm1_xmm2m128); + build_sse_66(0x5F, "MAXPD", OP_xmm1_xmm2m128, &Interpreter::MAXPD_xmm1_xmm2m128); build_sse_f3(0x5F, "MAXSS", OP_xmm1_xmm2m32, &Interpreter::MAXSS_xmm1_xmm2m32); + build_sse_f2(0x5F, "MAXSD", OP_xmm1_xmm2m32, &Interpreter::MAXSD_xmm1_xmm2m32); build_0f(0x60, "PUNPCKLBW", OP_mm1_mm2m32, &Interpreter::PUNPCKLBW_mm1_mm2m32); build_0f(0x61, "PUNPCKLWD", OP_mm1_mm2m32, &Interpreter::PUNPCKLWD_mm1_mm2m32); @@ -930,27 +1010,42 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, build_0f(0x69, "PUNPCKHWD", OP_mm1_mm2m64, &Interpreter::PUNPCKHWD_mm1_mm2m64); build_0f(0x6A, "PUNPCKHDQ", OP_mm1_mm2m64, &Interpreter::PUNPCKHDQ_mm1_mm2m64); build_0f(0x6B, "PACKSSDW", OP_mm1_mm2m64, &Interpreter::PACKSSDW_mm1_mm2m64); - build_0f(0x6E, "MOVD", OP_mm1_rm32, &Interpreter::MOVD_mm1_rm32); - build_0f(0x6F, "MOVQ", OP_mm1_mm2m64, &Interpreter::MOVQ_mm1_mm2m64); + build_sse_66(0x6C, "PUNPCKLQDQ", OP_xmm1_xmm2m128, &Interpreter::PUNPCKLQDQ_xmm1_xmm2m128); + build_sse_66(0x6D, "PUNPCKHQDQ", OP_xmm1_xmm2m128, &Interpreter::PUNPCKHQDQ_xmm1_xmm2m128); + build_0f(0x6E, "MOVD", OP_mm1_rm32, &Interpreter::MOVD_mm1_rm32); // FIXME: REX.W -> MOVQ + build_sse_np(0x6F, "MOVQ", OP_mm1_mm2m64, &Interpreter::MOVQ_mm1_mm2m64); + build_sse_66(0x6F, "MOVDQA", OP_xmm1_xmm2m128, &Interpreter::MOVDQA_xmm1_xmm2m128); + build_sse_f3(0x6F, "MOVDQU", OP_xmm1_xmm2m128, &Interpreter::MOVDQU_xmm1_xmm2m128); build_sse_np(0x70, "PSHUFW", OP_mm1_mm2m64_imm8, &Interpreter::PSHUFW_mm1_mm2m64_imm8); - build_0f_slash(0x71, 2, "PSRLW", OP_mm1_imm8, &Interpreter::PSRLW_mm1_mm2m64); + build_sse_66(0x70, "PSHUFD", OP_xmm1_xmm2m128_imm8, &Interpreter::PSHUFD_xmm1_xmm2m128_imm8); + build_sse_f3(0x70, "PSHUFHW", OP_xmm1_xmm2m128_imm8, &Interpreter::PSHUFHW_xmm1_xmm2m128_imm8); + build_sse_f2(0x70, "PSHUFLW", OP_xmm1_xmm2m128_imm8, &Interpreter::PSHUFLW_xmm1_xmm2m128_imm8); + build_0f_slash(0x71, 2, "PSRLW", OP_mm1_imm8, &Interpreter::PSRLW_mm1_imm8); build_0f_slash(0x71, 4, "PSRAW", OP_mm1_imm8, &Interpreter::PSRAW_mm1_imm8); build_0f_slash(0x71, 6, "PSLLW", OP_mm1_imm8, &Interpreter::PSLLD_mm1_imm8); - build_0f_slash(0x72, 2, "PSRLD", OP_mm1_imm8, &Interpreter::PSRLD_mm1_mm2m64); + build_0f_slash(0x72, 2, "PSRLD", OP_mm1_imm8, &Interpreter::PSRLD_mm1_imm8); build_0f_slash(0x72, 4, "PSRAD", OP_mm1_imm8, &Interpreter::PSRAD_mm1_imm8); build_0f_slash(0x72, 6, "PSLLW", OP_mm1_imm8, &Interpreter::PSLLW_mm1_imm8); - build_0f_slash(0x73, 2, "PSRLQ", OP_mm1_imm8, &Interpreter::PSRLQ_mm1_mm2m64); - build_0f_slash(0x73, 6, "PSLLQ", OP_mm1_imm8, &Interpreter::PSLLQ_mm1_imm8); + build_sse_np_slash(0x73, 2, "PSRLQ", OP_mm1_imm8, &Interpreter::PSRLQ_mm1_imm8); + build_sse_66_slash(0x73, 2, "PSRLQ", OP_xmm1_imm8, &Interpreter::PSRLQ_xmm1_imm8); + build_sse_66_slash(0x73, 3, "PSRLDQ", OP_xmm1_imm8, &Interpreter::PSRLDQ_xmm1_imm8); + build_sse_np_slash(0x73, 6, "PSLLQ", OP_mm1_imm8, &Interpreter::PSLLQ_mm1_imm8); + build_sse_66_slash(0x73, 6, "PSLLQ", OP_xmm1_imm8, &Interpreter::PSLLQ_xmm1_imm8); + build_sse_66_slash(0x73, 7, "PSLLDQ", OP_xmm1_imm8, &Interpreter::PSLLDQ_xmm1_imm8); build_0f(0x74, "PCMPEQB", OP_mm1_mm2m64, &Interpreter::PCMPEQB_mm1_mm2m64); - build_0f(0x76, "PCMPEQD", OP_mm1_mm2m64, &Interpreter::PCMPEQD_mm1_mm2m64); build_0f(0x75, "PCMPEQW", OP_mm1_mm2m64, &Interpreter::PCMPEQW_mm1_mm2m64); - build_0f(0x77, "EMMS", OP, &Interpreter::EMMS); - build_0f(0x7E, "MOVD", OP_rm32_mm2, &Interpreter::MOVD_rm32_mm2); - build_0f(0x7F, "MOVQ", OP_mm1m64_mm2, &Interpreter::MOVQ_mm1m64_mm2); + build_0f(0x76, "PCMPEQD", OP_mm1_mm2m64, &Interpreter::PCMPEQD_mm1_mm2m64); + build_0f(0x77, "EMMS", OP, &Interpreter::EMMS); // Technically NP + build_sse_np(0x7E, "MOVD", OP_rm32_mm2, &Interpreter::MOVD_rm32_mm2); // FIXME: REW.W -> MOVQ + build_sse_66(0x7E, "MOVD", OP_rm32_xmm2, &Interpreter::MOVD_rm32_xmm2); // FIXME: REW.W -> MOVQ + build_sse_f3(0x7E, "MOVQ", OP_xmm1_xmm2m128, &Interpreter::MOVQ_xmm1_xmm2m128); + build_sse_np(0x7F, "MOVQ", OP_mm1m64_mm2, &Interpreter::MOVQ_mm1m64_mm2); + build_sse_66(0x7F, "MOVDQA", OP_xmm1m128_xmm2, &Interpreter::MOVDQA_xmm1m128_xmm2); + build_sse_f3(0x7F, "MOVDQU", OP_xmm1m128_xmm2, &Interpreter::MOVDQU_xmm1m128_xmm2); build_0f(0x80, "JO", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm); build_0f(0x81, "JNO", OP_NEAR_imm, &Interpreter::Jcc_NEAR_imm); @@ -1015,13 +1110,16 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, build_0f(0xC0, "XADD", OP_RM8_reg8, &Interpreter::XADD_RM8_reg8, LockPrefixAllowed); build_0f(0xC1, "XADD", OP_RM16_reg16, &Interpreter::XADD_RM16_reg16, OP_RM32_reg32, &Interpreter::XADD_RM32_reg32, LockPrefixAllowed); build_sse_np(0xC2, "CMPPS", OP_xmm1_xmm2m128_imm8, &Interpreter::CMPPS_xmm1_xmm2m128_imm8); + build_sse_66(0xC2, "CMPPD", OP_xmm1_xmm2m128_imm8, &Interpreter::CMPPD_xmm1_xmm2m128_imm8); build_sse_f3(0xC2, "CMPSS", OP_xmm1_xmm2m32_imm8, &Interpreter::CMPSS_xmm1_xmm2m32_imm8); + build_sse_f2(0xC2, "CMPSD", OP_xmm1_xmm2m32_imm8, &Interpreter::CMPSD_xmm1_xmm2m32_imm8); - build_sse_np(0xC5, "PINSRW", OP_mm1_r32m16_imm8, &Interpreter::PINSRW_mm1_r32m16_imm8); - build_sse_66(0xC5, "PINSRW", OP_xmm1_r32m16_imm8, &Interpreter::PINSRW_xmm1_r32m16_imm8); + build_sse_np(0xC4, "PINSRW", OP_mm1_r32m16_imm8, &Interpreter::PINSRW_mm1_r32m16_imm8); + build_sse_66(0xC4, "PINSRW", OP_xmm1_r32m16_imm8, &Interpreter::PINSRW_xmm1_r32m16_imm8); build_sse_np(0xC5, "PEXTRW", OP_reg_mm1_imm8, &Interpreter::PEXTRW_reg_mm1_imm8); build_sse_66(0xC5, "PEXTRW", OP_reg_xmm1_imm8, &Interpreter::PEXTRW_reg_xmm1_imm8); 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); for (u8 i = 0xc8; i <= 0xcf; ++i) build_0f(i, "BSWAP", OP_reg32, &Interpreter::BSWAP_reg32); @@ -1029,8 +1127,12 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, build_0f(0xD1, "PSRLW", OP_mm1_mm2m64, &Interpreter::PSRLW_mm1_mm2m64); build_0f(0xD2, "PSRLD", OP_mm1_mm2m64, &Interpreter::PSRLD_mm1_mm2m64); build_0f(0xD3, "PSRLQ", OP_mm1_mm2m64, &Interpreter::PSRLQ_mm1_mm2m64); + build_0f(0xD4, "PADDQ", OP_mm1_mm2m64, &Interpreter::PADDQ_mm1_mm2m64); build_0f(0xD5, "PMULLW", OP_mm1_mm2m64, &Interpreter::PMULLW_mm1_mm2m64); + build_sse_66(0xD6, "MOVQ", OP_xmm1m128_xmm2, &Interpreter::MOVQ_xmm1m128_xmm2); + build_sse_f3(0xD6, "MOVQ2DQ", OP_xmm_mm, &Interpreter::MOVQ2DQ_xmm_mm); + build_sse_f2(0xD6, "MOVDQ2Q", OP_mm_xmm, &Interpreter::MOVDQ2Q_mm_xmm); build_sse_np(0xD7, "PMOVMSKB", OP_reg_mm1, &Interpreter::PMOVMSKB_reg_mm1); build_sse_66(0xD7, "PMOVMSKB", OP_reg_xmm1, &Interpreter::PMOVMSKB_reg_xmm1); @@ -1055,6 +1157,9 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, build_sse_66(0xE4, "PMULHUW ", OP_xmm1_xmm2m64, &Interpreter::PMULHUW_xmm1_xmm2m64); build_0f(0xE5, "PMULHW", OP_mm1_mm2m64, &Interpreter::PMULHW_mm1_mm2m64); + build_sse_66(0xE6, "CVTTPD2DQ", OP_xmm1_xmm2m128, &Interpreter::CVTTPD2DQ_xmm1_xmm2m128); + build_sse_f2(0xE6, "CVTPD2DQ", OP_xmm1_xmm2m128, &Interpreter::CVTPD2DQ_xmm1_xmm2m128); + build_sse_f3(0xE6, "CVTDQ2PD", OP_xmm1_xmm2m64, &Interpreter::CVTDQ2PD_xmm1_xmm2m64); build_sse_np(0xE7, "MOVNTQ", OP_mm1m64_mm2, &Interpreter::MOVNTQ_m64_mm1); build_sse_np(0xEA, "PMINSB", OP_mm1_mm2m64, &Interpreter::PMINSB_mm1_mm2m64); @@ -1073,6 +1178,8 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, build_0f(0xF1, "PSLLW", OP_mm1_mm2m64, &Interpreter::PSLLW_mm1_mm2m64); build_0f(0xF2, "PSLLD", OP_mm1_mm2m64, &Interpreter::PSLLD_mm1_mm2m64); build_0f(0xF3, "PSLLQ", OP_mm1_mm2m64, &Interpreter::PSLLQ_mm1_mm2m64); + build_sse_np(0xF4, "PMULUDQ", OP_mm1_mm2m64, &Interpreter::PMULUDQ_mm1_mm2m64); + build_sse_66(0xF4, "PMULUDQ", OP_xmm1_xmm2m128, &Interpreter::PMULUDQ_mm1_mm2m128); build_0f(0xF5, "PMADDWD", OP_mm1_mm2m64, &Interpreter::PMADDWD_mm1_mm2m64); build_sse_np(0xF6, "PSADBW", OP_mm1_mm2m64, &Interpreter::PSADBB_mm1_mm2m64); build_sse_66(0xF6, "PSADBW", OP_xmm1_xmm2m128, &Interpreter::PSADBB_xmm1_xmm2m128); @@ -1080,6 +1187,7 @@ static void build_sse_f3(u8 op, char const* mnemonic, InstructionFormat format, build_0f(0xF8, "PSUBB", OP_mm1_mm2m64, &Interpreter::PSUBB_mm1_mm2m64); build_0f(0xF9, "PSUBW", OP_mm1_mm2m64, &Interpreter::PSUBW_mm1_mm2m64); build_0f(0xFA, "PSUBD", OP_mm1_mm2m64, &Interpreter::PSUBD_mm1_mm2m64); + build_0f(0xFB, "PSUBQ", OP_mm1_mm2m64, &Interpreter::PSUBQ_mm1_mm2m64); build_0f(0xFC, "PADDB", OP_mm1_mm2m64, &Interpreter::PADDB_mm1_mm2m64); build_0f(0xFD, "PADDW", OP_mm1_mm2m64, &Interpreter::PADDW_mm1_mm2m64); build_0f(0xFE, "PADDD", OP_mm1_mm2m64, &Interpreter::PADDD_mm1_mm2m64); @@ -1414,7 +1522,8 @@ String Instruction::to_string(u32 origin, SymbolProvider const* symbol_provider, builder.appendff("{}: ", register_name(segment_prefix().value())); if (has_address_size_override_prefix()) builder.append(m_a32 ? "a32 " : "a16 "); - if (has_operand_size_override_prefix()) + // Note: SSE2 Uses this to change to doubles in SSE instruction or xmm registers in MMX instructions + if (has_operand_size_override_prefix() && !(m_descriptor->format > __SSE && m_descriptor->format < __EndFormatsWithRMByte)) builder.append(m_o32 ? "o32 " : "o16 "); if (has_lock_prefix()) builder.append("lock "); @@ -1491,6 +1600,22 @@ void Instruction::to_string_internal(StringBuilder& builder, u32 origin, SymbolP auto append_xmmrm64 = [&] { builder.append(m_modrm.to_string_xmm(*this)); }; auto append_xmmrm128 = [&] { builder.append(m_modrm.to_string_xmm(*this)); }; + auto append_mm_or_xmm = [&] { + if (has_operand_size_override_prefix()) + append_xmm(); + else + append_mm(); + }; + + auto append_mm_or_xmm_or_mem = [&] { + // FIXME: The sizes here dont fully match what is meant, but it does + // not really matter... + if (has_operand_size_override_prefix()) + append_xmmrm128(); + else + append_mmrm64(); + }; + auto append = [&](auto& content) { builder.append(content); }; auto append_moff = [&] { builder.append('['); @@ -2008,19 +2133,19 @@ void Instruction::to_string_internal(StringBuilder& builder, u32 origin, SymbolP break; case OP_mm1_imm8: append_mnemonic_space(); - append_mm(); + append_mm_or_xmm(); append(", "); append_imm8(); break; case OP_mm1_mm2m32: append_mnemonic_space(); - append_mm(); + append_mm_or_xmm(); append(", "); - append_mmrm32(); + append_mm_or_xmm_or_mem(); break; case OP_mm1_rm32: append_mnemonic_space(); - append_mm(); + append_mm_or_xmm(); append(", "); append_rm32(); break; @@ -2028,25 +2153,25 @@ void Instruction::to_string_internal(StringBuilder& builder, u32 origin, SymbolP append_mnemonic_space(); append_rm32(); append(", "); - append_mm(); + append_mm_or_xmm(); break; case OP_mm1_mm2m64: append_mnemonic_space(); - append_mm(); + append_mm_or_xmm(); append(", "); - append_mmrm64(); + append_mm_or_xmm_or_mem(); break; case OP_mm1m64_mm2: append_mnemonic_space(); - append_mmrm64(); + append_mm_or_xmm_or_mem(); append(", "); - append_mm(); + append_mm_or_xmm(); break; case OP_mm1_mm2m64_imm8: append_mnemonic_space(); - append_mm(); + append_mm_or_xmm(); append(", "); - append_mmrm64(); + append_mm_or_xmm_or_mem(); append(", "); append_imm8(); break; @@ -2054,25 +2179,44 @@ void Instruction::to_string_internal(StringBuilder& builder, u32 origin, SymbolP append_mnemonic_space(); append_rm32(); append(", "); - append_mm(); + append_mm_or_xmm(); break; case OP_reg_mm1_imm8: append_mnemonic_space(); append_reg32(); append(", "); - append_mmrm64(); + append_mm_or_xmm_or_mem(); append(", "); append_imm8(); break; case OP_mm1_r32m16_imm8: append_mnemonic_space(); - append_mm(); + append_mm_or_xmm(); append_rm32(); // FIXME: r32m16 append(", "); append_imm8(); break; case __SSE: break; + case OP_xmm_mm: + append_mnemonic_space(); + append_xmm(); + append(", "); + append_mmrm32(); // FIXME: No Memmory + break; + case OP_mm1_xmm2m128: + case OP_mm_xmm: + append_mnemonic_space(); + append_mm(); + append(", "); + append_xmmrm32(); // FIXME: No Memmory + break; + case OP_xmm1_imm8: + append_mnemonic_space(); + append_xmm(); + append(", "); + append_imm8(); + break; case OP_xmm1_xmm2m32: append_mnemonic_space(); append_xmm(); @@ -2126,11 +2270,18 @@ void Instruction::to_string_internal(StringBuilder& builder, u32 origin, SymbolP append_xmm(); break; case OP_reg_xmm1: + case OP_r32_xmm2m64: append_mnemonic_space(); append_reg32(); append(", "); append_xmmrm128(); // second entry in the rm byte break; + case OP_rm32_xmm2: + append_mnemonic_space(); + append_rm32(); + append(", "); + append_xmm(); + break; case OP_reg_xmm1_imm8: append_mnemonic_space(); append_reg32(); diff --git a/Userland/Libraries/LibX86/Instruction.h b/Userland/Libraries/LibX86/Instruction.h index 5ac628fb52..79f9059526 100644 --- a/Userland/Libraries/LibX86/Instruction.h +++ b/Userland/Libraries/LibX86/Instruction.h @@ -118,6 +118,7 @@ enum InstructionFormat { OP_reg_mm1_imm8, OP_mm1_r32m16_imm8, + OP_xmm1_imm8, OP_xmm1_xmm2m32, OP_xmm1_xmm2m64, OP_xmm1_xmm2m128, @@ -128,14 +129,19 @@ enum InstructionFormat { OP_xmm1m128_xmm2, OP_reg_xmm1, OP_reg_xmm1_imm8, + OP_r32_xmm2m32, + OP_r32_xmm2m64, + OP_rm32_xmm2, OP_xmm1_rm32, OP_xmm1_m64, OP_m64_xmm2, OP_rm8_xmm2m32, + OP_xmm_mm, OP_xmm1_mm2m64, OP_mm1m64_xmm2, + OP_mm_xmm, OP_mm1_xmm2m64, - OP_r32_xmm2m32, + OP_mm1_xmm2m128, OP_xmm1_r32m16_imm8, __EndFormatsWithRMByte, diff --git a/Userland/Libraries/LibX86/Interpreter.h b/Userland/Libraries/LibX86/Interpreter.h index 2cb489ecc4..c8ab6c3d81 100644 --- a/Userland/Libraries/LibX86/Interpreter.h +++ b/Userland/Libraries/LibX86/Interpreter.h @@ -736,6 +736,80 @@ public: virtual void PSADBB_xmm1_xmm2m128(Instruction const&) = 0; virtual void MASKMOVQ_mm1_mm2m64(Instruction const&) = 0; + virtual void MOVUPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void MOVSD_xmm1_xmm2m32(Instruction const&) = 0; + virtual void MOVUPD_xmm1m128_xmm2(Instruction const&) = 0; + virtual void MOVSD_xmm1m32_xmm2(Instruction const&) = 0; + virtual void MOVLPD_xmm1_m64(Instruction const&) = 0; + virtual void MOVLPD_m64_xmm2(Instruction const&) = 0; + virtual void UNPCKLPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void UNPCKHPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void MOVHPD_xmm1_xmm2m64(Instruction const&) = 0; + virtual void MOVAPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void MOVAPD_xmm1m128_xmm2(Instruction const&) = 0; + virtual void CVTPI2PD_xmm1_mm2m64(Instruction const&) = 0; + virtual void CVTSI2SD_xmm1_rm32(Instruction const&) = 0; + virtual void CVTTPD2PI_mm1_xmm2m128(Instruction const&) = 0; + virtual void CVTTSS2SI_r32_xmm2m64(Instruction const&) = 0; + virtual void CVTPD2PI_xmm1_mm2m128(Instruction const&) = 0; + virtual void CVTSD2SI_xmm1_rm64(Instruction const&) = 0; + virtual void UCOMISD_xmm1_xmm2m64(Instruction const&) = 0; + virtual void COMISD_xmm1_xmm2m64(Instruction const&) = 0; + virtual void MOVMSKPD_reg_xmm(Instruction const&) = 0; + virtual void SQRTPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void SQRTSD_xmm1_xmm2m32(Instruction const&) = 0; + virtual void ANDPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void ANDNPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void ORPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void XORPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void ADDPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void ADDSD_xmm1_xmm2m32(Instruction const&) = 0; + virtual void MULPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void MULSD_xmm1_xmm2m32(Instruction const&) = 0; + virtual void CVTPS2PD_xmm1_xmm2m64(Instruction const&) = 0; + virtual void CVTPD2PS_xmm1_xmm2m128(Instruction const&) = 0; + virtual void CVTSS2SD_xmm1_xmm2m32(Instruction const&) = 0; + virtual void CVTSD2SS_xmm1_xmm2m64(Instruction const&) = 0; + virtual void CVTDQ2PS_xmm1_xmm2m128(Instruction const&) = 0; + virtual void CVTPS2DQ_xmm1_xmm2m128(Instruction const&) = 0; + virtual void CVTTPS2DQ_xmm1_xmm2m128(Instruction const&) = 0; + virtual void SUBPD_xmm1_xmm2m128(X86::Instruction const&) = 0; + virtual void SUBSD_xmm1_xmm2m32(X86::Instruction const&) = 0; + virtual void MINPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void MINSD_xmm1_xmm2m32(Instruction const&) = 0; + virtual void DIVPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void DIVSD_xmm1_xmm2m32(Instruction const&) = 0; + virtual void MAXPD_xmm1_xmm2m128(Instruction const&) = 0; + virtual void MAXSD_xmm1_xmm2m32(Instruction const&) = 0; + virtual void PUNPCKLQDQ_xmm1_xmm2m128(Instruction const&) = 0; + virtual void PUNPCKHQDQ_xmm1_xmm2m128(Instruction const&) = 0; + virtual void MOVDQA_xmm1_xmm2m128(Instruction const&) = 0; + virtual void MOVDQU_xmm1_xmm2m128(Instruction const&) = 0; + virtual void PSHUFD_xmm1_xmm2m128_imm8(Instruction const&) = 0; + virtual void PSHUFHW_xmm1_xmm2m128_imm8(Instruction const&) = 0; + virtual void PSHUFLW_xmm1_xmm2m128_imm8(Instruction const&) = 0; + virtual void PSRLQ_xmm1_imm8(Instruction const&) = 0; + virtual void PSRLDQ_xmm1_imm8(Instruction const&) = 0; + virtual void PSLLQ_xmm1_imm8(Instruction const&) = 0; + virtual void PSLLDQ_xmm1_imm8(Instruction const&) = 0; + virtual void MOVD_rm32_xmm2(Instruction const&) = 0; + virtual void MOVQ_xmm1_xmm2m128(Instruction const&) = 0; + virtual void MOVDQA_xmm1m128_xmm2(Instruction const&) = 0; + virtual void MOVDQU_xmm1m128_xmm2(Instruction const&) = 0; + virtual void CMPPD_xmm1_xmm2m128_imm8(Instruction const&) = 0; + virtual void CMPSD_xmm1_xmm2m32_imm8(Instruction const&) = 0; + virtual void SHUFPD_xmm1_xmm2m128_imm8(Instruction const&) = 0; + virtual void PADDQ_mm1_mm2m64(Instruction const&) = 0; + virtual void MOVQ_xmm1m128_xmm2(Instruction const&) = 0; + virtual void MOVQ2DQ_xmm_mm(Instruction const&) = 0; + virtual void MOVDQ2Q_mm_xmm(Instruction const&) = 0; + virtual void CVTTPD2DQ_xmm1_xmm2m128(Instruction const&) = 0; + virtual void CVTPD2DQ_xmm1_xmm2m128(Instruction const&) = 0; + virtual void CVTDQ2PD_xmm1_xmm2m64(Instruction const&) = 0; + virtual void PMULUDQ_mm1_mm2m64(Instruction const&) = 0; + virtual void PMULUDQ_mm1_mm2m128(Instruction const&) = 0; + virtual void PSUBQ_mm1_mm2m64(Instruction const&) = 0; + protected: virtual ~Interpreter() = default; }; |