From: Andrew Waterman Date: Tue, 11 Apr 2017 00:35:24 +0000 (-0700) Subject: Implement new FP encoding X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d6fce459767509249311a120fddb21c844dc9b2c;p=riscv-isa-sim.git Implement new FP encoding https://groups.google.com/a/groups.riscv.org/d/msg/isa-dev/_r7hBlzsEd8/cWPyJKMzCQAJ --- diff --git a/riscv/decode.h b/riscv/decode.h index bec548a..c3487b1 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -17,11 +17,12 @@ #include "encoding.h" #include "config.h" #include "common.h" +#include "softfloat_types.h" +#include "specialize.h" #include typedef int64_t sreg_t; typedef uint64_t reg_t; -typedef uint64_t freg_t; const int NXPR = 32; const int NFPR = 32; @@ -134,7 +135,7 @@ private: #ifndef RISCV_ENABLE_COMMITLOG # define WRITE_REG(reg, value) STATE.XPR.write(reg, value) -# define WRITE_FREG(reg, value) DO_WRITE_FREG(reg, value) +# define WRITE_FREG(reg, value) DO_WRITE_FREG(reg, freg(value)) #else # define WRITE_REG(reg, value) ({ \ reg_t wdata = (value); /* value may have side effects */ \ @@ -142,7 +143,7 @@ private: STATE.XPR.write(reg, wdata); \ }) # define WRITE_FREG(reg, value) ({ \ - freg_t wdata = (value); /* value may have side effects */ \ + freg_t wdata = freg(value); /* value may have side effects */ \ STATE.log_reg_write = (commit_log_reg_t){((reg) << 1) | 1, wdata}; \ DO_WRITE_FREG(reg, wdata); \ }) @@ -218,8 +219,23 @@ private: #define invalid_pc(pc) ((pc) & 1) /* Convenience wrappers to simplify softfloat code sequences */ -#define f32(x) ((float32_t){(uint32_t)x}) -#define f64(x) ((float64_t){(uint64_t)x}) +#define isBoxedF32(r) (((r) & 0xffffffff00000000) == 0xffffffff00000000) +#define unboxF32(r) (isBoxedF32(r) ? (r) : defaultNaNF32UI) +#define unboxF64(r) (r) +struct freg_t { uint64_t v; }; +inline float32_t f32(uint32_t v) { return { v }; } +inline float64_t f64(uint64_t v) { return { v }; } +inline float32_t f32(freg_t r) { return f32(unboxF32(r.v)); } +inline float64_t f64(freg_t r) { return f64(unboxF64(r.v)); } +inline freg_t freg(float32_t f) { return { ((decltype(freg_t::v))-1 << 32) | f.v }; } +inline freg_t freg(float64_t f) { return { f.v }; } +inline freg_t freg(freg_t f) { return f; } +#define F64_SIGN ((decltype(freg_t::v))1 << 63) +#define F32_SIGN ((decltype(freg_t::v))1 << 31) +#define fsgnj32(a, b, n, x) \ + f32((f32(a).v & ~F32_SIGN) | ((((x) ? f32(a).v : (n) ? F32_SIGN : 0) ^ f32(b).v) & F32_SIGN)) +#define fsgnj64(a, b, n, x) \ + f64((f64(a).v & ~F64_SIGN) | ((((x) ? f64(a).v : (n) ? F64_SIGN : 0) ^ f64(b).v) & F64_SIGN)) #define validate_csr(which, write) ({ \ if (!STATE.serialized) return PC_SERIALIZE_BEFORE; \ diff --git a/riscv/insns/c_fld.h b/riscv/insns/c_fld.h index 10d14f8..319615b 100644 --- a/riscv/insns/c_fld.h +++ b/riscv/insns/c_fld.h @@ -1,4 +1,4 @@ require_extension('C'); require_extension('D'); require_fp; -WRITE_RVC_FRS2S(MMU.load_int64(RVC_RS1S + insn.rvc_ld_imm())); +WRITE_RVC_FRS2S(f64(MMU.load_uint64(RVC_RS1S + insn.rvc_ld_imm()))); diff --git a/riscv/insns/c_fldsp.h b/riscv/insns/c_fldsp.h index 8b1e19f..534eef7 100644 --- a/riscv/insns/c_fldsp.h +++ b/riscv/insns/c_fldsp.h @@ -1,4 +1,4 @@ require_extension('C'); require_extension('D'); require_fp; -WRITE_FRD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm())); +WRITE_FRD(f64(MMU.load_uint64(RVC_SP + insn.rvc_ldsp_imm()))); diff --git a/riscv/insns/c_flw.h b/riscv/insns/c_flw.h index 0be27a9..682566c 100644 --- a/riscv/insns/c_flw.h +++ b/riscv/insns/c_flw.h @@ -2,7 +2,7 @@ require_extension('C'); if (xlen == 32) { require_extension('F'); require_fp; - WRITE_RVC_FRS2S(MMU.load_int32(RVC_RS1S + insn.rvc_lw_imm())); + WRITE_RVC_FRS2S(f32(MMU.load_uint32(RVC_RS1S + insn.rvc_lw_imm()))); } else { // c.ld WRITE_RVC_RS2S(MMU.load_int64(RVC_RS1S + insn.rvc_ld_imm())); } diff --git a/riscv/insns/c_flwsp.h b/riscv/insns/c_flwsp.h index 26a4721..79058c4 100644 --- a/riscv/insns/c_flwsp.h +++ b/riscv/insns/c_flwsp.h @@ -2,7 +2,7 @@ require_extension('C'); if (xlen == 32) { require_extension('F'); require_fp; - WRITE_FRD(MMU.load_int32(RVC_SP + insn.rvc_lwsp_imm())); + WRITE_FRD(f32(MMU.load_uint32(RVC_SP + insn.rvc_lwsp_imm()))); } else { // c.ldsp require(insn.rvc_rd() != 0); WRITE_RD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm())); diff --git a/riscv/insns/c_fsd.h b/riscv/insns/c_fsd.h index 84f1a7f..8743266 100644 --- a/riscv/insns/c_fsd.h +++ b/riscv/insns/c_fsd.h @@ -1,4 +1,4 @@ require_extension('C'); require_extension('D'); require_fp; -MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_FRS2S); +MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_FRS2S.v); diff --git a/riscv/insns/c_fsdsp.h b/riscv/insns/c_fsdsp.h index 5c5c680..f62f8ff 100644 --- a/riscv/insns/c_fsdsp.h +++ b/riscv/insns/c_fsdsp.h @@ -1,4 +1,4 @@ require_extension('C'); require_extension('D'); require_fp; -MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_FRS2); +MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_FRS2.v); diff --git a/riscv/insns/c_fsw.h b/riscv/insns/c_fsw.h index 8923fef..b924a46 100644 --- a/riscv/insns/c_fsw.h +++ b/riscv/insns/c_fsw.h @@ -2,7 +2,7 @@ require_extension('C'); if (xlen == 32) { require_extension('F'); require_fp; - MMU.store_uint32(RVC_RS1S + insn.rvc_lw_imm(), RVC_FRS2S); + MMU.store_uint32(RVC_RS1S + insn.rvc_lw_imm(), RVC_FRS2S.v); } else { // c.sd MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S); } diff --git a/riscv/insns/c_fswsp.h b/riscv/insns/c_fswsp.h index c13aa12..011de55 100644 --- a/riscv/insns/c_fswsp.h +++ b/riscv/insns/c_fswsp.h @@ -2,7 +2,7 @@ require_extension('C'); if (xlen == 32) { require_extension('F'); require_fp; - MMU.store_uint32(RVC_SP + insn.rvc_swsp_imm(), RVC_FRS2); + MMU.store_uint32(RVC_SP + insn.rvc_swsp_imm(), RVC_FRS2.v); } else { // c.sdsp MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2); } diff --git a/riscv/insns/fadd_d.h b/riscv/insns/fadd_d.h index 9990174..4a436e2 100644 --- a/riscv/insns/fadd_d.h +++ b/riscv/insns/fadd_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_add(f64(FRS1), f64(FRS2)).v); +WRITE_FRD(f64_add(f64(FRS1), f64(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fadd_s.h b/riscv/insns/fadd_s.h index cdef36a..cc18d58 100644 --- a/riscv/insns/fadd_s.h +++ b/riscv/insns/fadd_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_add(f32(FRS1), f32(FRS2)).v); +WRITE_FRD(f32_add(f32(FRS1), f32(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fcvt_d_l.h b/riscv/insns/fcvt_d_l.h index fece227..08716cf 100644 --- a/riscv/insns/fcvt_d_l.h +++ b/riscv/insns/fcvt_d_l.h @@ -2,5 +2,5 @@ require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i64_to_f64(RS1).v); +WRITE_FRD(i64_to_f64(RS1)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_d_lu.h b/riscv/insns/fcvt_d_lu.h index 775c7ae..306d7fe 100644 --- a/riscv/insns/fcvt_d_lu.h +++ b/riscv/insns/fcvt_d_lu.h @@ -2,5 +2,5 @@ require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui64_to_f64(RS1).v); +WRITE_FRD(ui64_to_f64(RS1)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_d_s.h b/riscv/insns/fcvt_d_s.h index ec778cc..5f805b0 100644 --- a/riscv/insns/fcvt_d_s.h +++ b/riscv/insns/fcvt_d_s.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_to_f64(f32(FRS1)).v); +WRITE_FRD(f32_to_f64(f32(FRS1))); set_fp_exceptions; diff --git a/riscv/insns/fcvt_d_w.h b/riscv/insns/fcvt_d_w.h index 753250d..4c4861c 100644 --- a/riscv/insns/fcvt_d_w.h +++ b/riscv/insns/fcvt_d_w.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i32_to_f64((int32_t)RS1).v); +WRITE_FRD(i32_to_f64((int32_t)RS1)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_d_wu.h b/riscv/insns/fcvt_d_wu.h index af893b3..1dbf218 100644 --- a/riscv/insns/fcvt_d_wu.h +++ b/riscv/insns/fcvt_d_wu.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui32_to_f64((uint32_t)RS1).v); +WRITE_FRD(ui32_to_f64((uint32_t)RS1)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_d.h b/riscv/insns/fcvt_s_d.h index 211bbba..4033335 100644 --- a/riscv/insns/fcvt_s_d.h +++ b/riscv/insns/fcvt_s_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_to_f32(f64(FRS1)).v); +WRITE_FRD(f64_to_f32(f64(FRS1))); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_l.h b/riscv/insns/fcvt_s_l.h index 1c0581a..9abcc80 100644 --- a/riscv/insns/fcvt_s_l.h +++ b/riscv/insns/fcvt_s_l.h @@ -2,5 +2,5 @@ require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i64_to_f32(RS1).v); +WRITE_FRD(i64_to_f32(RS1)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_lu.h b/riscv/insns/fcvt_s_lu.h index e9bf78e..70c676e 100644 --- a/riscv/insns/fcvt_s_lu.h +++ b/riscv/insns/fcvt_s_lu.h @@ -2,5 +2,5 @@ require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui64_to_f32(RS1).v); +WRITE_FRD(ui64_to_f32(RS1)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_w.h b/riscv/insns/fcvt_s_w.h index 9411cbd..1ddabd8 100644 --- a/riscv/insns/fcvt_s_w.h +++ b/riscv/insns/fcvt_s_w.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i32_to_f32((int32_t)RS1).v); +WRITE_FRD(i32_to_f32((int32_t)RS1)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_wu.h b/riscv/insns/fcvt_s_wu.h index a6cf836..c1394c3 100644 --- a/riscv/insns/fcvt_s_wu.h +++ b/riscv/insns/fcvt_s_wu.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui32_to_f32((uint32_t)RS1).v); +WRITE_FRD(ui32_to_f32((uint32_t)RS1)); set_fp_exceptions; diff --git a/riscv/insns/fdiv_d.h b/riscv/insns/fdiv_d.h index d8943de..ae7911a 100644 --- a/riscv/insns/fdiv_d.h +++ b/riscv/insns/fdiv_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_div(f64(FRS1), f64(FRS2)).v); +WRITE_FRD(f64_div(f64(FRS1), f64(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fdiv_s.h b/riscv/insns/fdiv_s.h index 66ac48d..c74ff04 100644 --- a/riscv/insns/fdiv_s.h +++ b/riscv/insns/fdiv_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_div(f32(FRS1), f32(FRS2)).v); +WRITE_FRD(f32_div(f32(FRS1), f32(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fld.h b/riscv/insns/fld.h index 0b50b8a..4dea1d4 100644 --- a/riscv/insns/fld.h +++ b/riscv/insns/fld.h @@ -1,3 +1,3 @@ require_extension('D'); require_fp; -WRITE_FRD(MMU.load_int64(RS1 + insn.i_imm())); +WRITE_FRD(f64(MMU.load_uint64(RS1 + insn.i_imm()))); diff --git a/riscv/insns/flw.h b/riscv/insns/flw.h index 489e743..6129754 100644 --- a/riscv/insns/flw.h +++ b/riscv/insns/flw.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -WRITE_FRD(MMU.load_uint32(RS1 + insn.i_imm())); +WRITE_FRD(f32(MMU.load_uint32(RS1 + insn.i_imm()))); diff --git a/riscv/insns/fmadd_d.h b/riscv/insns/fmadd_d.h index 98f1cbc..ab22beb 100644 --- a/riscv/insns/fmadd_d.h +++ b/riscv/insns/fmadd_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(FRS3)).v); +WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(FRS3))); set_fp_exceptions; diff --git a/riscv/insns/fmadd_s.h b/riscv/insns/fmadd_s.h index a78ed25..e919190 100644 --- a/riscv/insns/fmadd_s.h +++ b/riscv/insns/fmadd_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(FRS3)).v); +WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(FRS3))); set_fp_exceptions; diff --git a/riscv/insns/fmax_d.h b/riscv/insns/fmax_d.h index 56c9c7a..9c8e5b3 100644 --- a/riscv/insns/fmax_d.h +++ b/riscv/insns/fmax_d.h @@ -1,6 +1,6 @@ require_extension('D'); require_fp; -WRITE_FRD(f64_le_quiet(f64(FRS2), f64(FRS1)) || isNaNF64UI(FRS2) ? FRS1 : FRS2); -if ((isNaNF64UI(FRS1) && isNaNF64UI(FRS2)) || softfloat_exceptionFlags) - WRITE_FRD(defaultNaNF64UI); +WRITE_FRD(f64_le_quiet(f64(FRS2), f64(FRS1)) || isNaNF64UI(f64(FRS2).v) ? FRS1 : FRS2); +if ((isNaNF64UI(f64(FRS1).v) && isNaNF64UI(f64(FRS2).v)) || softfloat_exceptionFlags) + WRITE_FRD(f64(defaultNaNF64UI)); set_fp_exceptions; diff --git a/riscv/insns/fmax_s.h b/riscv/insns/fmax_s.h index bf90356..2f570ea 100644 --- a/riscv/insns/fmax_s.h +++ b/riscv/insns/fmax_s.h @@ -1,6 +1,6 @@ require_extension('F'); require_fp; -WRITE_FRD(f32_le_quiet(f32(FRS2), f32(FRS1)) || isNaNF32UI(FRS2) ? FRS1 : FRS2); -if ((isNaNF32UI(FRS1) && isNaNF32UI(FRS2)) || softfloat_exceptionFlags) - WRITE_FRD(defaultNaNF32UI); +WRITE_FRD(f32_le_quiet(f32(FRS2), f32(FRS1)) || isNaNF32UI(f32(FRS2).v) ? FRS1 : FRS2); +if ((isNaNF32UI(f32(FRS1).v) && isNaNF32UI(f32(FRS2).v)) || softfloat_exceptionFlags) + WRITE_FRD(f32(defaultNaNF32UI)); set_fp_exceptions; diff --git a/riscv/insns/fmin_d.h b/riscv/insns/fmin_d.h index 2a1755e..cd40e15 100644 --- a/riscv/insns/fmin_d.h +++ b/riscv/insns/fmin_d.h @@ -1,6 +1,6 @@ require_extension('D'); require_fp; -WRITE_FRD(f64_lt_quiet(f64(FRS1), f64(FRS2)) || isNaNF64UI(FRS2) ? FRS1 : FRS2); -if ((isNaNF64UI(FRS1) && isNaNF64UI(FRS2)) || softfloat_exceptionFlags) - WRITE_FRD(defaultNaNF64UI); +WRITE_FRD(f64_lt_quiet(f64(FRS1), f64(FRS2)) || isNaNF64UI(f64(FRS2).v) ? FRS1 : FRS2); +if ((isNaNF64UI(f64(FRS1).v) && isNaNF64UI(f64(FRS2).v)) || softfloat_exceptionFlags) + WRITE_FRD(f64(defaultNaNF64UI)); set_fp_exceptions; diff --git a/riscv/insns/fmin_s.h b/riscv/insns/fmin_s.h index 831a7a2..b813f45 100644 --- a/riscv/insns/fmin_s.h +++ b/riscv/insns/fmin_s.h @@ -1,6 +1,6 @@ require_extension('F'); require_fp; -WRITE_FRD(f32_lt_quiet(f32(FRS1), f32(FRS2)) || isNaNF32UI(FRS2) ? FRS1 : FRS2); -if ((isNaNF32UI(FRS1) && isNaNF32UI(FRS2)) || softfloat_exceptionFlags) - WRITE_FRD(defaultNaNF32UI); +WRITE_FRD(f32_lt_quiet(f32(FRS1), f32(FRS2)) || isNaNF32UI(f32(FRS2).v) ? FRS1 : FRS2); +if ((isNaNF32UI(f32(FRS1).v) && isNaNF32UI(f32(FRS2).v)) || softfloat_exceptionFlags) + WRITE_FRD(f32(defaultNaNF32UI)); set_fp_exceptions; diff --git a/riscv/insns/fmsub_d.h b/riscv/insns/fmsub_d.h index afcea88..5b5bc0f 100644 --- a/riscv/insns/fmsub_d.h +++ b/riscv/insns/fmsub_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(FRS3 ^ (uint64_t)INT64_MIN)).v); +WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(f64(FRS3).v ^ F64_SIGN))); set_fp_exceptions; diff --git a/riscv/insns/fmsub_s.h b/riscv/insns/fmsub_s.h index 45945da..d46c887 100644 --- a/riscv/insns/fmsub_s.h +++ b/riscv/insns/fmsub_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(FRS3 ^ (uint32_t)INT32_MIN)).v); +WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(f32(FRS3).v ^ F32_SIGN))); set_fp_exceptions; diff --git a/riscv/insns/fmul_d.h b/riscv/insns/fmul_d.h index 04e7402..9189d8d 100644 --- a/riscv/insns/fmul_d.h +++ b/riscv/insns/fmul_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mul(f64(FRS1), f64(FRS2)).v); +WRITE_FRD(f64_mul(f64(FRS1), f64(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fmul_s.h b/riscv/insns/fmul_s.h index 9ae7b3c..145d5ce 100644 --- a/riscv/insns/fmul_s.h +++ b/riscv/insns/fmul_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mul(f32(FRS1), f32(FRS2)).v); +WRITE_FRD(f32_mul(f32(FRS1), f32(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fmv_d_x.h b/riscv/insns/fmv_d_x.h index c3f6049..0bff5fb 100644 --- a/riscv/insns/fmv_d_x.h +++ b/riscv/insns/fmv_d_x.h @@ -1,4 +1,4 @@ require_extension('D'); require_rv64; require_fp; -WRITE_FRD(RS1); +WRITE_FRD(f64(RS1)); diff --git a/riscv/insns/fmv_s_x.h b/riscv/insns/fmv_s_x.h index 2daf6da..5f71323 100644 --- a/riscv/insns/fmv_s_x.h +++ b/riscv/insns/fmv_s_x.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -WRITE_FRD(zext32(RS1)); +WRITE_FRD(f32(RS1)); diff --git a/riscv/insns/fmv_x_d.h b/riscv/insns/fmv_x_d.h index b97d7f5..da8e72a 100644 --- a/riscv/insns/fmv_x_d.h +++ b/riscv/insns/fmv_x_d.h @@ -1,4 +1,4 @@ require_extension('D'); require_rv64; require_fp; -WRITE_RD(FRS1); +WRITE_RD(FRS1.v); diff --git a/riscv/insns/fmv_x_s.h b/riscv/insns/fmv_x_s.h index 1bee87f..b722479 100644 --- a/riscv/insns/fmv_x_s.h +++ b/riscv/insns/fmv_x_s.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -WRITE_RD(sext32(FRS1)); +WRITE_RD(sext32(FRS1.v)); diff --git a/riscv/insns/fnmadd_d.h b/riscv/insns/fnmadd_d.h index d6e1f04..e8dd743 100644 --- a/riscv/insns/fnmadd_d.h +++ b/riscv/insns/fnmadd_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(f64(FRS1 ^ (uint64_t)INT64_MIN), f64(FRS2), f64(FRS3 ^ (uint64_t)INT64_MIN)).v); +WRITE_FRD(f64_mulAdd(f64(f64(FRS1).v ^ F64_SIGN), f64(FRS2), f64(f64(FRS3).v ^ F64_SIGN))); set_fp_exceptions; diff --git a/riscv/insns/fnmadd_s.h b/riscv/insns/fnmadd_s.h index 0d0b2e9..1c2996e 100644 --- a/riscv/insns/fnmadd_s.h +++ b/riscv/insns/fnmadd_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(f32(FRS1 ^ (uint32_t)INT32_MIN), f32(FRS2), f32(FRS3 ^ (uint32_t)INT32_MIN)).v); +WRITE_FRD(f32_mulAdd(f32(f32(FRS1).v ^ F32_SIGN), f32(FRS2), f32(f32(FRS3).v ^ F32_SIGN))); set_fp_exceptions; diff --git a/riscv/insns/fnmsub_d.h b/riscv/insns/fnmsub_d.h index ee74cab..c29a0b9 100644 --- a/riscv/insns/fnmsub_d.h +++ b/riscv/insns/fnmsub_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(f64(FRS1 ^ (uint64_t)INT64_MIN), f64(FRS2), f64(FRS3)).v); +WRITE_FRD(f64_mulAdd(f64(f64(FRS1).v ^ F64_SIGN), f64(FRS2), f64(FRS3))); set_fp_exceptions; diff --git a/riscv/insns/fnmsub_s.h b/riscv/insns/fnmsub_s.h index 3e0b8ea..4c61fc7 100644 --- a/riscv/insns/fnmsub_s.h +++ b/riscv/insns/fnmsub_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(f32(FRS1 ^ (uint32_t)INT32_MIN), f32(FRS2), f32(FRS3)).v); +WRITE_FRD(f32_mulAdd(f32(f32(FRS1).v ^ F32_SIGN), f32(FRS2), f32(FRS3))); set_fp_exceptions; diff --git a/riscv/insns/fsd.h b/riscv/insns/fsd.h index 63cc8e5..679cc95 100644 --- a/riscv/insns/fsd.h +++ b/riscv/insns/fsd.h @@ -1,3 +1,3 @@ require_extension('D'); require_fp; -MMU.store_uint64(RS1 + insn.s_imm(), FRS2); +MMU.store_uint64(RS1 + insn.s_imm(), FRS2.v); diff --git a/riscv/insns/fsgnj_d.h b/riscv/insns/fsgnj_d.h index 52648a1..78f9ce7 100644 --- a/riscv/insns/fsgnj_d.h +++ b/riscv/insns/fsgnj_d.h @@ -1,3 +1,3 @@ require_extension('D'); require_fp; -WRITE_FRD((FRS1 &~ INT64_MIN) | (FRS2 & INT64_MIN)); +WRITE_FRD(fsgnj64(FRS1, FRS2, false, false)); diff --git a/riscv/insns/fsgnj_s.h b/riscv/insns/fsgnj_s.h index 4c91ff3..c1a70cb 100644 --- a/riscv/insns/fsgnj_s.h +++ b/riscv/insns/fsgnj_s.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -WRITE_FRD((FRS1 &~ (uint32_t)INT32_MIN) | (FRS2 & (uint32_t)INT32_MIN)); +WRITE_FRD(fsgnj32(FRS1, FRS2, false, false)); diff --git a/riscv/insns/fsgnjn_d.h b/riscv/insns/fsgnjn_d.h index cdec924..f02c311 100644 --- a/riscv/insns/fsgnjn_d.h +++ b/riscv/insns/fsgnjn_d.h @@ -1,3 +1,3 @@ require_extension('D'); require_fp; -WRITE_FRD((FRS1 &~ INT64_MIN) | ((~FRS2) & INT64_MIN)); +WRITE_FRD(fsgnj64(FRS1, FRS2, true, false)); diff --git a/riscv/insns/fsgnjn_s.h b/riscv/insns/fsgnjn_s.h index f91a7b0..35906d6 100644 --- a/riscv/insns/fsgnjn_s.h +++ b/riscv/insns/fsgnjn_s.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -WRITE_FRD((FRS1 &~ (uint32_t)INT32_MIN) | ((~FRS2) & (uint32_t)INT32_MIN)); +WRITE_FRD(fsgnj32(FRS1, FRS2, true, false)); diff --git a/riscv/insns/fsgnjx_d.h b/riscv/insns/fsgnjx_d.h index b09d24c..c121737 100644 --- a/riscv/insns/fsgnjx_d.h +++ b/riscv/insns/fsgnjx_d.h @@ -1,3 +1,3 @@ require_extension('D'); require_fp; -WRITE_FRD(FRS1 ^ (FRS2 & INT64_MIN)); +WRITE_FRD(fsgnj64(FRS1, FRS2, false, true)); diff --git a/riscv/insns/fsgnjx_s.h b/riscv/insns/fsgnjx_s.h index 1fd2de6..4d5c624 100644 --- a/riscv/insns/fsgnjx_s.h +++ b/riscv/insns/fsgnjx_s.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -WRITE_FRD(FRS1 ^ (FRS2 & (uint32_t)INT32_MIN)); +WRITE_FRD(fsgnj32(FRS1, FRS2, false, true)); diff --git a/riscv/insns/fsqrt_d.h b/riscv/insns/fsqrt_d.h index 45f37ce..da138ba 100644 --- a/riscv/insns/fsqrt_d.h +++ b/riscv/insns/fsqrt_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_sqrt(f64(FRS1)).v); +WRITE_FRD(f64_sqrt(f64(FRS1))); set_fp_exceptions; diff --git a/riscv/insns/fsqrt_s.h b/riscv/insns/fsqrt_s.h index f3b3956..7476846 100644 --- a/riscv/insns/fsqrt_s.h +++ b/riscv/insns/fsqrt_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_sqrt(f32(FRS1)).v); +WRITE_FRD(f32_sqrt(f32(FRS1))); set_fp_exceptions; diff --git a/riscv/insns/fsub_d.h b/riscv/insns/fsub_d.h index 487743e..1418a06 100644 --- a/riscv/insns/fsub_d.h +++ b/riscv/insns/fsub_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_sub(f64(FRS1), f64(FRS2)).v); +WRITE_FRD(f64_sub(f64(FRS1), f64(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fsub_s.h b/riscv/insns/fsub_s.h index e7a7cf1..f6183ea 100644 --- a/riscv/insns/fsub_s.h +++ b/riscv/insns/fsub_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_sub(f32(FRS1), f32(FRS2)).v); +WRITE_FRD(f32_sub(f32(FRS1), f32(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fsw.h b/riscv/insns/fsw.h index 3135e9b..42fc683 100644 --- a/riscv/insns/fsw.h +++ b/riscv/insns/fsw.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -MMU.store_uint32(RS1 + insn.s_imm(), FRS2); +MMU.store_uint32(RS1 + insn.s_imm(), FRS2.v); diff --git a/riscv/interactive.cc b/riscv/interactive.cc index ee88375..31b9162 100644 --- a/riscv/interactive.cc +++ b/riscv/interactive.cc @@ -66,6 +66,7 @@ void sim_t::interactive() funcs["r"] = funcs["run"]; funcs["rs"] = &sim_t::interactive_run_silent; funcs["reg"] = &sim_t::interactive_reg; + funcs["freg"] = &sim_t::interactive_freg; funcs["fregs"] = &sim_t::interactive_fregs; funcs["fregd"] = &sim_t::interactive_fregd; funcs["pc"] = &sim_t::interactive_pc; @@ -199,7 +200,7 @@ reg_t sim_t::get_reg(const std::vector& args) return p->state.XPR[r]; } -reg_t sim_t::get_freg(const std::vector& args) +freg_t sim_t::get_freg(const std::vector& args) { if(args.size() != 2) throw trap_interactive(); @@ -231,11 +232,16 @@ void sim_t::interactive_reg(const std::string& cmd, const std::vector& args) +{ + fprintf(stderr, "0x%016" PRIx64 "\n", get_freg(args).v); +} + void sim_t::interactive_fregs(const std::string& cmd, const std::vector& args) { fpr f; diff --git a/riscv/sim.h b/riscv/sim.h index 57bdf8c..8586bee 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -76,6 +76,7 @@ private: void interactive_run_noisy(const std::string& cmd, const std::vector& args); void interactive_run_silent(const std::string& cmd, const std::vector& args); void interactive_reg(const std::string& cmd, const std::vector& args); + void interactive_freg(const std::string& cmd, const std::vector& args); void interactive_fregs(const std::string& cmd, const std::vector& args); void interactive_fregd(const std::string& cmd, const std::vector& args); void interactive_pc(const std::string& cmd, const std::vector& args); @@ -83,7 +84,7 @@ private: void interactive_str(const std::string& cmd, const std::vector& args); void interactive_until(const std::string& cmd, const std::vector& args); reg_t get_reg(const std::vector& args); - reg_t get_freg(const std::vector& args); + freg_t get_freg(const std::vector& args); reg_t get_mem(const std::vector& args); reg_t get_pc(const std::vector& args);