// Copyright (c) 2015 RISC-V Foundation
// Copyright (c) 2017 The University of Virginia
+// Copyright (c) 2020 Barkhausen Institut
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: Alec Roelke
////////////////////////////////////////////////////////////////////
//
decode QUADRANT default Unknown::unknown() {
0x0: decode COPCODE {
- 0x0: CIOp::c_addi4spn({{
+ 0x0: CIAddi4spnOp::c_addi4spn({{
imm = CIMM8<1:1> << 2 |
CIMM8<0:0> << 3 |
CIMM8<7:6> << 4 |
CIMM8<5:2> << 6;
}}, {{
if (machInst == 0)
- fault = make_shared<IllegalInstFault>("zero instruction",
- machInst);
+ fault = std::make_shared<IllegalInstFault>("zero instruction",
+ machInst);
Rp2 = sp + imm;
}}, uint64_t);
format CompressedLoad {
0x1: c_fld({{
offset = CIMM3 << 3 | CIMM2 << 6;
}}, {{
+ STATUS status = xc->readMiscReg(MISCREG_STATUS);
+ if (status.fs == FPUStatus::OFF)
+ fault = std::make_shared<IllegalInstFault>("FPU is off",
+ machInst);
+
Fp2_bits = Mem;
}}, {{
EA = Rp1 + offset;
0x5: c_fsd({{
offset = CIMM3 << 3 | CIMM2 << 6;
}}, {{
+ STATUS status = xc->readMiscReg(MISCREG_STATUS);
+ if (status.fs == FPUStatus::OFF)
+ fault = std::make_shared<IllegalInstFault>("FPU is off",
+ machInst);
+
Mem = Fp2_bits;
}}, {{
EA = Rp1 + offset;
}}, {{
if ((RC1 == 0) != (imm == 0)) {
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
} else // imm == 0
- fault = make_shared<IllegalInstFault>("immediate = 0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "immediate = 0", machInst);
}
Rc1_sd = Rc1_sd + imm;
}});
imm |= ~((uint64_t)0x1F);
}}, {{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
}
Rc1_sd = (int32_t)Rc1_sd + imm;
}});
imm |= ~((uint64_t)0x1F);
}}, {{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
}
Rc1_sd = imm;
}});
imm |= ~((int64_t)0x1FF);
}}, {{
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "immediate = 0", machInst);
}
sp_sd = sp_sd + imm;
}});
imm |= ~((uint64_t)0x1FFFF);
}}, {{
if (RC1 == 0 || RC1 == 2) {
- fault = make_shared<IllegalInstFault>("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
}
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "immediate = 0", machInst);
}
Rc1_sd = imm;
}});
imm = CIMM5 | (CIMM1 << 5);
}}, {{
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "immediate = 0", machInst);
}
Rp1 = Rp1 >> imm;
}}, uint64_t);
imm = CIMM5 | (CIMM1 << 5);
}}, {{
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "immediate = 0", machInst);
}
Rp1_sd = Rp1_sd >> imm;
}}, uint64_t);
Rp1 = Rp1 & imm;
}}, uint64_t);
}
- format ROp {
+ format CompressedROp {
0x3: decode CFUNCT1 {
0x0: decode CFUNCT2LOW {
0x0: c_sub({{
}
}
}
- 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);
+ 0x5: CJOp::c_j({{
+ NPC = PC + imm;
+ }}, IsDirectControl, IsUncondControl);
format CBOp {
0x6: c_beqz({{
if (Rp1 == 0)
imm = CIMM5 | (CIMM1 << 5);
}}, {{
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "immediate = 0", machInst);
}
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
}
Rc1 = Rc1 << imm;
}}, uint64_t);
CIMM5<1:0> << 6;
}}, {{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
}
Rc1_sd = Mem_sw;
}}, {{
CIMM5<2:0> << 6;
}}, {{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
}
Rc1_sd = Mem_sd;
}}, {{
0x0: decode RC2 {
0x0: Jump::c_jr({{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
}
NPC = Rc1;
}}, IsIndirectControl, IsUncondControl, IsCall);
default: CROp::c_mv({{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
}
Rc1 = Rc2;
}});
0x1: decode RC1 {
0x0: SystemOp::c_ebreak({{
if (RC2 != 0) {
- fault = make_shared<IllegalInstFault>("source reg x1",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x1", machInst);
}
- fault = make_shared<BreakpointFault>(xc->pcState());
+ fault = std::make_shared<BreakpointFault>(xc->pcState());
}}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
default: decode RC2 {
0x0: Jump::c_jalr({{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>
- ("source reg x0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x0", machInst);
}
ra = NPC;
NPC = Rc1;
}}, IsIndirectControl, IsUncondControl, IsCall);
- default: ROp::c_add({{
+ default: CompressedROp::c_add({{
Rc1_sd = Rc1_sd + Rc2_sd;
}});
}
0x01: decode FUNCT3 {
format Load {
0x2: flw({{
+ STATUS status = xc->readMiscReg(MISCREG_STATUS);
+ if (status.fs == FPUStatus::OFF) {
+ fault = std::make_shared<IllegalInstFault>(
+ "FPU is off", machInst);
+ }
+
Fd_bits = (uint64_t)Mem_uw;
}}, inst_flags=FloatMemReadOp);
0x3: fld({{
+ STATUS status = xc->readMiscReg(MISCREG_STATUS);
+ if (status.fs == FPUStatus::OFF)
+ fault = std::make_shared<IllegalInstFault>(
+ "FPU is off", machInst);
+
Fd_bits = Mem;
}}, inst_flags=FloatMemReadOp);
}
}
0x03: decode FUNCT3 {
- format IOp {
+ format FenceOp {
0x0: fence({{
- }}, uint64_t, IsNonSpeculative, IsMemBarrier, No_OpClass);
+ }}, uint64_t, IsReadBarrier, IsWriteBarrier, No_OpClass);
0x1: fence_i({{
}}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
}
Rd_sd = Rs1_sd + imm;
}});
0x1: slli({{
- Rd = Rs1 << SHAMT6;
- }});
+ Rd = Rs1 << imm;
+ }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
0x2: slti({{
Rd = (Rs1_sd < imm) ? 1 : 0;
}});
}}, uint64_t);
0x5: decode SRTYPE {
0x0: srli({{
- Rd = Rs1 >> SHAMT6;
- }});
+ Rd = Rs1 >> imm;
+ }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
0x1: srai({{
- Rd_sd = Rs1_sd >> SHAMT6;
- }});
+ Rd_sd = Rs1_sd >> imm;
+ }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }});
}
0x6: ori({{
Rd = Rs1 | imm;
}
0x05: UOp::auipc({{
- Rd = PC + imm;
+ Rd = PC + (sext<20>(imm) << 12);
}});
0x06: decode FUNCT3 {
Rd_sd = Rs1_sw + imm;
}}, int32_t);
0x1: slliw({{
- Rd_sd = Rs1_sw << SHAMT5;
- }});
+ Rd_sd = Rs1_sw << imm;
+ }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
0x5: decode SRTYPE {
0x0: srliw({{
- Rd_sd = (int32_t)(Rs1_uw >> SHAMT5);
- }});
+ Rd_sd = (int32_t)(Rs1_uw >> imm);
+ }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
0x1: sraiw({{
- Rd_sd = Rs1_sw >> SHAMT5;
- }});
+ Rd_sd = Rs1_sw >> imm;
+ }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }});
}
}
}
0x09: decode FUNCT3 {
format Store {
0x2: fsw({{
+ STATUS status = xc->readMiscReg(MISCREG_STATUS);
+ if (status.fs == FPUStatus::OFF)
+ fault = std::make_shared<IllegalInstFault>(
+ "FPU is off", machInst);
+
Mem_uw = (uint32_t)Fs2_bits;
}}, inst_flags=FloatMemWriteOp);
0x3: fsd({{
+ STATUS status = xc->readMiscReg(MISCREG_STATUS);
+ if (status.fs == FPUStatus::OFF)
+ fault = std::make_shared<IllegalInstFault>(
+ "FPU is off", machInst);
+
Mem_ud = Fs2_bits;
}}, inst_flags=FloatMemWriteOp);
}
}}, {{
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;}});
- }
+ 0x0: AtomicMemOp::amoadd_w({{
+ Rd_sd = Mem_sw;
+ }}, {{
+ TypedAtomicOpFunctor<int32_t> *amo_op =
+ new AtomicGenericOp<int32_t>(Rs2_sw,
+ [](int32_t* b, int32_t a){ *b += a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x1: AtomicMemOp::amoswap_w({{
+ Rd_sd = Mem_sw;
+ }}, {{
+ TypedAtomicOpFunctor<uint32_t> *amo_op =
+ new AtomicGenericOp<uint32_t>(Rs2_uw,
+ [](uint32_t* b, uint32_t a){ *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x4: AtomicMemOp::amoxor_w({{
+ Rd_sd = Mem_sw;
+ }}, {{
+ TypedAtomicOpFunctor<uint32_t> *amo_op =
+ new AtomicGenericOp<uint32_t>(Rs2_uw,
+ [](uint32_t* b, uint32_t a){ *b ^= a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x8: AtomicMemOp::amoor_w({{
+ Rd_sd = Mem_sw;
+ }}, {{
+ TypedAtomicOpFunctor<uint32_t> *amo_op =
+ new AtomicGenericOp<uint32_t>(Rs2_uw,
+ [](uint32_t* b, uint32_t a){ *b |= a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0xc: AtomicMemOp::amoand_w({{
+ Rd_sd = Mem_sw;
+ }}, {{
+ TypedAtomicOpFunctor<uint32_t> *amo_op =
+ new AtomicGenericOp<uint32_t>(Rs2_uw,
+ [](uint32_t* b, uint32_t a){ *b &= a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x10: AtomicMemOp::amomin_w({{
+ Rd_sd = Mem_sw;
+ }}, {{
+ TypedAtomicOpFunctor<int32_t> *amo_op =
+ new AtomicGenericOp<int32_t>(Rs2_sw,
+ [](int32_t* b, int32_t a){ if (a < *b) *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x14: AtomicMemOp::amomax_w({{
+ Rd_sd = Mem_sw;
+ }}, {{
+ TypedAtomicOpFunctor<int32_t> *amo_op =
+ new AtomicGenericOp<int32_t>(Rs2_sw,
+ [](int32_t* b, int32_t a){ if (a > *b) *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x18: AtomicMemOp::amominu_w({{
+ Rd_sd = Mem_sw;
+ }}, {{
+ TypedAtomicOpFunctor<uint32_t> *amo_op =
+ new AtomicGenericOp<uint32_t>(Rs2_uw,
+ [](uint32_t* b, uint32_t a){ if (a < *b) *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x1c: AtomicMemOp::amomaxu_w({{
+ Rd_sd = Mem_sw;
+ }}, {{
+ TypedAtomicOpFunctor<uint32_t> *amo_op =
+ new AtomicGenericOp<uint32_t>(Rs2_uw,
+ [](uint32_t* b, uint32_t a){ if (a > *b) *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
}
0x3: decode AMOFUNCT {
0x2: LoadReserved::lr_d({{
}}, {{
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;}});
- }
+ 0x0: AtomicMemOp::amoadd_d({{
+ Rd_sd = Mem_sd;
+ }}, {{
+ TypedAtomicOpFunctor<int64_t> *amo_op =
+ new AtomicGenericOp<int64_t>(Rs2_sd,
+ [](int64_t* b, int64_t a){ *b += a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x1: AtomicMemOp::amoswap_d({{
+ Rd_sd = Mem_sd;
+ }}, {{
+ TypedAtomicOpFunctor<uint64_t> *amo_op =
+ new AtomicGenericOp<uint64_t>(Rs2_ud,
+ [](uint64_t* b, uint64_t a){ *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x4: AtomicMemOp::amoxor_d({{
+ Rd_sd = Mem_sd;
+ }}, {{
+ TypedAtomicOpFunctor<uint64_t> *amo_op =
+ new AtomicGenericOp<uint64_t>(Rs2_ud,
+ [](uint64_t* b, uint64_t a){ *b ^= a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x8: AtomicMemOp::amoor_d({{
+ Rd_sd = Mem_sd;
+ }}, {{
+ TypedAtomicOpFunctor<uint64_t> *amo_op =
+ new AtomicGenericOp<uint64_t>(Rs2_ud,
+ [](uint64_t* b, uint64_t a){ *b |= a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0xc: AtomicMemOp::amoand_d({{
+ Rd_sd = Mem_sd;
+ }}, {{
+ TypedAtomicOpFunctor<uint64_t> *amo_op =
+ new AtomicGenericOp<uint64_t>(Rs2_ud,
+ [](uint64_t* b, uint64_t a){ *b &= a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x10: AtomicMemOp::amomin_d({{
+ Rd_sd = Mem_sd;
+ }}, {{
+ TypedAtomicOpFunctor<int64_t> *amo_op =
+ new AtomicGenericOp<int64_t>(Rs2_sd,
+ [](int64_t* b, int64_t a){ if (a < *b) *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x14: AtomicMemOp::amomax_d({{
+ Rd_sd = Mem_sd;
+ }}, {{
+ TypedAtomicOpFunctor<int64_t> *amo_op =
+ new AtomicGenericOp<int64_t>(Rs2_sd,
+ [](int64_t* b, int64_t a){ if (a > *b) *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x18: AtomicMemOp::amominu_d({{
+ Rd_sd = Mem_sd;
+ }}, {{
+ TypedAtomicOpFunctor<uint64_t> *amo_op =
+ new AtomicGenericOp<uint64_t>(Rs2_ud,
+ [](uint64_t* b, uint64_t a){ if (a < *b) *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
+ 0x1c: AtomicMemOp::amomaxu_d({{
+ Rd_sd = Mem_sd;
+ }}, {{
+ TypedAtomicOpFunctor<uint64_t> *amo_op =
+ new AtomicGenericOp<uint64_t>(Rs2_ud,
+ [](uint64_t* b, uint64_t a){ if (a > *b) *b = a; });
+ }}, mem_flags=ATOMIC_RETURN_OP);
}
}
0x0c: decode FUNCT3 {
0x1: div({{
if (Rs2_sd == 0) {
Rd_sd = -1;
- } else if (Rs1_sd == numeric_limits<int64_t>::min()
+ } else if (
+ Rs1_sd == std::numeric_limits<int64_t>::min()
&& Rs2_sd == -1) {
- Rd_sd = numeric_limits<int64_t>::min();
+ Rd_sd = std::numeric_limits<int64_t>::min();
} else {
Rd_sd = Rs1_sd/Rs2_sd;
}
}});
0x1: divu({{
if (Rs2 == 0) {
- Rd = numeric_limits<uint64_t>::max();
+ Rd = std::numeric_limits<uint64_t>::max();
} else {
Rd = Rs1/Rs2;
}
0x1: rem({{
if (Rs2_sd == 0) {
Rd = Rs1_sd;
- } else if (Rs1_sd == numeric_limits<int64_t>::min()
+ } else if (
+ Rs1_sd == std::numeric_limits<int64_t>::min()
&& Rs2_sd == -1) {
Rd = 0;
} else {
}
0x0d: UOp::lui({{
- Rd = (uint64_t)imm;
+ Rd = (uint64_t)(sext<20>(imm) << 12);
}});
0x0e: decode FUNCT3 {
0x4: divw({{
if (Rs2_sw == 0) {
Rd_sd = -1;
- } else if (Rs1_sw == numeric_limits<int32_t>::min()
+ } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
&& Rs2_sw == -1) {
- Rd_sd = numeric_limits<int32_t>::min();
+ Rd_sd = std::numeric_limits<int32_t>::min();
} else {
Rd_sd = Rs1_sw/Rs2_sw;
}
}});
0x1: divuw({{
if (Rs2_uw == 0) {
- Rd_sd = numeric_limits<IntReg>::max();
+ Rd_sd = std::numeric_limits<uint64_t>::max();
} else {
Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
}
0x6: remw({{
if (Rs2_sw == 0) {
Rd_sd = Rs1_sw;
- } else if (Rs1_sw == numeric_limits<int32_t>::min()
+ } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
&& Rs2_sw == -1) {
Rd_sd = 0;
} else {
|| issignalingnan(fs3)) {
FFLAGS |= FloatInvalid;
}
- fd = numeric_limits<float>::quiet_NaN();
+ fd = std::numeric_limits<float>::quiet_NaN();
} else if (std::isinf(fs1) || std::isinf(fs2) ||
std::isinf(fs3)) {
- if (signbit(fs1) == signbit(fs2)
+ if (std::signbit(fs1) == std::signbit(fs2)
&& !std::isinf(fs3)) {
- fd = numeric_limits<float>::infinity();
- } else if (signbit(fs1) != signbit(fs2)
+ fd = std::numeric_limits<float>::infinity();
+ } else if (std::signbit(fs1) != std::signbit(fs2)
&& !std::isinf(fs3)) {
- fd = -numeric_limits<float>::infinity();
+ fd = -std::numeric_limits<float>::infinity();
} else { // Fs3_sf is infinity
fd = fs3;
}
|| issignalingnan(Fs3)) {
FFLAGS |= FloatInvalid;
}
- Fd = numeric_limits<double>::quiet_NaN();
+ Fd = std::numeric_limits<double>::quiet_NaN();
} else if (std::isinf(Fs1) || std::isinf(Fs2) ||
std::isinf(Fs3)) {
- if (signbit(Fs1) == signbit(Fs2)
+ if (std::signbit(Fs1) == std::signbit(Fs2)
&& !std::isinf(Fs3)) {
- Fd = numeric_limits<double>::infinity();
- } else if (signbit(Fs1) != signbit(Fs2)
+ Fd = std::numeric_limits<double>::infinity();
+ } else if (std::signbit(Fs1) != std::signbit(Fs2)
&& !std::isinf(Fs3)) {
- Fd = -numeric_limits<double>::infinity();
+ Fd = -std::numeric_limits<double>::infinity();
} else {
Fd = Fs3;
}
|| issignalingnan(fs3)) {
FFLAGS |= FloatInvalid;
}
- fd = numeric_limits<float>::quiet_NaN();
+ fd = std::numeric_limits<float>::quiet_NaN();
} else if (std::isinf(fs1) || std::isinf(fs2) ||
std::isinf(fs3)) {
- if (signbit(fs1) == signbit(fs2)
+ if (std::signbit(fs1) == std::signbit(fs2)
&& !std::isinf(fs3)) {
- fd = numeric_limits<float>::infinity();
- } else if (signbit(fs1) != signbit(fs2)
+ fd = std::numeric_limits<float>::infinity();
+ } else if (std::signbit(fs1) != std::signbit(fs2)
&& !std::isinf(fs3)) {
- fd = -numeric_limits<float>::infinity();
+ fd = -std::numeric_limits<float>::infinity();
} else { // Fs3_sf is infinity
fd = -fs3;
}
|| issignalingnan(Fs3)) {
FFLAGS |= FloatInvalid;
}
- Fd = numeric_limits<double>::quiet_NaN();
+ Fd = std::numeric_limits<double>::quiet_NaN();
} else if (std::isinf(Fs1) || std::isinf(Fs2) ||
std::isinf(Fs3)) {
- if (signbit(Fs1) == signbit(Fs2)
+ if (std::signbit(Fs1) == std::signbit(Fs2)
&& !std::isinf(Fs3)) {
- Fd = numeric_limits<double>::infinity();
- } else if (signbit(Fs1) != signbit(Fs2)
+ Fd = std::numeric_limits<double>::infinity();
+ } else if (std::signbit(Fs1) != std::signbit(Fs2)
&& !std::isinf(Fs3)) {
- Fd = -numeric_limits<double>::infinity();
+ Fd = -std::numeric_limits<double>::infinity();
} else {
Fd = -Fs3;
}
|| issignalingnan(fs3)) {
FFLAGS |= FloatInvalid;
}
- fd = numeric_limits<float>::quiet_NaN();
+ fd = std::numeric_limits<float>::quiet_NaN();
} else if (std::isinf(fs1) || std::isinf(fs2) ||
std::isinf(fs3)) {
- if (signbit(fs1) == signbit(fs2)
+ if (std::signbit(fs1) == std::signbit(fs2)
&& !std::isinf(fs3)) {
- fd = -numeric_limits<float>::infinity();
- } else if (signbit(fs1) != signbit(fs2)
+ fd = -std::numeric_limits<float>::infinity();
+ } else if (std::signbit(fs1) != std::signbit(fs2)
&& !std::isinf(fs3)) {
- fd = numeric_limits<float>::infinity();
+ fd = std::numeric_limits<float>::infinity();
} else { // Fs3_sf is infinity
fd = fs3;
}
|| issignalingnan(Fs3)) {
FFLAGS |= FloatInvalid;
}
- Fd = numeric_limits<double>::quiet_NaN();
+ Fd = std::numeric_limits<double>::quiet_NaN();
} else if (std::isinf(Fs1) || std::isinf(Fs2)
|| std::isinf(Fs3)) {
- if (signbit(Fs1) == signbit(Fs2)
+ if (std::signbit(Fs1) == std::signbit(Fs2)
&& !std::isinf(Fs3)) {
- Fd = -numeric_limits<double>::infinity();
- } else if (signbit(Fs1) != signbit(Fs2)
+ Fd = -std::numeric_limits<double>::infinity();
+ } else if (std::signbit(Fs1) != std::signbit(Fs2)
&& !std::isinf(Fs3)) {
- Fd = numeric_limits<double>::infinity();
+ Fd = std::numeric_limits<double>::infinity();
} else {
Fd = Fs3;
}
|| issignalingnan(fs3)) {
FFLAGS |= FloatInvalid;
}
- fd = numeric_limits<float>::quiet_NaN();
+ fd = std::numeric_limits<float>::quiet_NaN();
} else if (std::isinf(fs1) || std::isinf(fs2) ||
std::isinf(fs3)) {
- if (signbit(fs1) == signbit(fs2)
+ if (std::signbit(fs1) == std::signbit(fs2)
&& !std::isinf(fs3)) {
- fd = -numeric_limits<float>::infinity();
- } else if (signbit(fs1) != signbit(fs2)
+ fd = -std::numeric_limits<float>::infinity();
+ } else if (std::signbit(fs1) != std::signbit(fs2)
&& !std::isinf(fs3)) {
- fd = numeric_limits<float>::infinity();
+ fd = std::numeric_limits<float>::infinity();
} else { // Fs3_sf is infinity
fd = -fs3;
}
|| issignalingnan(Fs3)) {
FFLAGS |= FloatInvalid;
}
- Fd = numeric_limits<double>::quiet_NaN();
+ Fd = std::numeric_limits<double>::quiet_NaN();
} else if (std::isinf(Fs1) || std::isinf(Fs2) ||
std::isinf(Fs3)) {
- if (signbit(Fs1) == signbit(Fs2)
+ if (std::signbit(Fs1) == std::signbit(Fs2)
&& !std::isinf(Fs3)) {
- Fd = -numeric_limits<double>::infinity();
- } else if (signbit(Fs1) != signbit(Fs2)
+ Fd = -std::numeric_limits<double>::infinity();
+ } else if (std::signbit(Fs1) != std::signbit(Fs2)
&& !std::isinf(Fs3)) {
- Fd = numeric_limits<double>::infinity();
+ Fd = std::numeric_limits<double>::infinity();
} else {
Fd = -Fs3;
}
if (issignalingnan(fs1) || issignalingnan(fs2)) {
FFLAGS |= FloatInvalid;
}
- fd = numeric_limits<float>::quiet_NaN();
+ fd = std::numeric_limits<float>::quiet_NaN();
} else {
fd = fs1 + fs2;
}
if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
FFLAGS |= FloatInvalid;
}
- Fd = numeric_limits<double>::quiet_NaN();
+ Fd = std::numeric_limits<double>::quiet_NaN();
} else {
Fd = Fs1 + Fs2;
}
if (issignalingnan(fs1) || issignalingnan(fs2)) {
FFLAGS |= FloatInvalid;
}
- fd = numeric_limits<float>::quiet_NaN();
+ fd = std::numeric_limits<float>::quiet_NaN();
} else {
fd = fs1 - fs2;
}
if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
FFLAGS |= FloatInvalid;
}
- Fd = numeric_limits<double>::quiet_NaN();
+ Fd = std::numeric_limits<double>::quiet_NaN();
} else {
Fd = Fs1 - Fs2;
}
if (issignalingnan(fs1) || issignalingnan(fs2)) {
FFLAGS |= FloatInvalid;
}
- fd = numeric_limits<float>::quiet_NaN();
+ fd = std::numeric_limits<float>::quiet_NaN();
} else {
fd = fs1*fs2;
}
if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
FFLAGS |= FloatInvalid;
}
- Fd = numeric_limits<double>::quiet_NaN();
+ Fd = std::numeric_limits<double>::quiet_NaN();
} else {
Fd = Fs1*Fs2;
}
if (issignalingnan(fs1) || issignalingnan(fs2)) {
FFLAGS |= FloatInvalid;
}
- fd = numeric_limits<float>::quiet_NaN();
+ fd = std::numeric_limits<float>::quiet_NaN();
} else {
fd = fs1/fs2;
}
if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
FFLAGS |= FloatInvalid;
}
- Fd = numeric_limits<double>::quiet_NaN();
+ Fd = std::numeric_limits<double>::quiet_NaN();
} else {
Fd = Fs1/Fs2;
}
float fd;
if (issignalingnan(fs1)) {
- fd = numeric_limits<float>::signaling_NaN();
+ fd = std::numeric_limits<float>::signaling_NaN();
feclearexcept(FE_INVALID);
} else {
fd = copysign(fs1, fs2);
float fd;
if (issignalingnan(fs1)) {
- fd = numeric_limits<float>::signaling_NaN();
+ fd = std::numeric_limits<float>::signaling_NaN();
feclearexcept(FE_INVALID);
} else {
fd = copysign(fs1, -fs2);
float fd;
if (issignalingnan(fs1)) {
- fd = numeric_limits<float>::signaling_NaN();
+ fd = std::numeric_limits<float>::signaling_NaN();
feclearexcept(FE_INVALID);
} else {
- fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
+ fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0);
}
Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
}}, FloatMiscOp);
0x11: decode ROUND_MODE {
0x0: fsgnj_d({{
if (issignalingnan(Fs1)) {
- Fd = numeric_limits<double>::signaling_NaN();
+ Fd = std::numeric_limits<double>::signaling_NaN();
feclearexcept(FE_INVALID);
} else {
Fd = copysign(Fs1, Fs2);
}}, FloatMiscOp);
0x1: fsgnjn_d({{
if (issignalingnan(Fs1)) {
- Fd = numeric_limits<double>::signaling_NaN();
+ Fd = std::numeric_limits<double>::signaling_NaN();
feclearexcept(FE_INVALID);
} else {
Fd = copysign(Fs1, -Fs2);
}}, FloatMiscOp);
0x2: fsgnjx_d({{
if (issignalingnan(Fs1)) {
- Fd = numeric_limits<double>::signaling_NaN();
+ Fd = std::numeric_limits<double>::signaling_NaN();
feclearexcept(FE_INVALID);
} else {
- Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
+ Fd = Fs1*(std::signbit(Fs2) ? -1.0 : 1.0);
}
}}, FloatMiscOp);
}
}
0x20: fcvt_s_d({{
if (CONV_SGN != 1) {
- fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "CONV_SGN != 1", machInst);
}
float fd;
if (issignalingnan(Fs1)) {
- fd = numeric_limits<float>::quiet_NaN();
+ fd = std::numeric_limits<float>::quiet_NaN();
FFLAGS |= FloatInvalid;
} else {
fd = (float)Fs1;
}}, FloatCvtOp);
0x21: fcvt_d_s({{
if (CONV_SGN != 0) {
- fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "CONV_SGN != 0", machInst);
}
uint32_t temp;
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
if (issignalingnan(fs1)) {
- Fd = numeric_limits<double>::quiet_NaN();
+ Fd = std::numeric_limits<double>::quiet_NaN();
FFLAGS |= FloatInvalid;
} else {
Fd = (double)fs1;
}}, FloatCvtOp);
0x2c: fsqrt_s({{
if (RS2 != 0) {
- fault = make_shared<IllegalInstFault>("source reg x1",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x1", machInst);
}
uint32_t temp;
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
}}, FloatSqrtOp);
0x2d: fsqrt_d({{
if (RS2 != 0) {
- fault = make_shared<IllegalInstFault>("source reg x1",
- machInst);
+ fault = std::make_shared<IllegalInstFault>(
+ "source reg x1", machInst);
}
Fd = sqrt(Fs1);
}}, FloatSqrtOp);
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
if (std::isnan(fs1)) {
- Rd_sd = numeric_limits<int32_t>::max();
+ Rd_sd = std::numeric_limits<int32_t>::max();
FFLAGS |= FloatInvalid;
- } else if (fs1 >= numeric_limits<int32_t>::max()) {
- Rd_sd = numeric_limits<int32_t>::max();
+ } else if (fs1 >=
+ float(std::numeric_limits<int32_t>::max())) {
+ Rd_sd = std::numeric_limits<int32_t>::max();
FFLAGS |= FloatInvalid;
- } else if (fs1 <= numeric_limits<int32_t>::min()) {
- Rd_sd = numeric_limits<int32_t>::min();
+ } else if (fs1 <=
+ float(std::numeric_limits<int32_t>::min())) {
+ Rd_sd = std::numeric_limits<int32_t>::min();
FFLAGS |= FloatInvalid;
} else {
Rd_sd = (int32_t)fs1;
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
if (std::isnan(fs1)) {
- Rd = numeric_limits<uint64_t>::max();
+ Rd = std::numeric_limits<uint64_t>::max();
FFLAGS |= FloatInvalid;
} else if (fs1 < 0.0) {
Rd = 0;
FFLAGS |= FloatInvalid;
- } else if (fs1 > numeric_limits<uint32_t>::max()) {
- Rd = numeric_limits<uint64_t>::max();
+ } else if (fs1 >
+ float(std::numeric_limits<uint32_t>::max())) {
+ Rd = std::numeric_limits<uint64_t>::max();
FFLAGS |= FloatInvalid;
} else {
Rd = (uint32_t)fs1;
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
if (std::isnan(fs1)) {
- Rd_sd = numeric_limits<int64_t>::max();
+ Rd_sd = std::numeric_limits<int64_t>::max();
FFLAGS |= FloatInvalid;
- } else if (fs1 > numeric_limits<int64_t>::max()) {
- Rd_sd = numeric_limits<int64_t>::max();
+ } else if (fs1 >
+ float(std::numeric_limits<int64_t>::max())) {
+ Rd_sd = std::numeric_limits<int64_t>::max();
FFLAGS |= FloatInvalid;
- } else if (fs1 < numeric_limits<int64_t>::min()) {
- Rd_sd = numeric_limits<int64_t>::min();
+ } else if (fs1 <
+ float(std::numeric_limits<int64_t>::min())) {
+ Rd_sd = std::numeric_limits<int64_t>::min();
FFLAGS |= FloatInvalid;
} else {
Rd_sd = (int64_t)fs1;
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
if (std::isnan(fs1)) {
- Rd = numeric_limits<uint64_t>::max();
+ Rd = std::numeric_limits<uint64_t>::max();
FFLAGS |= FloatInvalid;
} else if (fs1 < 0.0) {
Rd = 0;
FFLAGS |= FloatInvalid;
- } else if (fs1 > numeric_limits<uint64_t>::max()) {
- Rd = numeric_limits<uint64_t>::max();
+ } else if (fs1 >
+ float(std::numeric_limits<uint64_t>::max())) {
+ Rd = std::numeric_limits<uint64_t>::max();
FFLAGS |= FloatInvalid;
} else {
Rd = (uint64_t)fs1;
0x61: decode CONV_SGN {
0x0: fcvt_w_d({{
if (std::isnan(Fs1)) {
- Rd_sd = numeric_limits<int32_t>::max();
+ Rd_sd = std::numeric_limits<int32_t>::max();
FFLAGS |= FloatInvalid;
- } else if (Fs1 > numeric_limits<int32_t>::max()) {
- Rd_sd = numeric_limits<int32_t>::max();
+ } else if (Fs1 >
+ float(std::numeric_limits<int32_t>::max())) {
+ Rd_sd = std::numeric_limits<int32_t>::max();
FFLAGS |= FloatInvalid;
- } else if (Fs1 < numeric_limits<int32_t>::min()) {
- Rd_sd = numeric_limits<int32_t>::min();
+ } else if (Fs1 <
+ float(std::numeric_limits<int32_t>::min())) {
+ Rd_sd = std::numeric_limits<int32_t>::min();
FFLAGS |= FloatInvalid;
} else {
Rd_sd = (int32_t)Fs1;
}}, FloatCvtOp);
0x1: fcvt_wu_d({{
if (std::isnan(Fs1)) {
- Rd = numeric_limits<uint64_t>::max();
+ Rd = std::numeric_limits<uint64_t>::max();
FFLAGS |= FloatInvalid;
} else if (Fs1 < 0) {
Rd = 0;
FFLAGS |= FloatInvalid;
- } else if (Fs1 > numeric_limits<uint32_t>::max()) {
- Rd = numeric_limits<uint64_t>::max();
+ } else if (Fs1 >
+ float(std::numeric_limits<uint32_t>::max())) {
+ Rd = std::numeric_limits<uint64_t>::max();
FFLAGS |= FloatInvalid;
} else {
Rd = (uint32_t)Fs1;
}}, FloatCvtOp);
0x2: fcvt_l_d({{
if (std::isnan(Fs1)) {
- Rd_sd = numeric_limits<int64_t>::max();
+ Rd_sd = std::numeric_limits<int64_t>::max();
FFLAGS |= FloatInvalid;
- } else if (Fs1 > numeric_limits<int64_t>::max()) {
- Rd_sd = numeric_limits<int64_t>::max();
+ } else if (Fs1 >
+ float(std::numeric_limits<int64_t>::max())) {
+ Rd_sd = std::numeric_limits<int64_t>::max();
FFLAGS |= FloatInvalid;
- } else if (Fs1 < numeric_limits<int64_t>::min()) {
- Rd_sd = numeric_limits<int64_t>::min();
+ } else if (Fs1 <
+ float(std::numeric_limits<int64_t>::min())) {
+ Rd_sd = std::numeric_limits<int64_t>::min();
FFLAGS |= FloatInvalid;
} else {
Rd_sd = Fs1;
}}, FloatCvtOp);
0x3: fcvt_lu_d({{
if (std::isnan(Fs1)) {
- Rd = numeric_limits<uint64_t>::max();
+ Rd = std::numeric_limits<uint64_t>::max();
FFLAGS |= FloatInvalid;
} else if (Fs1 < 0) {
Rd = 0;
FFLAGS |= FloatInvalid;
- } else if (Fs1 > numeric_limits<uint64_t>::max()) {
- Rd = numeric_limits<uint64_t>::max();
+ } else if (Fs1 >
+ float(std::numeric_limits<uint64_t>::max())) {
+ Rd = std::numeric_limits<uint64_t>::max();
FFLAGS |= FloatInvalid;
} else {
Rd = Fs1;
0x1: fclass_s({{
uint32_t temp;
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
- switch (fpclassify(fs1)) {
+ switch (std::fpclassify(fs1)) {
case FP_INFINITE:
- if (signbit(fs1)) {
+ if (std::signbit(fs1)) {
Rd = 1 << 0;
} else {
Rd = 1 << 7;
}
break;
case FP_ZERO:
- if (signbit(fs1)) {
+ if (std::signbit(fs1)) {
Rd = 1 << 3;
} else {
Rd = 1 << 4;
}
break;
case FP_SUBNORMAL:
- if (signbit(fs1)) {
+ if (std::signbit(fs1)) {
Rd = 1 << 2;
} else {
Rd = 1 << 5;
}
break;
case FP_NORMAL:
- if (signbit(fs1)) {
+ if (std::signbit(fs1)) {
Rd = 1 << 1;
} else {
Rd = 1 << 6;
Rd = Fs1_bits;
}}, FloatCvtOp);
0x1: fclass_d({{
- switch (fpclassify(Fs1)) {
+ switch (std::fpclassify(Fs1)) {
case FP_INFINITE:
- if (signbit(Fs1)) {
+ if (std::signbit(Fs1)) {
Rd = 1 << 0;
} else {
Rd = 1 << 7;
}
break;
case FP_ZERO:
- if (signbit(Fs1)) {
+ if (std::signbit(Fs1)) {
Rd = 1 << 3;
} else {
Rd = 1 << 4;
}
break;
case FP_SUBNORMAL:
- if (signbit(Fs1)) {
+ if (std::signbit(Fs1)) {
Rd = 1 << 2;
} else {
Rd = 1 << 5;
}
break;
case FP_NORMAL:
- if (signbit(Fs1)) {
+ if (std::signbit(Fs1)) {
Rd = 1 << 1;
} else {
Rd = 1 << 6;
0x1c: decode FUNCT3 {
format SystemOp {
- 0x0: decode FUNCT12 {
- 0x0: ecall({{
- fault = make_shared<SyscallFault>(
+ 0x0: decode FUNCT7 {
+ 0x0: decode RS2 {
+ 0x0: ecall({{
+ fault = std::make_shared<SyscallFault>(
(PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
- }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
- No_OpClass);
- 0x1: ebreak({{
- fault = make_shared<BreakpointFault>(xc->pcState());
- }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
- 0x2: uret({{
- STATUS status = xc->readMiscReg(MISCREG_STATUS);
- status.uie = status.upie;
- status.upie = 1;
- xc->setMiscReg(MISCREG_STATUS, status);
- NPC = xc->readMiscReg(MISCREG_UEPC);
- }}, IsReturn);
- 0x102: sret({{
- if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
- fault = make_shared<IllegalInstFault>(
- "sret in user mode", machInst);
- NPC = NPC;
- } else {
+ }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
+ No_OpClass);
+ 0x1: ebreak({{
+ fault = std::make_shared<BreakpointFault>(
+ xc->pcState());
+ }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
+ 0x2: uret({{
STATUS status = xc->readMiscReg(MISCREG_STATUS);
- xc->setMiscReg(MISCREG_PRV, status.spp);
- status.sie = status.spie;
- status.spie = 1;
- status.spp = PRV_U;
+ status.uie = status.upie;
+ status.upie = 1;
xc->setMiscReg(MISCREG_STATUS, status);
- NPC = xc->readMiscReg(MISCREG_SEPC);
+ NPC = xc->readMiscReg(MISCREG_UEPC);
+ }}, IsSerializeAfter, IsNonSpeculative, IsReturn);
+ }
+ 0x8: decode RS2 {
+ 0x2: sret({{
+ STATUS status = xc->readMiscReg(MISCREG_STATUS);
+ auto pm = (PrivilegeMode)xc->readMiscReg(
+ MISCREG_PRV);
+ if (pm == PRV_U ||
+ (pm == PRV_S && status.tsr == 1)) {
+ fault = std::make_shared<IllegalInstFault>(
+ "sret in user mode or TSR enabled",
+ machInst);
+ NPC = NPC;
+ } else {
+ xc->setMiscReg(MISCREG_PRV, status.spp);
+ status.sie = status.spie;
+ status.spie = 1;
+ status.spp = PRV_U;
+ xc->setMiscReg(MISCREG_STATUS, status);
+ NPC = xc->readMiscReg(MISCREG_SEPC);
+ }
+ }}, IsSerializeAfter, IsNonSpeculative, IsReturn);
+ 0x5: wfi({{
+ STATUS status = xc->readMiscReg(MISCREG_STATUS);
+ auto pm = (PrivilegeMode)xc->readMiscReg(
+ MISCREG_PRV);
+ if (pm == PRV_U ||
+ (pm == PRV_S && status.tw == 1)) {
+ fault = std::make_shared<IllegalInstFault>(
+ "wfi in user mode or TW enabled",
+ machInst);
+ }
+ // don't do anything for now
+ }}, No_OpClass);
+ }
+ 0x9: sfence_vma({{
+ STATUS status = xc->readMiscReg(MISCREG_STATUS);
+ auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV);
+ if (pm == PRV_U || (pm == PRV_S && status.tvm == 1)) {
+ fault = std::make_shared<IllegalInstFault>(
+ "sfence in user mode or TVM enabled",
+ machInst);
}
- }}, IsReturn);
- 0x302: mret({{
+ xc->tcBase()->getMMUPtr()->demapPage(Rs1, Rs2);
+ }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
+ 0x18: mret({{
if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
- fault = make_shared<IllegalInstFault>(
+ fault = std::make_shared<IllegalInstFault>(
"mret at lower privilege", machInst);
NPC = NPC;
} else {
xc->setMiscReg(MISCREG_STATUS, status);
NPC = xc->readMiscReg(MISCREG_MEPC);
}
- }}, IsReturn);
+ }}, IsSerializeAfter, IsNonSpeculative, IsReturn);
}
}
format CSROp {
0x1: csrrw({{
Rd = data;
data = Rs1;
- }}, IsNonSpeculative, No_OpClass);
+ }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
0x2: csrrs({{
Rd = data;
data |= Rs1;
- }}, IsNonSpeculative, No_OpClass);
+ }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
0x3: csrrc({{
Rd = data;
data &= ~Rs1;
- }}, IsNonSpeculative, No_OpClass);
+ }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
0x5: csrrwi({{
Rd = data;
data = uimm;
- }}, IsNonSpeculative, No_OpClass);
+ }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
0x6: csrrsi({{
Rd = data;
data |= uimm;
- }}, IsNonSpeculative, No_OpClass);
+ }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
0x7: csrrci({{
Rd = data;
data &= ~uimm;
- }}, IsNonSpeculative, No_OpClass);
+ }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
}
}
+
+ 0x1e: M5Op::M5Op();
}
}