Implement Q extension
authorAndrew Waterman <andrew@sifive.com>
Mon, 25 Sep 2017 03:34:04 +0000 (20:34 -0700)
committerAndrew Waterman <andrew@sifive.com>
Thu, 28 Sep 2017 22:56:47 +0000 (15:56 -0700)
45 files changed:
riscv/decode.h
riscv/insns/c_fsd.h
riscv/insns/c_fsdsp.h
riscv/insns/c_fsw.h
riscv/insns/c_fswsp.h
riscv/insns/fadd_q.h [new file with mode: 0644]
riscv/insns/fclass_q.h [new file with mode: 0644]
riscv/insns/fcvt_d_q.h [new file with mode: 0644]
riscv/insns/fcvt_l_q.h [new file with mode: 0644]
riscv/insns/fcvt_lu_q.h [new file with mode: 0644]
riscv/insns/fcvt_q_d.h [new file with mode: 0644]
riscv/insns/fcvt_q_l.h [new file with mode: 0644]
riscv/insns/fcvt_q_lu.h [new file with mode: 0644]
riscv/insns/fcvt_q_s.h [new file with mode: 0644]
riscv/insns/fcvt_q_w.h [new file with mode: 0644]
riscv/insns/fcvt_q_wu.h [new file with mode: 0644]
riscv/insns/fcvt_s_q.h [new file with mode: 0644]
riscv/insns/fcvt_w_q.h [new file with mode: 0644]
riscv/insns/fcvt_wu_q.h [new file with mode: 0644]
riscv/insns/fdiv_q.h [new file with mode: 0644]
riscv/insns/feq_q.h [new file with mode: 0644]
riscv/insns/fle_q.h [new file with mode: 0644]
riscv/insns/flq.h [new file with mode: 0644]
riscv/insns/flt_q.h [new file with mode: 0644]
riscv/insns/fmadd_q.h [new file with mode: 0644]
riscv/insns/fmax_q.h [new file with mode: 0644]
riscv/insns/fmin_q.h [new file with mode: 0644]
riscv/insns/fmsub_q.h [new file with mode: 0644]
riscv/insns/fmul_q.h [new file with mode: 0644]
riscv/insns/fmv_x_d.h
riscv/insns/fmv_x_w.h
riscv/insns/fnmadd_q.h [new file with mode: 0644]
riscv/insns/fnmsub_q.h [new file with mode: 0644]
riscv/insns/fsd.h
riscv/insns/fsgnj_q.h [new file with mode: 0644]
riscv/insns/fsgnjn_q.h [new file with mode: 0644]
riscv/insns/fsgnjx_q.h [new file with mode: 0644]
riscv/insns/fsq.h [new file with mode: 0644]
riscv/insns/fsqrt_q.h [new file with mode: 0644]
riscv/insns/fsub_q.h [new file with mode: 0644]
riscv/insns/fsw.h
riscv/interactive.cc
riscv/mmu.h
riscv/processor.cc
riscv/riscv.mk.in

index 9dcd809eb70261e448f0deac980f1f74472b81c6..45dd3c43a83b7bd80c72604e69de5d35ccce614f 100644 (file)
@@ -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; \
index 874326683a670e59dbfb665a0eb37a057c073d02..6f2c8f4c3ac1743a40d94598eb1a8b49f969893e 100644 (file)
@@ -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]);
index f62f8ff24c55c26d7432647267e3d3d2b7897a84..27b933191930f3fc8413cfb0668139de7e946b7b 100644 (file)
@@ -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]);
index b924a4689dc58dc4b0e7352c135d5eecefbac6d2..70858229652189553e792b82a5a2178570107145 100644 (file)
@@ -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);
 }
