diff options
author | Nico Weber <thakis@chromium.org> | 2020-07-28 17:05:57 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-07-30 16:53:33 +0200 |
commit | 8593bdb711999f464cb8f92f21e48a16ddbd1ec1 (patch) | |
tree | 2333e00303b6859f69659c42bfc5b1b0bac7523d | |
parent | 06c59cce6f3849ef5d9599de5475c9b6fab98d26 (diff) | |
download | serenity-8593bdb711999f464cb8f92f21e48a16ddbd1ec1.zip |
LibX86: Disassemble most remaining FPU instructions
Some of the remaining instructions have different behavior for
register and non-register ops. Since we already have the
two-level flags tables, model this by setting all handlers in
the two-level table to the register op handler, while the
first-level flags table stores the action for the non-reg handler.
-rw-r--r-- | DevTools/UserspaceEmulator/SoftCPU.cpp | 67 | ||||
-rw-r--r-- | DevTools/UserspaceEmulator/SoftCPU.h | 67 | ||||
-rw-r--r-- | Libraries/LibX86/Instruction.cpp | 150 | ||||
-rw-r--r-- | Libraries/LibX86/Instruction.h | 8 | ||||
-rw-r--r-- | Libraries/LibX86/Interpreter.h | 67 |
5 files changed, 350 insertions, 9 deletions
diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index e8c2b3a834..a06b8b60f0 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -1415,6 +1415,36 @@ void SoftCPU::FRNDINT(const X86::Instruction&) { TODO(); }; void SoftCPU::FSCALE(const X86::Instruction&) { TODO(); }; void SoftCPU::FSIN(const X86::Instruction&) { TODO(); }; void SoftCPU::FCOS(const X86::Instruction&) { TODO(); }; +void SoftCPU::FIADD_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FCMOVB(const X86::Instruction&) { TODO(); }; +void SoftCPU::FIMUL_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FCMOVE(const X86::Instruction&) { TODO(); }; +void SoftCPU::FICOM_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FCMOVBE(const X86::Instruction&) { TODO(); }; +void SoftCPU::FICOMP_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FCMOVU(const X86::Instruction&) { TODO(); }; +void SoftCPU::FISUB_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FISUBR_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FUCOMPP(const X86::Instruction&) { TODO(); }; +void SoftCPU::FIDIV_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FIDIVR_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FILD_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FCMOVNB(const X86::Instruction&) { TODO(); }; +void SoftCPU::FISTTP_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FCMOVNE(const X86::Instruction&) { TODO(); }; +void SoftCPU::FIST_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FCMOVNBE(const X86::Instruction&) { TODO(); }; +void SoftCPU::FISTP_RM32(const X86::Instruction&) { TODO(); }; +void SoftCPU::FCMOVNU(const X86::Instruction&) { TODO(); }; +void SoftCPU::FNENI(const X86::Instruction&) { TODO(); }; +void SoftCPU::FNDISI(const X86::Instruction&) { TODO(); }; +void SoftCPU::FNCLEX(const X86::Instruction&) { TODO(); }; +void SoftCPU::FNINIT(const X86::Instruction&) { TODO(); }; +void SoftCPU::FNSETPM(const X86::Instruction&) { TODO(); }; +void SoftCPU::FLD_RM80(const X86::Instruction&) { TODO(); }; +void SoftCPU::FUCOMI(const X86::Instruction&) { TODO(); }; +void SoftCPU::FCOMI(const X86::Instruction&) { TODO(); }; +void SoftCPU::FSTP_RM80(const X86::Instruction&) { TODO(); }; void SoftCPU::FADD_RM64(const X86::Instruction&) { TODO(); } void SoftCPU::FMUL_RM64(const X86::Instruction&) { TODO(); } void SoftCPU::FCOM_RM64(const X86::Instruction&) { TODO(); } @@ -1423,6 +1453,43 @@ void SoftCPU::FSUB_RM64(const X86::Instruction&) { TODO(); } void SoftCPU::FSUBR_RM64(const X86::Instruction&) { TODO(); } void SoftCPU::FDIV_RM64(const X86::Instruction&) { TODO(); } void SoftCPU::FDIVR_RM64(const X86::Instruction&) { TODO(); } +void SoftCPU::FLD_RM64(const X86::Instruction&) { TODO(); } +void SoftCPU::FFREE(const X86::Instruction&) { TODO(); } +void SoftCPU::FISTTP_RM64(const X86::Instruction&) { TODO(); } +void SoftCPU::FST_RM64(const X86::Instruction&) { TODO(); } +void SoftCPU::FSTP_RM64(const X86::Instruction&) { TODO(); } +void SoftCPU::FRSTOR(const X86::Instruction&) { TODO(); } +void SoftCPU::FUCOM(const X86::Instruction&) { TODO(); } +void SoftCPU::FUCOMP(const X86::Instruction&) { TODO(); } +void SoftCPU::FNSAVE(const X86::Instruction&) { TODO(); } +void SoftCPU::FNSTSW(const X86::Instruction&) { TODO(); } +void SoftCPU::FIADD_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FADDP(const X86::Instruction&) { TODO(); } +void SoftCPU::FIMUL_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FMULP(const X86::Instruction&) { TODO(); } +void SoftCPU::FICOM_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FICOMP_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FCOMPP(const X86::Instruction&) { TODO(); } +void SoftCPU::FISUB_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FSUBRP(const X86::Instruction&) { TODO(); } +void SoftCPU::FISUBR_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FSUBP(const X86::Instruction&) { TODO(); } +void SoftCPU::FIDIV_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FDIVRP(const X86::Instruction&) { TODO(); } +void SoftCPU::FIDIVR_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FDIVP(const X86::Instruction&) { TODO(); } +void SoftCPU::FILD_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FFREEP(const X86::Instruction&) { TODO(); } +void SoftCPU::FISTTP_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FIST_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FISTP_RM16(const X86::Instruction&) { TODO(); } +void SoftCPU::FBLD_M80(const X86::Instruction&) { TODO(); } +void SoftCPU::FNSTSW_AX(const X86::Instruction&) { TODO(); } +void SoftCPU::FILD_RM64(const X86::Instruction&) { TODO(); } +void SoftCPU::FUCOMIP(const X86::Instruction&) { TODO(); } +void SoftCPU::FBSTP_M80(const X86::Instruction&) { TODO(); } +void SoftCPU::FCOMIP(const X86::Instruction&) { TODO(); } +void SoftCPU::FISTP_RM64(const X86::Instruction&) { TODO(); } void SoftCPU::HLT(const X86::Instruction&) { TODO(); } void SoftCPU::IDIV_RM16(const X86::Instruction& insn) diff --git a/DevTools/UserspaceEmulator/SoftCPU.h b/DevTools/UserspaceEmulator/SoftCPU.h index b2687abec5..9ed0e84672 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.h +++ b/DevTools/UserspaceEmulator/SoftCPU.h @@ -618,6 +618,36 @@ private: virtual void FSCALE(const X86::Instruction&) override; virtual void FSIN(const X86::Instruction&) override; virtual void FCOS(const X86::Instruction&) override; + virtual void FIADD_RM32(const X86::Instruction&) override; + virtual void FCMOVB(const X86::Instruction&) override; + virtual void FIMUL_RM32(const X86::Instruction&) override; + virtual void FCMOVE(const X86::Instruction&) override; + virtual void FICOM_RM32(const X86::Instruction&) override; + virtual void FCMOVBE(const X86::Instruction&) override; + virtual void FICOMP_RM32(const X86::Instruction&) override; + virtual void FCMOVU(const X86::Instruction&) override; + virtual void FISUB_RM32(const X86::Instruction&) override; + virtual void FISUBR_RM32(const X86::Instruction&) override; + virtual void FUCOMPP(const X86::Instruction&) override; + virtual void FIDIV_RM32(const X86::Instruction&) override; + virtual void FIDIVR_RM32(const X86::Instruction&) override; + virtual void FILD_RM32(const X86::Instruction&) override; + virtual void FCMOVNB(const X86::Instruction&) override; + virtual void FISTTP_RM32(const X86::Instruction&) override; + virtual void FCMOVNE(const X86::Instruction&) override; + virtual void FIST_RM32(const X86::Instruction&) override; + virtual void FCMOVNBE(const X86::Instruction&) override; + virtual void FISTP_RM32(const X86::Instruction&) override; + virtual void FCMOVNU(const X86::Instruction&) override; + virtual void FNENI(const X86::Instruction&) override; + virtual void FNDISI(const X86::Instruction&) override; + virtual void FNCLEX(const X86::Instruction&) override; + virtual void FNINIT(const X86::Instruction&) override; + virtual void FNSETPM(const X86::Instruction&) override; + virtual void FLD_RM80(const X86::Instruction&) override; + virtual void FUCOMI(const X86::Instruction&) override; + virtual void FCOMI(const X86::Instruction&) override; + virtual void FSTP_RM80(const X86::Instruction&) override; virtual void FADD_RM64(const X86::Instruction&) override; virtual void FMUL_RM64(const X86::Instruction&) override; virtual void FCOM_RM64(const X86::Instruction&) override; @@ -626,6 +656,43 @@ private: virtual void FSUBR_RM64(const X86::Instruction&) override; virtual void FDIV_RM64(const X86::Instruction&) override; virtual void FDIVR_RM64(const X86::Instruction&) override; + virtual void FLD_RM64(const X86::Instruction&) override; + virtual void FFREE(const X86::Instruction&) override; + virtual void FISTTP_RM64(const X86::Instruction&) override; + virtual void FST_RM64(const X86::Instruction&) override; + virtual void FSTP_RM64(const X86::Instruction&) override; + virtual void FRSTOR(const X86::Instruction&) override; + virtual void FUCOM(const X86::Instruction&) override; + virtual void FUCOMP(const X86::Instruction&) override; + virtual void FNSAVE(const X86::Instruction&) override; + virtual void FNSTSW(const X86::Instruction&) override; + virtual void FIADD_RM16(const X86::Instruction&) override; + virtual void FADDP(const X86::Instruction&) override; + virtual void FIMUL_RM16(const X86::Instruction&) override; + virtual void FMULP(const X86::Instruction&) override; + virtual void FICOM_RM16(const X86::Instruction&) override; + virtual void FICOMP_RM16(const X86::Instruction&) override; + virtual void FCOMPP(const X86::Instruction&) override; + virtual void FISUB_RM16(const X86::Instruction&) override; + virtual void FSUBRP(const X86::Instruction&) override; + virtual void FISUBR_RM16(const X86::Instruction&) override; + virtual void FSUBP(const X86::Instruction&) override; + virtual void FIDIV_RM16(const X86::Instruction&) override; + virtual void FDIVRP(const X86::Instruction&) override; + virtual void FIDIVR_RM16(const X86::Instruction&) override; + virtual void FDIVP(const X86::Instruction&) override; + virtual void FILD_RM16(const X86::Instruction&) override; + virtual void FFREEP(const X86::Instruction&) override; + virtual void FISTTP_RM16(const X86::Instruction&) override; + virtual void FIST_RM16(const X86::Instruction&) override; + virtual void FISTP_RM16(const X86::Instruction&) override; + virtual void FBLD_M80(const X86::Instruction&) override; + virtual void FNSTSW_AX(const X86::Instruction&) override; + virtual void FILD_RM64(const X86::Instruction&) override; + virtual void FUCOMIP(const X86::Instruction&) override; + virtual void FBSTP_M80(const X86::Instruction&) override; + virtual void FCOMIP(const X86::Instruction&) override; + virtual void FISTP_RM64(const X86::Instruction&) override; virtual void HLT(const X86::Instruction&) override; virtual void IDIV_RM16(const X86::Instruction&) override; virtual void IDIV_RM32(const X86::Instruction&) override; diff --git a/Libraries/LibX86/Instruction.cpp b/Libraries/LibX86/Instruction.cpp index fdfb39ca88..d8f8ea43f7 100644 --- a/Libraries/LibX86/Instruction.cpp +++ b/Libraries/LibX86/Instruction.cpp @@ -136,8 +136,12 @@ static void build(InstructionDescriptor* table, u8 op, const char* mnemonic, Ins case OP_RM32: case OP_FPU: case OP_FPU_reg: + case OP_FPU_mem: + case OP_FPU_AX16: + case OP_FPU_RM16: case OP_FPU_RM32: case OP_FPU_RM64: + case OP_FPU_M80: case OP_RM8_reg8: case OP_RM32_reg32: case OP_reg32_RM32: @@ -287,6 +291,12 @@ static void build_slash_rm(u8 op, u8 slash, u8 rm, const char* mnemonic, Instruc build_slash_rm(s_table32, op, slash, rm, mnemonic, format, impl, lock_prefix_allowed); } +static void build_slash_reg(u8 op, u8 slash, const char* mnemonic, InstructionFormat format, InstructionHandler impl, IsLockPrefixAllowed lock_prefix_allowed = LockPrefixNotAllowed) +{ + for (int i = 0; i < 8; ++i) + build_slash_rm(op, slash, 0xc0 | (slash << 3) | i, mnemonic, format, impl, lock_prefix_allowed); +} + [[gnu::constructor]] static void build_opcode_tables() { build(0x00, "ADD", OP_RM8_reg8, &Interpreter::ADD_RM8_reg8, LockPrefixAllowed); @@ -487,7 +497,7 @@ static void build_slash_rm(u8 op, u8 slash, u8 rm, const char* mnemonic, Instruc build_slash_rm(0xD9, 4, 0xE1, "FABS", OP_FPU, &Interpreter::FABS); build_slash_rm(0xD9, 4, 0xE2, "FTST", OP_FPU, &Interpreter::FTST); build_slash_rm(0xD9, 4, 0xE3, "FXAM", OP_FPU, &Interpreter::FXAM); - build_slash(0xD9, 5, "FLDCW", OP_FPU_RM32, &Interpreter::FLDCW); + build_slash(0xD9, 5, "FLDCW", OP_FPU_RM16, &Interpreter::FLDCW); build_slash_rm(0xD9, 5, 0xE8, "FLD1", OP_FPU, &Interpreter::FLD1); build_slash_rm(0xD9, 5, 0xE9, "FLDL2T", OP_FPU, &Interpreter::FLDL2T); build_slash_rm(0xD9, 5, 0xEA, "FLDL2E", OP_FPU, &Interpreter::FLDL2E); @@ -505,7 +515,7 @@ static void build_slash_rm(u8 op, u8 slash, u8 rm, const char* mnemonic, Instruc build_slash_rm(0xD9, 6, 0xF5, "FPREM1", OP_FPU, &Interpreter::FPREM1); build_slash_rm(0xD9, 6, 0xF6, "FDECSTP", OP_FPU, &Interpreter::FDECSTP); build_slash_rm(0xD9, 6, 0xF7, "FINCSTP", OP_FPU, &Interpreter::FINCSTP); - build_slash(0xD9, 7, "FNSTCW", OP_FPU_RM32, &Interpreter::FNSTCW); + build_slash(0xD9, 7, "FNSTCW", OP_FPU_RM16, &Interpreter::FNSTCW); // FIXME: Extraodinary prefix 0x9B + 0xD9/7: FSTCW build_slash_rm(0xD9, 7, 0xF8, "FPREM", OP_FPU, &Interpreter::FPREM); build_slash_rm(0xD9, 7, 0xF9, "FYL2XP1", OP_FPU, &Interpreter::FYL2XP1); @@ -516,9 +526,40 @@ static void build_slash_rm(u8 op, u8 slash, u8 rm, const char* mnemonic, Instruc build_slash_rm(0xD9, 7, 0xFE, "FSIN", OP_FPU, &Interpreter::FSIN); build_slash_rm(0xD9, 7, 0xFF, "FCOS", OP_FPU, &Interpreter::FCOS); - // FIXME - build(0xDA, "FPU?", OP_RM8, &Interpreter::ESCAPE); - build(0xDB, "FPU?", OP_RM8, &Interpreter::ESCAPE); + build_slash(0xDA, 0, "FIADD", OP_FPU_RM32, &Interpreter::FIADD_RM32); + build_slash_reg(0xDA, 0, "FCMOVB", OP_FPU_reg, &Interpreter::FCMOVB); + build_slash(0xDA, 1, "FIMUL", OP_FPU_RM32, &Interpreter::FIMUL_RM32); + build_slash_reg(0xDA, 1, "FCMOVE", OP_FPU_reg, &Interpreter::FCMOVE); + build_slash(0xDA, 2, "FICOM", OP_FPU_RM32, &Interpreter::FICOM_RM32); + build_slash_reg(0xDA, 2, "FCMOVBE", OP_FPU_reg, &Interpreter::FCMOVBE); + build_slash(0xDA, 3, "FICOMP", OP_FPU_RM32, &Interpreter::FICOMP_RM32); + build_slash_reg(0xDA, 3, "FCMOVU", OP_FPU_reg, &Interpreter::FCMOVU); + build_slash(0xDA, 4, "FISUB", OP_FPU_RM32, &Interpreter::FISUB_RM32); + build_slash(0xDA, 5, "FISUBR", OP_FPU_RM32, &Interpreter::FISUBR_RM32); + build_slash_rm(0xDA, 5, 0xE9, "FUCOMPP", OP_FPU, &Interpreter::FUCOMPP); + build_slash(0xDA, 6, "FIDIV", OP_FPU_RM32, &Interpreter::FIDIV_RM32); + build_slash(0xDA, 7, "FIDIVR", OP_FPU_RM32, &Interpreter::FIDIVR_RM32); + + build_slash(0xDB, 0, "FILD", OP_FPU_RM32, &Interpreter::FILD_RM32); + build_slash_reg(0xDB, 0, "FCMOVNB", OP_FPU_reg, &Interpreter::FCMOVNB); + build_slash(0xDB, 1, "FISTTP", OP_FPU_RM32, &Interpreter::FISTTP_RM32); + build_slash_reg(0xDB, 1, "FCMOVNE", OP_FPU_reg, &Interpreter::FCMOVNE); + build_slash(0xDB, 2, "FIST", OP_FPU_RM32, &Interpreter::FIST_RM32); + build_slash_reg(0xDB, 2, "FCMOVNBE", OP_FPU_reg, &Interpreter::FCMOVNBE); + build_slash(0xDB, 3, "FISTP", OP_FPU_RM32, &Interpreter::FISTP_RM32); + build_slash_reg(0xDB, 3, "FCMOVNU", OP_FPU_reg, &Interpreter::FCMOVNU); + build_slash(0xDB, 4, "FUNASSIGNED", OP_FPU, &Interpreter::ESCAPE); + build_slash_rm(0xDB, 4, 0xE0, "FNENI", OP_FPU_reg, &Interpreter::FNENI); + build_slash_rm(0xDB, 4, 0xE1, "FNDISI", OP_FPU_reg, &Interpreter::FNDISI); + build_slash_rm(0xDB, 4, 0xE2, "FNCLEX", OP_FPU_reg, &Interpreter::FNCLEX); + // FIXME: Extraodinary prefix 0x9B + 0xDB/4: FCLEX + build_slash_rm(0xDB, 4, 0xE3, "FNINIT", OP_FPU_reg, &Interpreter::FNINIT); + // FIXME: Extraodinary prefix 0x9B + 0xDB/4: FINIT + build_slash_rm(0xDB, 4, 0xE4, "FNSETPM", OP_FPU_reg, &Interpreter::FNSETPM); + build_slash(0xDB, 5, "FLD", OP_FPU_M80, &Interpreter::FLD_RM80); + build_slash_reg(0xDB, 5, "FUCOMI", OP_FPU_reg, &Interpreter::FUCOMI); + build_slash(0xDB, 6, "FCOMI", OP_FPU_reg, &Interpreter::FCOMI); + build_slash(0xDB, 7, "FSTP", OP_FPU_M80, &Interpreter::FSTP_RM80); build_slash(0xDC, 0, "FADD", OP_FPU_RM64, &Interpreter::FADD_RM64); build_slash(0xDC, 1, "FMUL", OP_FPU_RM64, &Interpreter::FMUL_RM64); @@ -529,10 +570,61 @@ static void build_slash_rm(u8 op, u8 slash, u8 rm, const char* mnemonic, Instruc build_slash(0xDC, 6, "FDIV", OP_FPU_RM64, &Interpreter::FDIV_RM64); build_slash(0xDC, 7, "FDIVR", OP_FPU_RM64, &Interpreter::FDIVR_RM64); - // FIXME - build(0xDD, "FPU?", OP_RM8, &Interpreter::ESCAPE); - build(0xDE, "FPU?", OP_RM8, &Interpreter::ESCAPE); - build(0xDF, "FPU?", OP_RM8, &Interpreter::ESCAPE); + build_slash(0xDD, 0, "FLD", OP_FPU_RM64, &Interpreter::FLD_RM64); + build_slash_reg(0xDD, 0, "FFREE", OP_FPU_reg, &Interpreter::FFREE); + build_slash(0xDD, 1, "FISTTP", OP_FPU_RM64, &Interpreter::FISTTP_RM64); + build_slash_reg(0xDD, 1, "FXCH4", OP_FPU_reg, &Interpreter::FXCH); + build_slash(0xDD, 2, "FST", OP_FPU_RM64, &Interpreter::FST_RM64); + build_slash(0xDD, 3, "FSTP", OP_FPU_RM64, &Interpreter::FSTP_RM64); + build_slash(0xDD, 4, "FRSTOR", OP_FPU_mem, &Interpreter::FRSTOR); + build_slash_reg(0xDD, 4, "FUCOM", OP_FPU_reg, &Interpreter::FUCOM); + // FIXME: DD/4 E1 (...but isn't this what DD/4 does naturally, with E1 just being normal R/M?) + build_slash(0xDD, 5, "FUCOMP", OP_FPU_reg, &Interpreter::FUCOMP); + // FIXME: DD/5 E9 (...but isn't this what DD/5 does naturally, with E9 just being normal R/M?) + build_slash(0xDD, 6, "FNSAVE", OP_FPU_mem, &Interpreter::FNSAVE); + // FIXME: Extraodinary prefix 0x9B + 0xDD/6: FSAVE + build_slash(0xDD, 7, "FNSTSW", OP_FPU_RM16, &Interpreter::FNSTSW); + // FIXME: Extraodinary prefix 0x9B + 0xDD/7: FSTSW + + build_slash(0xDE, 0, "FIADD", OP_FPU_RM16, &Interpreter::FIADD_RM16); + build_slash_reg(0xDE, 0, "FADDP", OP_FPU_reg, &Interpreter::FADDP); + // FIXME: DE/0 C1 (...but isn't this what DE/0 does naturally, with C1 just being normal R/M?) + build_slash(0xDE, 1, "FIMUL", OP_FPU_RM16, &Interpreter::FIMUL_RM16); + build_slash_reg(0xDE, 1, "FMULP", OP_FPU_reg, &Interpreter::FMULP); + // FIXME: DE/1 C9 (...but isn't this what DE/1 does naturally, with C9 just being normal R/M?) + build_slash(0xDE, 2, "FICOM", OP_FPU_RM16, &Interpreter::FICOM_RM16); + build_slash_reg(0xDE, 2, "FCOMP5", OP_FPU_reg, &Interpreter::FCOMP_RM32); + build_slash(0xDE, 3, "FICOMP", OP_FPU_RM16, &Interpreter::FICOMP_RM16); + build_slash_reg(0xDE, 3, "FCOMPP", OP_FPU_reg, &Interpreter::FCOMPP); + build_slash(0xDE, 4, "FISUB", OP_FPU_RM16, &Interpreter::FISUB_RM16); + build_slash_reg(0xDE, 4, "FSUBRP", OP_FPU_reg, &Interpreter::FSUBRP); + // FIXME: DE/4 E1 (...but isn't this what DE/4 does naturally, with E1 just being normal R/M?) + build_slash(0xDE, 5, "FISUBR", OP_FPU_RM16, &Interpreter::FISUBR_RM16); + build_slash_reg(0xDE, 5, "FSUBP", OP_FPU_reg, &Interpreter::FSUBP); + // FIXME: DE/5 E9 (...but isn't this what DE/5 does naturally, with E9 just being normal R/M?) + build_slash(0xDE, 6, "FIDIV", OP_FPU_RM16, &Interpreter::FIDIV_RM16); + build_slash_reg(0xDE, 6, "FDIVRP", OP_FPU_reg, &Interpreter::FDIVRP); + // FIXME: DE/6 F1 (...but isn't this what DE/6 does naturally, with F1 just being normal R/M?) + build_slash(0xDE, 7, "FIDIVR", OP_FPU_RM16, &Interpreter::FIDIVR_RM16); + build_slash_reg(0xDE, 7, "FDIVP", OP_FPU_reg, &Interpreter::FDIVP); + // FIXME: DE/7 F9 (...but isn't this what DE/7 does naturally, with F9 just being normal R/M?) + + build_slash(0xDF, 0, "FILD", OP_FPU_RM32, &Interpreter::FILD_RM16); + build_slash_reg(0xDF, 0, "FFREEP", OP_FPU_reg, &Interpreter::FFREEP); + build_slash(0xDF, 1, "FISTTP", OP_FPU_RM32, &Interpreter::FISTTP_RM16); + build_slash_reg(0xDF, 1, "FXCH7", OP_FPU_reg, &Interpreter::FXCH); + build_slash(0xDF, 2, "FIST", OP_FPU_RM32, &Interpreter::FIST_RM16); + build_slash_reg(0xDF, 2, "FSTP8", OP_FPU_reg, &Interpreter::FSTP_RM32); + build_slash(0xDF, 3, "FISTP", OP_FPU_RM32, &Interpreter::FISTP_RM16); + build_slash_reg(0xDF, 3, "FSTP9", OP_FPU_reg, &Interpreter::FSTP_RM32); + build_slash(0xDF, 4, "FBLD", OP_FPU_M80, &Interpreter::FBLD_M80); + build_slash_reg(0xDF, 4, "FNSTSW", OP_FPU_AX16, &Interpreter::FNSTSW_AX); + // FIXME: Extraodinary prefix 0x9B + 0xDF/e: FSTSW_AX + build_slash(0xDF, 5, "FILD", OP_FPU_RM64, &Interpreter::FILD_RM64); + build_slash_reg(0xDF, 5, "FUCOMIP", OP_FPU_reg, &Interpreter::FUCOMIP); + build_slash(0xDF, 6, "FBSTP", OP_FPU_M80, &Interpreter::FBSTP_M80); + build_slash_reg(0xDF, 6, "FCOMIP", OP_FPU_reg, &Interpreter::FCOMIP); + build_slash(0xDF, 7, "FISTP", OP_FPU_RM64, &Interpreter::FISTP_RM64); build(0xE0, "LOOPNZ", OP_imm8, &Interpreter::LOOPNZ_imm8); build(0xE1, "LOOPZ", OP_imm8, &Interpreter::LOOPZ_imm8); @@ -849,6 +941,25 @@ String MemoryOrRegisterReference::to_string_fpu_reg() const return register_name(reg_fpu()); } +String MemoryOrRegisterReference::to_string_fpu_mem(const Instruction& insn) const +{ + ASSERT(!is_register()); + return String::format("[%s]", to_string(insn).characters()); +} + +String MemoryOrRegisterReference::to_string_fpu_ax16() const +{ + ASSERT(is_register()); + return register_name(reg16()); +} + +String MemoryOrRegisterReference::to_string_fpu16(const Instruction& insn) const +{ + if (is_register()) + return register_name(reg_fpu()); + return String::format("word ptr [%s]", to_string(insn).characters()); +} + String MemoryOrRegisterReference::to_string_fpu32(const Instruction& insn) const { if (is_register()) @@ -863,6 +974,11 @@ String MemoryOrRegisterReference::to_string_fpu64(const Instruction& insn) const return String::format("qword ptr [%s]", to_string(insn).characters()); } +String MemoryOrRegisterReference::to_string_fpu80(const Instruction& insn) const +{ + ASSERT(!is_register()); + return String::format("tbyte ptr [%s]", to_string(insn).characters()); +} String MemoryOrRegisterReference::to_string_mm(const Instruction& insn) const { if (is_register()) @@ -1153,8 +1269,12 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_ auto append_rm16 = [&] { builder.append(m_modrm.to_string_o16(*this)); }; auto append_rm32 = [&] { builder.append(m_modrm.to_string_o32(*this)); }; auto append_fpu_reg = [&] { builder.append(m_modrm.to_string_fpu_reg()); }; + auto append_fpu_mem = [&] { builder.append(m_modrm.to_string_fpu_mem(*this)); }; + auto append_fpu_ax16 = [&] { builder.append(m_modrm.to_string_fpu_ax16()); }; + auto append_fpu_rm16 = [&] { builder.append(m_modrm.to_string_fpu16(*this)); }; auto append_fpu_rm32 = [&] { builder.append(m_modrm.to_string_fpu32(*this)); }; auto append_fpu_rm64 = [&] { builder.append(m_modrm.to_string_fpu64(*this)); }; + auto append_fpu_rm80 = [&] { builder.append(m_modrm.to_string_fpu80(*this)); }; auto append_imm8 = [&] { builder.appendf("%#02x", imm8()); }; auto append_imm8_2 = [&] { builder.appendf("%#02x", imm8_2()); }; auto append_imm16 = [&] { builder.appendf("%#04x", imm16()); }; @@ -1423,12 +1543,24 @@ String Instruction::to_string_internal(u32 origin, const SymbolProvider* symbol_ case OP_FPU_reg: append_fpu_reg(); break; + case OP_FPU_mem: + append_fpu_mem(); + break; + case OP_FPU_AX16: + append_fpu_ax16(); + break; + case OP_FPU_RM16: + append_fpu_rm16(); + break; case OP_FPU_RM32: append_fpu_rm32(); break; case OP_FPU_RM64: append_fpu_rm64(); break; + case OP_FPU_M80: + append_fpu_rm80(); + break; case OP_RM8_reg8: append_rm8(); append(", "); diff --git a/Libraries/LibX86/Instruction.h b/Libraries/LibX86/Instruction.h index cd259077c6..93cab62ba4 100644 --- a/Libraries/LibX86/Instruction.h +++ b/Libraries/LibX86/Instruction.h @@ -83,8 +83,12 @@ enum InstructionFormat { OP_RM32, OP_FPU, OP_FPU_reg, + OP_FPU_mem, + OP_FPU_AX16, + OP_FPU_RM16, OP_FPU_RM32, OP_FPU_RM64, + OP_FPU_M80, OP_RM8_reg8, OP_RM32_reg32, OP_reg32_RM32, @@ -359,8 +363,12 @@ public: String to_string_o16(const Instruction&) const; String to_string_o32(const Instruction&) const; String to_string_fpu_reg() const; + String to_string_fpu_mem(const Instruction&) const; + String to_string_fpu_ax16() const; + String to_string_fpu16(const Instruction&) const; String to_string_fpu32(const Instruction&) const; String to_string_fpu64(const Instruction&) const; + String to_string_fpu80(const Instruction&) const; String to_string_mm(const Instruction&) const; bool is_register() const { return m_register_index != 0xffffffff; } diff --git a/Libraries/LibX86/Interpreter.h b/Libraries/LibX86/Interpreter.h index ae0e6133ef..efbf4164d8 100644 --- a/Libraries/LibX86/Interpreter.h +++ b/Libraries/LibX86/Interpreter.h @@ -200,6 +200,36 @@ public: virtual void FSCALE(const Instruction&) = 0; virtual void FSIN(const Instruction&) = 0; virtual void FCOS(const Instruction&) = 0; + virtual void FIADD_RM32(const Instruction&) = 0; + virtual void FADDP(const Instruction&) = 0; + virtual void FIMUL_RM32(const Instruction&) = 0; + virtual void FCMOVE(const Instruction&) = 0; + virtual void FICOM_RM32(const Instruction&) = 0; + virtual void FCMOVBE(const Instruction&) = 0; + virtual void FICOMP_RM32(const Instruction&) = 0; + virtual void FCMOVU(const Instruction&) = 0; + virtual void FISUB_RM32(const Instruction&) = 0; + virtual void FISUBR_RM32(const Instruction&) = 0; + virtual void FUCOMPP(const Instruction&) = 0; + virtual void FIDIV_RM32(const Instruction&) = 0; + virtual void FIDIVR_RM32(const Instruction&) = 0; + virtual void FILD_RM32(const Instruction&) = 0; + virtual void FCMOVNB(const Instruction&) = 0; + virtual void FISTTP_RM32(const Instruction&) = 0; + virtual void FCMOVNE(const Instruction&) = 0; + virtual void FIST_RM32(const Instruction&) = 0; + virtual void FCMOVNBE(const Instruction&) = 0; + virtual void FISTP_RM32(const Instruction&) = 0; + virtual void FCMOVNU(const Instruction&) = 0; + virtual void FNENI(const Instruction&) = 0; + virtual void FNDISI(const Instruction&) = 0; + virtual void FNCLEX(const Instruction&) = 0; + virtual void FNINIT(const Instruction&) = 0; + virtual void FNSETPM(const Instruction&) = 0; + virtual void FLD_RM80(const Instruction&) = 0; + virtual void FUCOMI(const Instruction&) = 0; + virtual void FCOMI(const Instruction&) = 0; + virtual void FSTP_RM80(const Instruction&) = 0; virtual void FADD_RM64(const Instruction&) = 0; virtual void FMUL_RM64(const Instruction&) = 0; virtual void FCOM_RM64(const Instruction&) = 0; @@ -208,6 +238,43 @@ public: virtual void FSUBR_RM64(const Instruction&) = 0; virtual void FDIV_RM64(const Instruction&) = 0; virtual void FDIVR_RM64(const Instruction&) = 0; + virtual void FLD_RM64(const Instruction&) = 0; + virtual void FFREE(const Instruction&) = 0; + virtual void FISTTP_RM64(const Instruction&) = 0; + virtual void FST_RM64(const Instruction&) = 0; + virtual void FSTP_RM64(const Instruction&) = 0; + virtual void FRSTOR(const Instruction&) = 0; + virtual void FUCOM(const Instruction&) = 0; + virtual void FUCOMP(const Instruction&) = 0; + virtual void FNSAVE(const Instruction&) = 0; + virtual void FNSTSW(const Instruction&) = 0; + virtual void FIADD_RM16(const Instruction&) = 0; + virtual void FCMOVB(const Instruction&) = 0; + virtual void FIMUL_RM16(const Instruction&) = 0; + virtual void FMULP(const Instruction&) = 0; + virtual void FICOM_RM16(const Instruction&) = 0; + virtual void FICOMP_RM16(const Instruction&) = 0; + virtual void FCOMPP(const Instruction&) = 0; + virtual void FISUB_RM16(const Instruction&) = 0; + virtual void FSUBRP(const Instruction&) = 0; + virtual void FISUBR_RM16(const Instruction&) = 0; + virtual void FSUBP(const Instruction&) = 0; + virtual void FIDIV_RM16(const Instruction&) = 0; + virtual void FDIVRP(const Instruction&) = 0; + virtual void FIDIVR_RM16(const Instruction&) = 0; + virtual void FDIVP(const Instruction&) = 0; + virtual void FILD_RM16(const Instruction&) = 0; + virtual void FFREEP(const Instruction&) = 0; + virtual void FISTTP_RM16(const Instruction&) = 0; + virtual void FIST_RM16(const Instruction&) = 0; + virtual void FISTP_RM16(const Instruction&) = 0; + virtual void FBLD_M80(const Instruction&) = 0; + virtual void FNSTSW_AX(const Instruction&) = 0; + virtual void FILD_RM64(const Instruction&) = 0; + virtual void FUCOMIP(const Instruction&) = 0; + virtual void FBSTP_M80(const Instruction&) = 0; + virtual void FCOMIP(const Instruction&) = 0; + virtual void FISTP_RM64(const Instruction&) = 0; virtual void HLT(const Instruction&) = 0; virtual void IDIV_RM16(const Instruction&) = 0; virtual void IDIV_RM32(const Instruction&) = 0; |