diff --git a/emu/decode.h b/emu/decode.h index be96d2c705..270d827519 100644 --- a/emu/decode.h +++ b/emu/decode.h @@ -571,6 +571,8 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) { switch (insn << 4 | modrm.opcode) { case 0xd80: TRACE("fadd mem32"); FADDM(mem_addr_real,32); break; case 0xd81: TRACE("fmul mem32"); FMULM(mem_addr_real,32); break; + case 0xd82: TRACE("fcom mem32"); FCOMM(mem_addr_real,32); break; + case 0xd83: TRACE("fcomp mem32"); FCOMM(mem_addr_real,32); FPOP; break; case 0xd84: TRACE("fsub mem32"); FSUBM(mem_addr_real,32); break; case 0xd85: TRACE("fsubr mem32"); FSUBRM(mem_addr_real,32); break; case 0xd86: TRACE("fdiv mem32"); FDIVM(mem_addr_real,32); break; @@ -612,6 +614,8 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) { switch (insn << 4 | modrm.opcode) { case 0xd80: TRACE("fadd st(i), st"); FADD(st_i, st_0); break; case 0xd81: TRACE("fmul st(i), st"); FMUL(st_i, st_0); break; + case 0xd82: TRACE("fcom st"); FCOM(); break; + case 0xd83: TRACE("fcomp st"); FCOM(); FPOP; break; case 0xd84: TRACE("fsub st(i), st"); FSUB(st_i, st_0); break; case 0xd85: TRACE("fsubr st(i), st"); FSUBR(st_i, st_0); break; case 0xd86: TRACE("fdiv st(i), st"); FDIV(st_i, st_0); break; @@ -640,6 +644,7 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) { default: switch (insn << 8 | modrm.opcode << 4 | modrm.rm_opcode) { case 0xd940: TRACE("fchs"); FCHS(); break; case 0xd941: TRACE("fabs"); FABS(); break; + case 0xd944: TRACE("fchs"); FCHS(); break; case 0xd945: TRACE("fxam"); FXAM(); break; case 0xd950: TRACE("fld1"); FLDC(one); break; case 0xd951: TRACE("fldl2t"); FLDC(log2t); break; @@ -654,6 +659,7 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) { case 0xd970: TRACE("fprem"); FPREM(); break; case 0xd972: TRACE("fsqrt"); FSQRT(); break; case 0xd974: TRACE("frndint"); FRNDINT(); break; + case 0xde31: TRACE("fcompp"); FCOM(); FPOP; FPOP; break; case 0xdf40: TRACE("fnstsw ax"); FSTSW(reg_a); break; default: TRACE("undefined"); UNDEFINED; }} diff --git a/emu/float80.c b/emu/float80.c index cf9892753d..6fa067c5a4 100644 --- a/emu/float80.c +++ b/emu/float80.c @@ -452,6 +452,8 @@ float80 f80_log2(float80 x) { float80 zero = f80_from_int(0); float80 one = f80_from_int(1); float80 two = f80_from_int(2); + if (f80_isnan(x) || f80_lte(x, zero)) + return F80_NAN; int ipart = 0; while (f80_lt(x, one)) { diff --git a/emu/fpu.c b/emu/fpu.c index 24b8bdc6b7..046690c86b 100644 --- a/emu/fpu.c +++ b/emu/fpu.c @@ -125,9 +125,15 @@ void fpu_com(struct cpu_state *cpu, int i) { void fpu_comi(struct cpu_state *cpu, int i) { fpu_comparei(cpu, ST(i)); } +void fpu_comm32(struct cpu_state *cpu, float *f) { + fpu_compare(cpu, f80_from_double(*f)); +} void fpu_comm64(struct cpu_state *cpu, double *f) { fpu_compare(cpu, f80_from_double(*f)); } +void fpu_tst(struct cpu_state *cpu) { + fpu_compare(cpu, fpu_consts[fconst_zero]); +} void fpu_abs(struct cpu_state *cpu) { ST(0) = f80_abs(ST(0)); diff --git a/emu/fpu.h b/emu/fpu.h index d6b15d6363..036f8808a6 100644 --- a/emu/fpu.h +++ b/emu/fpu.h @@ -54,8 +54,10 @@ void fpu_yl2x(struct cpu_state *cpu); void fpu_2xm1(struct cpu_state *cpu); void fpu_com(struct cpu_state *cpu, int i); +void fpu_comm32(struct cpu_state *cpu, float *f); void fpu_comm64(struct cpu_state *cpu, double *f); void fpu_comi(struct cpu_state *cpu, int i); +void fpu_tst(struct cpu_state *cpu); #define fpu_ucom fpu_com #define fpu_ucomi fpu_comi diff --git a/emu/interp/fpu.h b/emu/interp/fpu.h index 8095323d14..5c7ed683e2 100644 --- a/emu/interp/fpu.h +++ b/emu/interp/fpu.h @@ -101,6 +101,7 @@ #define FCOM() F_COMPARE(ST_i) #define FUCOM FCOM #define FCOMM(val,z) F_COMPARE(f80_from_float(get(val,z),z)) +#define FTST() F_COMPARE(fpu_consts[fconst_zero]) #define FILD(val,z) \ FPUSH(f80_from_int((sint(z)) get(val,z))) diff --git a/jit/gen.c b/jit/gen.c index 0ff1a24a57..c6062e2ca1 100644 --- a/jit/gen.c +++ b/jit/gen.c @@ -356,6 +356,8 @@ void helper_rdtsc(struct cpu_state *cpu); #define FUCOM() hh(fpu_ucom, st_i) #define FUCOMI() hh(fpu_ucomi, st_i) #define FCOMI() hh(fpu_comi, st_i) +#define FTST() h(fpu_tst) +#define FXAM() h(fpu_xam) #define FST() hh(fpu_st, st_i) #define FCHS() h(fpu_chs) #define FABS() h(fpu_abs) @@ -388,7 +390,6 @@ void helper_rdtsc(struct cpu_state *cpu); #define FIDIVR(val,z) h_read(fpu_idivr, z) #define FDIVRM(val,z) h_read(fpu_divrm, z) #define FPATAN() h(fpu_patan) -#define FXAM() h(fpu_xam) #define DECODER_RET int #define DECODER_NAME gen_step