index 011de555f3de08cb426f41e01b8c65931b2eca44..c5a003fcd1f057df93f407747173772f3ab7a4df 100644 (file)
@@ -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 (file)
index 0000000..1139a74
--- /dev/null
@@ -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 (file)
index 0000000..5330758
--- /dev/null
@@ -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 (file)
index 0000000..b50a43d
--- /dev/null
@@ -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 (file)
index 0000000..b28bca2
--- /dev/null
@@ -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 (file)
index 0000000..8c5be7c
--- /dev/null
@@ -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 (file)
index 0000000..c2437b1
--- /dev/null
@@ -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 (file)
index 0000000..f1f45ca
--- /dev/null
@@ -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 (file)
index 0000000..850212e
--- /dev/null
@@ -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 (file)
index 0000000..79e6bb6
--- /dev/null
@@ -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 (file)
index 0000000..fb83f15
--- /dev/null
@@ -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 (file)
index 0000000..7c2ae97
--- /dev/null
@@ -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 (file)
index 0000000..b0f118e
--- /dev/null
@@ -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 (file)
index 0000000..e10bafc
--- /dev/null
@@ -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 (file)
index 0000000..c391dc8
--- /dev/null
@@ -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 (file)
index 0000000..2204831
--- /dev/null
@@ -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 (file)
index 0000000..cee2da9
--- /dev/null
@@ -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 (file)
index 0000000..8368af9
--- /dev/null
@@ -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 (file)
index 0000000..81d225c
--- /dev/null
@@ -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 (file)
index 0000000..c452141
--- /dev/null
@@ -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 (file)
index 0000000..882dfc1
--- /dev/null
@@ -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 (file)
index 0000000..719e6d0
--- /dev/null
@@ -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 (file)
index 0000000..675c7fd
--- /dev/null
@@ -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 (file)
index 0000000..1bb96c2
--- /dev/null
@@ -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 (file)
index 0000000..66f5a05
--- /dev/null
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_mul(f128(FRS1), f128(FRS2)));
+set_fp_exceptions;
index da8e72a82ecd0d04eac3e9ab40e9860dcff23872..e1a23f482735b1dd97221b0f69eeaa2bcc98e39a 100644 (file)
@@ -1,4 +1,4 @@
 require_extension('D');
 require_rv64;
 require_fp;
-WRITE_RD(FRS1.v);
+WRITE_RD(FRS1.v[0]);
index b72247958c762237a2316ab7ed7f4a9d29eaf1fd..6754f8693f329bc16faed03f54c4481dbb305a56 100644 (file)
@@ -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 (file)
index 0000000..a36ce18
--- /dev/null
@@ -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 (file)
index 0000000..130b4ce
--- /dev/null
@@ -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;
index 679cc95fb7c5fd1f28c65dcb16b18ffc25f07940..38c702b7a01bccb72eeb623ee5a84f68f61db615 100644 (file)
@@ -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 (file)
index 0000000..0b9a270
--- /dev/null
@@ -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 (file)
index 0000000..38c7bbf
--- /dev/null
@@ -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 (file)
index 0000000..fc86d26
--- /dev/null
@@ -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 (file)
index 0000000..610960e
--- /dev/null
@@ -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 (file)
index 0000000..6cb6ba3
--- /dev/null
@@ -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 (file)
index 0000000..e050e3a
--- /dev/null
@@ -0,0 +1,5 @@
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_sub(f128(FRS1), f128(FRS2)));
+set_fp_exceptions;
index 42fc68373f5370635a58327a27980c9f5bfda620..8af51845f4a5306ef12cf2a703b16f15b6a0ce67 100644 (file)
@@ -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]);
index 31b91622720f5f7e2efcc5fe00a41e523e5a7a00..e6e86169e4ff90fe4b0119438fa223cf7d65a484 100644 (file)
@@ -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)
index f70a969be48eba4a148d25c8b9684d789bbb2cb3..7d6ea88be5cfbc4ac766ffadd25b621c10e4b6c9 100644 (file)
@@ -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)
index 6804ba7b06be721cf1cf1c09ced173b78bb0e37a..ae021657b680819b89b766eca566582731ebf29d 100644 (file)
@@ -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');
index 05e316a438ad4dd68e1e9f2646328afc1d5c1758..f8abb1b592e1052662a29c6f4384a8f2beb9cd1c 100644 (file)
@@ -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 \