aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2017-09-24 20:34:04 -0700
committerAndrew Waterman <andrew@sifive.com>2017-09-28 15:56:47 -0700
commit85c40db208db3e26f507dc6a74a5dc540b504b5c (patch)
tree88ddd7440be666a4305a55e4ca1130ae7636a4f6
parentbd85811c35ea38180d27440507fc222d585ef780 (diff)
downloadspike-85c40db208db3e26f507dc6a74a5dc540b504b5c.zip
spike-85c40db208db3e26f507dc6a74a5dc540b504b5c.tar.gz
spike-85c40db208db3e26f507dc6a74a5dc540b504b5c.tar.bz2
Implement Q extension
-rw-r--r--riscv/decode.h43
-rw-r--r--riscv/insns/c_fsd.h2
-rw-r--r--riscv/insns/c_fsdsp.h2
-rw-r--r--riscv/insns/c_fsw.h2
-rw-r--r--riscv/insns/c_fswsp.h2
-rw-r--r--riscv/insns/fadd_q.h5
-rw-r--r--riscv/insns/fclass_q.h3
-rw-r--r--riscv/insns/fcvt_d_q.h5
-rw-r--r--riscv/insns/fcvt_l_q.h6
-rw-r--r--riscv/insns/fcvt_lu_q.h6
-rw-r--r--riscv/insns/fcvt_q_d.h5
-rw-r--r--riscv/insns/fcvt_q_l.h6
-rw-r--r--riscv/insns/fcvt_q_lu.h6
-rw-r--r--riscv/insns/fcvt_q_s.h5
-rw-r--r--riscv/insns/fcvt_q_w.h5
-rw-r--r--riscv/insns/fcvt_q_wu.h5
-rw-r--r--riscv/insns/fcvt_s_q.h5
-rw-r--r--riscv/insns/fcvt_w_q.h5
-rw-r--r--riscv/insns/fcvt_wu_q.h5
-rw-r--r--riscv/insns/fdiv_q.h5
-rw-r--r--riscv/insns/feq_q.h4
-rw-r--r--riscv/insns/fle_q.h4
-rw-r--r--riscv/insns/flq.h3
-rw-r--r--riscv/insns/flt_q.h4
-rw-r--r--riscv/insns/fmadd_q.h5
-rw-r--r--riscv/insns/fmax_q.h8
-rw-r--r--riscv/insns/fmin_q.h8
-rw-r--r--riscv/insns/fmsub_q.h5
-rw-r--r--riscv/insns/fmul_q.h5
-rw-r--r--riscv/insns/fmv_x_d.h2
-rw-r--r--riscv/insns/fmv_x_w.h2
-rw-r--r--riscv/insns/fnmadd_q.h5
-rw-r--r--riscv/insns/fnmsub_q.h5
-rw-r--r--riscv/insns/fsd.h2
-rw-r--r--riscv/insns/fsgnj_q.h3
-rw-r--r--riscv/insns/fsgnjn_q.h3
-rw-r--r--riscv/insns/fsgnjx_q.h3
-rw-r--r--riscv/insns/fsq.h3
-rw-r--r--riscv/insns/fsqrt_q.h5
-rw-r--r--riscv/insns/fsub_q.h5
-rw-r--r--riscv/insns/fsw.h2
-rw-r--r--riscv/interactive.cc7
-rw-r--r--riscv/mmu.h19
-rw-r--r--riscv/processor.cc10
-rw-r--r--riscv/riscv.mk.in32
45 files changed, 258 insertions, 24 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 9dcd809..45dd3c4 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -219,24 +219,45 @@ private:
#define invalid_pc(pc) ((pc) & 1)
/* Convenience wrappers to simplify softfloat code sequences */
-#define isBoxedF32(r) (((r) & 0xffffffff00000000) == 0xffffffff00000000)
-#define unboxF32(r) (isBoxedF32(r) ? (r) : defaultNaNF32UI)
-#define unboxF64(r) (r)
-struct freg_t { uint64_t v; };
+#define isBoxedF32(r) (isBoxedF64(r) && ((uint32_t)((r.v[0] >> 32) + 1) == 0))
+#define unboxF32(r) (isBoxedF32(r) ? (uint32_t)r.v[0] : defaultNaNF32UI)
+#define isBoxedF64(r) ((r.v[1] + 1) == 0)
+#define unboxF64(r) (isBoxedF64(r) ? r.v[0] : defaultNaNF64UI)
+typedef float128_t freg_t;
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)
+inline float32_t f32(freg_t r) { return f32(unboxF32(r)); }
+inline float64_t f64(freg_t r) { return f64(unboxF64(r)); }
+inline float128_t f128(freg_t r) { return r; }
+inline freg_t freg(float32_t f) { return { ((uint64_t)-1 << 32) | f.v, (uint64_t)-1 }; }
+inline freg_t freg(float64_t f) { return { f.v, (uint64_t)-1 }; }
+inline freg_t freg(float128_t f) { return f; }
+#define F32_SIGN ((uint32_t)1 << 31)
+#define F64_SIGN ((uint64_t)1 << 63)
#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 isNaNF128(x) isNaNF128UI(x.v[1], x.v[0])
+inline float128_t defaultNaNF128()
+{
+ float128_t nan;
+ nan.v[1] = defaultNaNF128UI64;
+ nan.v[0] = defaultNaNF128UI0;
+ return nan;
+}
+inline freg_t fsgnj128(freg_t a, freg_t b, bool n, bool x)
+{
+ a.v[1] = (a.v[1] & ~F64_SIGN) | (((x ? a.v[1] : n ? F64_SIGN : 0) ^ b.v[1]) & F64_SIGN);
+ return a;
+}
+inline freg_t f128_negate(freg_t a)
+{
+ a.v[1] ^= F64_SIGN;
+ return a;
+}
+
#define validate_csr(which, write) ({ \
if (!STATE.serialized) return PC_SERIALIZE_BEFORE; \
STATE.serialized = false; \
diff --git a/riscv/insns/c_fsd.h b/riscv/insns/c_fsd.h
index 8743266..6f2c8f4 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.v);
+MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_FRS2S.v[0]);
diff --git a/riscv/insns/c_fsdsp.h b/riscv/insns/c_fsdsp.h
index f62f8ff..27b9331 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.v);
+MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_FRS2.v[0]);
diff --git a/riscv/insns/c_fsw.h b/riscv/insns/c_fsw.h
index b924a46..7085822 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.v);
+ MMU.store_uint32(RVC_RS1S + insn.rvc_lw_imm(), RVC_FRS2S.v[0]);
} 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 011de55..c5a003f 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.v);
+ MMU.store_uint32(RVC_SP + insn.rvc_swsp_imm(), RVC_FRS2.v[0]);
} else { // c.sdsp
MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2);
}
diff --git a/riscv/insns/fadd_q.h b/riscv/insns/fadd_q.h
new file mode 100644
index 0000000..1139a74
--- /dev/null
+++ b/riscv/insns/fadd_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_add(f128(FRS1), f128(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fclass_q.h b/riscv/insns/fclass_q.h
new file mode 100644
index 0000000..5330758
--- /dev/null
+++ b/riscv/insns/fclass_q.h
@@ -0,0 +1,3 @@
+require_extension('Q');
+require_fp;
+WRITE_RD(f128_classify(f128(FRS1)));
diff --git a/riscv/insns/fcvt_d_q.h b/riscv/insns/fcvt_d_q.h
new file mode 100644
index 0000000..b50a43d
--- /dev/null
+++ b/riscv/insns/fcvt_d_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_to_f64(f128(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_l_q.h b/riscv/insns/fcvt_l_q.h
new file mode 100644
index 0000000..b28bca2
--- /dev/null
+++ b/riscv/insns/fcvt_l_q.h
@@ -0,0 +1,6 @@
+require_extension('Q');
+require_rv64;
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_RD(f128_to_i64(f128(FRS1), RM, true));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_lu_q.h b/riscv/insns/fcvt_lu_q.h
new file mode 100644
index 0000000..8c5be7c
--- /dev/null
+++ b/riscv/insns/fcvt_lu_q.h
@@ -0,0 +1,6 @@
+require_extension('Q');
+require_rv64;
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_RD(f128_to_ui64(f128(FRS1), RM, true));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_q_d.h b/riscv/insns/fcvt_q_d.h
new file mode 100644
index 0000000..c2437b1
--- /dev/null
+++ b/riscv/insns/fcvt_q_d.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f64_to_f128(f64(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_q_l.h b/riscv/insns/fcvt_q_l.h
new file mode 100644
index 0000000..f1f45ca
--- /dev/null
+++ b/riscv/insns/fcvt_q_l.h
@@ -0,0 +1,6 @@
+require_extension('Q');
+require_rv64;
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(i64_to_f128(RS1));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_q_lu.h b/riscv/insns/fcvt_q_lu.h
new file mode 100644
index 0000000..850212e
--- /dev/null
+++ b/riscv/insns/fcvt_q_lu.h
@@ -0,0 +1,6 @@
+require_extension('Q');
+require_rv64;
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(ui64_to_f128(RS1));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_q_s.h b/riscv/insns/fcvt_q_s.h
new file mode 100644
index 0000000..79e6bb6
--- /dev/null
+++ b/riscv/insns/fcvt_q_s.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f32_to_f128(f32(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_q_w.h b/riscv/insns/fcvt_q_w.h
new file mode 100644
index 0000000..fb83f15
--- /dev/null
+++ b/riscv/insns/fcvt_q_w.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(i32_to_f128((int32_t)RS1));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_q_wu.h b/riscv/insns/fcvt_q_wu.h
new file mode 100644
index 0000000..7c2ae97
--- /dev/null
+++ b/riscv/insns/fcvt_q_wu.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(ui32_to_f128((uint32_t)RS1));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_s_q.h b/riscv/insns/fcvt_s_q.h
new file mode 100644
index 0000000..b0f118e
--- /dev/null
+++ b/riscv/insns/fcvt_s_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_to_f32(f128(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_w_q.h b/riscv/insns/fcvt_w_q.h
new file mode 100644
index 0000000..e10bafc
--- /dev/null
+++ b/riscv/insns/fcvt_w_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_RD(sext32(f128_to_i32(f128(FRS1), RM, true)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_wu_q.h b/riscv/insns/fcvt_wu_q.h
new file mode 100644
index 0000000..c391dc8
--- /dev/null
+++ b/riscv/insns/fcvt_wu_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_RD(sext32(f128_to_ui32(f128(FRS1), RM, true)));
+set_fp_exceptions;
diff --git a/riscv/insns/fdiv_q.h b/riscv/insns/fdiv_q.h
new file mode 100644
index 0000000..2204831
--- /dev/null
+++ b/riscv/insns/fdiv_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_div(f128(FRS1), f128(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/feq_q.h b/riscv/insns/feq_q.h
new file mode 100644
index 0000000..cee2da9
--- /dev/null
+++ b/riscv/insns/feq_q.h
@@ -0,0 +1,4 @@
+require_extension('Q');
+require_fp;
+WRITE_RD(f128_eq(f128(FRS1), f128(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fle_q.h b/riscv/insns/fle_q.h
new file mode 100644
index 0000000..8368af9
--- /dev/null
+++ b/riscv/insns/fle_q.h
@@ -0,0 +1,4 @@
+require_extension('Q');
+require_fp;
+WRITE_RD(f128_le(f128(FRS1), f128(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/flq.h b/riscv/insns/flq.h
new file mode 100644
index 0000000..81d225c
--- /dev/null
+++ b/riscv/insns/flq.h
@@ -0,0 +1,3 @@
+require_extension('Q');
+require_fp;
+WRITE_FRD(MMU.load_float128(RS1 + insn.i_imm()));
diff --git a/riscv/insns/flt_q.h b/riscv/insns/flt_q.h
new file mode 100644
index 0000000..c452141
--- /dev/null
+++ b/riscv/insns/flt_q.h
@@ -0,0 +1,4 @@
+require_extension('Q');
+require_fp;
+WRITE_RD(f128_lt(f128(FRS1), f128(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fmadd_q.h b/riscv/insns/fmadd_q.h
new file mode 100644
index 0000000..882dfc1
--- /dev/null
+++ b/riscv/insns/fmadd_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_mulAdd(f128(FRS1), f128(FRS2), f128(FRS3)));
+set_fp_exceptions;
diff --git a/riscv/insns/fmax_q.h b/riscv/insns/fmax_q.h
new file mode 100644
index 0000000..719e6d0
--- /dev/null
+++ b/riscv/insns/fmax_q.h
@@ -0,0 +1,8 @@
+require_extension('Q');
+require_fp;
+bool greater = f128_lt_quiet(f128(FRS2), f128(FRS1)) ||
+ (f128_eq(f128(FRS2), f128(FRS1)) && (f128(FRS2).v[1] & F64_SIGN));
+WRITE_FRD(greater || isNaNF128(f128(FRS2)) ? FRS1 : FRS2);
+if (isNaNF128(f128(FRS1)) && isNaNF128(f128(FRS2)))
+ WRITE_FRD(f128(defaultNaNF128()));
+set_fp_exceptions;
diff --git a/riscv/insns/fmin_q.h b/riscv/insns/fmin_q.h
new file mode 100644
index 0000000..675c7fd
--- /dev/null
+++ b/riscv/insns/fmin_q.h
@@ -0,0 +1,8 @@
+require_extension('Q');
+require_fp;
+bool less = f128_lt_quiet(f128(FRS1), f128(FRS2)) ||
+ (f128_eq(f128(FRS1), f128(FRS2)) && (f128(FRS1).v[1] & F64_SIGN));
+WRITE_FRD(less || isNaNF128(f128(FRS2)) ? FRS1 : FRS2);
+if (isNaNF128(f128(FRS1)) && isNaNF128(f128(FRS2)))
+ WRITE_FRD(f128(defaultNaNF128()));
+set_fp_exceptions;
diff --git a/riscv/insns/fmsub_q.h b/riscv/insns/fmsub_q.h
new file mode 100644
index 0000000..1bb96c2
--- /dev/null
+++ b/riscv/insns/fmsub_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_mulAdd(f128(FRS1), f128(FRS2), f128_negate(f128(FRS3))));
+set_fp_exceptions;
diff --git a/riscv/insns/fmul_q.h b/riscv/insns/fmul_q.h
new file mode 100644
index 0000000..66f5a05
--- /dev/null
+++ b/riscv/insns/fmul_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_mul(f128(FRS1), f128(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fmv_x_d.h b/riscv/insns/fmv_x_d.h
index da8e72a..e1a23f4 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.v);
+WRITE_RD(FRS1.v[0]);
diff --git a/riscv/insns/fmv_x_w.h b/riscv/insns/fmv_x_w.h
index b722479..6754f86 100644
--- a/riscv/insns/fmv_x_w.h
+++ b/riscv/insns/fmv_x_w.h
@@ -1,3 +1,3 @@
require_extension('F');
require_fp;
-WRITE_RD(sext32(FRS1.v));
+WRITE_RD(sext32(FRS1.v[0]));
diff --git a/riscv/insns/fnmadd_q.h b/riscv/insns/fnmadd_q.h
new file mode 100644
index 0000000..a36ce18
--- /dev/null
+++ b/riscv/insns/fnmadd_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_mulAdd(f128_negate(f128(FRS1)), f128(FRS2), f128_negate(f128(FRS3))));
+set_fp_exceptions;
diff --git a/riscv/insns/fnmsub_q.h b/riscv/insns/fnmsub_q.h
new file mode 100644
index 0000000..130b4ce
--- /dev/null
+++ b/riscv/insns/fnmsub_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_mulAdd(f128_negate(f128(FRS1)), f128(FRS2), f128(FRS3)));
+set_fp_exceptions;
diff --git a/riscv/insns/fsd.h b/riscv/insns/fsd.h
index 679cc95..38c702b 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.v);
+MMU.store_uint64(RS1 + insn.s_imm(), FRS2.v[0]);
diff --git a/riscv/insns/fsgnj_q.h b/riscv/insns/fsgnj_q.h
new file mode 100644
index 0000000..0b9a270
--- /dev/null
+++ b/riscv/insns/fsgnj_q.h
@@ -0,0 +1,3 @@
+require_extension('Q');
+require_fp;
+WRITE_FRD(fsgnj128(FRS1, FRS2, false, false));
diff --git a/riscv/insns/fsgnjn_q.h b/riscv/insns/fsgnjn_q.h
new file mode 100644
index 0000000..38c7bbf
--- /dev/null
+++ b/riscv/insns/fsgnjn_q.h
@@ -0,0 +1,3 @@
+require_extension('Q');
+require_fp;
+WRITE_FRD(fsgnj128(FRS1, FRS2, true, false));
diff --git a/riscv/insns/fsgnjx_q.h b/riscv/insns/fsgnjx_q.h
new file mode 100644
index 0000000..fc86d26
--- /dev/null
+++ b/riscv/insns/fsgnjx_q.h
@@ -0,0 +1,3 @@
+require_extension('Q');
+require_fp;
+WRITE_FRD(fsgnj128(FRS1, FRS2, false, true));
diff --git a/riscv/insns/fsq.h b/riscv/insns/fsq.h
new file mode 100644
index 0000000..610960e
--- /dev/null
+++ b/riscv/insns/fsq.h
@@ -0,0 +1,3 @@
+require_extension('Q');
+require_fp;
+MMU.store_float128(RS1 + insn.s_imm(), FRS2);
diff --git a/riscv/insns/fsqrt_q.h b/riscv/insns/fsqrt_q.h
new file mode 100644
index 0000000..6cb6ba3
--- /dev/null
+++ b/riscv/insns/fsqrt_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_sqrt(f128(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fsub_q.h b/riscv/insns/fsub_q.h
new file mode 100644
index 0000000..e050e3a
--- /dev/null
+++ b/riscv/insns/fsub_q.h
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_sub(f128(FRS1), f128(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fsw.h b/riscv/insns/fsw.h
index 42fc683..8af5184 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.v);
+MMU.store_uint32(RS1 + insn.s_imm(), FRS2.v[0]);
diff --git a/riscv/interactive.cc b/riscv/interactive.cc
index 31b9162..e6e8616 100644
--- a/riscv/interactive.cc
+++ b/riscv/interactive.cc
@@ -239,21 +239,22 @@ union fpr
void sim_t::interactive_freg(const std::string& cmd, const std::vector<std::string>& args)
{
- fprintf(stderr, "0x%016" PRIx64 "\n", get_freg(args).v);
+ freg_t r = get_freg(args);
+ fprintf(stderr, "0x%016" PRIx64 "%016" PRIx64 "\n", r.v[1], r.v[0]);
}
void sim_t::interactive_fregs(const std::string& cmd, const std::vector<std::string>& args)
{
fpr f;
f.r = get_freg(args);
- fprintf(stderr, "%g\n",f.s);
+ fprintf(stderr, "%g\n", isBoxedF32(f.r) ? (double)f.s : NAN);
}
void sim_t::interactive_fregd(const std::string& cmd, const std::vector<std::string>& args)
{
fpr f;
f.r = get_freg(args);
- fprintf(stderr, "%g\n",f.d);
+ fprintf(stderr, "%g\n", isBoxedF64(f.r) ? f.d : NAN);
}
reg_t sim_t::get_mem(const std::vector<std::string>& args)
diff --git a/riscv/mmu.h b/riscv/mmu.h
index f70a969..7d6ea88 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -151,6 +151,25 @@ public:
} \
}
+ void store_float128(reg_t addr, float128_t val)
+ {
+#ifndef RISCV_ENABLE_MISALIGNED
+ if (unlikely(addr & (sizeof(float128_t)-1)))
+ throw trap_store_address_misaligned(addr);
+#endif
+ store_uint64(addr, val.v[0]);
+ store_uint64(addr + 8, val.v[1]);
+ }
+
+ float128_t load_float128(reg_t addr)
+ {
+#ifndef RISCV_ENABLE_MISALIGNED
+ if (unlikely(addr & (sizeof(float128_t)-1)))
+ throw trap_load_address_misaligned(addr);
+#endif
+ return (float128_t){load_uint64(addr), load_uint64(addr + 8)};
+ }
+
// store value to memory at aligned address
store_func(uint8)
store_func(uint16)
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 6804ba7..ae02165 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -61,7 +61,7 @@ void processor_t::parse_isa_string(const char* str)
lowercase += std::tolower(*r);
const char* p = lowercase.c_str();
- const char* all_subsets = "imafdc";
+ const char* all_subsets = "imafdqc";
max_xlen = 64;
isa = reg_t(2) << 62;
@@ -74,7 +74,7 @@ void processor_t::parse_isa_string(const char* str)
p += 2;
if (!*p) {
- p = all_subsets;
+ p = "imafdc";
} else if (*p == 'g') { // treat "G" as "IMAFD"
tmp = std::string("imafd") + (p+1);
p = &tmp[0];
@@ -106,6 +106,12 @@ void processor_t::parse_isa_string(const char* str)
if (supports_extension('D') && !supports_extension('F'))
bad_isa_string(str);
+ if (supports_extension('Q') && !supports_extension('D'))
+ bad_isa_string(str);
+
+ if (supports_extension('Q') && max_xlen < 64)
+ bad_isa_string(str);
+
// advertise support for supervisor and user modes
isa |= 1L << ('s' - 'a');
isa |= 1L << ('u' - 'a');
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 05e316a..f8abb1b 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -138,67 +138,99 @@ riscv_insn_list = \
ebreak \
ecall \
fadd_d \
+ fadd_q \
fadd_s \
fclass_d \
+ fclass_q \
fclass_s \
fcvt_d_l \
fcvt_d_lu \
+ fcvt_d_q \
fcvt_d_s \
fcvt_d_w \
fcvt_d_wu \
fcvt_l_d \
+ fcvt_l_q \
fcvt_l_s \
fcvt_lu_d \
+ fcvt_lu_q \
fcvt_lu_s \
+ fcvt_q_d \
+ fcvt_q_l \
+ fcvt_q_lu \
+ fcvt_q_s \
+ fcvt_q_w \
+ fcvt_q_wu \
fcvt_s_d \
fcvt_s_l \
fcvt_s_lu \
+ fcvt_s_q \
fcvt_s_w \
fcvt_s_wu \
fcvt_w_d \
+ fcvt_w_q \
fcvt_w_s \
fcvt_wu_d \
+ fcvt_wu_q \
fcvt_wu_s \
fdiv_d \
+ fdiv_q \
fdiv_s \
fence \
fence_i \
feq_d \
+ feq_q \
feq_s \
fld \
fle_d \
+ fle_q \
fle_s \
+ flq \
flt_d \
+ flt_q \
flt_s \
flw \
fmadd_d \
+ fmadd_q \
fmadd_s \
fmax_d \
+ fmax_q \
fmax_s \
fmin_d \
+ fmin_q \
fmin_s \
fmsub_d \
+ fmsub_q \
fmsub_s \
fmul_d \
+ fmul_q \
fmul_s \
fmv_d_x \
fmv_w_x \
fmv_x_d \
fmv_x_w \
fnmadd_d \
+ fnmadd_q \
fnmadd_s \
fnmsub_d \
+ fnmsub_q \
fnmsub_s \
fsd \
fsgnj_d \
+ fsgnj_q \
fsgnjn_d \
+ fsgnjn_q \
fsgnjn_s \
fsgnj_s \
fsgnjx_d \
+ fsgnjx_q \
fsgnjx_s \
+ fsq \
fsqrt_d \
+ fsqrt_q \
fsqrt_s \
fsub_d \
+ fsub_q \
fsub_s \
fsw \
jal \