4c4
< // Copyright (c) 2016 The University of Virginia
---
> // Copyright (c) 2017 The University of Virginia
37,41c37,54
< decode OPCODE default Unknown::unknown() {
< 0x03: decode FUNCT3 {
< format Load {
< 0x0: lb({{
< Rd_sd = Mem_sb;
---
> decode QUADRANT default Unknown::unknown() {
> 0x0: decode COPCODE {
> 0x0: CUIOp::c_addi4spn({{
> imm = CIMM8<1:1> << 2 |
> CIMM8<0:0> << 3 |
> CIMM8<7:6> << 4 |
> CIMM8<5:2> << 6;
> }}, {{
> assert(imm != 0);
> Rp2 = sp + imm;
> }});
> format CompressedLoad {
> 0x1: c_fld({{
> ldisp = CIMM3 << 3 | CIMM2 << 6;
> }}, {{
> Fp2_bits = Mem;
> }}, {{
> EA = Rp1 + ldisp;
43,44c56,63
< 0x1: lh({{
< Rd_sd = Mem_sh;
---
> 0x2: c_lw({{
> ldisp = CIMM2<1:1> << 2 |
> CIMM3 << 3 |
> CIMM2<0:0> << 6;
> }}, {{
> Rp2_sd = Mem_sw;
> }}, {{
> EA = Rp1 + ldisp;
46,47c65,70
< 0x2: lw({{
< Rd_sd = Mem_sw;
---
> 0x3: c_ld({{
> ldisp = CIMM3 << 3 | CIMM2 << 6;
> }}, {{
> Rp2_sd = Mem_sd;
> }}, {{
> EA = Rp1 + ldisp;
49,50c72,79
< 0x3: ld({{
< Rd_sd = Mem_sd;
---
> }
> format CompressedStore {
> 0x5: c_fsd({{
> sdisp = CIMM3 << 3 | CIMM2 << 6;
> }}, {{
> Mem = Fp2_bits;
> }}, {{
> EA = Rp1 + sdisp;
52,53c81,88
< 0x4: lbu({{
< Rd = Mem_ub;
---
> 0x6: c_sw({{
> sdisp = CIMM2<1:1> << 2 |
> CIMM3 << 3 |
> CIMM2<0:0> << 6;
> }}, {{
> Mem_uw = Rp2_uw;
> }}, ea_code={{
> EA = Rp1 + sdisp;
55,56c90,95
< 0x5: lhu({{
< Rd = Mem_uh;
---
> 0x7: c_sd({{
> sdisp = CIMM3 << 3 | CIMM2 << 6;
> }}, {{
> Mem_ud = Rp2_ud;
> }}, {{
> EA = Rp1 + sdisp;
58,60d96
< 0x6: lwu({{
< Rd = Mem_uw;
< }});
63,67c99,107
<
< 0x07: decode FUNCT3 {
< format Load {
< 0x2: flw({{
< Fd_bits = (uint64_t)Mem_uw;
---
> 0x1: decode COPCODE {
> format CIOp {
> 0x0: c_addi({{
> imm = CIMM5;
> if (CIMM1 > 0)
> imm |= ~((uint64_t)0x1F);
> }}, {{
> assert((RC1 == 0) == (imm == 0));
> Rc1_sd = Rc1_sd + imm;
69,70c109,115
< 0x3: fld({{
< Fd_bits = Mem;
---
> 0x1: c_addiw({{
> imm = CIMM5;
> if (CIMM1 > 0)
> imm |= ~((uint64_t)0x1F);
> }}, {{
> assert(RC1 != 0);
> Rc1_sd = (int32_t)Rc1_sd + imm;
72,87c117,123
< }
< }
<
< 0x0f: decode FUNCT3 {
< format IOp {
< 0x0: fence({{
< }}, IsNonSpeculative, IsMemBarrier, No_OpClass);
< 0x1: fence_i({{
< }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
< }
< }
<
< 0x13: decode FUNCT3 {
< format IOp {
< 0x0: addi({{
< Rd_sd = Rs1_sd + imm;
---
> 0x2: c_li({{
> imm = CIMM5;
> if (CIMM1 > 0)
> imm |= ~((uint64_t)0x1F);
> }}, {{
> assert(RC1 != 0);
> Rc1_sd = imm;
89,103c125,135
< 0x1: slli({{
< Rd = Rs1 << SHAMT6;
< }});
< 0x2: slti({{
< Rd = (Rs1_sd < imm) ? 1 : 0;
< }});
< 0x3: sltiu({{
< Rd = (Rs1 < (uint64_t)imm) ? 1 : 0;
< }});
< 0x4: xori({{
< Rd = Rs1 ^ (uint64_t)imm;
< }});
< 0x5: decode SRTYPE {
< 0x0: srli({{
< Rd = Rs1 >> SHAMT6;
---
> 0x3: decode RC1 {
> 0x2: c_addi16sp({{
> imm = CIMM5<4:4> << 4 |
> CIMM5<0:0> << 5 |
> CIMM5<3:3> << 6 |
> CIMM5<2:1> << 7;
> if (CIMM1 > 0)
> imm |= ~((int64_t)0x1FF);
> }}, {{
> assert(imm != 0);
> sp_sd = sp_sd + imm;
105,106c137,144
< 0x1: srai({{
< Rd_sd = Rs1_sd >> SHAMT6;
---
> default: c_lui({{
> imm = CIMM5 << 12;
> if (CIMM1 > 0)
> imm |= ~((uint64_t)0x1FFFF);
> }}, {{
> assert(RC1 != 0 && RC1 != 2);
> assert(imm != 0);
> Rc1_sd = imm;
109,114d146
< 0x6: ori({{
< Rd = Rs1 | (uint64_t)imm;
< }});
< 0x7: andi({{
< Rd = Rs1 & (uint64_t)imm;
< }});
116,132c148,154
< }
<
< 0x17: UOp::auipc({{
< Rd = PC + imm;
< }});
<
< 0x1b: decode FUNCT3 {
< format IOp {
< 0x0: addiw({{
< Rd_sd = (int32_t)Rs1 + (int32_t)imm;
< }});
< 0x1: slliw({{
< Rd_sd = Rs1_sw << SHAMT5;
< }});
< 0x5: decode SRTYPE {
< 0x0: srliw({{
< Rd = Rs1_uw >> SHAMT5;
---
> 0x4: decode CFUNCT2HIGH {
> format CUIOp {
> 0x0: c_srli({{
> imm = CIMM5 | (CIMM1 << 5);
> assert(imm != 0);
> }}, {{
> Rp1 = Rp1 >> imm;
134,135c156,160
< 0x1: sraiw({{
< Rd_sd = Rs1_sw >> SHAMT5;
---
> 0x1: c_srai({{
> imm = CIMM5 | (CIMM1 << 5);
> assert(imm != 0);
> }}, {{
> Rp1_sd = Rp1_sd >> imm;
136a162,168
> 0x2: c_andi({{
> imm = CIMM5;
> if (CIMM1 > 0)
> imm |= ~((uint64_t)0x1F);
> }}, {{
> Rp1 = Rp1 & imm;
> }});
137a170,195
> format ROp {
> 0x3: decode CFUNCT1 {
> 0x0: decode CFUNCT2LOW {
> 0x0: c_sub({{
> Rp1 = Rp1 - Rp2;
> }});
> 0x1: c_xor({{
> Rp1 = Rp1 ^ Rp2;
> }});
> 0x2: c_or({{
> Rp1 = Rp1 | Rp2;
> }});
> 0x3: c_and({{
> Rp1 = Rp1 & Rp2;
> }});
> }
> 0x1: decode CFUNCT2LOW {
> 0x0: c_subw({{
> Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
> }});
> 0x1: c_addw({{
> Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
> }});
> }
> }
> }
139c197,216
< }
---
> 0x5: JOp::c_j({{
> int64_t offset = CJUMPIMM<3:1> << 1 |
> CJUMPIMM<9:9> << 4 |
> CJUMPIMM<0:0> << 5 |
> CJUMPIMM<5:5> << 6 |
> CJUMPIMM<4:4> << 7 |
> CJUMPIMM<8:7> << 8 |
> CJUMPIMM<6:6> << 10;
> if (CJUMPIMM<10:10> > 0)
> offset |= ~((int64_t)0x7FF);
> NPC = PC + offset;
> }}, IsIndirectControl, IsUncondControl, IsCall);
> format BOp {
> 0x6: c_beqz({{
> int64_t offset = CIMM5<2:1> << 1 |
> CIMM3<1:0> << 3 |
> CIMM5<0:0> << 5 |
> CIMM5<4:3> << 6;
> if (CIMM3<2:2> > 0)
> offset |= ~((int64_t)0xFF);
141,154c218,235
< 0x23: decode FUNCT3 {
< format Store {
< 0x0: sb({{
< Mem_ub = Rs2_ub;
< }});
< 0x1: sh({{
< Mem_uh = Rs2_uh;
< }});
< 0x2: sw({{
< Mem_uw = Rs2_uw;
< }});
< 0x3: sd({{
< Mem_ud = Rs2_ud;
< }});
---
> if (Rp1 == 0)
> NPC = PC + offset;
> else
> NPC = NPC;
> }}, IsDirectControl, IsCondControl);
> 0x7: c_bnez({{
> int64_t offset = CIMM5<2:1> << 1 |
> CIMM3<1:0> << 3 |
> CIMM5<0:0> << 5 |
> CIMM5<4:3> << 6;
> if (CIMM3<2:2> > 0)
> offset |= ~((int64_t)0xFF);
>
> if (Rp1 != 0)
> NPC = PC + offset;
> else
> NPC = NPC;
> }}, IsDirectControl, IsCondControl);
157,161c238,254
<
< 0x27: decode FUNCT3 {
< format Store {
< 0x2: fsw({{
< Mem_uw = (uint32_t)Fs2_bits;
---
> 0x2: decode COPCODE {
> 0x0: CUIOp::c_slli({{
> imm = CIMM5 | (CIMM1 << 5);
> assert(imm != 0);
> }}, {{
> assert(RC1 != 0);
> Rc1 = Rc1 << imm;
> }});
> format CompressedLoad {
> 0x1: c_fldsp({{
> ldisp = CIMM5<4:3> << 3 |
> CIMM1 << 5 |
> CIMM5<2:0> << 6;
> }}, {{
> Fc1_bits = Mem;
> }}, {{
> EA = sp + ldisp;
163,164c256,264
< 0x3: fsd({{
< Mem_ud = Fs2_bits;
---
> 0x2: c_lwsp({{
> ldisp = CIMM5<4:2> << 2 |
> CIMM1 << 5 |
> CIMM5<1:0> << 6;
> }}, {{
> assert(RC1 != 0);
> Rc1_sd = Mem_sw;
> }}, {{
> EA = sp + ldisp;
166,175c266,269
< }
< }
<
< 0x2f: decode FUNCT3 {
< 0x2: decode AMOFUNCT {
< 0x2: LoadReserved::lr_w({{
< Rd_sd = Mem_sw;
< }}, mem_flags=LLSC);
< 0x3: StoreCond::sc_w({{
< Mem_uw = Rs2_uw;
---
> 0x3: c_ldsp({{
> ldisp = CIMM5<4:3> << 3 |
> CIMM1 << 5 |
> CIMM5<2:0> << 6;
177,215c271,286
< Rd = result;
< }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
< format AtomicMemOp {
< 0x0: amoadd_w({{Rt_sd = Mem_sw;}}, {{
< Mem_sw = Rs2_sw + Rt_sd;
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x1: amoswap_w({{Rt_sd = Mem_sw;}}, {{
< Mem_sw = Rs2_uw;
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x4: amoxor_w({{Rt_sd = Mem_sw;}}, {{
< Mem_sw = Rs2_uw^Rt_sd;
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x8: amoor_w({{Rt_sd = Mem_sw;}}, {{
< Mem_sw = Rs2_uw | Rt_sd;
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0xc: amoand_w({{Rt_sd = Mem_sw;}}, {{
< Mem_sw = Rs2_uw&Rt_sd;
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x10: amomin_w({{Rt_sd = Mem_sw;}}, {{
< Mem_sw = std::min<int32_t>(Rs2_sw, Rt_sd);
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x14: amomax_w({{Rt_sd = Mem_sw;}}, {{
< Mem_sw = std::max<int32_t>(Rs2_sw, Rt_sd);
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x18: amominu_w({{Rt_sd = Mem_sw;}}, {{
< Mem_sw = std::min<uint32_t>(Rs2_uw, Rt_sd);
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x1c: amomaxu_w({{Rt_sd = Mem_sw;}}, {{
< Mem_sw = std::max<uint32_t>(Rs2_uw, Rt_sd);
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
---
> assert(RC1 != 0);
> Rc1_sd = Mem_sd;
> }}, {{
> EA = sp + ldisp;
> }});
> }
> 0x4: decode CFUNCT1 {
> 0x0: decode RC2 {
> 0x0: Jump::c_jr({{
> assert(RC1 != 0);
> NPC = Rc1;
> }}, IsIndirectControl, IsUncondControl, IsCall);
> default: CROp::c_mv({{
> assert(RC1 != 0);
> Rc1 = Rc2;
> }});
216a288,303
> 0x1: decode RC1 {
> 0x0: SystemOp::c_ebreak({{
> assert(RC2 == 0);
> fault = make_shared<BreakpointFault>();
> }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
> default: decode RC2 {
> 0x0: Jump::c_jalr({{
> assert(RC1 != 0);
> ra = NPC;
> NPC = Rc1;
> }}, IsIndirectControl, IsUncondControl, IsCall);
> default: ROp::c_add({{
> Rc1_sd = Rc1_sd + Rc2_sd;
> }});
> }
> }
218,223c305,308
< 0x3: decode AMOFUNCT {
< 0x2: LoadReserved::lr_d({{
< Rd_sd = Mem_sd;
< }}, mem_flags=LLSC);
< 0x3: StoreCond::sc_d({{
< Mem = Rs2;
---
> format CompressedStore {
> 0x5: c_fsdsp({{
> sdisp = CIMM6<5:3> << 3 |
> CIMM6<2:0> << 6;
225,264c310,329
< Rd = result;
< }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
< format AtomicMemOp {
< 0x0: amoadd_d({{Rt_sd = Mem_sd;}}, {{
< Mem_sd = Rs2_sd + Rt_sd;
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x1: amoswap_d({{Rt = Mem;}}, {{
< Mem = Rs2;
< Rd = Rt;
< }}, {{EA = Rs1;}});
< 0x4: amoxor_d({{Rt = Mem;}}, {{
< Mem = Rs2^Rt;
< Rd = Rt;
< }}, {{EA = Rs1;}});
< 0x8: amoor_d({{Rt = Mem;}}, {{
< Mem = Rs2 | Rt;
< Rd = Rt;
< }}, {{EA = Rs1;}});
< 0xc: amoand_d({{Rt = Mem;}}, {{
< Mem = Rs2&Rt;
< Rd = Rt;
< }}, {{EA = Rs1;}});
< 0x10: amomin_d({{Rt_sd = Mem_sd;}}, {{
< Mem_sd = std::min(Rs2_sd, Rt_sd);
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x14: amomax_d({{Rt_sd = Mem_sd;}}, {{
< Mem_sd = std::max(Rs2_sd, Rt_sd);
< Rd_sd = Rt_sd;
< }}, {{EA = Rs1;}});
< 0x18: amominu_d({{Rt = Mem;}}, {{
< Mem = std::min(Rs2, Rt);
< Rd = Rt;
< }}, {{EA = Rs1;}});
< 0x1c: amomaxu_d({{Rt = Mem;}}, {{
< Mem = std::max(Rs2, Rt);
< Rd = Rt;
< }}, {{EA = Rs1;}});
< }
---
> Mem_ud = Fc2_bits;
> }}, {{
> EA = sp + sdisp;
> }});
> 0x6: c_swsp({{
> sdisp = CIMM6<5:2> << 2 |
> CIMM6<1:0> << 6;
> }}, {{
> Mem_uw = Rc2_uw;
> }}, {{
> EA = sp + sdisp;
> }});
> 0x7: c_sdsp({{
> sdisp = CIMM6<5:3> << 3 |
> CIMM6<2:0> << 6;
> }}, {{
> Mem = Rc2;
> }}, {{
> EA = sp + sdisp;
> }});
267,271c332,336
< 0x33: decode FUNCT3 {
< format ROp {
< 0x0: decode FUNCT7 {
< 0x0: add({{
< Rd = Rs1_sd + Rs2_sd;
---
> 0x3: decode OPCODE {
> 0x00: decode FUNCT3 {
> format Load {
> 0x0: lb({{
> Rd_sd = Mem_sb;
273,277c338,339
< 0x1: mul({{
< Rd = Rs1_sd*Rs2_sd;
< }}, IntMultOp);
< 0x20: sub({{
< Rd = Rs1_sd - Rs2_sd;
---
> 0x1: lh({{
> Rd_sd = Mem_sh;
279,282c341,342
< }
< 0x1: decode FUNCT7 {
< 0x0: sll({{
< Rd = Rs1 << Rs2<5:0>;
---
> 0x2: lw({{
> Rd_sd = Mem_sw;
284,305c344,345
< 0x1: mulh({{
< bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
<
< uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
< uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
< uint64_t Rs2_lo = (uint32_t)std::abs(Rs2_sd);
< uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd) >> 32;
<
< uint64_t hi = Rs1_hi*Rs2_hi;
< uint64_t mid1 = Rs1_hi*Rs2_lo;
< uint64_t mid2 = Rs1_lo*Rs2_hi;
< uint64_t lo = Rs2_lo*Rs1_lo;
< uint64_t carry = ((uint64_t)(uint32_t)mid1
< + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
<
< uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
< Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0) : res;
< }}, IntMultOp);
< }
< 0x2: decode FUNCT7 {
< 0x0: slt({{
< Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
---
> 0x3: ld({{
> Rd_sd = Mem_sd;
307,327c347,348
< 0x1: mulhsu({{
< bool negate = Rs1_sd < 0;
< uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
< uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
< uint64_t Rs2_lo = (uint32_t)Rs2;
< uint64_t Rs2_hi = Rs2 >> 32;
<
< uint64_t hi = Rs1_hi*Rs2_hi;
< uint64_t mid1 = Rs1_hi*Rs2_lo;
< uint64_t mid2 = Rs1_lo*Rs2_hi;
< uint64_t lo = Rs1_lo*Rs2_lo;
< uint64_t carry = ((uint64_t)(uint32_t)mid1
< + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
<
< uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
< Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
< }}, IntMultOp);
< }
< 0x3: decode FUNCT7 {
< 0x0: sltu({{
< Rd = (Rs1 < Rs2) ? 1 : 0;
---
> 0x4: lbu({{
> Rd = Mem_ub;
329,347c350,351
< 0x1: mulhu({{
< uint64_t Rs1_lo = (uint32_t)Rs1;
< uint64_t Rs1_hi = Rs1 >> 32;
< uint64_t Rs2_lo = (uint32_t)Rs2;
< uint64_t Rs2_hi = Rs2 >> 32;
<
< uint64_t hi = Rs1_hi*Rs2_hi;
< uint64_t mid1 = Rs1_hi*Rs2_lo;
< uint64_t mid2 = Rs1_lo*Rs2_hi;
< uint64_t lo = Rs1_lo*Rs2_lo;
< uint64_t carry = ((uint64_t)(uint32_t)mid1
< + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
<
< Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
< }}, IntMultOp);
< }
< 0x4: decode FUNCT7 {
< 0x0: xor({{
< Rd = Rs1 ^ Rs2;
---
> 0x5: lhu({{
> Rd = Mem_uh;
349,362c353,354
< 0x1: div({{
< if (Rs2_sd == 0) {
< Rd_sd = -1;
< } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
< && Rs2_sd == -1) {
< Rd_sd = std::numeric_limits<int64_t>::min();
< } else {
< Rd_sd = Rs1_sd/Rs2_sd;
< }
< }}, IntDivOp);
< }
< 0x5: decode FUNCT7 {
< 0x0: srl({{
< Rd = Rs1 >> Rs2<5:0>;
---
> 0x6: lwu({{
> Rd = Mem_uw;
364,373d355
< 0x1: divu({{
< if (Rs2 == 0) {
< Rd = std::numeric_limits<uint64_t>::max();
< } else {
< Rd = Rs1/Rs2;
< }
< }}, IntDivOp);
< 0x20: sra({{
< Rd_sd = Rs1_sd >> Rs2<5:0>;
< }});
375,377c357,362
< 0x6: decode FUNCT7 {
< 0x0: or({{
< Rd = Rs1 | Rs2;
---
> }
>
> 0x01: decode FUNCT3 {
> format Load {
> 0x2: flw({{
> Fd_bits = (uint64_t)Mem_uw;
379,392c364,365
< 0x1: rem({{
< if (Rs2_sd == 0) {
< Rd = Rs1_sd;
< } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
< && Rs2_sd == -1) {
< Rd = 0;
< } else {
< Rd = Rs1_sd%Rs2_sd;
< }
< }}, IntDivOp);
< }
< 0x7: decode FUNCT7 {
< 0x0: and({{
< Rd = Rs1 & Rs2;
---
> 0x3: fld({{
> Fd_bits = Mem;
394,400d366
< 0x1: remu({{
< if (Rs2 == 0) {
< Rd = Rs1;
< } else {
< Rd = Rs1%Rs2;
< }
< }}, IntDivOp);
403d368
< }
405,407c370,377
< 0x37: UOp::lui({{
< Rd = (uint64_t)imm;
< }});
---
> 0x03: decode FUNCT3 {
> format IOp {
> 0x0: fence({{
> }}, IsNonSpeculative, IsMemBarrier, No_OpClass);
> 0x1: fence_i({{
> }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
> }
> }
409,413c379,382
< 0x3b: decode FUNCT3 {
< format ROp {
< 0x0: decode FUNCT7 {
< 0x0: addw({{
< Rd_sd = Rs1_sw + Rs2_sw;
---
> 0x04: decode FUNCT3 {
> format IOp {
> 0x0: addi({{
> Rd_sd = Rs1_sd + imm;
415,419c384,385
< 0x1: mulw({{
< Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
< }}, IntMultOp);
< 0x20: subw({{
< Rd_sd = Rs1_sw - Rs2_sw;
---
> 0x1: slli({{
> Rd = Rs1 << SHAMT6;
421,432c387,402
< }
< 0x1: sllw({{
< Rd_sd = Rs1_sw << Rs2<4:0>;
< }});
< 0x4: divw({{
< if (Rs2_sw == 0) {
< Rd_sd = -1;
< } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
< && Rs2_sw == -1) {
< Rd_sd = std::numeric_limits<int32_t>::min();
< } else {
< Rd_sd = Rs1_sw/Rs2_sw;
---
> 0x2: slti({{
> Rd = (Rs1_sd < imm) ? 1 : 0;
> }});
> 0x3: sltiu({{
> Rd = (Rs1 < (uint64_t)imm) ? 1 : 0;
> }});
> 0x4: xori({{
> Rd = Rs1 ^ (uint64_t)imm;
> }});
> 0x5: decode SRTYPE {
> 0x0: srli({{
> Rd = Rs1 >> SHAMT6;
> }});
> 0x1: srai({{
> Rd_sd = Rs1_sd >> SHAMT6;
> }});
434,437c404,405
< }}, IntDivOp);
< 0x5: decode FUNCT7 {
< 0x0: srlw({{
< Rd_uw = Rs1_uw >> Rs2<4:0>;
---
> 0x6: ori({{
> Rd = Rs1 | (uint64_t)imm;
439,447c407,408
< 0x1: divuw({{
< if (Rs2_uw == 0) {
< Rd_sd = std::numeric_limits<IntReg>::max();
< } else {
< Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
< }
< }}, IntDivOp);
< 0x20: sraw({{
< Rd_sd = Rs1_sw >> Rs2<4:0>;
---
> 0x7: andi({{
> Rd = Rs1 & (uint64_t)imm;
450,466d410
< 0x6: remw({{
< if (Rs2_sw == 0) {
< Rd_sd = Rs1_sw;
< } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
< && Rs2_sw == -1) {
< Rd_sd = 0;
< } else {
< Rd_sd = Rs1_sw%Rs2_sw;
< }
< }}, IntDivOp);
< 0x7: remuw({{
< if (Rs2_uw == 0) {
< Rd_sd = (int32_t)Rs1_uw;
< } else {
< Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
< }
< }}, IntDivOp);
468d411
< }
470,477c413,415
< format FPROp {
< 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;
---
> 0x05: UOp::auipc({{
> Rd = PC + imm;
> }});
479,497c417,431
< 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;
---
> 0x06: decode FUNCT3 {
> format IOp {
> 0x0: addiw({{
> Rd_sd = (int32_t)Rs1 + (int32_t)imm;
> }});
> 0x1: slliw({{
> Rd_sd = Rs1_sw << SHAMT5;
> }});
> 0x5: decode SRTYPE {
> 0x0: srliw({{
> Rd = Rs1_uw >> SHAMT5;
> }});
> 0x1: sraiw({{
> Rd_sd = Rs1_sw >> SHAMT5;
> }});
499,522c433
< 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);
---
> }
524,530d434
< 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;
532,575c436,450
< 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);
---
> 0x08: decode FUNCT3 {
> format Store {
> 0x0: sb({{
> Mem_ub = Rs2_ub;
> }});
> 0x1: sh({{
> Mem_uh = Rs2_uh;
> }});
> 0x2: sw({{
> Mem_uw = Rs2_uw;
> }});
> 0x3: sd({{
> Mem_ud = Rs2_ud;
> }});
> }
577,583d451
< 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;
585,628c453,461
< 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);
---
> 0x09: decode FUNCT3 {
> format Store {
> 0x2: fsw({{
> Mem_uw = (uint32_t)Fs2_bits;
> }});
> 0x3: fsd({{
> Mem_ud = Fs2_bits;
> }});
> }
630,636d462
< 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;
638,656c464,510
< 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);
---
> 0x0b: decode FUNCT3 {
> 0x2: decode AMOFUNCT {
> 0x2: LoadReserved::lr_w({{
> Rd_sd = Mem_sw;
> }}, mem_flags=LLSC);
> 0x3: StoreCond::sc_w({{
> Mem_uw = Rs2_uw;
> }}, {{
> Rd = result;
> }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
> format AtomicMemOp {
> 0x0: amoadd_w({{Rt_sd = Mem_sw;}}, {{
> Mem_sw = Rs2_sw + Rt_sd;
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x1: amoswap_w({{Rt_sd = Mem_sw;}}, {{
> Mem_sw = Rs2_uw;
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x4: amoxor_w({{Rt_sd = Mem_sw;}}, {{
> Mem_sw = Rs2_uw^Rt_sd;
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x8: amoor_w({{Rt_sd = Mem_sw;}}, {{
> Mem_sw = Rs2_uw | Rt_sd;
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0xc: amoand_w({{Rt_sd = Mem_sw;}}, {{
> Mem_sw = Rs2_uw&Rt_sd;
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x10: amomin_w({{Rt_sd = Mem_sw;}}, {{
> Mem_sw = min<int32_t>(Rs2_sw, Rt_sd);
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x14: amomax_w({{Rt_sd = Mem_sw;}}, {{
> Mem_sw = max<int32_t>(Rs2_sw, Rt_sd);
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x18: amominu_w({{Rt_sd = Mem_sw;}}, {{
> Mem_sw = min<uint32_t>(Rs2_uw, Rt_sd);
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x1c: amomaxu_w({{Rt_sd = Mem_sw;}}, {{
> Mem_sw = max<uint32_t>(Rs2_uw, Rt_sd);
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
658,679c512,558
< 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);
---
> }
> 0x3: decode AMOFUNCT {
> 0x2: LoadReserved::lr_d({{
> Rd_sd = Mem_sd;
> }}, mem_flags=LLSC);
> 0x3: StoreCond::sc_d({{
> Mem = Rs2;
> }}, {{
> Rd = result;
> }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
> format AtomicMemOp {
> 0x0: amoadd_d({{Rt_sd = Mem_sd;}}, {{
> Mem_sd = Rs2_sd + Rt_sd;
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x1: amoswap_d({{Rt = Mem;}}, {{
> Mem = Rs2;
> Rd = Rt;
> }}, {{EA = Rs1;}});
> 0x4: amoxor_d({{Rt = Mem;}}, {{
> Mem = Rs2^Rt;
> Rd = Rt;
> }}, {{EA = Rs1;}});
> 0x8: amoor_d({{Rt = Mem;}}, {{
> Mem = Rs2 | Rt;
> Rd = Rt;
> }}, {{EA = Rs1;}});
> 0xc: amoand_d({{Rt = Mem;}}, {{
> Mem = Rs2&Rt;
> Rd = Rt;
> }}, {{EA = Rs1;}});
> 0x10: amomin_d({{Rt_sd = Mem_sd;}}, {{
> Mem_sd = min(Rs2_sd, Rt_sd);
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x14: amomax_d({{Rt_sd = Mem_sd;}}, {{
> Mem_sd = max(Rs2_sd, Rt_sd);
> Rd_sd = Rt_sd;
> }}, {{EA = Rs1;}});
> 0x18: amominu_d({{Rt = Mem;}}, {{
> Mem = min(Rs2, Rt);
> Rd = Rt;
> }}, {{EA = Rs1;}});
> 0x1c: amomaxu_d({{Rt = Mem;}}, {{
> Mem = max(Rs2, Rt);
> Rd = Rt;
> }}, {{EA = Rs1;}});
681c560
< }}, FloatMultOp);
---
> }
682a562,580
> 0x0c: decode FUNCT3 {
> format ROp {
> 0x0: decode FUNCT7 {
> 0x0: add({{
> Rd = Rs1_sd + Rs2_sd;
> }});
> 0x1: mul({{
> Rd = Rs1_sd*Rs2_sd;
> }}, IntMultOp);
> 0x20: sub({{
> Rd = Rs1_sd - Rs2_sd;
> }});
> }
> 0x1: decode FUNCT7 {
> 0x0: sll({{
> Rd = Rs1 << Rs2<5:0>;
> }});
> 0x1: mulh({{
> bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
684,689c582,585
< 0x53: decode FUNCT7 {
< 0x0: fadd_s({{
< uint32_t temp;
< float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
< float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
< float fd;
---
> uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
> uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
> uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd);
> uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
691,697c587,600
< 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;
---
> uint64_t hi = Rs1_hi*Rs2_hi;
> uint64_t mid1 = Rs1_hi*Rs2_lo;
> uint64_t mid2 = Rs1_lo*Rs2_hi;
> uint64_t lo = Rs2_lo*Rs1_lo;
> uint64_t carry = ((uint64_t)(uint32_t)mid1
> + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
>
> uint64_t res = hi +
> (mid1 >> 32) +
> (mid2 >> 32) +
> carry;
> Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
> : res;
> }}, IntMultOp);
699,708c602,625
< 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;
---
> 0x2: decode FUNCT7 {
> 0x0: slt({{
> Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
> }});
> 0x1: mulhsu({{
> bool negate = Rs1_sd < 0;
> uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
> uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
> uint64_t Rs2_lo = (uint32_t)Rs2;
> uint64_t Rs2_hi = Rs2 >> 32;
>
> uint64_t hi = Rs1_hi*Rs2_hi;
> uint64_t mid1 = Rs1_hi*Rs2_lo;
> uint64_t mid2 = Rs1_lo*Rs2_hi;
> uint64_t lo = Rs1_lo*Rs2_lo;
> uint64_t carry = ((uint64_t)(uint32_t)mid1
> + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
>
> uint64_t res = hi +
> (mid1 >> 32) +
> (mid2 >> 32) +
> carry;
> Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
> }}, IntMultOp);
710,715c627,635
< }}, 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;
---
> 0x3: decode FUNCT7 {
> 0x0: sltu({{
> Rd = (Rs1 < Rs2) ? 1 : 0;
> }});
> 0x1: mulhu({{
> uint64_t Rs1_lo = (uint32_t)Rs1;
> uint64_t Rs1_hi = Rs1 >> 32;
> uint64_t Rs2_lo = (uint32_t)Rs2;
> uint64_t Rs2_hi = Rs2 >> 32;
717,723c637,645
< 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;
---
> uint64_t hi = Rs1_hi*Rs2_hi;
> uint64_t mid1 = Rs1_hi*Rs2_lo;
> uint64_t mid2 = Rs1_lo*Rs2_hi;
> uint64_t lo = Rs1_lo*Rs2_lo;
> uint64_t carry = ((uint64_t)(uint32_t)mid1
> + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
>
> Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
> }}, IntMultOp);
725,734c647,660
< 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;
---
> 0x4: decode FUNCT7 {
> 0x0: xor({{
> Rd = Rs1 ^ Rs2;
> }});
> 0x1: div({{
> if (Rs2_sd == 0) {
> Rd_sd = -1;
> } else if (Rs1_sd == numeric_limits<int64_t>::min()
> && Rs2_sd == -1) {
> Rd_sd = numeric_limits<int64_t>::min();
> } else {
> Rd_sd = Rs1_sd/Rs2_sd;
> }
> }}, IntDivOp);
736,749c662,675
< }}, 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;
---
> 0x5: decode FUNCT7 {
> 0x0: srl({{
> Rd = Rs1 >> Rs2<5:0>;
> }});
> 0x1: divu({{
> if (Rs2 == 0) {
> Rd = numeric_limits<uint64_t>::max();
> } else {
> Rd = Rs1/Rs2;
> }
> }}, IntDivOp);
> 0x20: sra({{
> Rd_sd = Rs1_sd >> Rs2<5:0>;
> }});
751,760c677,690
< 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;
---
> 0x6: decode FUNCT7 {
> 0x0: or({{
> Rd = Rs1 | Rs2;
> }});
> 0x1: rem({{
> if (Rs2_sd == 0) {
> Rd = Rs1_sd;
> } else if (Rs1_sd == numeric_limits<int64_t>::min()
> && Rs2_sd == -1) {
> Rd = 0;
> } else {
> Rd = Rs1_sd%Rs2_sd;
> }
> }}, IntDivOp);
762,767c692,705
< }}, 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;
---
> 0x7: decode FUNCT7 {
> 0x0: and({{
> Rd = Rs1 & Rs2;
> }});
> 0x1: remu({{
> if (Rs2 == 0) {
> Rd = Rs1;
> } else {
> Rd = Rs1%Rs2;
> }
> }}, IntDivOp);
> }
> }
> }
769,775c707,722
< 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;
---
> 0x0d: UOp::lui({{
> Rd = (uint64_t)imm;
> }});
>
> 0x0e: decode FUNCT3 {
> format ROp {
> 0x0: decode FUNCT7 {
> 0x0: addw({{
> Rd_sd = Rs1_sw + Rs2_sw;
> }});
> 0x1: mulw({{
> Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
> }}, IntMultOp);
> 0x20: subw({{
> Rd_sd = Rs1_sw - Rs2_sw;
> }});
777,782c724,734
< 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;
---
> 0x1: sllw({{
> Rd_sd = Rs1_sw << Rs2<4:0>;
> }});
> 0x4: divw({{
> if (Rs2_sw == 0) {
> Rd_sd = -1;
> } else if (Rs1_sw == numeric_limits<int32_t>::min()
> && Rs2_sw == -1) {
> Rd_sd = numeric_limits<int32_t>::min();
> } else {
> Rd_sd = Rs1_sw/Rs2_sw;
784,786c736,750
< Fd = std::numeric_limits<double>::quiet_NaN();
< } else {
< Fd = Fs1/Fs2;
---
> }}, IntDivOp);
> 0x5: decode FUNCT7 {
> 0x0: srlw({{
> Rd_uw = Rs1_uw >> Rs2<4:0>;
> }});
> 0x1: divuw({{
> if (Rs2_uw == 0) {
> Rd_sd = numeric_limits<IntReg>::max();
> } else {
> Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
> }
> }}, IntDivOp);
> 0x20: sraw({{
> Rd_sd = Rs1_sw >> Rs2<4:0>;
> }});
788,790c752,774
< }}, FloatDivOp);
< 0x10: decode ROUND_MODE {
< 0x0: fsgnj_s({{
---
> 0x6: remw({{
> if (Rs2_sw == 0) {
> Rd_sd = Rs1_sw;
> } else if (Rs1_sw == numeric_limits<int32_t>::min()
> && Rs2_sw == -1) {
> Rd_sd = 0;
> } else {
> Rd_sd = Rs1_sw%Rs2_sw;
> }
> }}, IntDivOp);
> 0x7: remuw({{
> if (Rs2_uw == 0) {
> Rd_sd = (int32_t)Rs1_uw;
> } else {
> Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
> }
> }}, IntDivOp);
> }
> }
>
> format FPROp {
> 0x10: decode FUNCT2 {
> 0x0: fmadd_s({{
793a778
> float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
796,798c781,797
< if (issignalingnan(fs1)) {
< fd = std::numeric_limits<float>::signaling_NaN();
< std::feclearexcept(FE_INVALID);
---
> if (isnan(fs1) || isnan(fs2) || isnan(fs3)) {
> if (issignalingnan(fs1) || issignalingnan(fs2)
> || issignalingnan(fs3)) {
> FFLAGS |= FloatInvalid;
> }
> fd = numeric_limits<float>::quiet_NaN();
> } else if (isinf(fs1) || isinf(fs2) ||
> isinf(fs3)) {
> if (signbit(fs1) == signbit(fs2)
> && !isinf(fs3)) {
> fd = numeric_limits<float>::infinity();
> } else if (signbit(fs1) != signbit(fs2)
> && !isinf(fs3)) {
> fd = -numeric_limits<float>::infinity();
> } else { // Fs3_sf is infinity
> fd = fs3;
> }
800c799
< fd = std::copysign(fs1, fs2);
---
> fd = fs1*fs2 + fs3;
803,804c802,827
< }});
< 0x1: fsgnjn_s({{
---
> }}, FloatMultOp);
> 0x1: fmadd_d({{
> if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) {
> if (issignalingnan(Fs1) || issignalingnan(Fs2)
> || issignalingnan(Fs3)) {
> FFLAGS |= FloatInvalid;
> }
> Fd = numeric_limits<double>::quiet_NaN();
> } else if (isinf(Fs1) || isinf(Fs2) ||
> isinf(Fs3)) {
> if (signbit(Fs1) == signbit(Fs2)
> && !isinf(Fs3)) {
> Fd = numeric_limits<double>::infinity();
> } else if (signbit(Fs1) != signbit(Fs2)
> && !isinf(Fs3)) {
> Fd = -numeric_limits<double>::infinity();
> } else {
> Fd = Fs3;
> }
> } else {
> Fd = Fs1*Fs2 + Fs3;
> }
> }}, FloatMultOp);
> }
> 0x11: decode FUNCT2 {
> 0x0: fmsub_s({{
807a831
> float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
810,812c834,850
< if (issignalingnan(fs1)) {
< fd = std::numeric_limits<float>::signaling_NaN();
< std::feclearexcept(FE_INVALID);
---
> if (isnan(fs1) || isnan(fs2) || isnan(fs3)) {
> if (issignalingnan(fs1) || issignalingnan(fs2)
> || issignalingnan(fs3)) {
> FFLAGS |= FloatInvalid;
> }
> fd = numeric_limits<float>::quiet_NaN();
> } else if (isinf(fs1) || isinf(fs2) ||
> isinf(fs3)) {
> if (signbit(fs1) == signbit(fs2)
> && !isinf(fs3)) {
> fd = numeric_limits<float>::infinity();
> } else if (signbit(fs1) != signbit(fs2)
> && !isinf(fs3)) {
> fd = -numeric_limits<float>::infinity();
> } else { // Fs3_sf is infinity
> fd = -fs3;
> }
814c852
< fd = std::copysign(fs1, -fs2);
---
> fd = fs1*fs2 - fs3;
817,818c855,880
< }});
< 0x2: fsgnjx_s({{
---
> }}, FloatMultOp);
> 0x1: fmsub_d({{
> if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) {
> if (issignalingnan(Fs1) || issignalingnan(Fs2)
> || issignalingnan(Fs3)) {
> FFLAGS |= FloatInvalid;
> }
> Fd = numeric_limits<double>::quiet_NaN();
> } else if (isinf(Fs1) || isinf(Fs2) ||
> isinf(Fs3)) {
> if (signbit(Fs1) == signbit(Fs2)
> && !isinf(Fs3)) {
> Fd = numeric_limits<double>::infinity();
> } else if (signbit(Fs1) != signbit(Fs2)
> && !isinf(Fs3)) {
> Fd = -numeric_limits<double>::infinity();
> } else {
> Fd = -Fs3;
> }
> } else {
> Fd = Fs1*Fs2 - Fs3;
> }
> }}, FloatMultOp);
> }
> 0x12: decode FUNCT2 {
> 0x0: fnmsub_s({{
821a884
> float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
824,826c887,903
< if (issignalingnan(fs1)) {
< fd = std::numeric_limits<float>::signaling_NaN();
< std::feclearexcept(FE_INVALID);
---
> if (isnan(fs1) || isnan(fs2) || isnan(fs3)) {
> if (issignalingnan(fs1) || issignalingnan(fs2)
> || issignalingnan(fs3)) {
> FFLAGS |= FloatInvalid;
> }
> fd = numeric_limits<float>::quiet_NaN();
> } else if (isinf(fs1) || isinf(fs2) ||
> isinf(fs3)) {
> if (signbit(fs1) == signbit(fs2)
> && !isinf(fs3)) {
> fd = -numeric_limits<float>::infinity();
> } else if (signbit(fs1) != signbit(fs2)
> && !isinf(fs3)) {
> fd = numeric_limits<float>::infinity();
> } else { // Fs3_sf is infinity
> fd = fs3;
> }
828c905
< fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0);
---
> fd = -(fs1*fs2 - fs3);
831,837c908,926
< }});
< }
< 0x11: decode ROUND_MODE {
< 0x0: fsgnj_d({{
< if (issignalingnan(Fs1)) {
< Fd = std::numeric_limits<double>::signaling_NaN();
< std::feclearexcept(FE_INVALID);
---
> }}, FloatMultOp);
> 0x1: fnmsub_d({{
> if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) {
> if (issignalingnan(Fs1) || issignalingnan(Fs2)
> || issignalingnan(Fs3)) {
> FFLAGS |= FloatInvalid;
> }
> Fd = numeric_limits<double>::quiet_NaN();
> } else if (isinf(Fs1) || isinf(Fs2)
> || isinf(Fs3)) {
> if (signbit(Fs1) == signbit(Fs2)
> && !isinf(Fs3)) {
> Fd = -numeric_limits<double>::infinity();
> } else if (signbit(Fs1) != signbit(Fs2)
> && !isinf(Fs3)) {
> Fd = numeric_limits<double>::infinity();
> } else {
> Fd = Fs3;
> }
839c928
< Fd = std::copysign(Fs1, Fs2);
---
> Fd = -(Fs1*Fs2 - Fs3);
841,857c930
< }});
< 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);
< }
< }});
---
> }}, FloatMultOp);
859,860c932,933
< 0x14: decode ROUND_MODE {
< 0x0: fmin_s({{
---
> 0x13: decode FUNCT2 {
> 0x0: fnmadd_s({{
863a937
> float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
866,871c940,956
< if (issignalingnan(fs2)) {
< fd = fs1;
< FFLAGS |= FloatInvalid;
< } else if (issignalingnan(fs1)) {
< fd = fs2;
< FFLAGS |= FloatInvalid;
---
> if (isnan(fs1) || isnan(fs2) || isnan(fs3)) {
> if (issignalingnan(fs1) || issignalingnan(fs2)
> || issignalingnan(fs3)) {
> FFLAGS |= FloatInvalid;
> }
> fd = numeric_limits<float>::quiet_NaN();
> } else if (isinf(fs1) || isinf(fs2) ||
> isinf(fs3)) {
> if (signbit(fs1) == signbit(fs2)
> && !isinf(fs3)) {
> fd = -numeric_limits<float>::infinity();
> } else if (signbit(fs1) != signbit(fs2)
> && !isinf(fs3)) {
> fd = numeric_limits<float>::infinity();
> } else { // Fs3_sf is infinity
> fd = -fs3;
> }
873c958
< fd = std::fmin(fs1, fs2);
---
> fd = -(fs1*fs2 + fs3);
876,877c961,986
< }}, FloatCmpOp);
< 0x1: fmax_s({{
---
> }}, FloatMultOp);
> 0x1: fnmadd_d({{
> if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) {
> if (issignalingnan(Fs1) || issignalingnan(Fs2)
> || issignalingnan(Fs3)) {
> FFLAGS |= FloatInvalid;
> }
> Fd = numeric_limits<double>::quiet_NaN();
> } else if (isinf(Fs1) || isinf(Fs2) ||
> isinf(Fs3)) {
> if (signbit(Fs1) == signbit(Fs2)
> && !isinf(Fs3)) {
> Fd = -numeric_limits<double>::infinity();
> } else if (signbit(Fs1) != signbit(Fs2)
> && !isinf(Fs3)) {
> Fd = numeric_limits<double>::infinity();
> } else {
> Fd = -Fs3;
> }
> } else {
> Fd = -(Fs1*Fs2 + Fs3);
> }
> }}, FloatMultOp);
> }
> 0x14: decode FUNCT7 {
> 0x0: fadd_s({{
883,888c992,996
< if (issignalingnan(fs2)) {
< fd = fs1;
< FFLAGS |= FloatInvalid;
< } else if (issignalingnan(fs1)) {
< fd = fs2;
< FFLAGS |= FloatInvalid;
---
> if (isnan(fs1) || isnan(fs2)) {
> if (issignalingnan(fs1) || issignalingnan(fs2)) {
> FFLAGS |= FloatInvalid;
> }
> fd = numeric_limits<float>::quiet_NaN();
890c998
< fd = std::fmax(fs1, fs2);
---
> fd = fs1 + fs2;
893,902c1001,1007
< }}, FloatCmpOp);
< }
< 0x15: decode ROUND_MODE {
< 0x0: fmin_d({{
< if (issignalingnan(Fs2)) {
< Fd = Fs1;
< FFLAGS |= FloatInvalid;
< } else if (issignalingnan(Fs1)) {
< Fd = Fs2;
< FFLAGS |= FloatInvalid;
---
> }}, FloatAddOp);
> 0x1: fadd_d({{
> if (isnan(Fs1) || isnan(Fs2)) {
> if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
> FFLAGS |= FloatInvalid;
> }
> Fd = numeric_limits<double>::quiet_NaN();
904c1009
< Fd = std::fmin(Fs1, Fs2);
---
> Fd = Fs1 + Fs2;
906,959c1011,1012
< }}, 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({{
---
> }}, FloatAddOp);
> 0x4: fsub_s({{
962a1016
> float fd;
964,966c1018,1022
< if (std::isnan(fs1) || std::isnan(fs2)) {
< FFLAGS |= FloatInvalid;
< Rd = 0;
---
> if (isnan(fs1) || isnan(fs2)) {
> if (issignalingnan(fs1) || issignalingnan(fs2)) {
> FFLAGS |= FloatInvalid;
> }
> fd = numeric_limits<float>::quiet_NaN();
968c1024
< Rd = fs1 <= fs2 ? 1 : 0;
---
> fd = fs1 - fs2;
970,978c1026,1033
< }}, 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;
---
> Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
> }}, FloatAddOp);
> 0x5: fsub_d({{
> if (isnan(Fs1) || isnan(Fs2)) {
> if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
> FFLAGS |= FloatInvalid;
> }
> Fd = numeric_limits<double>::quiet_NaN();
980c1035
< Rd = fs1 < fs2 ? 1 : 0;
---
> Fd = Fs1 - Fs2;
982,983c1037,1038
< }}, FloatCmpOp);
< 0x2: feq_s({{
---
> }}, FloatAddOp);
> 0x8: fmul_s({{
986a1042
> float fd;
988,998c1044,1048
< 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;
---
> if (isnan(fs1) || isnan(fs2)) {
> if (issignalingnan(fs1) || issignalingnan(fs2)) {
> FFLAGS |= FloatInvalid;
> }
> fd = numeric_limits<float>::quiet_NaN();
1000c1050
< Rd = Fs1 <= Fs2 ? 1 : 0;
---
> fd = fs1*fs2;
1002,1006c1052,1059
< }}, FloatCmpOp);
< 0x1: flt_d({{
< if (std::isnan(Fs1) || std::isnan(Fs2)) {
< FFLAGS |= FloatInvalid;
< Rd = 0;
---
> Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
> }}, FloatMultOp);
> 0x9: fmul_d({{
> if (isnan(Fs1) || isnan(Fs2)) {
> if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
> FFLAGS |= FloatInvalid;
> }
> Fd = numeric_limits<double>::quiet_NaN();
1008c1061
< Rd = Fs1 < Fs2 ? 1 : 0;
---
> Fd = Fs1*Fs2;
1010,1019c1063,1064
< }}, 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({{
---
> }}, FloatMultOp);
> 0xc: fdiv_s({{
1021a1067,1068
> float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
> float fd;
1023,1025c1070,1074
< if (std::isnan(fs1)) {
< Rd_sd = std::numeric_limits<int32_t>::max();
< FFLAGS |= FloatInvalid;
---
> if (isnan(fs1) || isnan(fs2)) {
> if (issignalingnan(fs1) || issignalingnan(fs2)) {
> FFLAGS |= FloatInvalid;
> }
> fd = numeric_limits<float>::quiet_NaN();
1027,1034c1076,1083
< 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);
---
> fd = fs1/fs2;
> }
> Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
> }}, FloatDivOp);
> 0xd: fdiv_d({{
> if (isnan(Fs1) || isnan(Fs2)) {
> if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
> FFLAGS |= FloatInvalid;
1035a1085,1087
> Fd = numeric_limits<double>::quiet_NaN();
> } else {
> Fd = Fs1/Fs2;
1037,1040c1089,1095
< }}, FloatCvtOp);
< 0x1: fcvt_wu_s({{
< uint32_t temp;
< float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
---
> }}, 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;
1042,1043c1097,1224
< if (fs1 < 0.0) {
< Rd = 0;
---
> if (issignalingnan(fs1)) {
> fd = numeric_limits<float>::signaling_NaN();
> feclearexcept(FE_INVALID);
> } else {
> fd = 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 = numeric_limits<float>::signaling_NaN();
> feclearexcept(FE_INVALID);
> } else {
> fd = 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 = numeric_limits<float>::signaling_NaN();
> feclearexcept(FE_INVALID);
> } else {
> fd = fs1*(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 = numeric_limits<double>::signaling_NaN();
> feclearexcept(FE_INVALID);
> } else {
> Fd = copysign(Fs1, Fs2);
> }
> }});
> 0x1: fsgnjn_d({{
> if (issignalingnan(Fs1)) {
> Fd = numeric_limits<double>::signaling_NaN();
> feclearexcept(FE_INVALID);
> } else {
> Fd = copysign(Fs1, -Fs2);
> }
> }});
> 0x2: fsgnjx_d({{
> if (issignalingnan(Fs1)) {
> Fd = numeric_limits<double>::signaling_NaN();
> feclearexcept(FE_INVALID);
> } else {
> Fd = Fs1*(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 = 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 = 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 = fmin(Fs1, Fs2);
> }
> }}, FloatCmpOp);
> 0x1: fmax_d({{
> if (issignalingnan(Fs2)) {
> Fd = Fs1;
> FFLAGS |= FloatInvalid;
> } else if (issignalingnan(Fs1)) {
> Fd = Fs2;
> FFLAGS |= FloatInvalid;
> } else {
> Fd = fmax(Fs1, Fs2);
> }
> }}, FloatCmpOp);
> }
> 0x20: fcvt_s_d({{
> assert(CONV_SGN == 1);
> float fd;
> if (issignalingnan(Fs1)) {
> fd = numeric_limits<float>::quiet_NaN();
1046,1050c1227
< Rd = (uint32_t)fs1;
< if (std::fetestexcept(FE_INVALID)) {
< Rd = std::numeric_limits<uint64_t>::max();
< std::feclearexcept(FE_INEXACT);
< }
---
> fd = (float)Fs1;
1051a1229
> Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1053c1231,1232
< 0x2: fcvt_l_s({{
---
> 0x21: fcvt_d_s({{
> assert(CONV_SGN == 0);
1057,1058c1236,1237
< if (std::isnan(fs1)) {
< Rd_sd = std::numeric_limits<int64_t>::max();
---
> if (issignalingnan(fs1)) {
> Fd = numeric_limits<double>::quiet_NaN();
1061,1069c1240
< 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);
< }
---
> Fd = (double)fs1;
1072c1243,1244
< 0x3: fcvt_lu_s({{
---
> 0x2c: fsqrt_s({{
> assert(RS2 == 0);
1074a1247
> float fd;
1076,1077c1249
< if (fs1 < 0.0) {
< Rd = 0;
---
> if (issignalingnan(Fs1_sf)) {
1079,1084d1250
< } else {
< Rd = (uint64_t)fs1;
< if (std::fetestexcept(FE_INVALID)) {
< Rd = std::numeric_limits<uint64_t>::max();
< std::feclearexcept(FE_INEXACT);
< }
1086,1093c1252,1267
< }}, 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();
---
> fd = sqrt(fs1);
> Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
> }}, FloatSqrtOp);
> 0x2d: fsqrt_d({{
> assert(RS2 == 0);
> Fd = 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 (isnan(fs1) || isnan(fs2)) {
> FFLAGS |= FloatInvalid;
> Rd = 0;
1095c1269
< Rd_sd = std::numeric_limits<int32_t>::max();
---
> Rd = fs1 <= fs2 ? 1 : 0;
1097,1116c1271,1279
< 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();
---
> }}, FloatCmpOp);
> 0x1: flt_s({{
> uint32_t temp;
> float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
> float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
>
> if (isnan(fs1) || isnan(fs2)) {
> FFLAGS |= FloatInvalid;
> Rd = 0;
1118c1281
< Rd_sd = std::numeric_limits<int64_t>::max();
---
> Rd = fs1 < fs2 ? 1 : 0;
1120,1131c1283,1290
< 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);
---
> }}, 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;
1133,1181c1292,1299
< }
< }}, 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;
---
> Rd = fs1 == fs2 ? 1 : 0;
> }}, FloatCmpOp);
> }
> 0x51: decode ROUND_MODE {
> 0x0: fle_d({{
> if (isnan(Fs1) || isnan(Fs2)) {
> FFLAGS |= FloatInvalid;
> Rd = 0;
1183c1301
< Rd = 1 << 7;
---
> Rd = Fs1 <= Fs2 ? 1 : 0;
1185,1188c1303,1307
< break;
< case FP_NAN:
< if (issignalingnan(fs1)) {
< Rd = 1 << 8;
---
> }}, FloatCmpOp);
> 0x1: flt_d({{
> if (isnan(Fs1) || isnan(Fs2)) {
> FFLAGS |= FloatInvalid;
> Rd = 0;
1190c1309
< Rd = 1 << 9;
---
> Rd = Fs1 < Fs2 ? 1 : 0;
1192,1197c1311,1314
< break;
< case FP_ZERO:
< if (std::signbit(fs1)) {
< Rd = 1 << 3;
< } else {
< Rd = 1 << 4;
---
> }}, FloatCmpOp);
> 0x2: feq_d({{
> if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
> FFLAGS |= FloatInvalid;
1199,1202c1316,1326
< break;
< case FP_SUBNORMAL:
< if (std::signbit(fs1)) {
< Rd = 1 << 2;
---
> 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 (isnan(fs1)) {
> Rd_sd = numeric_limits<int32_t>::max();
> FFLAGS |= FloatInvalid;
1204c1328,1336
< Rd = 1 << 5;
---
> Rd_sd = (int32_t)fs1;
> if (fetestexcept(FE_INVALID)) {
> if (signbit(fs1)) {
> Rd_sd = numeric_limits<int32_t>::min();
> } else {
> Rd_sd = numeric_limits<int32_t>::max();
> }
> feclearexcept(FE_INEXACT);
> }
1206,1209c1338,1345
< break;
< case FP_NORMAL:
< if (std::signbit(fs1)) {
< Rd = 1 << 1;
---
> }}, FloatCvtOp);
> 0x1: fcvt_wu_s({{
> uint32_t temp;
> float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
>
> if (fs1 < 0.0) {
> Rd = 0;
> FFLAGS |= FloatInvalid;
1211c1347,1351
< Rd = 1 << 6;
---
> Rd = (uint32_t)fs1;
> if (fetestexcept(FE_INVALID)) {
> Rd = numeric_limits<uint64_t>::max();
> feclearexcept(FE_INEXACT);
> }
1213,1228c1353,1360
< 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;
---
> }}, FloatCvtOp);
> 0x2: fcvt_l_s({{
> uint32_t temp;
> float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
>
> if (isnan(fs1)) {
> Rd_sd = numeric_limits<int64_t>::max();
> FFLAGS |= FloatInvalid;
1230c1362,1370
< Rd = 1 << 7;
---
> Rd_sd = (int64_t)fs1;
> if (fetestexcept(FE_INVALID)) {
> if (signbit(fs1)) {
> Rd_sd = numeric_limits<int64_t>::min();
> } else {
> Rd_sd = numeric_limits<int64_t>::max();
> }
> feclearexcept(FE_INEXACT);
> }
1232,1235c1372,1379
< break;
< case FP_NAN:
< if (issignalingnan(Fs1)) {
< Rd = 1 << 8;
---
> }}, FloatCvtOp);
> 0x3: fcvt_lu_s({{
> uint32_t temp;
> float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
>
> if (fs1 < 0.0) {
> Rd = 0;
> FFLAGS |= FloatInvalid;
1237c1381,1385
< Rd = 1 << 9;
---
> Rd = (uint64_t)fs1;
> if (fetestexcept(FE_INVALID)) {
> Rd = numeric_limits<uint64_t>::max();
> feclearexcept(FE_INEXACT);
> }
1239,1244c1387,1398
< break;
< case FP_ZERO:
< if (std::signbit(Fs1)) {
< Rd = 1 << 3;
< } else {
< Rd = 1 << 4;
---
> }}, FloatCvtOp);
> }
> 0x61: decode CONV_SGN {
> 0x0: fcvt_w_d({{
> Rd_sd = (int32_t)Fs1;
> if (fetestexcept(FE_INVALID)) {
> if (Fs1 < 0.0) {
> Rd_sd = numeric_limits<int32_t>::min();
> } else {
> Rd_sd = numeric_limits<int32_t>::max();
> }
> feclearexcept(FE_INEXACT);
1246,1249c1400,1404
< break;
< case FP_SUBNORMAL:
< if (std::signbit(Fs1)) {
< Rd = 1 << 2;
---
> }}, FloatCvtOp);
> 0x1: fcvt_wu_d({{
> if (Fs1 < 0.0) {
> Rd = 0;
> FFLAGS |= FloatInvalid;
1251c1406,1410
< Rd = 1 << 5;
---
> Rd = (uint32_t)Fs1;
> if (fetestexcept(FE_INVALID)) {
> Rd = numeric_limits<uint64_t>::max();
> feclearexcept(FE_INEXACT);
> }
1253,1256c1412,1427
< break;
< case FP_NORMAL:
< if (std::signbit(Fs1)) {
< Rd = 1 << 1;
---
> }}, FloatCvtOp);
> 0x2: fcvt_l_d({{
> Rd_sd = Fs1;
> if (fetestexcept(FE_INVALID)) {
> if (Fs1 < 0.0) {
> Rd_sd = numeric_limits<int64_t>::min();
> } else {
> Rd_sd = numeric_limits<int64_t>::max();
> }
> feclearexcept(FE_INEXACT);
> }
> }}, FloatCvtOp);
> 0x3: fcvt_lu_d({{
> if (Fs1 < 0.0) {
> Rd = 0;
> FFLAGS |= FloatInvalid;
1258c1429,1433
< Rd = 1 << 6;
---
> Rd = (uint64_t)Fs1;
> if (fetestexcept(FE_INVALID)) {
> Rd = numeric_limits<uint64_t>::max();
> feclearexcept(FE_INEXACT);
> }
1260,1282c1435
< 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 BOp {
< 0x0: beq({{
< if (Rs1 == Rs2) {
< NPC = PC + imm;
< } else {
< NPC = NPC;
---
> }}, FloatCvtOp);
1284,1289c1437,1453
< }}, IsDirectControl, IsCondControl);
< 0x1: bne({{
< if (Rs1 != Rs2) {
< NPC = PC + imm;
< } else {
< NPC = NPC;
---
> 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);
1291,1296c1455,1467
< }}, IsDirectControl, IsCondControl);
< 0x4: blt({{
< if (Rs1_sd < Rs2_sd) {
< NPC = PC + imm;
< } else {
< NPC = NPC;
---
> 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);
1298,1303c1469,1519
< }}, IsDirectControl, IsCondControl);
< 0x5: bge({{
< if (Rs1_sd >= Rs2_sd) {
< NPC = PC + imm;
< } else {
< NPC = NPC;
---
> 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 (fpclassify(fs1)) {
> case FP_INFINITE:
> if (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 (signbit(fs1)) {
> Rd = 1 << 3;
> } else {
> Rd = 1 << 4;
> }
> break;
> case FP_SUBNORMAL:
> if (signbit(fs1)) {
> Rd = 1 << 2;
> } else {
> Rd = 1 << 5;
> }
> break;
> case FP_NORMAL:
> if (signbit(fs1)) {
> Rd = 1 << 1;
> } else {
> Rd = 1 << 6;
> }
> break;
> default:
> panic("Unknown classification for operand.");
> break;
> }
> }});
1305,1310c1521,1566
< }}, IsDirectControl, IsCondControl);
< 0x6: bltu({{
< if (Rs1 < Rs2) {
< NPC = PC + imm;
< } else {
< NPC = NPC;
---
> 0x71: decode ROUND_MODE {
> 0x0: fmv_x_d({{
> Rd = Fs1_bits;
> }}, FloatCvtOp);
> 0x1: fclass_d({{
> switch (fpclassify(Fs1)) {
> case FP_INFINITE:
> if (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 (signbit(Fs1)) {
> Rd = 1 << 3;
> } else {
> Rd = 1 << 4;
> }
> break;
> case FP_SUBNORMAL:
> if (signbit(Fs1)) {
> Rd = 1 << 2;
> } else {
> Rd = 1 << 5;
> }
> break;
> case FP_NORMAL:
> if (signbit(Fs1)) {
> Rd = 1 << 1;
> } else {
> Rd = 1 << 6;
> }
> break;
> default:
> panic("Unknown classification for operand.");
> break;
> }
> }});
1312,1319c1568,1574
< }}, IsDirectControl, IsCondControl);
< 0x7: bgeu({{
< if (Rs1 >= Rs2) {
< NPC = PC + imm;
< } else {
< NPC = NPC;
< }
< }}, IsDirectControl, IsCondControl);
---
> 0x78: fmv_s_x({{
> Fd_bits = (uint64_t)Rs1_uw;
> }}, FloatCvtOp);
> 0x79: fmv_d_x({{
> Fd_bits = Rs1;
> }}, FloatCvtOp);
> }
1321d1575
< }
1323,1328c1577,1622
< 0x67: decode FUNCT3 {
< 0x0: Jump::jalr({{
< Rd = NPC;
< NPC = (imm + Rs1) & (~0x1);
< }}, IsIndirectControl, IsUncondControl, IsCall);
< }
---
> 0x18: decode FUNCT3 {
> format BOp {
> 0x0: beq({{
> if (Rs1 == Rs2) {
> NPC = PC + imm;
> } else {
> NPC = NPC;
> }
> }}, IsDirectControl, IsCondControl);
> 0x1: bne({{
> if (Rs1 != Rs2) {
> NPC = PC + imm;
> } else {
> NPC = NPC;
> }
> }}, IsDirectControl, IsCondControl);
> 0x4: blt({{
> if (Rs1_sd < Rs2_sd) {
> NPC = PC + imm;
> } else {
> NPC = NPC;
> }
> }}, IsDirectControl, IsCondControl);
> 0x5: bge({{
> if (Rs1_sd >= Rs2_sd) {
> NPC = PC + imm;
> } else {
> NPC = NPC;
> }
> }}, IsDirectControl, IsCondControl);
> 0x6: bltu({{
> if (Rs1 < Rs2) {
> NPC = PC + imm;
> } else {
> NPC = NPC;
> }
> }}, IsDirectControl, IsCondControl);
> 0x7: bgeu({{
> if (Rs1 >= Rs2) {
> NPC = PC + imm;
> } else {
> NPC = NPC;
> }
> }}, IsDirectControl, IsCondControl);
> }
> }
1330,1333c1624,1629
< 0x6f: JOp::jal({{
< Rd = NPC;
< NPC = PC + imm;
< }}, IsDirectControl, IsUncondControl, IsCall);
---
> 0x19: decode FUNCT3 {
> 0x0: Jump::jalr({{
> Rd = NPC;
> NPC = (imm + Rs1) & (~0x1);
> }}, IsIndirectControl, IsUncondControl, IsCall);
> }
1335,1346c1631,1649
< 0x73: decode FUNCT3 {
< format SystemOp {
< 0x0: decode FUNCT12 {
< 0x0: ecall({{
< fault = std::make_shared<SyscallFault>();
< }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass);
< 0x1: ebreak({{
< fault = std::make_shared<BreakpointFault>();
< }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
< 0x100: eret({{
< fault = std::make_shared<UnimplementedFault>("eret");
< }}, No_OpClass);
---
> 0x1b: JOp::jal({{
> Rd = NPC;
> NPC = PC + imm;
> }}, IsDirectControl, IsUncondControl, IsCall);
>
> 0x1c: decode FUNCT3 {
> format SystemOp {
> 0x0: decode FUNCT12 {
> 0x0: ecall({{
> fault = make_shared<SyscallFault>();
> }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
> No_OpClass);
> 0x1: ebreak({{
> fault = make_shared<BreakpointFault>();
> }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
> 0x100: eret({{
> fault = make_shared<UnimplementedFault>("eret");
> }}, No_OpClass);
> }
1347a1651,1684
> format CSROp {
> 0x1: csrrw({{
> Rd = xc->readMiscReg(csr);
> xc->setMiscReg(csr, Rs1);
> }}, IsNonSpeculative, No_OpClass);
> 0x2: csrrs({{
> Rd = xc->readMiscReg(csr);
> if (Rs1 != 0) {
> xc->setMiscReg(csr, Rd | Rs1);
> }
> }}, IsNonSpeculative, No_OpClass);
> 0x3: csrrc({{
> Rd = xc->readMiscReg(csr);
> if (Rs1 != 0) {
> xc->setMiscReg(csr, Rd & ~Rs1);
> }
> }}, IsNonSpeculative, No_OpClass);
> 0x5: csrrwi({{
> Rd = xc->readMiscReg(csr);
> xc->setMiscReg(csr, uimm);
> }}, IsNonSpeculative, No_OpClass);
> 0x6: csrrsi({{
> Rd = xc->readMiscReg(csr);
> if (uimm != 0) {
> xc->setMiscReg(csr, Rd | uimm);
> }
> }}, IsNonSpeculative, No_OpClass);
> 0x7: csrrci({{
> Rd = xc->readMiscReg(csr);
> if (uimm != 0) {
> xc->setMiscReg(csr, Rd & ~uimm);
> }
> }}, IsNonSpeculative, No_OpClass);
> }
1349,1382d1685
< format CSROp {
< 0x1: csrrw({{
< Rd = xc->readMiscReg(csr);
< xc->setMiscReg(csr, Rs1);
< }}, IsNonSpeculative, No_OpClass);
< 0x2: csrrs({{
< Rd = xc->readMiscReg(csr);
< if (Rs1 != 0) {
< xc->setMiscReg(csr, Rd | Rs1);
< }
< }}, IsNonSpeculative, No_OpClass);
< 0x3: csrrc({{
< Rd = xc->readMiscReg(csr);
< if (Rs1 != 0) {
< xc->setMiscReg(csr, Rd & ~Rs1);
< }
< }}, IsNonSpeculative, No_OpClass);
< 0x5: csrrwi({{
< Rd = xc->readMiscReg(csr);
< xc->setMiscReg(csr, uimm);
< }}, IsNonSpeculative, No_OpClass);
< 0x6: csrrsi({{
< Rd = xc->readMiscReg(csr);
< if (uimm != 0) {
< xc->setMiscReg(csr, Rd | uimm);
< }
< }}, IsNonSpeculative, No_OpClass);
< 0x7: csrrci({{
< Rd = xc->readMiscReg(csr);
< if (uimm != 0) {
< xc->setMiscReg(csr, Rd & ~uimm);
< }
< }}, IsNonSpeculative, No_OpClass);
< }