Skip to content

Commit

Permalink
Downgrade to softfloat 2, for improved hackability
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Jun 24, 2018
1 parent 9cce538 commit 2e53637
Show file tree
Hide file tree
Showing 9 changed files with 6,617 additions and 55 deletions.
4 changes: 2 additions & 2 deletions emu/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#define EMU_H

#include <stddef.h>
#include <softfloat.h>
#include "misc.h"
#include "emu/softfloat.h"
#include "emu/memory.h"
#include "emu/tlb.h"

Expand Down Expand Up @@ -102,7 +102,7 @@ struct cpu_state {
};

// fpu
extFloat80_t fp[8];
floatx80 fp[8];
union {
word_t fsw;
struct {
Expand Down
2 changes: 1 addition & 1 deletion emu/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
union xmm_reg xmm_src; \
union xmm_reg xmm_dst; \
\
extFloat80_t ftmp;
floatx80 ftmp;

#define FINISH \
return -1 // everything is ok.
Expand Down
85 changes: 38 additions & 47 deletions emu/interp/fpu.h
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
#include <softfloat.h>//0xffffb390
#include "emu/softfloat.h"

// a few extra things not included in the softfloat library
static inline extFloat80_t extF80_to_f80(extFloat80_t f) { return f; }
static inline extFloat80_t f80_to_extF80(extFloat80_t f) { return f; }

static inline extFloat80_t extF80_neg(extFloat80_t f) {
f.signExp ^= 1 << 15; // flip the sign bit
return f;
}
static inline extFloat80_t extF80_abs(extFloat80_t f) {
f.signExp &= ~(1 << 15); // clear the sign bit
return f;
}
// yay hack
static inline floatx80 floatx80_to_float80(floatx80 f) { return f; }
static inline floatx80 float80_to_floatx80(floatx80 f) { return f; }

#define ty_real(x) ty_real_##x
#define ty_real_16 float16_t
#define ty_real_32 float32_t
#define ty_real_64 float64_t
#define ty_real_80 extFloat80_t
#define ty_real_16 float16
#define ty_real_32 float32
#define ty_real_64 float64
#define ty_real_80 floatx80

#define mem_read_real(addr, size) mem_read_ts(addr, ty_real(size), size)
#define mem_write_real(addr, val, size) mem_write_ts(addr, val, ty_real(size), size)
#define get_mem_addr_real(size) mem_read_real(addr, size)
#define set_mem_addr_real(to, size) mem_write_real(addr, to, size)

#define extF80_to_f(f, z) glue(extF80_to_f, sz(z))(f)
#define f_to_extF80(f_, z) glue3(f, sz(z), _to_extF80)(f_)
#define extF80_to_i(i, round, exact, z) glue(extF80_to_i, sz(z))(i, round, exact)
#define i_to_extF80(i_, round, exact, z) glue3(i, sz(z), _to_extF80)(i_, round, exact)
#define floatx80_to_float(f, z) glue(floatx80_to_float, sz(z))(f)
#define float_to_floatx80(f_, z) glue3(float, sz(z), _to_floatx80)(f_)
#define floatx80_to_int(i, z) glue(floatx80_to_int, sz(z))(i)
#define int_to_floatx80(i_, z) glue3(int, sz(z), _to_floatx80)(i_)

#define ST(i) cpu->fp[cpu->top + i]
#define ST_i ST(modrm.rm_opcode)
Expand All @@ -37,74 +28,74 @@ static inline extFloat80_t extF80_abs(extFloat80_t f) {
cpu->top++

#define FXCH() \
extFloat80_t ftmp = ST(0); ST(0) = ST_i; ST_i = ftmp
floatx80 ftmp = ST(0); ST(0) = ST_i; ST_i = ftmp

#define st_0 ST(0)
#define st_i ST(modrm.rm_opcode)

#define FADD(src, dst) \
dst = extF80_add(dst, src)
dst = floatx80_add(dst, src)
#define FIADD(val,z) \
ST(0) = extF80_add(ST(0), i64_to_extF80((sint(z)) get(val,z)))
ST(0) = floatx80_add(ST(0), int64_to_floatx80((sint(z)) get(val,z)))
#define FADDM(val,z) \
ST(0) = extF80_add(ST(0), f_to_extF80(get(val,z),z))
ST(0) = floatx80_add(ST(0), float_to_floatx80(get(val,z),z))
#define FSUB(src, dst) \
dst = extF80_sub(dst, src)
dst = floatx80_sub(dst, src)
#define FSUBM(val,z) \
ST(0) = extF80_sub(ST(0), f_to_extF80(get(val,z),z))
ST(0) = floatx80_sub(ST(0), float_to_floatx80(get(val,z),z))
#define FISUB(val,z) \
ST(0) = extF80_sub(ST(0), i64_to_extF80((sint(z)) get(val,z)))
ST(0) = floatx80_sub(ST(0), int64_to_floatx80((sint(z)) get(val,z)))
#define FMUL(src, dst) \
dst = extF80_mul(dst, src)
dst = floatx80_mul(dst, src)
#define FIMUL(val,z) \
ST(0) = extF80_mul(ST(0), i64_to_extF80((sint(z)) get(val,z)))
ST(0) = floatx80_mul(ST(0), int64_to_floatx80((sint(z)) get(val,z)))
#define FMULM(val,z) \
ST(0) = extF80_mul(ST(0), f_to_extF80(get(val,z),z))
ST(0) = floatx80_mul(ST(0), float_to_floatx80(get(val,z),z))
#define FDIV(src, dst) \
dst = extF80_div(dst, src)
dst = floatx80_div(dst, src)
#define FIDIV(val,z) \
ST(0) = extF80_div(ST(0), i64_to_extF80((sint(z)) get(val,z)))
ST(0) = floatx80_div(ST(0), int64_to_floatx80((sint(z)) get(val,z)))
#define FDIVM(val,z) \
ST(0) = extF80_div(ST(0), f_to_extF80(get(val,z),z))
ST(0) = floatx80_div(ST(0), float_to_floatx80(get(val,z),z))

#define FCHS() \
ST(0) = extF80_neg(ST(0))
floatx80_neg(ST(0))
#define FABS() \
ST(0) = extF80_abs(ST(0))
floatx80_abs(ST(0))

// FIXME this is the IEEE ABSOLUTELY CORRECT AND AWESOME REMAINDER which is
// computed by fprem1, not fprem
// only known case of intel naming an instruction by taking another instruction
// that does the same thing but wrong and adding a 1
#define FPREM() \
ST(0) = extF80_rem(ST(0), ST(1))
ST(0) = floatx80_rem(ST(0), ST(1))

#define FUCOMI() \
cpu->zf = extF80_eq(ST(0), ST_i); \
cpu->cf = extF80_lt(ST(0), ST_i); \
cpu->zf = floatx80_eq(ST(0), ST_i); \
cpu->cf = floatx80_lt(ST(0), ST_i); \
cpu->pf = 0; cpu->pf_res = 0
// not worrying about nans and shit yet

#define FUCOM() \
cpu->c0 = extF80_lt(ST(0), ST_i); \
cpu->c0 = floatx80_lt(ST(0), ST_i); \
cpu->c1 = 0; \
cpu->c2 = 0; /* again, not worrying about nans */ \
cpu->c3 = extF80_eq(ST(0), ST_i)
cpu->c3 = floatx80_eq(ST(0), ST_i)

#define FILD(val,z) \
FPUSH(i64_to_extF80((sint(z)) get(val,z)))
FPUSH(int64_to_floatx80((sint(z)) get(val,z)))
#define FLD() FPUSH(ST_i)
#define FLDM(val,z) \
FPUSH(f_to_extF80(get(val,z),z))
FPUSH(float_to_floatx80(get(val,z),z))

#define FLDC(what) FPUSH(fconst_##what)
#define fconst_one i64_to_extF80(1)
#define fconst_zero i64_to_extF80(0)
#define fconst_one int64_to_floatx80(1)
#define fconst_zero int64_to_floatx80(0)

#define FSTM(dst,z) \
set(dst, extF80_to_f(ST(0),z),z)
set(dst, floatx80_to_float(ST(0),z),z)
#define FIST(dst,z) \
set(dst, extF80_to_i(ST(0), softfloat_roundingMode, false, z),z)
set(dst, floatx80_to_int(ST(0), z),z)

#define FST() ST_i = ST(0)

Expand Down
4 changes: 2 additions & 2 deletions emu/interp/sse.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@
#define MOVD(src, dst) \
set(dst, get(src,128).dw[0],32)

#include <softfloat.h>
#include "emu/softfloat.h"
#define CVTTSD2SI(src, dst) \
set(dst, f64_to_i32(get(src,64), softfloat_round_minMag, false),32)
set(dst, float64_to_int32(get(src,64)),32)
Loading

0 comments on commit 2e53637

Please sign in to comment.