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.
This commit is contained in:
parent
06c59cce6f
commit
8593bdb711
Notes:
sideshowbarker
2024-07-19 04:28:16 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/8593bdb7119 Pull-request: https://github.com/SerenityOS/serenity/pull/2918 Reviewed-by: https://github.com/awesomekling
5 changed files with 350 additions and 9 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(", ");
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue