aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2020-06-16 01:51:38 -0700
committerGitHub <noreply@github.com>2020-06-16 01:51:38 -0700
commit3369e92602c090b1a0744145301c5abb5f2ece33 (patch)
tree3e1e80be2dd11485ff5e2f631947e6d3e7c8bec2
parent2495301866ef4c432dab63bc140092994771adde (diff)
parent07bbbb52e9304aef7bedc65d236ccbb81979edcd (diff)
downloadspike-3369e92602c090b1a0744145301c5abb5f2ece33.zip
spike-3369e92602c090b1a0744145301c5abb5f2ece33.tar.gz
spike-3369e92602c090b1a0744145301c5abb5f2ece33.tar.bz2
Merge pull request #489 from chihminchao/extension-zfh
Extension zfh
-rw-r--r--riscv/encoding.h108
-rw-r--r--riscv/insns/fadd_h.h5
-rw-r--r--riscv/insns/fclass_h.h3
-rw-r--r--riscv/insns/fcvt_d_h.h6
-rw-r--r--riscv/insns/fcvt_h_d.h6
-rw-r--r--riscv/insns/fcvt_h_l.h6
-rw-r--r--riscv/insns/fcvt_h_lu.h6
-rw-r--r--riscv/insns/fcvt_h_q.h6
-rw-r--r--riscv/insns/fcvt_h_s.h5
-rw-r--r--riscv/insns/fcvt_h_w.h5
-rw-r--r--riscv/insns/fcvt_h_wu.h5
-rw-r--r--riscv/insns/fcvt_l_h.h6
-rw-r--r--riscv/insns/fcvt_lu_h.h6
-rw-r--r--riscv/insns/fcvt_q_h.h6
-rw-r--r--riscv/insns/fcvt_s_h.h5
-rw-r--r--riscv/insns/fcvt_w_h.h5
-rw-r--r--riscv/insns/fcvt_wu_h.h5
-rw-r--r--riscv/insns/fdiv_h.h5
-rw-r--r--riscv/insns/feq_h.h4
-rw-r--r--riscv/insns/fle_h.h4
-rw-r--r--riscv/insns/flh.h3
-rw-r--r--riscv/insns/flt_h.h4
-rw-r--r--riscv/insns/fmadd_h.h5
-rw-r--r--riscv/insns/fmax_h.h4
-rw-r--r--riscv/insns/fmin_h.h4
-rw-r--r--riscv/insns/fmsub_h.h5
-rw-r--r--riscv/insns/fmul_h.h5
-rw-r--r--riscv/insns/fmv_h_x.h3
-rw-r--r--riscv/insns/fmv_x_h.h3
-rw-r--r--riscv/insns/fnmadd_h.h5
-rw-r--r--riscv/insns/fnmsub_h.h5
-rw-r--r--riscv/insns/fsgnj_h.h3
-rw-r--r--riscv/insns/fsgnjn_h.h3
-rw-r--r--riscv/insns/fsgnjx_h.h3
-rw-r--r--riscv/insns/fsh.h3
-rw-r--r--riscv/insns/fsqrt_h.h5
-rw-r--r--riscv/insns/fsub_h.h5
-rw-r--r--riscv/processor.cc4
-rw-r--r--riscv/riscv.mk.in41
-rw-r--r--spike_main/disasm.cc38
40 files changed, 357 insertions, 1 deletions
diff --git a/riscv/encoding.h b/riscv/encoding.h
index 1f66a67..2471ec1 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -645,6 +645,78 @@
#define MASK_FMV_X_Q 0xfff0707f
#define MATCH_FMV_Q_X 0xf6000053
#define MASK_FMV_Q_X 0xfff0707f
+#define MATCH_FADD_H 0x4000053
+#define MASK_FADD_H 0xfe00007f
+#define MATCH_FSUB_H 0xc000053
+#define MASK_FSUB_H 0xfe00007f
+#define MATCH_FMUL_H 0x14000053
+#define MASK_FMUL_H 0xfe00007f
+#define MATCH_FDIV_H 0x1c000053
+#define MASK_FDIV_H 0xfe00007f
+#define MATCH_FSGNJ_H 0x24000053
+#define MASK_FSGNJ_H 0xfe00707f
+#define MATCH_FSGNJN_H 0x24001053
+#define MASK_FSGNJN_H 0xfe00707f
+#define MATCH_FSGNJX_H 0x24002053
+#define MASK_FSGNJX_H 0xfe00707f
+#define MATCH_FMIN_H 0x2c000053
+#define MASK_FMIN_H 0xfe00707f
+#define MATCH_FMAX_H 0x2c001053
+#define MASK_FMAX_H 0xfe00707f
+#define MATCH_FCVT_H_S 0x44000053
+#define MASK_FCVT_H_S 0xfff0007f
+#define MATCH_FCVT_S_H 0x40200053
+#define MASK_FCVT_S_H 0xfff0007f
+#define MATCH_FSQRT_H 0x5c000053
+#define MASK_FSQRT_H 0xfff0007f
+#define MATCH_FLE_H 0xa4000053
+#define MASK_FLE_H 0xfe00707f
+#define MATCH_FLT_H 0xa4001053
+#define MASK_FLT_H 0xfe00707f
+#define MATCH_FEQ_H 0xa4002053
+#define MASK_FEQ_H 0xfe00707f
+#define MATCH_FCVT_W_H 0xc4000053
+#define MASK_FCVT_W_H 0xfff0007f
+#define MATCH_FCVT_WU_H 0xc4100053
+#define MASK_FCVT_WU_H 0xfff0007f
+#define MATCH_FMV_X_H 0xe4000053
+#define MASK_FMV_X_H 0xfff0707f
+#define MATCH_FCLASS_H 0xe4001053
+#define MASK_FCLASS_H 0xfff0707f
+#define MATCH_FCVT_H_W 0xd4000053
+#define MASK_FCVT_H_W 0xfff0007f
+#define MATCH_FCVT_H_WU 0xd4100053
+#define MASK_FCVT_H_WU 0xfff0007f
+#define MATCH_FMV_H_X 0xf4000053
+#define MASK_FMV_H_X 0xfff0707f
+#define MATCH_FLH 0x1007
+#define MASK_FLH 0x707f
+#define MATCH_FSH 0x1027
+#define MASK_FSH 0x707f
+#define MATCH_FMADD_H 0x4000043
+#define MASK_FMADD_H 0x600007f
+#define MATCH_FMSUB_H 0x4000047
+#define MASK_FMSUB_H 0x600007f
+#define MATCH_FNMSUB_H 0x400004b
+#define MASK_FNMSUB_H 0x600007f
+#define MATCH_FNMADD_H 0x400004f
+#define MASK_FNMADD_H 0x600007f
+#define MATCH_FCVT_H_D 0x44100053
+#define MASK_FCVT_H_D 0xfff0007f
+#define MATCH_FCVT_D_H 0x42200053
+#define MASK_FCVT_D_H 0xfff0007f
+#define MATCH_FCVT_H_Q 0x44300053
+#define MASK_FCVT_H_Q 0xfff0007f
+#define MATCH_FCVT_Q_H 0x46200053
+#define MASK_FCVT_Q_H 0xfff0007f
+#define MATCH_FCVT_L_H 0xc4200053
+#define MASK_FCVT_L_H 0xfff0007f
+#define MATCH_FCVT_LU_H 0xc4300053
+#define MASK_FCVT_LU_H 0xfff0007f
+#define MATCH_FCVT_H_L 0xd4200053
+#define MASK_FCVT_H_L 0xfff0007f
+#define MATCH_FCVT_H_LU 0xd4300053
+#define MASK_FCVT_H_LU 0xfff0007f
#define MATCH_ECALL 0x73
#define MASK_ECALL 0xffffffff
#define MATCH_EBREAK 0x100073
@@ -2158,6 +2230,42 @@ DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q)
DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X)
+DECLARE_INSN(fadd_h, MATCH_FADD_H, MASK_FADD_H)
+DECLARE_INSN(fsub_h, MATCH_FSUB_H, MASK_FSUB_H)
+DECLARE_INSN(fmul_h, MATCH_FMUL_H, MASK_FMUL_H)
+DECLARE_INSN(fdiv_h, MATCH_FDIV_H, MASK_FDIV_H)
+DECLARE_INSN(fsgnj_h, MATCH_FSGNJ_H, MASK_FSGNJ_H)
+DECLARE_INSN(fsgnjn_h, MATCH_FSGNJN_H, MASK_FSGNJN_H)
+DECLARE_INSN(fsgnjx_h, MATCH_FSGNJX_H, MASK_FSGNJX_H)
+DECLARE_INSN(fmin_h, MATCH_FMIN_H, MASK_FMIN_H)
+DECLARE_INSN(fmax_h, MATCH_FMAX_H, MASK_FMAX_H)
+DECLARE_INSN(fcvt_h_s, MATCH_FCVT_H_S, MASK_FCVT_H_S)
+DECLARE_INSN(fcvt_s_h, MATCH_FCVT_S_H, MASK_FCVT_S_H)
+DECLARE_INSN(fsqrt_h, MATCH_FSQRT_H, MASK_FSQRT_H)
+DECLARE_INSN(fle_h, MATCH_FLE_H, MASK_FLE_H)
+DECLARE_INSN(flt_h, MATCH_FLT_H, MASK_FLT_H)
+DECLARE_INSN(feq_h, MATCH_FEQ_H, MASK_FEQ_H)
+DECLARE_INSN(fcvt_w_h, MATCH_FCVT_W_H, MASK_FCVT_W_H)
+DECLARE_INSN(fcvt_wu_h, MATCH_FCVT_WU_H, MASK_FCVT_WU_H)
+DECLARE_INSN(fmv_x_h, MATCH_FMV_X_H, MASK_FMV_X_H)
+DECLARE_INSN(fclass_h, MATCH_FCLASS_H, MASK_FCLASS_H)
+DECLARE_INSN(fcvt_h_w, MATCH_FCVT_H_W, MASK_FCVT_H_W)
+DECLARE_INSN(fcvt_h_wu, MATCH_FCVT_H_WU, MASK_FCVT_H_WU)
+DECLARE_INSN(fmv_h_x, MATCH_FMV_H_X, MASK_FMV_H_X)
+DECLARE_INSN(flh, MATCH_FLH, MASK_FLH)
+DECLARE_INSN(fsh, MATCH_FSH, MASK_FSH)
+DECLARE_INSN(fmadd_h, MATCH_FMADD_H, MASK_FMADD_H)
+DECLARE_INSN(fmsub_h, MATCH_FMSUB_H, MASK_FMSUB_H)
+DECLARE_INSN(fnmsub_h, MATCH_FNMSUB_H, MASK_FNMSUB_H)
+DECLARE_INSN(fnmadd_h, MATCH_FNMADD_H, MASK_FNMADD_H)
+DECLARE_INSN(fcvt_h_d, MATCH_FCVT_H_D, MASK_FCVT_H_D)
+DECLARE_INSN(fcvt_d_h, MATCH_FCVT_D_H, MASK_FCVT_D_H)
+DECLARE_INSN(fcvt_h_q, MATCH_FCVT_H_Q, MASK_FCVT_H_Q)
+DECLARE_INSN(fcvt_q_h, MATCH_FCVT_Q_H, MASK_FCVT_Q_H)
+DECLARE_INSN(fcvt_l_h, MATCH_FCVT_L_H, MASK_FCVT_L_H)
+DECLARE_INSN(fcvt_lu_h, MATCH_FCVT_LU_H, MASK_FCVT_LU_H)
+DECLARE_INSN(fcvt_h_l, MATCH_FCVT_H_L, MASK_FCVT_H_L)
+DECLARE_INSN(fcvt_h_lu, MATCH_FCVT_H_LU, MASK_FCVT_H_LU)
DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
DECLARE_INSN(uret, MATCH_URET, MASK_URET)
diff --git a/riscv/insns/fadd_h.h b/riscv/insns/fadd_h.h
new file mode 100644
index 0000000..2b646ae
--- /dev/null
+++ b/riscv/insns/fadd_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_add(f16(FRS1), f16(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fclass_h.h b/riscv/insns/fclass_h.h
new file mode 100644
index 0000000..066a2d2
--- /dev/null
+++ b/riscv/insns/fclass_h.h
@@ -0,0 +1,3 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_RD(f16_classify(f16(FRS1)));
diff --git a/riscv/insns/fcvt_d_h.h b/riscv/insns/fcvt_d_h.h
new file mode 100644
index 0000000..6906fc0
--- /dev/null
+++ b/riscv/insns/fcvt_d_h.h
@@ -0,0 +1,6 @@
+require_extension(EXT_ZFH);
+require_extension('D');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_to_f64(f16(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_h_d.h b/riscv/insns/fcvt_h_d.h
new file mode 100644
index 0000000..f463dd5
--- /dev/null
+++ b/riscv/insns/fcvt_h_d.h
@@ -0,0 +1,6 @@
+require_extension(EXT_ZFH);
+require_extension('D');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f64_to_f16(f64(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_h_l.h b/riscv/insns/fcvt_h_l.h
new file mode 100644
index 0000000..39178c2
--- /dev/null
+++ b/riscv/insns/fcvt_h_l.h
@@ -0,0 +1,6 @@
+require_extension(EXT_ZFH);
+require_rv64;
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(i64_to_f16(RS1));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_h_lu.h b/riscv/insns/fcvt_h_lu.h
new file mode 100644
index 0000000..a872c48
--- /dev/null
+++ b/riscv/insns/fcvt_h_lu.h
@@ -0,0 +1,6 @@
+require_extension(EXT_ZFH);
+require_rv64;
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(ui64_to_f16(RS1));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_h_q.h b/riscv/insns/fcvt_h_q.h
new file mode 100644
index 0000000..94b0001
--- /dev/null
+++ b/riscv/insns/fcvt_h_q.h
@@ -0,0 +1,6 @@
+require_extension(EXT_ZFH);
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f128_to_f16(f128(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_h_s.h b/riscv/insns/fcvt_h_s.h
new file mode 100644
index 0000000..eb928e9
--- /dev/null
+++ b/riscv/insns/fcvt_h_s.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f32_to_f16(f32(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_h_w.h b/riscv/insns/fcvt_h_w.h
new file mode 100644
index 0000000..c082454
--- /dev/null
+++ b/riscv/insns/fcvt_h_w.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(i32_to_f16((int32_t)RS1));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_h_wu.h b/riscv/insns/fcvt_h_wu.h
new file mode 100644
index 0000000..9f2f5f6
--- /dev/null
+++ b/riscv/insns/fcvt_h_wu.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(ui32_to_f16((uint32_t)RS1));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_l_h.h b/riscv/insns/fcvt_l_h.h
new file mode 100644
index 0000000..5a1fea8
--- /dev/null
+++ b/riscv/insns/fcvt_l_h.h
@@ -0,0 +1,6 @@
+require_extension(EXT_ZFH);
+require_rv64;
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_RD(f16_to_i64(f16(FRS1), RM, true));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_lu_h.h b/riscv/insns/fcvt_lu_h.h
new file mode 100644
index 0000000..f1454c3
--- /dev/null
+++ b/riscv/insns/fcvt_lu_h.h
@@ -0,0 +1,6 @@
+require_extension(EXT_ZFH);
+require_rv64;
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_RD(f16_to_ui64(f16(FRS1), RM, true));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_q_h.h b/riscv/insns/fcvt_q_h.h
new file mode 100644
index 0000000..8a5f680
--- /dev/null
+++ b/riscv/insns/fcvt_q_h.h
@@ -0,0 +1,6 @@
+require_extension(EXT_ZFH);
+require_extension('Q');
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_to_f128(f16(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_s_h.h b/riscv/insns/fcvt_s_h.h
new file mode 100644
index 0000000..bfa2e91
--- /dev/null
+++ b/riscv/insns/fcvt_s_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_to_f32(f16(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_w_h.h b/riscv/insns/fcvt_w_h.h
new file mode 100644
index 0000000..fe8bb48
--- /dev/null
+++ b/riscv/insns/fcvt_w_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_RD(sext32(f16_to_i32(f16(FRS1), RM, true)));
+set_fp_exceptions;
diff --git a/riscv/insns/fcvt_wu_h.h b/riscv/insns/fcvt_wu_h.h
new file mode 100644
index 0000000..bf6648d
--- /dev/null
+++ b/riscv/insns/fcvt_wu_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_RD(sext32(f16_to_ui32(f16(FRS1), RM, true)));
+set_fp_exceptions;
diff --git a/riscv/insns/fdiv_h.h b/riscv/insns/fdiv_h.h
new file mode 100644
index 0000000..a169eae
--- /dev/null
+++ b/riscv/insns/fdiv_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_div(f16(FRS1), f16(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/feq_h.h b/riscv/insns/feq_h.h
new file mode 100644
index 0000000..47e75a5
--- /dev/null
+++ b/riscv/insns/feq_h.h
@@ -0,0 +1,4 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_RD(f16_eq(f16(FRS1), f16(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fle_h.h b/riscv/insns/fle_h.h
new file mode 100644
index 0000000..9fc5968
--- /dev/null
+++ b/riscv/insns/fle_h.h
@@ -0,0 +1,4 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_RD(f16_le(f16(FRS1), f16(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/flh.h b/riscv/insns/flh.h
new file mode 100644
index 0000000..c887999
--- /dev/null
+++ b/riscv/insns/flh.h
@@ -0,0 +1,3 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_FRD(f16(MMU.load_uint16(RS1 + insn.i_imm())));
diff --git a/riscv/insns/flt_h.h b/riscv/insns/flt_h.h
new file mode 100644
index 0000000..f516a38
--- /dev/null
+++ b/riscv/insns/flt_h.h
@@ -0,0 +1,4 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_RD(f16_lt(f16(FRS1), f16(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fmadd_h.h b/riscv/insns/fmadd_h.h
new file mode 100644
index 0000000..6551de5
--- /dev/null
+++ b/riscv/insns/fmadd_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_mulAdd(f16(FRS1), f16(FRS2), f16(FRS3)));
+set_fp_exceptions;
diff --git a/riscv/insns/fmax_h.h b/riscv/insns/fmax_h.h
new file mode 100644
index 0000000..3d4c40e
--- /dev/null
+++ b/riscv/insns/fmax_h.h
@@ -0,0 +1,4 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_FRD(f16_max(f16(FRS1), f16(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fmin_h.h b/riscv/insns/fmin_h.h
new file mode 100644
index 0000000..5fb1404
--- /dev/null
+++ b/riscv/insns/fmin_h.h
@@ -0,0 +1,4 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_FRD(f16_min(f16(FRS1), f16(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fmsub_h.h b/riscv/insns/fmsub_h.h
new file mode 100644
index 0000000..934291f
--- /dev/null
+++ b/riscv/insns/fmsub_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_mulAdd(f16(FRS1), f16(FRS2), f16(f16(FRS3).v ^ F16_SIGN)));
+set_fp_exceptions;
diff --git a/riscv/insns/fmul_h.h b/riscv/insns/fmul_h.h
new file mode 100644
index 0000000..0152df8
--- /dev/null
+++ b/riscv/insns/fmul_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_mul(f16(FRS1), f16(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/insns/fmv_h_x.h b/riscv/insns/fmv_h_x.h
new file mode 100644
index 0000000..c022508
--- /dev/null
+++ b/riscv/insns/fmv_h_x.h
@@ -0,0 +1,3 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_FRD(f16(RS1));
diff --git a/riscv/insns/fmv_x_h.h b/riscv/insns/fmv_x_h.h
new file mode 100644
index 0000000..5e89c4f
--- /dev/null
+++ b/riscv/insns/fmv_x_h.h
@@ -0,0 +1,3 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_RD(sext32((int16_t)(FRS1.v[0])));
diff --git a/riscv/insns/fnmadd_h.h b/riscv/insns/fnmadd_h.h
new file mode 100644
index 0000000..e4c619e
--- /dev/null
+++ b/riscv/insns/fnmadd_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_mulAdd(f16(f16(FRS1).v ^ F16_SIGN), f16(FRS2), f16(f16(FRS3).v ^ F16_SIGN)));
+set_fp_exceptions;
diff --git a/riscv/insns/fnmsub_h.h b/riscv/insns/fnmsub_h.h
new file mode 100644
index 0000000..0410c3b
--- /dev/null
+++ b/riscv/insns/fnmsub_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_mulAdd(f16(f16(FRS1).v ^ F16_SIGN), f16(FRS2), f16(FRS3)));
+set_fp_exceptions;
diff --git a/riscv/insns/fsgnj_h.h b/riscv/insns/fsgnj_h.h
new file mode 100644
index 0000000..79d50f5
--- /dev/null
+++ b/riscv/insns/fsgnj_h.h
@@ -0,0 +1,3 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_FRD(fsgnj16(FRS1, FRS2, false, false));
diff --git a/riscv/insns/fsgnjn_h.h b/riscv/insns/fsgnjn_h.h
new file mode 100644
index 0000000..ebb4ac9
--- /dev/null
+++ b/riscv/insns/fsgnjn_h.h
@@ -0,0 +1,3 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_FRD(fsgnj16(FRS1, FRS2, true, false));
diff --git a/riscv/insns/fsgnjx_h.h b/riscv/insns/fsgnjx_h.h
new file mode 100644
index 0000000..9310269
--- /dev/null
+++ b/riscv/insns/fsgnjx_h.h
@@ -0,0 +1,3 @@
+require_extension(EXT_ZFH);
+require_fp;
+WRITE_FRD(fsgnj16(FRS1, FRS2, false, true));
diff --git a/riscv/insns/fsh.h b/riscv/insns/fsh.h
new file mode 100644
index 0000000..b9fa4e0
--- /dev/null
+++ b/riscv/insns/fsh.h
@@ -0,0 +1,3 @@
+require_extension(EXT_ZFH);
+require_fp;
+MMU.store_uint16(RS1 + insn.s_imm(), FRS2.v[0]);
diff --git a/riscv/insns/fsqrt_h.h b/riscv/insns/fsqrt_h.h
new file mode 100644
index 0000000..138d572
--- /dev/null
+++ b/riscv/insns/fsqrt_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_sqrt(f16(FRS1)));
+set_fp_exceptions;
diff --git a/riscv/insns/fsub_h.h b/riscv/insns/fsub_h.h
new file mode 100644
index 0000000..43b51cc
--- /dev/null
+++ b/riscv/insns/fsub_h.h
@@ -0,0 +1,5 @@
+require_extension(EXT_ZFH);
+require_fp;
+softfloat_roundingMode = RM;
+WRITE_FRD(f16_sub(f16(FRS1), f16(FRS2)));
+set_fp_exceptions;
diff --git a/riscv/processor.cc b/riscv/processor.cc
index deaadae..b779004 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -1213,6 +1213,10 @@ void processor_t::register_extension(extension_t* x)
register_insn(insn);
build_opcode_map();
+ if (disassembler)
+ for (auto disasm_insn : x->get_disasms())
+ disassembler->add_insn(disasm_insn);
+
if (ext != NULL)
throw std::logic_error("only one extension may be registered");
ext = x;
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 175ab68..1aa3352 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -263,6 +263,44 @@ riscv_insn_ext_d = \
fsqrt_d \
fsub_d \
+riscv_insn_ext_zfh = \
+ fadd_h \
+ fclass_h \
+ fcvt_l_h \
+ fcvt_lu_h \
+ fcvt_d_h \
+ fcvt_h_d \
+ fcvt_h_l \
+ fcvt_h_lu \
+ fcvt_h_q \
+ fcvt_h_s \
+ fcvt_h_w \
+ fcvt_h_wu \
+ fcvt_q_h \
+ fcvt_s_h \
+ fcvt_w_h \
+ fcvt_wu_h \
+ fdiv_h \
+ feq_h \
+ fle_h \
+ flh \
+ flt_h \
+ fmadd_h \
+ fmax_h \
+ fmin_h \
+ fmsub_h \
+ fmul_h \
+ fmv_h_x \
+ fmv_x_h \
+ fnmadd_h \
+ fnmsub_h \
+ fsgnj_h \
+ fsgnjn_h \
+ fsgnjx_h \
+ fsh \
+ fsqrt_h \
+ fsub_h \
+
riscv_insn_ext_q = \
fadd_q \
fclass_q \
@@ -697,7 +735,7 @@ riscv_insn_ext_v_ctrl = \
riscv_insn_ext_v = \
$(riscv_insn_ext_v_alu_fp) \
$(riscv_insn_ext_v_alu_int) \
- $(riscv_insn_ext_v_amo) \
+ $(riscv_insn_ext_v_amo) \
$(riscv_insn_ext_v_ctrl) \
$(riscv_insn_ext_v_ldst) \
@@ -724,6 +762,7 @@ riscv_insn_list = \
$(riscv_insn_ext_m) \
$(riscv_insn_ext_f) \
$(riscv_insn_ext_d) \
+ $(riscv_insn_ext_zfh) \
$(riscv_insn_ext_q) \
$(if $(HAVE_INT128),$(riscv_insn_ext_v),) \
$(riscv_insn_priv) \
diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc
index d2947ee..e163130 100644
--- a/spike_main/disasm.cc
+++ b/spike_main/disasm.cc
@@ -457,10 +457,12 @@ disassembler_t::disassembler_t(int xlen)
DEFINE_FLOAD(flw)
DEFINE_FLOAD(fld)
+ DEFINE_FLOAD(flh)
DEFINE_FLOAD(flq)
DEFINE_FSTORE(fsw)
DEFINE_FSTORE(fsd)
+ DEFINE_FSTORE(fsh)
DEFINE_FSTORE(fsq)
add_insn(new disasm_insn_t("j", match_jal, mask_jal | mask_rd, {&jump_target}));
@@ -629,6 +631,42 @@ disassembler_t::disassembler_t(int xlen)
DEFINE_FX2TYPE(flt_d);
DEFINE_FX2TYPE(fle_d);
+ DEFINE_FRTYPE(fadd_h);
+ DEFINE_FRTYPE(fsub_h);
+ DEFINE_FRTYPE(fmul_h);
+ DEFINE_FRTYPE(fdiv_h);
+ DEFINE_FR1TYPE(fsqrt_h);
+ DEFINE_FRTYPE(fmin_h);
+ DEFINE_FRTYPE(fmax_h);
+ DEFINE_FR3TYPE(fmadd_h);
+ DEFINE_FR3TYPE(fmsub_h);
+ DEFINE_FR3TYPE(fnmadd_h);
+ DEFINE_FR3TYPE(fnmsub_h);
+ DEFINE_FRTYPE(fsgnj_h);
+ DEFINE_FRTYPE(fsgnjn_h);
+ DEFINE_FRTYPE(fsgnjx_h);
+ DEFINE_FR1TYPE(fcvt_h_s);
+ DEFINE_FR1TYPE(fcvt_h_d);
+ DEFINE_FR1TYPE(fcvt_h_q);
+ DEFINE_FR1TYPE(fcvt_s_h);
+ DEFINE_FR1TYPE(fcvt_d_h);
+ DEFINE_FR1TYPE(fcvt_q_h);
+ DEFINE_XFTYPE(fcvt_h_l);
+ DEFINE_XFTYPE(fcvt_h_lu);
+ DEFINE_XFTYPE(fcvt_h_w);
+ DEFINE_XFTYPE(fcvt_h_wu);
+ DEFINE_XFTYPE(fcvt_h_wu);
+ DEFINE_XFTYPE(fmv_h_x);
+ DEFINE_FXTYPE(fcvt_l_h);
+ DEFINE_FXTYPE(fcvt_lu_h);
+ DEFINE_FXTYPE(fcvt_w_h);
+ DEFINE_FXTYPE(fcvt_wu_h);
+ DEFINE_FXTYPE(fclass_h);
+ DEFINE_FXTYPE(fmv_x_h);
+ DEFINE_FX2TYPE(feq_h);
+ DEFINE_FX2TYPE(flt_h);
+ DEFINE_FX2TYPE(fle_h);
+
DEFINE_FRTYPE(fadd_q);
DEFINE_FRTYPE(fsub_q);
DEFINE_FRTYPE(fmul_q);