Skip to content

Commit

Permalink
Implement fnstenv/fldenv
Browse files Browse the repository at this point in the history
  • Loading branch information
Theodore Dubois committed Nov 18, 2019
1 parent eeae17c commit dca7617
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 10 deletions.
6 changes: 6 additions & 0 deletions emu/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,13 @@ __no_instrument DECODER_RET glue(DECODER_NAME, OP_SIZE)(DECODER_ARGS) {
case 0xd90: TRACE("fld mem32"); FLDM(mem_addr_real,32); break;
case 0xd92: TRACE("fst mem32"); FSTM(mem_addr_real,32); break;
case 0xd93: TRACE("fstp mem32"); FSTM(mem_addr_real,32); FPOP; break;
#if OP_SIZE == 32
case 0xd94: TRACE("fldenv mem32"); FLDENV(mem_addr,32); break;
#endif
case 0xd95: TRACE("fldcw mem16"); FLDCW(mem_addr); break;
#if OP_SIZE == 32
case 0xd96: TRACE("fnstenv mem32"); FSTENV(mem_addr,32); break;
#endif
case 0xd97: TRACE("fnstcw mem16"); FSTCW(mem_addr); break;
case 0xda0: TRACE("fiadd mem32"); FIADD(mem_addr,32); break;
case 0xda1: TRACE("fimul mem32"); FIMUL(mem_addr,32); break;
Expand Down
41 changes: 33 additions & 8 deletions emu/fpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,6 @@ void fpu_divrm64(struct cpu_state *cpu, float64 *f) {
ST(0) = f80_div(f80_from_double(*f), ST(0));
}

void fpu_stcw16(struct cpu_state *cpu, uint16_t *i) {
*i = cpu->fcw;
}
void fpu_ldcw16(struct cpu_state *cpu, uint16_t *i) {
cpu->fcw = *i;
f80_rounding_mode = cpu->rc;
}

void fpu_patan(struct cpu_state *cpu) {
// there's no native atan2 for 80-bit float yet.
ST(1) = f80_from_double(atan2(f80_to_double(ST(1)), f80_to_double(ST(0))));
Expand Down Expand Up @@ -291,3 +283,36 @@ void fpu_xam(struct cpu_state *cpu) {
cpu->c2 = (outflags >> 1) & 1;
cpu->c3 = (outflags >> 2) & 1;
}

// meta

void fpu_stcw16(struct cpu_state *cpu, uint16_t *i) {
*i = cpu->fcw;
}
void fpu_ldcw16(struct cpu_state *cpu, uint16_t *i) {
cpu->fcw = *i;
f80_rounding_mode = cpu->rc;
}

struct fpu_env32 {
uint32_t control;
uint32_t status;
uint32_t tag;
uint32_t ip;
uint32_t ip_selector;
uint32_t operand;
uint32_t operand_selector;
};

void fpu_stenv32(struct cpu_state *cpu, struct fpu_env32 *env) {
env->control = cpu->fcw;
env->status = cpu->fsw;
// hope nobody looks at these
env->tag = 0;
env->ip = env->ip_selector = 0;
env->operand = env->operand_selector = 0;
}
void fpu_ldenv32(struct cpu_state *cpu, struct fpu_env32 *env) {
cpu->fcw = env->control;
cpu->fsw = env->status;
}
8 changes: 6 additions & 2 deletions emu/fpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define EMU_FPU_H
#include "emu/float80.h"
struct cpu_state;
struct fpu_env32;

typedef float float32;
typedef double float64;
Expand Down Expand Up @@ -95,9 +96,12 @@ void fpu_mulm64(struct cpu_state *cpu, double *f);
void fpu_divm64(struct cpu_state *cpu, double *f);
void fpu_divrm64(struct cpu_state *cpu, double *f);

void fpu_stcw16(struct cpu_state *cpu, uint16_t *i);
void fpu_ldcw16(struct cpu_state *cpu, uint16_t *i);
void fpu_patan(struct cpu_state *cpu);
void fpu_xam(struct cpu_state *cpu);

void fpu_stcw16(struct cpu_state *cpu, uint16_t *i);
void fpu_ldcw16(struct cpu_state *cpu, uint16_t *i);
void fpu_stenv32(struct cpu_state *cpu, struct fpu_env32 *env);
void fpu_ldenv32(struct cpu_state *cpu, struct fpu_env32 *env);

#endif
2 changes: 2 additions & 0 deletions jit/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ void helper_rdtsc(struct cpu_state *cpu);
#define FSTSW(dst) if (arg_##dst == arg_reg_a) g(fstsw_ax); else UNDEFINED
#define FSTCW(dst) if (arg_##dst == arg_reg_a) UNDEFINED; else h_write(fpu_stcw, 16)
#define FLDCW(dst) if (arg_##dst == arg_reg_a) UNDEFINED; else h_read(fpu_ldcw, 16)
#define FSTENV(val,z) h_write(fpu_stenv, z)
#define FLDENV(val,z) h_write(fpu_ldenv, z)
#define FPOP h(fpu_pop)
#define FADD(src, dst) hhh(fpu_add, src, dst)
#define FIADD(val,z) h_read(fpu_iadd, z)
Expand Down

0 comments on commit dca7617

Please sign in to comment.