summaryrefslogtreecommitdiff
path: root/src/arch/riscv/isa/decoder.isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/riscv/isa/decoder.isa')
-rw-r--r--src/arch/riscv/isa/decoder.isa829
1 files changed, 829 insertions, 0 deletions
diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa
index e02d507de..1b28ae1de 100644
--- a/src/arch/riscv/isa/decoder.isa
+++ b/src/arch/riscv/isa/decoder.isa
@@ -61,6 +61,17 @@ decode OPCODE default Unknown::unknown() {
}
}
+ 0x07: decode FUNCT3 {
+ format Load {
+ 0x2: flw({{
+ Fd_bits = (uint64_t)Mem_uw;
+ }});
+ 0x3: fld({{
+ Fd_bits = Mem;
+ }});
+ }
+ }
+
0x0f: decode FUNCT3 {
format IOp {
0x0: fence({{
@@ -144,6 +155,17 @@ decode OPCODE default Unknown::unknown() {
}
}
+ 0x27: decode FUNCT3 {
+ format Store {
+ 0x2: fsw({{
+ Mem_uw = (uint32_t)Fs2_bits;
+ }});
+ 0x3: fsd({{
+ Mem_ud = Fs2_bits;
+ }});
+ }
+ }
+
0x33: decode FUNCT3 {
format ROp {
0x0: decode FUNCT7 {
@@ -347,6 +369,813 @@ decode OPCODE default Unknown::unknown() {
}
}
+ format FPR4Op {
+ 0x43: decode FUNCT2 {
+ 0x0: fmadd_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
+ float fd;
+
+ if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
+ if (issignalingnan(fs1) || issignalingnan(fs2)
+ || issignalingnan(fs3)) {
+ FFLAGS |= FloatInvalid;
+ }
+ fd = std::numeric_limits<float>::quiet_NaN();
+ } else if (std::isinf(fs1) || std::isinf(fs2) ||
+ std::isinf(fs3)) {
+ if (std::signbit(fs1) == std::signbit(fs2)
+ && !std::isinf(fs3)) {
+ fd = std::numeric_limits<float>::infinity();
+ } else if (std::signbit(fs1) != std::signbit(fs2)
+ && !std::isinf(fs3)) {
+ fd = -std::numeric_limits<float>::infinity();
+ } else { // Fs3_sf is infinity
+ fd = fs3;
+ }
+ } else {
+ fd = fs1*fs2 + fs3;
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatMultOp);
+ 0x1: fmadd_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
+ if (issignalingnan(Fs1) || issignalingnan(Fs2)
+ || issignalingnan(Fs3)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Fd = std::numeric_limits<double>::quiet_NaN();
+ } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
+ std::isinf(Fs3)) {
+ if (std::signbit(Fs1) == std::signbit(Fs2)
+ && !std::isinf(Fs3)) {
+ Fd = std::numeric_limits<double>::infinity();
+ } else if (std::signbit(Fs1) != std::signbit(Fs2)
+ && !std::isinf(Fs3)) {
+ Fd = -std::numeric_limits<double>::infinity();
+ } else {
+ Fd = Fs3;
+ }
+ } else {
+ Fd = Fs1*Fs2 + Fs3;
+ }
+ }}, FloatMultOp);
+ }
+ 0x47: decode FUNCT2 {
+ 0x0: fmsub_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
+ float fd;
+
+ if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
+ if (issignalingnan(fs1) || issignalingnan(fs2)
+ || issignalingnan(fs3)) {
+ FFLAGS |= FloatInvalid;
+ }
+ fd = std::numeric_limits<float>::quiet_NaN();
+ } else if (std::isinf(fs1) || std::isinf(fs2) ||
+ std::isinf(fs3)) {
+ if (std::signbit(fs1) == std::signbit(fs2)
+ && !std::isinf(fs3)) {
+ fd = std::numeric_limits<float>::infinity();
+ } else if (std::signbit(fs1) != std::signbit(fs2)
+ && !std::isinf(fs3)) {
+ fd = -std::numeric_limits<float>::infinity();
+ } else { // Fs3_sf is infinity
+ fd = -fs3;
+ }
+ } else {
+ fd = fs1*fs2 - fs3;
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatMultOp);
+ 0x1: fmsub_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
+ if (issignalingnan(Fs1) || issignalingnan(Fs2)
+ || issignalingnan(Fs3)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Fd = std::numeric_limits<double>::quiet_NaN();
+ } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
+ std::isinf(Fs3)) {
+ if (std::signbit(Fs1) == std::signbit(Fs2)
+ && !std::isinf(Fs3)) {
+ Fd = std::numeric_limits<double>::infinity();
+ } else if (std::signbit(Fs1) != std::signbit(Fs2)
+ && !std::isinf(Fs3)) {
+ Fd = -std::numeric_limits<double>::infinity();
+ } else {
+ Fd = -Fs3;
+ }
+ } else {
+ Fd = Fs1*Fs2 - Fs3;
+ }
+ }}, FloatMultOp);
+ }
+ 0x4b: decode FUNCT2 {
+ 0x0: fnmsub_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
+ float fd;
+
+ if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
+ if (issignalingnan(fs1) || issignalingnan(fs2)
+ || issignalingnan(fs3)) {
+ FFLAGS |= FloatInvalid;
+ }
+ fd = std::numeric_limits<float>::quiet_NaN();
+ } else if (std::isinf(fs1) || std::isinf(fs2) ||
+ std::isinf(fs3)) {
+ if (std::signbit(fs1) == std::signbit(fs2)
+ && !std::isinf(fs3)) {
+ fd = -std::numeric_limits<float>::infinity();
+ } else if (std::signbit(fs1) != std::signbit(fs2)
+ && !std::isinf(fs3)) {
+ fd = std::numeric_limits<float>::infinity();
+ } else { // Fs3_sf is infinity
+ fd = fs3;
+ }
+ } else {
+ fd = -(fs1*fs2 - fs3);
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatMultOp);
+ 0x1: fnmsub_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
+ if (issignalingnan(Fs1) || issignalingnan(Fs2)
+ || issignalingnan(Fs3)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Fd = std::numeric_limits<double>::quiet_NaN();
+ } else if (std::isinf(Fs1) || std::isinf(Fs2)
+ || std::isinf(Fs3)) {
+ if (std::signbit(Fs1) == std::signbit(Fs2)
+ && !std::isinf(Fs3)) {
+ Fd = -std::numeric_limits<double>::infinity();
+ } else if (std::signbit(Fs1) != std::signbit(Fs2)
+ && !std::isinf(Fs3)) {
+ Fd = std::numeric_limits<double>::infinity();
+ } else {
+ Fd = Fs3;
+ }
+ } else {
+ Fd = -(Fs1*Fs2 - Fs3);
+ }
+ }}, FloatMultOp);
+ }
+ 0x4f: decode FUNCT2 {
+ 0x0: fnmadd_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
+ float fd;
+
+ if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
+ if (issignalingnan(fs1) || issignalingnan(fs2)
+ || issignalingnan(fs3)) {
+ FFLAGS |= FloatInvalid;
+ }
+ fd = std::numeric_limits<float>::quiet_NaN();
+ } else if (std::isinf(fs1) || std::isinf(fs2) ||
+ std::isinf(fs3)) {
+ if (std::signbit(fs1) == std::signbit(fs2)
+ && !std::isinf(fs3)) {
+ fd = -std::numeric_limits<float>::infinity();
+ } else if (std::signbit(fs1) != std::signbit(fs2)
+ && !std::isinf(fs3)) {
+ fd = std::numeric_limits<float>::infinity();
+ } else { // Fs3_sf is infinity
+ fd = -fs3;
+ }
+ } else {
+ fd = -(fs1*fs2 + fs3);
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatMultOp);
+ 0x1: fnmadd_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
+ if (issignalingnan(Fs1) || issignalingnan(Fs2)
+ || issignalingnan(Fs3)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Fd = std::numeric_limits<double>::quiet_NaN();
+ } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
+ std::isinf(Fs3)) {
+ if (std::signbit(Fs1) == std::signbit(Fs2)
+ && !std::isinf(Fs3)) {
+ Fd = -std::numeric_limits<double>::infinity();
+ } else if (std::signbit(Fs1) != std::signbit(Fs2)
+ && !std::isinf(Fs3)) {
+ Fd = std::numeric_limits<double>::infinity();
+ } else {
+ Fd = -Fs3;
+ }
+ } else {
+ Fd = -(Fs1*Fs2 + Fs3);
+ }
+ }}, FloatMultOp);
+ }
+ }
+
+ 0x53: decode FUNCT7 {
+ format FPROp {
+ 0x0: fadd_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fd;
+
+ if (std::isnan(fs1) || std::isnan(fs2)) {
+ if (issignalingnan(fs1) || issignalingnan(fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ fd = std::numeric_limits<float>::quiet_NaN();
+ } else {
+ fd = fs1 + fs2;
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatAddOp);
+ 0x1: fadd_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2)) {
+ if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Fd = std::numeric_limits<double>::quiet_NaN();
+ } else {
+ Fd = Fs1 + Fs2;
+ }
+ }}, FloatAddOp);
+ 0x4: fsub_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fd;
+
+ if (std::isnan(fs1) || std::isnan(fs2)) {
+ if (issignalingnan(fs1) || issignalingnan(fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ fd = std::numeric_limits<float>::quiet_NaN();
+ } else {
+ fd = fs1 - fs2;
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatAddOp);
+ 0x5: fsub_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2)) {
+ if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Fd = std::numeric_limits<double>::quiet_NaN();
+ } else {
+ Fd = Fs1 - Fs2;
+ }
+ }}, FloatAddOp);
+ 0x8: fmul_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fd;
+
+ if (std::isnan(fs1) || std::isnan(fs2)) {
+ if (issignalingnan(fs1) || issignalingnan(fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ fd = std::numeric_limits<float>::quiet_NaN();
+ } else {
+ fd = fs1*fs2;
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatMultOp);
+ 0x9: fmul_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2)) {
+ if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Fd = std::numeric_limits<double>::quiet_NaN();
+ } else {
+ Fd = Fs1*Fs2;
+ }
+ }}, FloatMultOp);
+ 0xc: fdiv_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fd;
+
+ if (std::isnan(fs1) || std::isnan(fs2)) {
+ if (issignalingnan(fs1) || issignalingnan(fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ fd = std::numeric_limits<float>::quiet_NaN();
+ } else {
+ fd = fs1/fs2;
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatDivOp);
+ 0xd: fdiv_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2)) {
+ if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Fd = std::numeric_limits<double>::quiet_NaN();
+ } else {
+ Fd = Fs1/Fs2;
+ }
+ }}, FloatDivOp);
+ 0x10: decode ROUND_MODE {
+ 0x0: fsgnj_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fd;
+
+ if (issignalingnan(fs1)) {
+ fd = std::numeric_limits<float>::signaling_NaN();
+ std::feclearexcept(FE_INVALID);
+ } else {
+ fd = std::copysign(fs1, fs2);
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }});
+ 0x1: fsgnjn_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fd;
+
+ if (issignalingnan(fs1)) {
+ fd = std::numeric_limits<float>::signaling_NaN();
+ std::feclearexcept(FE_INVALID);
+ } else {
+ fd = std::copysign(fs1, -fs2);
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }});
+ 0x2: fsgnjx_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fd;
+
+ if (issignalingnan(fs1)) {
+ fd = std::numeric_limits<float>::signaling_NaN();
+ std::feclearexcept(FE_INVALID);
+ } else {
+ fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0);
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }});
+ }
+ 0x11: decode ROUND_MODE {
+ 0x0: fsgnj_d({{
+ if (issignalingnan(Fs1)) {
+ Fd = std::numeric_limits<double>::signaling_NaN();
+ std::feclearexcept(FE_INVALID);
+ } else {
+ Fd = std::copysign(Fs1, Fs2);
+ }
+ }});
+ 0x1: fsgnjn_d({{
+ if (issignalingnan(Fs1)) {
+ Fd = std::numeric_limits<double>::signaling_NaN();
+ std::feclearexcept(FE_INVALID);
+ } else {
+ Fd = std::copysign(Fs1, -Fs2);
+ }
+ }});
+ 0x2: fsgnjx_d({{
+ if (issignalingnan(Fs1)) {
+ Fd = std::numeric_limits<double>::signaling_NaN();
+ std::feclearexcept(FE_INVALID);
+ } else {
+ Fd = Fs1*(std::signbit(Fs2) ? -1.0 : 1.0);
+ }
+ }});
+ }
+ 0x14: decode ROUND_MODE {
+ 0x0: fmin_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fd;
+
+ if (issignalingnan(fs2)) {
+ fd = fs1;
+ FFLAGS |= FloatInvalid;
+ } else if (issignalingnan(fs1)) {
+ fd = fs2;
+ FFLAGS |= FloatInvalid;
+ } else {
+ fd = std::fmin(fs1, fs2);
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatCmpOp);
+ 0x1: fmax_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+ float fd;
+
+ if (issignalingnan(fs2)) {
+ fd = fs1;
+ FFLAGS |= FloatInvalid;
+ } else if (issignalingnan(fs1)) {
+ fd = fs2;
+ FFLAGS |= FloatInvalid;
+ } else {
+ fd = std::fmax(fs1, fs2);
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatCmpOp);
+ }
+ 0x15: decode ROUND_MODE {
+ 0x0: fmin_d({{
+ if (issignalingnan(Fs2)) {
+ Fd = Fs1;
+ FFLAGS |= FloatInvalid;
+ } else if (issignalingnan(Fs1)) {
+ Fd = Fs2;
+ FFLAGS |= FloatInvalid;
+ } else {
+ Fd = std::fmin(Fs1, Fs2);
+ }
+ }}, FloatCmpOp);
+ 0x1: fmax_d({{
+ if (issignalingnan(Fs2)) {
+ Fd = Fs1;
+ FFLAGS |= FloatInvalid;
+ } else if (issignalingnan(Fs1)) {
+ Fd = Fs2;
+ FFLAGS |= FloatInvalid;
+ } else {
+ Fd = std::fmax(Fs1, Fs2);
+ }
+ }}, FloatCmpOp);
+ }
+ 0x20: fcvt_s_d({{
+ assert(CONV_SGN == 1);
+ float fd;
+ if (issignalingnan(Fs1)) {
+ fd = std::numeric_limits<float>::quiet_NaN();
+ FFLAGS |= FloatInvalid;
+ } else {
+ fd = (float)Fs1;
+ }
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatCvtOp);
+ 0x21: fcvt_d_s({{
+ assert(CONV_SGN == 0);
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+
+ if (issignalingnan(fs1)) {
+ Fd = std::numeric_limits<double>::quiet_NaN();
+ FFLAGS |= FloatInvalid;
+ } else {
+ Fd = (double)fs1;
+ }
+ }}, FloatCvtOp);
+ 0x2c: fsqrt_s({{
+ assert(RS2 == 0);
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fd;
+
+ if (issignalingnan(Fs1_sf)) {
+ FFLAGS |= FloatInvalid;
+ }
+ fd = std::sqrt(fs1);
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
+ }}, FloatSqrtOp);
+ 0x2d: fsqrt_d({{
+ assert(RS2 == 0);
+ Fd = std::sqrt(Fs1);
+ }}, FloatSqrtOp);
+ 0x50: decode ROUND_MODE {
+ 0x0: fle_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+
+ if (std::isnan(fs1) || std::isnan(fs2)) {
+ FFLAGS |= FloatInvalid;
+ Rd = 0;
+ } else {
+ Rd = fs1 <= fs2 ? 1 : 0;
+ }
+ }}, FloatCmpOp);
+ 0x1: flt_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+
+ if (std::isnan(fs1) || std::isnan(fs2)) {
+ FFLAGS |= FloatInvalid;
+ Rd = 0;
+ } else {
+ Rd = fs1 < fs2 ? 1 : 0;
+ }
+ }}, FloatCmpOp);
+ 0x2: feq_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
+
+ if (issignalingnan(fs1) || issignalingnan(fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Rd = fs1 == fs2 ? 1 : 0;
+ }}, FloatCmpOp);
+ }
+ 0x51: decode ROUND_MODE {
+ 0x0: fle_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2)) {
+ FFLAGS |= FloatInvalid;
+ Rd = 0;
+ } else {
+ Rd = Fs1 <= Fs2 ? 1 : 0;
+ }
+ }}, FloatCmpOp);
+ 0x1: flt_d({{
+ if (std::isnan(Fs1) || std::isnan(Fs2)) {
+ FFLAGS |= FloatInvalid;
+ Rd = 0;
+ } else {
+ Rd = Fs1 < Fs2 ? 1 : 0;
+ }
+ }}, FloatCmpOp);
+ 0x2: feq_d({{
+ if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
+ FFLAGS |= FloatInvalid;
+ }
+ Rd = Fs1 == Fs2 ? 1 : 0;
+ }}, FloatCmpOp);
+ }
+ 0x60: decode CONV_SGN {
+ 0x0: fcvt_w_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+
+ if (std::isnan(fs1)) {
+ Rd_sd = std::numeric_limits<int32_t>::max();
+ FFLAGS |= FloatInvalid;
+ } else {
+ Rd_sd = (int32_t)fs1;
+ if (std::fetestexcept(FE_INVALID)) {
+ if (std::signbit(fs1)) {
+ Rd_sd = std::numeric_limits<int32_t>::min();
+ } else {
+ Rd_sd = std::numeric_limits<int32_t>::max();
+ }
+ std::feclearexcept(FE_INEXACT);
+ }
+ }
+ }}, FloatCvtOp);
+ 0x1: fcvt_wu_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+
+ if (fs1 < 0.0) {
+ Rd = 0;
+ FFLAGS |= FloatInvalid;
+ } else {
+ Rd = (uint32_t)fs1;
+ if (std::fetestexcept(FE_INVALID)) {
+ Rd = std::numeric_limits<uint64_t>::max();
+ std::feclearexcept(FE_INEXACT);
+ }
+ }
+ }}, FloatCvtOp);
+ 0x2: fcvt_l_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+
+ if (std::isnan(fs1)) {
+ Rd_sd = std::numeric_limits<int64_t>::max();
+ FFLAGS |= FloatInvalid;
+ } else {
+ Rd_sd = (int64_t)fs1;
+ if (std::fetestexcept(FE_INVALID)) {
+ if (std::signbit(fs1)) {
+ Rd_sd = std::numeric_limits<int64_t>::min();
+ } else {
+ Rd_sd = std::numeric_limits<int64_t>::max();
+ }
+ std::feclearexcept(FE_INEXACT);
+ }
+ }
+ }}, FloatCvtOp);
+ 0x3: fcvt_lu_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+
+ if (fs1 < 0.0) {
+ Rd = 0;
+ FFLAGS |= FloatInvalid;
+ } else {
+ Rd = (uint64_t)fs1;
+ if (std::fetestexcept(FE_INVALID)) {
+ Rd = std::numeric_limits<uint64_t>::max();
+ std::feclearexcept(FE_INEXACT);
+ }
+ }
+ }}, FloatCvtOp);
+ }
+ 0x61: decode CONV_SGN {
+ 0x0: fcvt_w_d({{
+ Rd_sd = (int32_t)Fs1;
+ if (std::fetestexcept(FE_INVALID)) {
+ if (Fs1 < 0.0) {
+ Rd_sd = std::numeric_limits<int32_t>::min();
+ } else {
+ Rd_sd = std::numeric_limits<int32_t>::max();
+ }
+ std::feclearexcept(FE_INEXACT);
+ }
+ }}, FloatCvtOp);
+ 0x1: fcvt_wu_d({{
+ if (Fs1 < 0.0) {
+ Rd = 0;
+ FFLAGS |= FloatInvalid;
+ } else {
+ Rd = (uint32_t)Fs1;
+ if (std::fetestexcept(FE_INVALID)) {
+ Rd = std::numeric_limits<uint64_t>::max();
+ std::feclearexcept(FE_INEXACT);
+ }
+ }
+ }}, FloatCvtOp);
+ 0x2: fcvt_l_d({{
+ Rd_sd = Fs1;
+ if (std::fetestexcept(FE_INVALID)) {
+ if (Fs1 < 0.0) {
+ Rd_sd = std::numeric_limits<int64_t>::min();
+ } else {
+ Rd_sd = std::numeric_limits<int64_t>::max();
+ }
+ std::feclearexcept(FE_INEXACT);
+ }
+ }}, FloatCvtOp);
+ 0x3: fcvt_lu_d({{
+ if (Fs1 < 0.0) {
+ Rd = 0;
+ FFLAGS |= FloatInvalid;
+ } else {
+ Rd = (uint64_t)Fs1;
+ if (std::fetestexcept(FE_INVALID)) {
+ Rd = std::numeric_limits<uint64_t>::max();
+ std::feclearexcept(FE_INEXACT);
+ }
+ }
+ }}, FloatCvtOp);
+ }
+ 0x68: decode CONV_SGN {
+ 0x0: fcvt_s_w({{
+ float temp = (float)Rs1_sw;
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
+ }}, FloatCvtOp);
+ 0x1: fcvt_s_wu({{
+ float temp = (float)Rs1_uw;
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
+ }}, FloatCvtOp);
+ 0x2: fcvt_s_l({{
+ float temp = (float)Rs1_sd;
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
+ }}, FloatCvtOp);
+ 0x3: fcvt_s_lu({{
+ float temp = (float)Rs1;
+ Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
+ }}, FloatCvtOp);
+ }
+ 0x69: decode CONV_SGN {
+ 0x0: fcvt_d_w({{
+ Fd = (double)Rs1_sw;
+ }}, FloatCvtOp);
+ 0x1: fcvt_d_wu({{
+ Fd = (double)Rs1_uw;
+ }}, FloatCvtOp);
+ 0x2: fcvt_d_l({{
+ Fd = (double)Rs1_sd;
+ }}, FloatCvtOp);
+ 0x3: fcvt_d_lu({{
+ Fd = (double)Rs1;
+ }}, FloatCvtOp);
+ }
+ 0x70: decode ROUND_MODE {
+ 0x0: fmv_x_s({{
+ Rd = (uint32_t)Fs1_bits;
+ if ((Rd&0x80000000) != 0) {
+ Rd |= (0xFFFFFFFFULL << 32);
+ }
+ }}, FloatCvtOp);
+ 0x1: fclass_s({{
+ uint32_t temp;
+ float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
+ switch (std::fpclassify(fs1)) {
+ case FP_INFINITE:
+ if (std::signbit(fs1)) {
+ Rd = 1 << 0;
+ } else {
+ Rd = 1 << 7;
+ }
+ break;
+ case FP_NAN:
+ if (issignalingnan(fs1)) {
+ Rd = 1 << 8;
+ } else {
+ Rd = 1 << 9;
+ }
+ break;
+ case FP_ZERO:
+ if (std::signbit(fs1)) {
+ Rd = 1 << 3;
+ } else {
+ Rd = 1 << 4;
+ }
+ break;
+ case FP_SUBNORMAL:
+ if (std::signbit(fs1)) {
+ Rd = 1 << 2;
+ } else {
+ Rd = 1 << 5;
+ }
+ break;
+ case FP_NORMAL:
+ if (std::signbit(fs1)) {
+ Rd = 1 << 1;
+ } else {
+ Rd = 1 << 6;
+ }
+ break;
+ default:
+ panic("Unknown classification for operand.");
+ break;
+ }
+ }});
+ }
+ 0x71: decode ROUND_MODE {
+ 0x0: fmv_x_d({{
+ Rd = Fs1_bits;
+ }}, FloatCvtOp);
+ 0x1: fclass_d({{
+ switch (std::fpclassify(Fs1)) {
+ case FP_INFINITE:
+ if (std::signbit(Fs1)) {
+ Rd = 1 << 0;
+ } else {
+ Rd = 1 << 7;
+ }
+ break;
+ case FP_NAN:
+ if (issignalingnan(Fs1)) {
+ Rd = 1 << 8;
+ } else {
+ Rd = 1 << 9;
+ }
+ break;
+ case FP_ZERO:
+ if (std::signbit(Fs1)) {
+ Rd = 1 << 3;
+ } else {
+ Rd = 1 << 4;
+ }
+ break;
+ case FP_SUBNORMAL:
+ if (std::signbit(Fs1)) {
+ Rd = 1 << 2;
+ } else {
+ Rd = 1 << 5;
+ }
+ break;
+ case FP_NORMAL:
+ if (std::signbit(Fs1)) {
+ Rd = 1 << 1;
+ } else {
+ Rd = 1 << 6;
+ }
+ break;
+ default:
+ panic("Unknown classification for operand.");
+ break;
+ }
+ }});
+ }
+ 0x78: fmv_s_x({{
+ Fd_bits = (uint64_t)Rs1_uw;
+ }}, FloatCvtOp);
+ 0x79: fmv_d_x({{
+ Fd_bits = Rs1;
+ }}, FloatCvtOp);
+ }
+ }
0x63: decode FUNCT3 {
format SBOp {
0x0: beq({{