Skip to content

Instantly share code, notes, and snippets.

@jrtc27
Created November 22, 2021 00:36
Show Gist options
  • Save jrtc27/c26d373d866a6fac78ec69bc43f6c31f to your computer and use it in GitHub Desktop.
Save jrtc27/c26d373d866a6fac78ec69bc43f6c31f to your computer and use it in GitHub Desktop.
Zfinx interdiff
diff --git a/c_emulator/riscv_sim.c b/c_emulator/riscv_sim.c
index c4a13f4..a2d1bce 100644
--- a/c_emulator/riscv_sim.c
+++ b/c_emulator/riscv_sim.c
@@ -330,6 +330,7 @@ char *process_args(int argc, char **argv)
case 'x':
fprintf(stderr, "enabling Zfinx support.\n");
rv_enable_zfinx = true;
+ rv_enable_fdext = false;
break;
#ifdef SAILCOV
case 'c':
diff --git a/model/riscv_csr_map.sail b/model/riscv_csr_map.sail
index 87211ea..31872d3 100644
--- a/model/riscv_csr_map.sail
+++ b/model/riscv_csr_map.sail
@@ -186,5 +186,5 @@ val ext_read_CSR : csreg -> option(xlenbits) effect {rreg}
scattered function ext_read_CSR
/* returns new value (after legalisation) if the CSR is defined */
-val ext_write_CSR : (csreg, xlenbits) -> option(xlenbits) effect {rreg, wreg}
+val ext_write_CSR : (csreg, xlenbits) -> option(xlenbits) effect {rreg, wreg, escape}
scattered function ext_write_CSR
diff --git a/model/riscv_fdext_regs.sail b/model/riscv_fdext_regs.sail
index 4180a72..4f48b3e 100644
--- a/model/riscv_fdext_regs.sail
+++ b/model/riscv_fdext_regs.sail
@@ -83,30 +83,23 @@
function canonical_NaN_S() -> bits(32) = 0x_7fc0_0000
function canonical_NaN_D() -> bits(64) = 0x_7ff8_0000_0000_0000
-val nan_unbox_do : (bool, bits(64)) -> bits(32)
-function nan_unbox_do (zfinx_en, regval) =
- if zfinx_en
- then regval [31..0]
- else if regval [63..32] == 0x_FFFF_FFFF
- then regval [31..0]
- else canonical_NaN_S()
-
-val nan_unbox_pass : (bool, bits(32)) -> bits(32)
-function nan_unbox_pass (zfinx_en, regval) =
- regval
-
-val nan_box_do : (bool, bits(32)) -> bits(64)
-function nan_box_do (zfinx_en, regval) =
- 0x_FFFF_FFFF @ regval
-
-
-val nan_box_pass : (bool, bits(32)) -> bits(32)
-function nan_box_pass (zfinx_en, regval) =
- regval
-
-overload nan_unbox = { nan_unbox_do, nan_unbox_pass }
-overload nan_box = { nan_box_do, nan_box_pass }
+val nan_box : bits(32) -> flenbits effect {escape}
+function nan_box val_32b = {
+ assert(sys_enable_fdext());
+ if (sizeof(flen) == 32)
+ then val_32b
+ else 0x_FFFF_FFFF @ val_32b
+}
+val nan_unbox : flenbits -> bits(32) effect {escape}
+function nan_unbox regval = {
+ assert(sys_enable_fdext());
+ if (sizeof(flen) == 32)
+ then regval
+ else if regval [63..32] == 0x_FFFF_FFFF
+ then regval [31..0]
+ else canonical_NaN_S()
+}
/* **************************************************************** */
/* Floating point register file */
@@ -145,12 +138,19 @@ register f30 : fregtype
register f31 : fregtype
function dirty_fd_context() -> unit = {
+ assert(sys_enable_fdext());
mstatus->FS() = extStatus_to_bits(Dirty);
mstatus->SD() = 0b1
}
+function dirty_fd_context_if_present() -> unit = {
+ assert(sys_enable_fdext() != sys_enable_zfinx());
+ if sys_enable_fdext() then dirty_fd_context()
+}
+
val rF : forall 'n, 0 <= 'n < 32. regno('n) -> flenbits effect {rreg, escape}
function rF r = {
+ assert(sys_enable_fdext());
let v : fregtype =
match r {
0 => f0,
@@ -192,6 +192,7 @@ function rF r = {
val wF : forall 'n, 0 <= 'n < 32. (regno('n), flenbits) -> unit effect {wreg, escape}
function wF (r, in_v) = {
+ assert(sys_enable_fdext());
let v = fregval_into_freg(in_v);
match r {
0 => f0 = v,
@@ -245,57 +246,57 @@ function wF_bits(i: bits(5), data: flenbits) -> unit = {
overload F = {rF_bits, wF_bits, rF, wF}
-/* ---- Register Read/ Writes */
-
-val rX_or_F_32 : (bool, bits(5)) -> bits(32) effect {escape, rreg}
-function rX_or_F_32(zfinx_en, i) = {
- if zfinx_en then
- nan_unbox(zfinx_en, rX(unsigned(i)))
- else
- nan_unbox(zfinx_en, rF(unsigned(i)))
+val rF_or_X_S : bits(5) -> bits(32) effect {escape, rreg}
+function rF_or_X_S(i) = {
+ assert(sizeof(flen) >= 32);
+ assert(sys_enable_fdext() != sys_enable_zfinx());
+ if sys_enable_fdext()
+ then nan_unbox(F(i))
+ else X(i)[31..0]
}
-val rX_or_F_64 : (bool, bits(5)) -> bits(64) effect {escape, rreg}
-function rX_or_F_64(zfinx_en, i) = {
- assert (zfinx_en | sizeof(flen) == 64);
- if zfinx_en & sizeof (xlen) == 32 then {
- assert (i[0] == bitzero);
- if i == 0b00000 then
- sail_zeros(64)
- else rX(unsigned(i+1)) @ rX(unsigned(i))
+val rF_or_X_D : bits(5) -> bits(64) effect {escape, rreg}
+function rF_or_X_D(i) = {
+ assert(sizeof(flen) >= 64);
+ assert(sys_enable_fdext() != sys_enable_zfinx());
+ if sys_enable_fdext()
+ then F(unsigned(i))
+ else if sizeof(xlen) >= 64
+ then X(i)[63..0]
+ else {
+ assert(i[0] == bitzero);
+ if i == zeros() then zeros() else X(i + 1) @ X(i)
}
- else if zfinx_en & sizeof(xlen) == 64 then
- rX(unsigned(i))
- else
- rF(unsigned(i))
}
-val wX_or_F_64 : (bool, bits(5), bits(64)) -> unit effect {escape, wreg}
-function wX_or_F_64(zfinx_en: bool, i: bits(5), data: bits(64)) = {
- assert (zfinx_en | sizeof(flen) == 64);
- if zfinx_en & sizeof(xlen) == 32 then {
+val wF_or_X_S : (bits(5), bits(32)) -> unit effect {escape, wreg}
+function wF_or_X_S(i, data) = {
+ assert(sizeof(flen) >= 32);
+ assert(sys_enable_fdext() != sys_enable_zfinx());
+ if sys_enable_fdext()
+ then F(i) = nan_box(data)
+ else X(i) = EXTS(data)
+}
+
+val wF_or_X_D : (bits(5), bits(64)) -> unit effect {escape, wreg}
+function wF_or_X_D(i, data) = {
+ assert (sizeof(flen) >= 64);
+ assert(sys_enable_fdext() != sys_enable_zfinx());
+ if sys_enable_fdext()
+ then F(i) = data
+ else if sizeof(xlen) >= 64
+ then X(i) = EXTS(data)
+ else {
assert (i[0] == bitzero);
- if i != 0b00000 then {
- wX(unsigned(i)) = data[31..0];
- wX(unsigned(i+1)) = data[63..32];
+ if i != zeros() then {
+ X(i) = data[31..0];
+ X(i + 1) = data[63..32];
}
}
- else if zfinx_en & sizeof (xlen) == 64 then
- wX(unsigned(i)) = data
- else if ~ (zfinx_en) & sizeof (flen) == 64 then
- wF(unsigned(i)) = data
-}
-
-val wX_or_F_32 : (bool, bits(5), bits(32)) -> unit effect {escape, wreg}
-function wX_or_F_32(zfinx_en: bool, i: bits(5), data : bits(32)) = {
- if zfinx_en then
- wX(unsigned(i)) = nan_box(zfinx_en, data)
- else
- wF(unsigned(i)) = nan_box(zfinx_en, data)
}
-overload X_or_F_S = { rX_or_F_32, wX_or_F_32 }
-overload X_or_F_D = { rX_or_F_64, wX_or_F_64 }
+overload F_or_X_S = { rF_or_X_S, wF_or_X_S }
+overload F_or_X_D = { rF_or_X_D, wF_or_X_D }
/* register names */
@@ -376,10 +377,10 @@ mapping freg_name = {
0b11111 <-> "ft11"
}
-val reg_or_freg_name : bits(5) <-> string
-mapping reg_or_freg_name = {
- reg if sys_enable_zfinx() <-> reg_name(reg) if sys_enable_zfinx(),
- reg if ~ (sys_enable_zfinx()) <-> freg_name(reg) if ~ (sys_enable_zfinx())
+val freg_or_reg_name : bits(5) <-> string
+mapping freg_or_reg_name = {
+ reg if sys_enable_fdext() <-> freg_name(reg) if sys_enable_fdext(),
+ reg if sys_enable_zfinx() <-> reg_name(reg) if sys_enable_zfinx()
}
val init_fdext_regs : unit -> unit effect {wreg}
@@ -432,30 +433,30 @@ bitfield Fcsr : bits(32) = {
register fcsr : Fcsr
-val ext_write_fcsr : (bits(3), bits(5)) -> unit effect {rreg, wreg}
+val ext_write_fcsr : (bits(3), bits(5)) -> unit effect {rreg, wreg, escape}
function ext_write_fcsr (frm, fflags) = {
fcsr->FRM() = frm; /* Note: frm can be an illegal value, 101, 110, 111 */
fcsr->FFLAGS() = fflags;
update_softfloat_fflags(fflags);
- if ~ (sys_enable_zfinx()) then dirty_fd_context();
+ dirty_fd_context_if_present();
}
/* called for softfloat paths (softfloat flags are consistent) */
-val write_fflags : (bits(5)) -> unit effect {rreg, wreg}
+val write_fflags : (bits(5)) -> unit effect {rreg, wreg, escape}
function write_fflags(fflags) = {
- if fcsr.FFLAGS() != fflags & ~ (sys_enable_zfinx())
- then dirty_fd_context();
+ if fcsr.FFLAGS() != fflags
+ then dirty_fd_context_if_present();
fcsr->FFLAGS() = fflags;
}
/* called for non-softfloat paths (softfloat flags need updating) */
-val accrue_fflags : (bits(5)) -> unit effect {rreg, wreg}
+val accrue_fflags : (bits(5)) -> unit effect {rreg, wreg, escape}
function accrue_fflags(flags) = {
let f = fcsr.FFLAGS() | flags;
if fcsr.FFLAGS() != f
then {
fcsr->FFLAGS() = f;
update_softfloat_fflags(f);
- if ~ (sys_enable_zfinx()) then dirty_fd_context();
+ dirty_fd_context_if_present();
}
}
diff --git a/model/riscv_insts_cdext.sail b/model/riscv_insts_cdext.sail
index 0c6bbd1..77a6302 100644
--- a/model/riscv_insts_cdext.sail
+++ b/model/riscv_insts_cdext.sail
@@ -77,9 +77,9 @@
union clause ast = C_FLDSP : (bits(6), regidx)
mapping clause encdec_compressed = C_FLDSP(ui86 @ ui5 @ ui43, rd)
- if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt() & ~ (sys_enable_zfinx())
+ if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt()
<-> 0b001 @ ui5 : bits(1) @ rd : regidx @ ui43 : bits(2) @ ui86 : bits(3) @ 0b10
- if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt() & ~ (sys_enable_zfinx())
+ if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt()
function clause execute (C_FLDSP(uimm, rd)) = {
let imm : bits(12) = EXTZ(uimm @ 0b000);
@@ -95,9 +95,9 @@ mapping clause assembly = C_FLDSP(uimm, rd)
union clause ast = C_FSDSP : (bits(6), regidx)
mapping clause encdec_compressed = C_FSDSP(ui86 @ ui53, rs2)
- if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt() & ~ (sys_enable_zfinx())
+ if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt()
<-> 0b101 @ ui53 : bits(3) @ ui86 : bits(3) @ rs2 : regidx @ 0b10
- if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt() & ~ (sys_enable_zfinx())
+ if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt()
function clause execute (C_FSDSP(uimm, rs2)) = {
let imm : bits(12) = EXTZ(uimm @ 0b000);
@@ -113,9 +113,9 @@ mapping clause assembly = C_FSDSP(uimm, rs2)
union clause ast = C_FLD : (bits(5), cregidx, cregidx)
mapping clause encdec_compressed = C_FLD(ui76 @ ui53, rs1, rd)
- if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt() & ~ (sys_enable_zfinx())
+ if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt()
<-> 0b001 @ ui53 : bits(3) @ rs1 : cregidx @ ui76 : bits(2) @ rd : cregidx @ 0b00
- if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt() & ~ (sys_enable_zfinx())
+ if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt()
function clause execute (C_FLD(uimm, rsc, rdc)) = {
let imm : bits(12) = EXTZ(uimm @ 0b000);
@@ -133,9 +133,9 @@ mapping clause assembly = C_FLD(uimm, rsc, rdc)
union clause ast = C_FSD : (bits(5), cregidx, cregidx)
mapping clause encdec_compressed = C_FSD(ui76 @ ui53, rs1, rs2)
- if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt() & ~ (sys_enable_zfinx())
+ if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt()
<-> 0b101 @ ui53 : bits(3) @ rs1 : bits(3) @ ui76 : bits(2) @ rs2 : bits(3) @ 0b00
- if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt() & ~ (sys_enable_zfinx())
+ if (sizeof(xlen) == 32 | sizeof(xlen) == 64) & haveRVC() & haveDExt()
function clause execute (C_FSD(uimm, rsc1, rsc2)) = {
let imm : bits(12) = EXTZ(uimm @ 0b000);
diff --git a/model/riscv_insts_cfext.sail b/model/riscv_insts_cfext.sail
index 98eea24..9aa94ef 100644
--- a/model/riscv_insts_cfext.sail
+++ b/model/riscv_insts_cfext.sail
@@ -77,9 +77,9 @@
union clause ast = C_FLWSP : (bits(6), regidx)
mapping clause encdec_compressed = C_FLWSP(ui76 @ ui5 @ ui42, rd)
- if sizeof(xlen) == 32 & haveRVC() & haveFExt() & ~ (sys_enable_zfinx())
+ if sizeof(xlen) == 32 & haveRVC() & haveFExt()
<-> 0b011 @ ui5 : bits(1) @ rd : regidx @ ui42 : bits(3) @ ui76 : bits(2) @ 0b10
- if sizeof(xlen) == 32 & haveRVC() & haveFExt() & ~ (sys_enable_zfinx())
+ if sizeof(xlen) == 32 & haveRVC() & haveFExt()
function clause execute (C_FLWSP(imm, rd)) = {
let imm : bits(12) = EXTZ(imm @ 0b00);
@@ -95,9 +95,9 @@ mapping clause assembly = C_FLWSP(imm, rd)
union clause ast = C_FSWSP : (bits(6), regidx)
mapping clause encdec_compressed = C_FSWSP(ui76 @ ui52, rs2)
- if sizeof(xlen) == 32 & haveRVC() & haveFExt() & ~ (sys_enable_zfinx())
+ if sizeof(xlen) == 32 & haveRVC() & haveFExt()
<-> 0b111 @ ui52 : bits(4) @ ui76 : bits(2) @ rs2 : regidx @ 0b10
- if sizeof(xlen) == 32 & haveRVC() & haveFExt() & ~ (sys_enable_zfinx())
+ if sizeof(xlen) == 32 & haveRVC() & haveFExt()
function clause execute (C_FSWSP(uimm, rs2)) = {
let imm : bits(12) = EXTZ(uimm @ 0b00);
@@ -113,9 +113,9 @@ mapping clause assembly = C_FSWSP(uimm, rd)
union clause ast = C_FLW : (bits(5), cregidx, cregidx)
mapping clause encdec_compressed = C_FLW(ui6 @ ui53 @ ui2, rs1, rd)
- if sizeof(xlen) == 32 & haveRVC() & haveFExt() & ~ (sys_enable_zfinx())
+ if sizeof(xlen) == 32 & haveRVC() & haveFExt()
<-> 0b011 @ ui53 : bits(3) @ rs1 : cregidx @ ui2 : bits(1) @ ui6 : bits(1) @ rd : cregidx @ 0b00
- if sizeof(xlen) == 32 & haveRVC() & haveFExt() & ~ (sys_enable_zfinx())
+ if sizeof(xlen) == 32 & haveRVC() & haveFExt()
function clause execute (C_FLW(uimm, rsc, rdc)) = {
let imm : bits(12) = EXTZ(uimm @ 0b00);
@@ -133,9 +133,9 @@ mapping clause assembly = C_FLW(uimm, rsc, rdc)
union clause ast = C_FSW : (bits(5), cregidx, cregidx)
mapping clause encdec_compressed = C_FSW(ui6 @ ui53 @ ui2, rs1, rs2)
- if sizeof(xlen) == 32 & haveRVC() & haveFExt() & ~ (sys_enable_zfinx())
+ if sizeof(xlen) == 32 & haveRVC() & haveFExt()
<-> 0b111 @ ui53 : bits(3) @ rs1 : cregidx @ ui2 : bits(1) @ ui6 : bits(1) @ rs2 : cregidx @ 0b00
- if sizeof(xlen) == 32 & haveRVC() & haveFExt() & ~ (sys_enable_zfinx())
+ if sizeof(xlen) == 32 & haveRVC() & haveFExt()
function clause execute (C_FSW(uimm, rsc1, rsc2)) = {
let imm : bits(12) = EXTZ(uimm @ 0b00);
diff --git a/model/riscv_insts_dext.sail b/model/riscv_insts_dext.sail
index 068bba6..ebd6eae 100644
--- a/model/riscv_insts_dext.sail
+++ b/model/riscv_insts_dext.sail
@@ -280,6 +280,21 @@ function fle_D (v1, v2, is_quiet) = {
(result, fflags)
}
+/* **************************************************************** */
+/* Helper functions for 'encdec()' */
+
+function haveDoubleFPU() -> bool = haveDExt() | haveZdinx()
+
+/* RV32Zdinx requires even register pairs; can be omitted for code */
+/* not used for RV32Zdinx (i.e. RV64-only or D-only). */
+val validDoubleRegs : forall 'n, 'n > 0. (implicit('n), vector('n, dec, regidx)) -> bool
+function validDoubleRegs(n, regs) = {
+ if haveZdinx() & sizeof(xlen) == 32 then
+ foreach (i from 0 to (n - 1))
+ if (regs[i][0] == bitone) then return false;
+ true
+}
+
/* ****************************************************************** */
/* Floating-point loads */
/* These are defined in: riscv_insts_fext.sail */
@@ -298,27 +313,27 @@ union clause ast = F_MADD_TYPE_D : (regidx, regidx, regidx, rounding_mode, regid
/* AST <-> Binary encoding ================================ */
mapping clause encdec =
- F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, FMADD_D) if supports_RV32D_or_RV64D([rs3, rs2, rs1, rd])
-<-> rs3 @ 0b01 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_0011 if supports_RV32D_or_RV64D([rs3, rs2, rs1, rd])
+ F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, FMADD_D) if haveDoubleFPU() & validDoubleRegs([rs3, rs2, rs1, rd])
+<-> rs3 @ 0b01 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_0011 if haveDoubleFPU() & validDoubleRegs([rs3, rs2, rs1, rd])
mapping clause encdec =
- F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, FMSUB_D) if supports_RV32D_or_RV64D([rs3, rs2, rs1, rd])
-<-> rs3 @ 0b01 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_0111 if supports_RV32D_or_RV64D([rs3, rs2, rs1, rd])
+ F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, FMSUB_D) if haveDoubleFPU() & validDoubleRegs([rs3, rs2, rs1, rd])
+<-> rs3 @ 0b01 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_0111 if haveDoubleFPU() & validDoubleRegs([rs3, rs2, rs1, rd])
mapping clause encdec =
- F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, FNMSUB_D) if supports_RV32D_or_RV64D([rs3, rs2, rs1, rd])
-<-> rs3 @ 0b01 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_1011 if supports_RV32D_or_RV64D([rs3, rs2, rs1, rd])
+ F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, FNMSUB_D) if haveDoubleFPU() & validDoubleRegs([rs3, rs2, rs1, rd])
+<-> rs3 @ 0b01 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_1011 if haveDoubleFPU() & validDoubleRegs([rs3, rs2, rs1, rd])
mapping clause encdec =
- F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, FNMADD_D) if supports_RV32D_or_RV64D([rs3, rs2, rs1, rd])
-<-> rs3 @ 0b01 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_1111 if supports_RV32D_or_RV64D([rs3, rs2, rs1, rd])
+ F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, FNMADD_D) if haveDoubleFPU() & validDoubleRegs([rs3, rs2, rs1, rd])
+<-> rs3 @ 0b01 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_1111 if haveDoubleFPU() & validDoubleRegs([rs3, rs2, rs1, rd])
/* Execution semantics ================================ */
function clause execute (F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, op)) = {
- let rs1_val_64b = X_or_F_D(sys_enable_zfinx(), rs1);
- let rs2_val_64b = X_or_F_D(sys_enable_zfinx(), rs2);
- let rs3_val_64b = X_or_F_D(sys_enable_zfinx(), rs3);
+ let rs1_val_64b = F_or_X_D(rs1);
+ let rs2_val_64b = F_or_X_D(rs2);
+ let rs3_val_64b = F_or_X_D(rs3);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
@@ -332,7 +347,7 @@ function clause execute (F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, op)) = {
FNMADD_D => riscv_f64MulAdd (rm_3b, negate_D (rs1_val_64b), rs2_val_64b, negate_D (rs3_val_64b))
};
write_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_64b);
+ F_or_X_D(rd) = rd_val_64b;
RETIRE_SUCCESS
}
}
@@ -349,10 +364,10 @@ mapping f_madd_type_mnemonic_D : f_madd_op_D <-> string = {
mapping clause assembly = F_MADD_TYPE_D(rs3, rs2, rs1, rm, rd, op)
<-> f_madd_type_mnemonic_D(op)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
- ^ sep() ^ reg_or_freg_name(rs3)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
+ ^ sep() ^ freg_or_reg_name(rs3)
^ sep() ^ frm_mnemonic(rm)
/* ****************************************************************** */
@@ -365,26 +380,26 @@ union clause ast = F_BIN_RM_TYPE_D : (regidx, regidx, rounding_mode, regidx, f_b
/* AST <-> Binary encoding ================================ */
mapping clause encdec =
- F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, FADD_D) if supports_RV32D_or_RV64D([rs2, rs1, rd])
-<-> 0b000_0001 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1, rd])
+ F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, FADD_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
+<-> 0b000_0001 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
mapping clause encdec =
- F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, FSUB_D) if supports_RV32D_or_RV64D([rs2, rs1, rd])
-<-> 0b000_0101 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1, rd])
+ F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, FSUB_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
+<-> 0b000_0101 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
mapping clause encdec =
- F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, FMUL_D) if supports_RV32D_or_RV64D([rs2, rs1, rd])
-<-> 0b000_1001 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1, rd])
+ F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, FMUL_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
+<-> 0b000_1001 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
mapping clause encdec =
- F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, FDIV_D) if supports_RV32D_or_RV64D([rs2, rs1, rd])
-<-> 0b000_1101 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1, rd])
+ F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, FDIV_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
+<-> 0b000_1101 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
/* Execution semantics ================================ */
function clause execute (F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, op)) = {
- rs1_val_64b = X_or_F_D(sys_enable_zfinx(), rs1);
- rs2_val_64b = X_or_F_D(sys_enable_zfinx(), rs2);
+ let rs1_val_64b = F_or_X_D(rs1);
+ let rs2_val_64b = F_or_X_D(rs2);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -396,7 +411,7 @@ function clause execute (F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, op)) = {
FDIV_D => riscv_f64Div (rm_3b, rs1_val_64b, rs2_val_64b)
};
write_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_64b);
+ F_or_X_D(rd) = rd_val_64b;
RETIRE_SUCCESS
}
}
@@ -413,9 +428,9 @@ mapping f_bin_rm_type_mnemonic_D : f_bin_rm_op_D <-> string = {
mapping clause assembly = F_BIN_RM_TYPE_D(rs2, rs1, rm, rd, op)
<-> f_bin_rm_type_mnemonic_D(op)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
^ sep() ^ frm_mnemonic(rm)
/* ****************************************************************** */
@@ -428,55 +443,55 @@ union clause ast = F_UN_RM_TYPE_D : (regidx, rounding_mode, regidx, f_un_rm_op_D
/* AST <-> Binary encoding ================================ */
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FSQRT_D) if supports_RV32D_or_RV64D([rs1, rd])
-<-> 0b010_1101 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs1, rd])
+ F_UN_RM_TYPE_D(rs1, rm, rd, FSQRT_D) if haveDoubleFPU() & validDoubleRegs([rs1, rd])
+<-> 0b010_1101 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs1, rd])
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_W_D) if supports_RV32D_or_RV64D([rs1])
-<-> 0b110_0001 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs1])
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_W_D) if haveDoubleFPU() & validDoubleRegs([rs1])
+<-> 0b110_0001 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs1])
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_WU_D) if supports_RV32D_or_RV64D([rs1])
-<-> 0b110_0001 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs1])
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_WU_D) if haveDoubleFPU() & validDoubleRegs([rs1])
+<-> 0b110_0001 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs1])
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_W) if supports_RV32D_or_RV64D([rd])
-<-> 0b110_1001 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rd])
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_W) if haveDoubleFPU() & validDoubleRegs([rd])
+<-> 0b110_1001 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rd])
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_WU) if supports_RV32D_or_RV64D([rd])
-<-> 0b110_1001 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rd])
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_WU) if haveDoubleFPU() & validDoubleRegs([rd])
+<-> 0b110_1001 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rd])
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_S_D) if supports_RV32D_or_RV64D([rs1])
-<-> 0b010_0000 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs1])
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_S_D) if haveDoubleFPU() & validDoubleRegs([rs1])
+<-> 0b010_0000 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs1])
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_S) if supports_RV32D_or_RV64D([rd])
-<-> 0b010_0001 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rd])
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_S) if haveDoubleFPU() & validDoubleRegs([rd])
+<-> 0b010_0001 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rd])
/* D instructions, RV64 only */
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_L_D) if is_RV64D()
-<-> 0b110_0001 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV64D()
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_L_D) if haveDoubleFPU() & sizeof(xlen) >= 64
+<-> 0b110_0001 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & sizeof(xlen) >= 64
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_LU_D) if is_RV64D()
-<-> 0b110_0001 @ 0b00011 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV64D()
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_LU_D) if haveDoubleFPU() & sizeof(xlen) >= 64
+<-> 0b110_0001 @ 0b00011 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & sizeof(xlen) >= 64
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_L) if is_RV64D()
-<-> 0b110_1001 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV64D()
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_L) if haveDoubleFPU() & sizeof(xlen) >= 64
+<-> 0b110_1001 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & sizeof(xlen) >= 64
mapping clause encdec =
- F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_LU) if is_RV64D()
-<-> 0b110_1001 @ 0b00011 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV64D()
+ F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_LU) if haveDoubleFPU() & sizeof(xlen) >= 64
+<-> 0b110_1001 @ 0b00011 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveDoubleFPU() & sizeof(xlen) >= 64
/* Execution semantics ================================ */
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FSQRT_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
+ let rs1_val_D = F_or_X_D(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -484,14 +499,14 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FSQRT_D)) = {
let (fflags, rd_val_D) = riscv_f64Sqrt (rm_3b, rs1_val_D);
write_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
}
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_W_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
+ let rs1_val_D = F_or_X_D(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -506,7 +521,7 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_W_D)) = {
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_WU_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
+ let rs1_val_D = F_or_X_D(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -529,7 +544,7 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_W)) = {
let (fflags, rd_val_D) = riscv_i32ToF64 (rm_3b, rs1_val_W);
write_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
}
@@ -544,14 +559,14 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_WU)) = {
let (fflags, rd_val_D) = riscv_ui32ToF64 (rm_3b, rs1_val_WU);
write_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
}
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_S_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
+ let rs1_val_D = F_or_X_D(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -559,14 +574,14 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_S_D)) = {
let (fflags, rd_val_S) = riscv_f64ToF32 (rm_3b, rs1_val_D);
write_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
}
}
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_S)) = {
- rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
+ let rs1_val_S = F_or_X_S(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -574,7 +589,7 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_S)) = {
let (fflags, rd_val_D) = riscv_f32ToF64 (rm_3b, rs1_val_S);
write_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
}
@@ -582,7 +597,7 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_S)) = {
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_L_D)) = {
assert(sizeof(xlen) >= 64);
- rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
+ let rs1_val_D = F_or_X_D(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -598,7 +613,7 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_L_D)) = {
function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_LU_D)) = {
assert(sizeof(xlen) >= 64);
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
+ let rs1_val_D = F_or_X_D(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -606,7 +621,7 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_LU_D)) = {
let (fflags, rd_val_LU) = riscv_f64ToUi64 (rm_3b, rs1_val_D);
write_fflags(fflags);
- X(rd) = rd_val_LU;
+ X(rd) = EXTS(rd_val_LU);
RETIRE_SUCCESS
}
}
@@ -622,7 +637,7 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_L)) = {
let (fflags, rd_val_D) = riscv_i64ToF64 (rm_3b, rs1_val_L);
write_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
}
@@ -638,7 +653,7 @@ function clause execute (F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_LU)) = {
let (fflags, rd_val_D) = riscv_ui64ToF64 (rm_3b, rs1_val_LU);
write_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
}
@@ -664,68 +679,68 @@ mapping f_un_rm_type_mnemonic_D : f_un_rm_op_D <-> string = {
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FSQRT_D)
<-> f_un_rm_type_mnemonic_D(FSQRT_D)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_W_D)
<-> f_un_rm_type_mnemonic_D(FCVT_W_D)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_WU_D)
<-> f_un_rm_type_mnemonic_D(FCVT_WU_D)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_W)
<-> f_un_rm_type_mnemonic_D(FCVT_D_W)
- ^ spc() ^ reg_or_freg_name(rd)
+ ^ spc() ^ freg_or_reg_name(rd)
^ sep() ^ reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_WU)
<-> f_un_rm_type_mnemonic_D(FCVT_D_WU)
- ^ spc() ^ reg_or_freg_name(rd)
+ ^ spc() ^ freg_or_reg_name(rd)
^ sep() ^ reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_L_D)
<-> f_un_rm_type_mnemonic_D(FCVT_L_D)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_LU_D)
<-> f_un_rm_type_mnemonic_D(FCVT_LU_D)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_L)
<-> f_un_rm_type_mnemonic_D(FCVT_D_L)
- ^ spc() ^ reg_or_freg_name(rd)
+ ^ spc() ^ freg_or_reg_name(rd)
^ sep() ^ reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_LU)
<-> f_un_rm_type_mnemonic_D(FCVT_D_LU)
- ^ spc() ^ reg_or_freg_name(rd)
+ ^ spc() ^ freg_or_reg_name(rd)
^ sep() ^ reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_S_D)
<-> f_un_rm_type_mnemonic_D(FCVT_S_D)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_D(rs1, rm, rd, FCVT_D_S)
<-> f_un_rm_type_mnemonic_D(FCVT_D_S)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
/* ****************************************************************** */
@@ -737,69 +752,69 @@ union clause ast = F_BIN_TYPE_D : (regidx, regidx, regidx, f_bin_op_D)
/* AST <-> Binary encoding ================================ */
-mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FSGNJ_D) if supports_RV32D_or_RV64D([rs2, rs1, rd])
- <-> 0b001_0001 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1, rd])
+mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FSGNJ_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
+ <-> 0b001_0001 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
-mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FSGNJN_D) if supports_RV32D_or_RV64D([rs2, rs1, rd])
- <-> 0b001_0001 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1, rd])
+mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FSGNJN_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
+ <-> 0b001_0001 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
-mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FSGNJX_D) if supports_RV32D_or_RV64D([rs2, rs1, rd])
- <-> 0b001_0001 @ rs2 @ rs1 @ 0b010 @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1, rd])
+mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FSGNJX_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
+ <-> 0b001_0001 @ rs2 @ rs1 @ 0b010 @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
-mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FMIN_D) if supports_RV32D_or_RV64D([rs2, rs1, rd])
- <-> 0b001_0101 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1, rd])
+mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FMIN_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
+ <-> 0b001_0101 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
-mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FMAX_D) if supports_RV32D_or_RV64D([rs2, rs1, rd])
- <-> 0b001_0101 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1, rd])
+mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FMAX_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
+ <-> 0b001_0101 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1, rd])
-mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FEQ_D) if supports_RV32D_or_RV64D([rs2, rs1])
- <-> 0b101_0001 @ rs2 @ rs1 @ 0b010 @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1])
+mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FEQ_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1])
+ <-> 0b101_0001 @ rs2 @ rs1 @ 0b010 @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1])
-mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FLT_D) if supports_RV32D_or_RV64D([rs2, rs1])
- <-> 0b101_0001 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1])
+mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FLT_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1])
+ <-> 0b101_0001 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1])
-mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FLE_D) if supports_RV32D_or_RV64D([rs2, rs1])
- <-> 0b101_0001 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs2, rs1])
+mapping clause encdec = F_BIN_TYPE_D(rs2, rs1, rd, FLE_D) if haveDoubleFPU() & validDoubleRegs([rs2, rs1])
+ <-> 0b101_0001 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs2, rs1])
/* Execution semantics ================================ */
function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FSGNJ_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
- let rs2_val_D = X_or_F_D(sys_enable_zfinx(), rs2);
+ let rs1_val_D = F_or_X_D(rs1);
+ let rs2_val_D = F_or_X_D(rs2);
let (s1, e1, m1) = fsplit_D (rs1_val_D);
let (s2, e2, m2) = fsplit_D (rs2_val_D);
let rd_val_D = fmake_D (s2, e1, m1);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FSGNJN_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
- let rs2_val_D = X_or_F_D(sys_enable_zfinx(), rs2);
+ let rs1_val_D = F_or_X_D(rs1);
+ let rs2_val_D = F_or_X_D(rs2);
let (s1, e1, m1) = fsplit_D (rs1_val_D);
let (s2, e2, m2) = fsplit_D (rs2_val_D);
let rd_val_D = fmake_D (0b1 ^ s2, e1, m1);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FSGNJX_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
- let rs2_val_D = X_or_F_D(sys_enable_zfinx(), rs2);
+ let rs1_val_D = F_or_X_D(rs1);
+ let rs2_val_D = F_or_X_D(rs2);
let (s1, e1, m1) = fsplit_D (rs1_val_D);
let (s2, e2, m2) = fsplit_D (rs2_val_D);
let rd_val_D = fmake_D (s1 ^ s2, e1, m1);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FMIN_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
- let rs2_val_D = X_or_F_D(sys_enable_zfinx(), rs2);
+ let rs1_val_D = F_or_X_D(rs1);
+ let rs2_val_D = F_or_X_D(rs2);
let is_quiet = true;
let (rs1_lt_rs2, fflags) = fle_D (rs1_val_D, rs2_val_D, is_quiet);
@@ -813,13 +828,13 @@ function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FMIN_D)) = {
else /* (not rs1_lt_rs2) */ rs2_val_D;
accrue_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FMAX_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
- let rs2_val_D = X_or_F_D(sys_enable_zfinx(), rs2);
+ let rs1_val_D = F_or_X_D(rs1);
+ let rs2_val_D = F_or_X_D(rs2);
let is_quiet = true;
let (rs2_lt_rs1, fflags) = fle_D (rs2_val_D, rs1_val_D, is_quiet);
@@ -833,13 +848,13 @@ function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FMAX_D)) = {
else /* (not rs2_lt_rs1) */ rs2_val_D;
accrue_fflags(fflags);
- X_or_F_D(sys_enable_zfinx(), rd, rd_val_D);
+ F_or_X_D(rd) = rd_val_D;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FEQ_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
- let rs2_val_D = X_or_F_D(sys_enable_zfinx(), rs2);
+ let rs1_val_D = F_or_X_D(rs1);
+ let rs2_val_D = F_or_X_D(rs2);
let (fflags, rd_val) : (bits_fflags, bool) =
riscv_f64Eq (rs1_val_D, rs2_val_D);
@@ -850,11 +865,11 @@ function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FEQ_D)) = {
}
function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FLT_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
- let rs2_val_D = X_or_F_D(sys_enable_zfinx(), rs2);
+ let rs1_val_D = F_or_X_D(rs1);
+ let rs2_val_D = F_or_X_D(rs2);
let (fflags, rd_val) : (bits_fflags, bool) =
- riscv_f64Lt (rs1_val_D, rs2_val_D);
+ riscv_f64Lt (rs1_val_D, rs2_val_D);
write_fflags(fflags);
X(rd) = EXTZ(bool_to_bits(rd_val));
@@ -862,8 +877,8 @@ function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FLT_D)) = {
}
function clause execute (F_BIN_TYPE_D(rs2, rs1, rd, FLE_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
- let rs2_val_D = X_or_F_D(sys_enable_zfinx(), rs2);
+ let rs1_val_D = F_or_X_D(rs1);
+ let rs2_val_D = F_or_X_D(rs2);
let (fflags, rd_val) : (bits_fflags, bool) =
riscv_f64Le (rs1_val_D, rs2_val_D);
@@ -888,51 +903,51 @@ mapping f_bin_type_mnemonic_D : f_bin_op_D <-> string = {
mapping clause assembly = F_BIN_TYPE_D(rs2, rs1, rd, FSGNJ_D)
<-> f_bin_type_mnemonic_D(FSGNJ_D)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_D(rs2, rs1, rd, FSGNJN_D)
<-> f_bin_type_mnemonic_D(FSGNJN_D)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_D(rs2, rs1, rd, FSGNJX_D)
<-> f_bin_type_mnemonic_D(FSGNJX_D)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_D(rs2, rs1, rd, FMIN_D)
<-> f_bin_type_mnemonic_D(FMIN_D)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_D(rs2, rs1, rd, FMAX_D)
<-> f_bin_type_mnemonic_D(FMAX_D)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_D(rs2, rs1, rd, FEQ_D)
<-> f_bin_type_mnemonic_D(FEQ_D)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_D(rs2, rs1, rd, FLT_D)
<-> f_bin_type_mnemonic_D(FLT_D)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_D(rs2, rs1, rd, FLE_D)
<-> f_bin_type_mnemonic_D(FLE_D)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
/* ****************************************************************** */
/* Unary, no rounding mode */
@@ -941,21 +956,21 @@ union clause ast = F_UN_TYPE_D : (regidx, regidx, f_un_op_D)
/* AST <-> Binary encoding ================================ */
-mapping clause encdec = F_UN_TYPE_D(rs1, rd, FCLASS_D) if supports_RV32D_or_RV64D([rs1])
- <-> 0b111_0001 @ 0b00000 @ rs1 @ 0b001 @ rd @ 0b101_0011 if supports_RV32D_or_RV64D([rs1])
+mapping clause encdec = F_UN_TYPE_D(rs1, rd, FCLASS_D) if haveDoubleFPU() & validDoubleRegs([rs1])
+ <-> 0b111_0001 @ 0b00000 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveDoubleFPU() & validDoubleRegs([rs1])
/* D instructions, RV64 only */
-mapping clause encdec = F_UN_TYPE_D(rs1, rd, FMV_X_D) if is_RV64D() & ~ (sys_enable_zfinx())
- <-> 0b111_0001 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if is_RV64D() & ~ (sys_enable_zfinx())
+mapping clause encdec = F_UN_TYPE_D(rs1, rd, FMV_X_D) if haveDExt()
+ <-> 0b111_0001 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveDExt()
-mapping clause encdec = F_UN_TYPE_D(rs1, rd, FMV_D_X) if is_RV64D() & ~ (sys_enable_zfinx())
- <-> 0b111_1001 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if is_RV64D() & ~ (sys_enable_zfinx())
+mapping clause encdec = F_UN_TYPE_D(rs1, rd, FMV_D_X) if haveDExt()
+ <-> 0b111_1001 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveDExt()
/* Execution semantics ================================ */
function clause execute (F_UN_TYPE_D(rs1, rd, FCLASS_D)) = {
- let rs1_val_D = X_or_F_D(sys_enable_zfinx(), rs1);
+ let rs1_val_D = F_or_X_D(rs1);
let rd_val_10b : bits (10) =
if f_is_neg_inf_D (rs1_val_D) then 0b_00_0000_0001
@@ -1011,6 +1026,6 @@ mapping clause assembly = F_UN_TYPE_D(rs1, rd, FMV_D_X)
mapping clause assembly = F_UN_TYPE_D(rs1, rd, FCLASS_D)
<-> f_un_type_mnemonic_D(FCLASS_D)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
/* ****************************************************************** */
diff --git a/model/riscv_insts_fext.sail b/model/riscv_insts_fext.sail
index 8e42b01..2995f19 100644
--- a/model/riscv_insts_fext.sail
+++ b/model/riscv_insts_fext.sail
@@ -316,26 +316,10 @@ function fle_S (v1, v2, is_quiet) = {
}
/* **************************************************************** */
-/* Help-functions for 'encdec()' to restrict to certain */
-/* combinations of {F,D} x {RV32,RV64} */
+/* Helper functions for 'encdec()' */
-function is_RV32F_or_RV64F () -> bool = (haveFExt() & (sizeof(xlen) == 32 | sizeof(xlen) == 64))
-function is_RV64F () -> bool = (haveFExt() & sizeof(xlen) == 64)
+function haveSingleFPU() -> bool = haveFExt() | haveZfinx()
-function is_RV32D_or_RV64D () -> bool = (haveDExt() & (sizeof(xlen) == 32 | sizeof(xlen) == 64))
-function is_RV64D () -> bool = (haveDExt() & sizeof(xlen) == 64)
-
-val supports_RV32D_or_RV64D : forall 'n, 'n > 0. (implicit('n), vector('n, dec, bits(5))) -> bool effect {rreg}
-function supports_RV32D_or_RV64D (reg_vec_len, registers) = {
- if ~ (sys_enable_zfinx()) then is_RV32D_or_RV64D()
- else if sys_enable_zfinx() & is_RV64D() then true
- else {
- foreach (x from 0 to (reg_vec_len - 1) ) {
- if (registers[x][0] == bitone) then return false
- };
- true
- }
-}
/* ****************************************************************** */
/* Floating-point loads */
@@ -346,11 +330,11 @@ union clause ast = LOAD_FP : (bits(12), regidx, regidx, word_width)
/* AST <-> Binary encoding ================================ */
-mapping clause encdec = LOAD_FP(imm, rs1, rd, WORD) if is_RV32F_or_RV64F() & ~ (sys_enable_zfinx())
- <-> imm @ rs1 @ 0b010 @ rd @ 0b000_0111 if is_RV32F_or_RV64F() & ~ (sys_enable_zfinx())
+mapping clause encdec = LOAD_FP(imm, rs1, rd, WORD) if haveFExt()
+ <-> imm @ rs1 @ 0b010 @ rd @ 0b000_0111 if haveFExt()
-mapping clause encdec = LOAD_FP(imm, rs1, rd, DOUBLE) if is_RV32D_or_RV64D() & ~ (sys_enable_zfinx())
- <-> imm @ rs1 @ 0b011 @ rd @ 0b000_0111 if is_RV32D_or_RV64D() & ~ (sys_enable_zfinx())
+mapping clause encdec = LOAD_FP(imm, rs1, rd, DOUBLE) if haveDExt()
+ <-> imm @ rs1 @ 0b011 @ rd @ 0b000_0111 if haveDExt()
/* Execution semantics ================================ */
@@ -371,7 +355,7 @@ val process_fload32 : (regidx, xlenbits, MemoryOpResult(bits(32)))
-> Retired effect {escape, rreg, wreg}
function process_fload32(rd, addr, value) =
match value {
- MemValue(result) => { F(rd) = nan_box(false, result); RETIRE_SUCCESS },
+ MemValue(result) => { F(rd) = nan_box(result); RETIRE_SUCCESS },
MemException(e) => { handle_mem_exception(addr, e); RETIRE_FAIL }
}
@@ -406,7 +390,7 @@ function clause execute(LOAD_FP(imm, rs1, rd, width)) = {
mapping clause assembly = LOAD_FP(imm, rs1, rd, width)
<-> "fl" ^ size_mnemonic(width)
- ^ spc() ^ reg_or_freg_name(rd)
+ ^ spc() ^ freg_or_reg_name(rd)
^ sep() ^ hex_bits_12(imm)
^ opt_spc() ^ "(" ^ opt_spc() ^ reg_name(rs1) ^ opt_spc() ^ ")"
@@ -420,11 +404,11 @@ union clause ast = STORE_FP : (bits(12), regidx, regidx, word_width)
/* AST <-> Binary encoding ================================ */
-mapping clause encdec = STORE_FP(imm7 @ imm5, rs2, rs1, WORD) if is_RV32F_or_RV64F() & ~ (sys_enable_zfinx())
- <-> imm7 : bits(7) @ rs2 @ rs1 @ 0b010 @ imm5 : bits(5) @ 0b010_0111 if is_RV32F_or_RV64F() & ~ (sys_enable_zfinx())
+mapping clause encdec = STORE_FP(imm7 @ imm5, rs2, rs1, WORD) if haveFExt()
+ <-> imm7 : bits(7) @ rs2 @ rs1 @ 0b010 @ imm5 : bits(5) @ 0b010_0111 if haveFExt()
-mapping clause encdec = STORE_FP(imm7 @ imm5, rs2, rs1, DOUBLE) if is_RV32D_or_RV64D() & ~ (sys_enable_zfinx())
- <-> imm7 : bits(7) @ rs2 @ rs1 @ 0b011 @ imm5 : bits(5) @ 0b010_0111 if is_RV32D_or_RV64D() & ~ (sys_enable_zfinx())
+mapping clause encdec = STORE_FP(imm7 @ imm5, rs2, rs1, DOUBLE) if haveDExt()
+ <-> imm7 : bits(7) @ rs2 @ rs1 @ 0b011 @ imm5 : bits(5) @ 0b010_0111 if haveDExt()
/* Execution semantics ================================ */
@@ -490,27 +474,27 @@ union clause ast = F_MADD_TYPE_S : (regidx, regidx, regidx, rounding_mode, regid
/* AST <-> Binary encoding ================================ */
mapping clause encdec =
- F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, FMADD_S) if is_RV32F_or_RV64F()
-<-> rs3 @ 0b00 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_0011 if is_RV32F_or_RV64F()
+ F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, FMADD_S) if haveSingleFPU()
+<-> rs3 @ 0b00 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_0011 if haveSingleFPU()
mapping clause encdec =
- F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, FMSUB_S) if is_RV32F_or_RV64F()
-<-> rs3 @ 0b00 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_0111 if is_RV32F_or_RV64F()
+ F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, FMSUB_S) if haveSingleFPU()
+<-> rs3 @ 0b00 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_0111 if haveSingleFPU()
mapping clause encdec =
- F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, FNMSUB_S) if is_RV32F_or_RV64F()
-<-> rs3 @ 0b00 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_1011 if is_RV32F_or_RV64F()
+ F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, FNMSUB_S) if haveSingleFPU()
+<-> rs3 @ 0b00 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_1011 if haveSingleFPU()
mapping clause encdec =
- F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, FNMADD_S) if is_RV32F_or_RV64F()
-<-> rs3 @ 0b00 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_1111 if is_RV32F_or_RV64F()
+ F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, FNMADD_S) if haveSingleFPU()
+<-> rs3 @ 0b00 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b100_1111 if haveSingleFPU()
/* Execution semantics ================================ */
function clause execute (F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, op)) = {
- let rs1_val_32b = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_32b = X_or_F_S(sys_enable_zfinx(), rs2);
- let rs3_val_32b = X_or_F_S(sys_enable_zfinx(), rs3);
+ let rs1_val_32b = F_or_X_S(rs1);
+ let rs2_val_32b = F_or_X_S(rs2);
+ let rs3_val_32b = F_or_X_S(rs3);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -523,7 +507,7 @@ function clause execute (F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, op)) = {
FNMADD_S => riscv_f32MulAdd (rm_3b, negate_S (rs1_val_32b), rs2_val_32b, negate_S (rs3_val_32b))
};
write_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_32b);
+ F_or_X_S(rd) = rd_val_32b;
RETIRE_SUCCESS
}
}
@@ -540,10 +524,10 @@ mapping f_madd_type_mnemonic_S : f_madd_op_S <-> string = {
mapping clause assembly = F_MADD_TYPE_S(rs3, rs2, rs1, rm, rd, op)
<-> f_madd_type_mnemonic_S(op)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
- ^ sep() ^ reg_or_freg_name(rs3)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
+ ^ sep() ^ freg_or_reg_name(rs3)
^ sep() ^ frm_mnemonic(rm)
/* ****************************************************************** */
@@ -556,26 +540,26 @@ union clause ast = F_BIN_RM_TYPE_S : (regidx, regidx, rounding_mode, regidx, f_b
/* AST <-> Binary encoding ================================ */
mapping clause encdec =
- F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, FADD_S) if is_RV32F_or_RV64F()
-<-> 0b000_0000 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+ F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, FADD_S) if haveSingleFPU()
+<-> 0b000_0000 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU()
mapping clause encdec =
- F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, FSUB_S) if is_RV32F_or_RV64F()
-<-> 0b000_0100 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+ F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, FSUB_S) if haveSingleFPU()
+<-> 0b000_0100 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU()
mapping clause encdec =
- F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, FMUL_S) if is_RV32F_or_RV64F()
-<-> 0b000_1000 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+ F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, FMUL_S) if haveSingleFPU()
+<-> 0b000_1000 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU()
mapping clause encdec =
- F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, FDIV_S) if is_RV32F_or_RV64F()
-<-> 0b000_1100 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+ F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, FDIV_S) if haveSingleFPU()
+<-> 0b000_1100 @ rs2 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU()
/* Execution semantics ================================ */
function clause execute (F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, op)) = {
- let rs1_val_32b = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_32b = X_or_F_S(sys_enable_zfinx(), rs2);
+ let rs1_val_32b = F_or_X_S(rs1);
+ let rs2_val_32b = F_or_X_S(rs2);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -587,7 +571,7 @@ function clause execute (F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, op)) = {
FDIV_S => riscv_f32Div (rm_3b, rs1_val_32b, rs2_val_32b)
};
write_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_32b);
+ F_or_X_S(rd) = rd_val_32b;
RETIRE_SUCCESS
}
}
@@ -604,9 +588,9 @@ mapping f_bin_rm_type_mnemonic_S : f_bin_rm_op_S <-> string = {
mapping clause assembly = F_BIN_RM_TYPE_S(rs2, rs1, rm, rd, op)
<-> f_bin_rm_type_mnemonic_S(op)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
^ sep() ^ frm_mnemonic(rm)
/* ****************************************************************** */
@@ -619,47 +603,47 @@ union clause ast = F_UN_RM_TYPE_S : (regidx, rounding_mode, regidx, f_un_rm_op_S
/* AST <-> Binary encoding ================================ */
mapping clause encdec =
- F_UN_RM_TYPE_S(rs1, rm, rd, FSQRT_S) if is_RV32F_or_RV64F()
-<-> 0b010_1100 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+ F_UN_RM_TYPE_S(rs1, rm, rd, FSQRT_S) if haveSingleFPU()
+<-> 0b010_1100 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU()
mapping clause encdec =
- F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_W_S) if is_RV32F_or_RV64F()
-<-> 0b110_0000 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+ F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_W_S) if haveSingleFPU()
+<-> 0b110_0000 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU()
mapping clause encdec =
- F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_WU_S) if is_RV32F_or_RV64F()
-<-> 0b110_0000 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+ F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_WU_S) if haveSingleFPU()
+<-> 0b110_0000 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU()
mapping clause encdec =
- F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_W) if is_RV32F_or_RV64F()
-<-> 0b110_1000 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+ F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_W) if haveSingleFPU()
+<-> 0b110_1000 @ 0b00000 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU()
mapping clause encdec =
- F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_WU) if is_RV32F_or_RV64F()
-<-> 0b110_1000 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+ F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_WU) if haveSingleFPU()
+<-> 0b110_1000 @ 0b00001 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU()
/* F instructions, RV64 only */
mapping clause encdec =
- F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_L_S) if is_RV64F()
-<-> 0b110_0000 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV64F()
+ F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_L_S) if haveSingleFPU() & sizeof(xlen) >= 64
+<-> 0b110_0000 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU() & sizeof(xlen) >= 64
mapping clause encdec =
- F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_LU_S) if is_RV64F()
-<-> 0b110_0000 @ 0b00011 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV64F()
+ F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_LU_S) if haveSingleFPU() & sizeof(xlen) >= 64
+<-> 0b110_0000 @ 0b00011 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU() & sizeof(xlen) >= 64
mapping clause encdec =
- F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_L) if is_RV64F()
-<-> 0b110_1000 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV64F()
+ F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_L) if haveSingleFPU() & sizeof(xlen) >= 64
+<-> 0b110_1000 @ 0b00010 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU() & sizeof(xlen) >= 64
mapping clause encdec =
- F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_LU) if is_RV64F()
-<-> 0b110_1000 @ 0b00011 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if is_RV64F()
+ F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_LU) if haveSingleFPU() & sizeof(xlen) >= 64
+<-> 0b110_1000 @ 0b00011 @ rs1 @ encdec_rounding_mode (rm) @ rd @ 0b101_0011 if haveSingleFPU() & sizeof(xlen) >= 64
/* Execution semantics ================================ */
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FSQRT_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
+ let rs1_val_S = F_or_X_S(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -667,14 +651,14 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FSQRT_S)) = {
let (fflags, rd_val_S) = riscv_f32Sqrt (rm_3b, rs1_val_S);
write_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
}
}
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_W_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
+ let rs1_val_S = F_or_X_S(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -689,7 +673,7 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_W_S)) = {
}
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_WU_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
+ let rs1_val_S = F_or_X_S(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -712,7 +696,7 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_W)) = {
let (fflags, rd_val_S) = riscv_i32ToF32 (rm_3b, rs1_val_W);
write_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
}
@@ -727,7 +711,7 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_WU)) = {
let (fflags, rd_val_S) = riscv_ui32ToF32 (rm_3b, rs1_val_WU);
write_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
}
@@ -735,7 +719,7 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_WU)) = {
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_L_S)) = {
assert(sizeof(xlen) >= 64);
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
+ let rs1_val_S = F_or_X_S(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -751,7 +735,7 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_L_S)) = {
function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_LU_S)) = {
assert(sizeof(xlen) >= 64);
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
+ let rs1_val_S = F_or_X_S(rs1);
match (select_instr_or_fcsr_rm (rm)) {
None() => { handle_illegal(); RETIRE_FAIL },
Some(rm') => {
@@ -775,7 +759,7 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_L)) = {
let (fflags, rd_val_S) = riscv_i64ToF32 (rm_3b, rs1_val_L);
write_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
}
@@ -791,7 +775,7 @@ function clause execute (F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_LU)) = {
let (fflags, rd_val_S) = riscv_ui64ToF32 (rm_3b, rs1_val_LU);
write_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
}
@@ -814,55 +798,55 @@ mapping f_un_rm_type_mnemonic_S : f_un_rm_op_S <-> string = {
mapping clause assembly = F_UN_RM_TYPE_S(rs1, rm, rd, FSQRT_S)
<-> f_un_rm_type_mnemonic_S(FSQRT_S)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_W_S)
<-> f_un_rm_type_mnemonic_S(FCVT_W_S)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_WU_S)
<-> f_un_rm_type_mnemonic_S(FCVT_WU_S)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_W)
<-> f_un_rm_type_mnemonic_S(FCVT_S_W)
- ^ spc() ^ reg_or_freg_name(rd)
+ ^ spc() ^ freg_or_reg_name(rd)
^ sep() ^ reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_WU)
<-> f_un_rm_type_mnemonic_S(FCVT_S_WU)
- ^ spc() ^ reg_or_freg_name(rd)
+ ^ spc() ^ freg_or_reg_name(rd)
^ sep() ^ reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_L_S)
<-> f_un_rm_type_mnemonic_S(FCVT_L_S)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_LU_S)
<-> f_un_rm_type_mnemonic_S(FCVT_LU_S)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_L)
<-> f_un_rm_type_mnemonic_S(FCVT_S_L)
- ^ spc() ^ reg_or_freg_name(rd)
+ ^ spc() ^ freg_or_reg_name(rd)
^ sep() ^ reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
mapping clause assembly = F_UN_RM_TYPE_S(rs1, rm, rd, FCVT_S_LU)
<-> f_un_rm_type_mnemonic_S(FCVT_S_LU)
- ^ spc() ^ reg_or_freg_name(rd)
+ ^ spc() ^ freg_or_reg_name(rd)
^ sep() ^ reg_name(rs1)
^ sep() ^ frm_mnemonic(rm)
@@ -876,68 +860,68 @@ union clause ast = F_BIN_TYPE_S : (regidx, regidx, regidx, f_bin_op_S)
/* AST <-> Binary encoding ================================ */
-mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FSGNJ_S) if is_RV32F_or_RV64F()
- <-> 0b001_0000 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FSGNJ_S) if haveSingleFPU()
+ <-> 0b001_0000 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveSingleFPU()
-mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FSGNJN_S) if is_RV32F_or_RV64F()
- <-> 0b001_0000 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FSGNJN_S) if haveSingleFPU()
+ <-> 0b001_0000 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveSingleFPU()
-mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FSGNJX_S) if is_RV32F_or_RV64F()
- <-> 0b001_0000 @ rs2 @ rs1 @ 0b010 @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FSGNJX_S) if haveSingleFPU()
+ <-> 0b001_0000 @ rs2 @ rs1 @ 0b010 @ rd @ 0b101_0011 if haveSingleFPU()
-mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FMIN_S) if is_RV32F_or_RV64F()
- <-> 0b001_0100 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FMIN_S) if haveSingleFPU()
+ <-> 0b001_0100 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveSingleFPU()
-mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FMAX_S) if is_RV32F_or_RV64F()
- <-> 0b001_0100 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FMAX_S) if haveSingleFPU()
+ <-> 0b001_0100 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveSingleFPU()
-mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FEQ_S) if is_RV32F_or_RV64F()
- <-> 0b101_0000 @ rs2 @ rs1 @ 0b010 @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FEQ_S) if haveSingleFPU()
+ <-> 0b101_0000 @ rs2 @ rs1 @ 0b010 @ rd @ 0b101_0011 if haveSingleFPU()
-mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FLT_S) if is_RV32F_or_RV64F()
- <-> 0b101_0000 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FLT_S) if haveSingleFPU()
+ <-> 0b101_0000 @ rs2 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveSingleFPU()
-mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FLE_S) if is_RV32F_or_RV64F()
- <-> 0b101_0000 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if is_RV32F_or_RV64F()
+mapping clause encdec = F_BIN_TYPE_S(rs2, rs1, rd, FLE_S) if haveSingleFPU()
+ <-> 0b101_0000 @ rs2 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveSingleFPU()
/* Execution semantics ================================ */
function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FSGNJ_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_S = X_or_F_S(sys_enable_zfinx(), rs2);
+ let rs1_val_S = F_or_X_S(rs1);
+ let rs2_val_S = F_or_X_S(rs2);
let (s1, e1, m1) = fsplit_S (rs1_val_S);
let (s2, e2, m2) = fsplit_S (rs2_val_S);
let rd_val_S = fmake_S (s2, e1, m1);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FSGNJN_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_S = X_or_F_S(sys_enable_zfinx(), rs2);
+ let rs1_val_S = F_or_X_S(rs1);
+ let rs2_val_S = F_or_X_S(rs2);
let (s1, e1, m1) = fsplit_S (rs1_val_S);
let (s2, e2, m2) = fsplit_S (rs2_val_S);
let rd_val_S = fmake_S (0b1 ^ s2, e1, m1);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FSGNJX_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_S = X_or_F_S(sys_enable_zfinx(), rs2);
+ let rs1_val_S = F_or_X_S(rs1);
+ let rs2_val_S = F_or_X_S(rs2);
let (s1, e1, m1) = fsplit_S (rs1_val_S);
let (s2, e2, m2) = fsplit_S (rs2_val_S);
let rd_val_S = fmake_S (s1 ^ s2, e1, m1);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FMIN_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_S = X_or_F_S(sys_enable_zfinx(), rs2);
+ let rs1_val_S = F_or_X_S(rs1);
+ let rs2_val_S = F_or_X_S(rs2);
let is_quiet = true;
let (rs1_lt_rs2, fflags) = fle_S (rs1_val_S, rs2_val_S, is_quiet);
@@ -951,13 +935,13 @@ function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FMIN_S)) = {
else /* (not rs1_lt_rs2) */ rs2_val_S;
accrue_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FMAX_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_S = X_or_F_S(sys_enable_zfinx(), rs2);
+ let rs1_val_S = F_or_X_S(rs1);
+ let rs2_val_S = F_or_X_S(rs2);
let is_quiet = true;
let (rs2_lt_rs1, fflags) = fle_S (rs2_val_S, rs1_val_S, is_quiet);
@@ -971,13 +955,13 @@ function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FMAX_S)) = {
else /* (not rs2_lt_rs1) */ rs2_val_S;
accrue_fflags(fflags);
- X_or_F_S(sys_enable_zfinx(), rd, rd_val_S);
+ F_or_X_S(rd) = rd_val_S;
RETIRE_SUCCESS
}
function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FEQ_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_S = X_or_F_S(sys_enable_zfinx(), rs2);
+ let rs1_val_S = F_or_X_S(rs1);
+ let rs2_val_S = F_or_X_S(rs2);
let (fflags, rd_val) : (bits_fflags, bool) =
riscv_f32Eq (rs1_val_S, rs2_val_S);
@@ -988,8 +972,8 @@ function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FEQ_S)) = {
}
function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FLT_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_S = X_or_F_S(sys_enable_zfinx(), rs2);
+ let rs1_val_S = F_or_X_S(rs1);
+ let rs2_val_S = F_or_X_S(rs2);
let (fflags, rd_val) : (bits_fflags, bool) =
riscv_f32Lt (rs1_val_S, rs2_val_S);
@@ -1000,8 +984,8 @@ function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FLT_S)) = {
}
function clause execute (F_BIN_TYPE_S(rs2, rs1, rd, FLE_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
- let rs2_val_S = X_or_F_S(sys_enable_zfinx(), rs2);
+ let rs1_val_S = F_or_X_S(rs1);
+ let rs2_val_S = F_or_X_S(rs2);
let (fflags, rd_val) : (bits_fflags, bool) =
riscv_f32Le (rs1_val_S, rs2_val_S);
@@ -1026,51 +1010,51 @@ mapping f_bin_type_mnemonic_S : f_bin_op_S <-> string = {
mapping clause assembly = F_BIN_TYPE_S(rs2, rs1, rd, FSGNJ_S)
<-> f_bin_type_mnemonic_S(FSGNJ_S)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_S(rs2, rs1, rd, FSGNJN_S)
<-> f_bin_type_mnemonic_S(FSGNJN_S)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_S(rs2, rs1, rd, FSGNJX_S)
<-> f_bin_type_mnemonic_S(FSGNJX_S)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_S(rs2, rs1, rd, FMIN_S)
<-> f_bin_type_mnemonic_S(FMIN_S)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_S(rs2, rs1, rd, FMAX_S)
<-> f_bin_type_mnemonic_S(FMAX_S)
- ^ spc() ^ reg_or_freg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ spc() ^ freg_or_reg_name(rd)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_S(rs2, rs1, rd, FEQ_S)
<-> f_bin_type_mnemonic_S(FEQ_S)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_S(rs2, rs1, rd, FLT_S)
<-> f_bin_type_mnemonic_S(FLT_S)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
mapping clause assembly = F_BIN_TYPE_S(rs2, rs1, rd, FLE_S)
<-> f_bin_type_mnemonic_S(FLE_S)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
- ^ sep() ^ reg_or_freg_name(rs2)
+ ^ sep() ^ freg_or_reg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs2)
/* ****************************************************************** */
/* Unary, no rounding mode */
@@ -1079,19 +1063,19 @@ union clause ast = F_UN_TYPE_S : (regidx, regidx, f_un_op_S)
/* AST <-> Binary encoding ================================ */
-mapping clause encdec = F_UN_TYPE_S(rs1, rd, FCLASS_S) if haveFExt()
- <-> 0b111_0000 @ 0b00000 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveFExt()
+mapping clause encdec = F_UN_TYPE_S(rs1, rd, FCLASS_S) if haveSingleFPU()
+ <-> 0b111_0000 @ 0b00000 @ rs1 @ 0b001 @ rd @ 0b101_0011 if haveSingleFPU()
-mapping clause encdec = F_UN_TYPE_S(rs1, rd, FMV_X_W) if haveFExt() & ~ (sys_enable_zfinx())
- <-> 0b111_0000 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveFExt() & ~ (sys_enable_zfinx())
+mapping clause encdec = F_UN_TYPE_S(rs1, rd, FMV_X_W) if haveFExt()
+ <-> 0b111_0000 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveFExt()
-mapping clause encdec = F_UN_TYPE_S(rs1, rd, FMV_W_X) if haveFExt() & ~ (sys_enable_zfinx())
- <-> 0b111_1000 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveFExt() & ~ (sys_enable_zfinx())
+mapping clause encdec = F_UN_TYPE_S(rs1, rd, FMV_W_X) if haveFExt()
+ <-> 0b111_1000 @ 0b00000 @ rs1 @ 0b000 @ rd @ 0b101_0011 if haveFExt()
/* Execution semantics ================================ */
function clause execute (F_UN_TYPE_S(rs1, rd, FCLASS_S)) = {
- let rs1_val_S = X_or_F_S(sys_enable_zfinx(), rs1);
+ let rs1_val_S = F_or_X_S(rs1);
let rd_val_10b : bits (10) =
if f_is_neg_inf_S (rs1_val_S) then 0b_00_0000_0001
@@ -1120,7 +1104,7 @@ function clause execute (F_UN_TYPE_S(rs1, rd, FMV_X_W)) = {
function clause execute (F_UN_TYPE_S(rs1, rd, FMV_W_X)) = {
let rs1_val_X = X(rs1);
let rd_val_S = rs1_val_X [31..0];
- F(rd) = nan_box(false, rd_val_S);
+ F(rd) = nan_box (rd_val_S);
RETIRE_SUCCESS
}
@@ -1145,6 +1129,6 @@ mapping clause assembly = F_UN_TYPE_S(rs1, rd, FMV_W_X)
mapping clause assembly = F_UN_TYPE_S(rs1, rd, FCLASS_S)
<-> f_un_type_mnemonic_S(FCLASS_S)
^ spc() ^ reg_name(rd)
- ^ sep() ^ reg_or_freg_name(rs1)
+ ^ sep() ^ freg_or_reg_name(rs1)
/* ****************************************************************** */
diff --git a/model/riscv_sys_control.sail b/model/riscv_sys_control.sail
index 06be736..6204ae5 100644
--- a/model/riscv_sys_control.sail
+++ b/model/riscv_sys_control.sail
@@ -559,10 +559,13 @@ function init_sys() -> unit = {
misa->U() = 0b1; /* user-mode */
misa->S() = 0b1; /* supervisor-mode */
+ if sys_enable_fdext() & sys_enable_zfinx()
+ then internal_error("F and Zfinx cannot both be enabled!");
+
/* We currently support both F and D */
- misa->F() = bool_to_bits(sys_enable_fdext() & ~ (sys_enable_zfinx())); /* single-precision */
- misa->D() = if sizeof(flen) >= 64 & ~ (sys_enable_zfinx())
- then bool_to_bits(sys_enable_fdext()) /* double-precision */
+ misa->F() = bool_to_bits(sys_enable_fdext()); /* single-precision */
+ misa->D() = if sizeof(flen) >= 64
+ then bool_to_bits(sys_enable_fdext()) /* double-precision */
else 0b0;
mstatus = set_mstatus_SXL(mstatus, misa.MXL());
diff --git a/model/riscv_sys_regs.sail b/model/riscv_sys_regs.sail
index 28505e3..2e638cf 100644
--- a/model/riscv_sys_regs.sail
+++ b/model/riscv_sys_regs.sail
@@ -145,7 +145,7 @@ val sys_enable_rvc = {c: "sys_enable_rvc", ocaml: "Platform.enable_rvc", _: "sys
/* whether misa.{f,d} were enabled at boot */
val sys_enable_fdext = {c: "sys_enable_fdext", ocaml: "Platform.enable_fdext", _: "sys_enable_fdext"} : unit -> bool
/* whether zfinx was enabled at boot */
-val sys_enable_zfinx = {c: "sys_enable_zfinx",ocaml: "Platform.enable_zfinx", _: "sys_enable_zfinx"} : unit -> bool
+val sys_enable_zfinx = {c: "sys_enable_zfinx", ocaml: "Platform.enable_zfinx", _: "sys_enable_zfinx"} : unit -> bool
/* whether the N extension was enabled at boot */
val sys_enable_next = {c: "sys_enable_next", ocaml: "Platform.enable_next", _: "sys_enable_next"} : unit -> bool
@@ -165,7 +165,7 @@ function legalize_misa(m : Misa, v : xlenbits) -> Misa = {
then m
else update_C(m, v.C());
/* Handle updates for F/D. */
- if ~(sys_enable_fdext()) | (v.D() == 0b1 & v.F() == 0b0) | sys_enable_zfinx()
+ if ~(sys_enable_fdext()) | (v.D() == 0b1 & v.F() == 0b0)
then m
else update_D(update_F(m, v.F()), v.D())
}
@@ -180,7 +180,7 @@ function haveMulDiv() -> bool = misa.M() == 0b1
function haveSupMode() -> bool = misa.S() == 0b1
function haveUsrMode() -> bool = misa.U() == 0b1
function haveNExt() -> bool = misa.N() == 0b1
-/* see below for F and D extension tests */
+/* see below for F and D (and Z*inx counterparts) extension tests */
/* Cryptography extension support. Note these will need updating once */
/* Sail can be dynamically configured with different extension support */
@@ -280,12 +280,13 @@ function legalize_mstatus(o : Mstatus, v : xlenbits) -> Mstatus = {
/* We don't have any extension context yet. */
let m = update_XS(m, extStatus_to_bits(Off));
- let m = if sys_enable_zfinx() then update_FS(m, extStatus_to_bits(Off)) else m;
+
/* FS is WARL, and making FS writable can support the M-mode emulation of an FPU
- * to support code running in S/U-modes. Spike does this, and for now, we match it.
+ * to support code running in S/U-modes. Spike does this, and for now, we match it,
+ * but only if Zfinx isn't enabled.
* FIXME: This should be made a platform parameter.
*/
-
+ let m = if sys_enable_zfinx() then update_FS(m, extStatus_to_bits(Off)) else m;
let dirty = extStatus_of_bits(m.FS()) == Dirty | extStatus_of_bits(m.XS()) == Dirty;
let m = update_SD(m, bool_to_bits(dirty));
@@ -331,8 +332,12 @@ function in32BitMode() -> bool = {
}
/* F and D extensions have to enabled both via misa.{FD} as well as mstatus.FS */
-function haveFExt() -> bool = (misa.F() == 0b1 & mstatus.FS() != 0b00) | sys_enable_zfinx()
-function haveDExt() -> bool = (misa.D() == 0b1 & mstatus.FS() != 0b00) | (sys_enable_zfinx() & sizeof(flen)==64)
+function haveFExt() -> bool = (misa.F() == 0b1) & (mstatus.FS() != 0b00)
+function haveDExt() -> bool = (misa.D() == 0b1) & (mstatus.FS() != 0b00)
+
+/* Zfinx and Zdinx extensions (TODO: gate FCSR access on [mhs]stateen0 bit 1 when implemented) */
+function haveZfinx() -> bool = sys_enable_zfinx()
+function haveZdinx() -> bool = sys_enable_zfinx() & sizeof(flen) >= 64
/* interrupt processing state */
diff --git a/ocaml_emulator/platform.ml b/ocaml_emulator/platform.ml
index a1d9c82..ccf4875 100644
--- a/ocaml_emulator/platform.ml
+++ b/ocaml_emulator/platform.ml
@@ -11,7 +11,6 @@ let config_enable_dirty_update = ref false
let config_enable_misaligned_access = ref false
let config_mtval_has_illegal_inst_bits = ref false
let config_enable_pmp = ref false
-let config_enable_zfinx = ref false
let platform_arch = ref P.RV64
@@ -83,7 +82,7 @@ let enable_dirty_update () = !config_enable_dirty_update
let enable_misaligned_access () = !config_enable_misaligned_access
let mtval_has_illegal_inst_bits () = !config_mtval_has_illegal_inst_bits
let enable_pmp () = !config_enable_pmp
-let enable_zfinx () = !config_enable_zfinx
+let enable_zfinx () = false
let rom_base () = arch_bits_of_int64 P.rom_base
let rom_size () = arch_bits_of_int !rom_size_ref
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment