From: Tuan Ta Date: Thu, 1 Mar 2018 15:32:26 +0000 (-0500) Subject: riscv: throw IllegalInstFault when decoding invalid instructions X-Git-Tag: v19.0.0.0~2223 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=212649b01e90b28df6e1a66c1b98a944af5b05a9;p=gem5.git riscv: throw IllegalInstFault when decoding invalid instructions If an instruction is invalid, some assertions may in the decoder may fail the entire simulation. Instead, we want to raise an IllegalInstFault instead of failing immediately in the decoder if the invalid instruction is being speculatively executed. Change-Id: I5cb72ba06f07f173922f86897ddfdf677e8c702f Reviewed-on: https://gem5-review.googlesource.com/9261 Maintainer: Alec Roelke Reviewed-by: Monir Zaman Reviewed-by: Jason Lowe-Power --- diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index bbed650ca..e3992d712 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -117,7 +117,9 @@ decode QUADRANT default Unknown::unknown() { if (CIMM1 > 0) imm |= ~((uint64_t)0x1F); }}, {{ - assert(RC1 != 0); + if (RC1 == 0) { + fault = make_shared("source reg x0"); + } Rc1_sd = (int32_t)Rc1_sd + imm; }}); 0x2: c_li({{ @@ -125,7 +127,9 @@ decode QUADRANT default Unknown::unknown() { if (CIMM1 > 0) imm |= ~((uint64_t)0x1F); }}, {{ - assert(RC1 != 0); + if (RC1 == 0) { + fault = make_shared("source reg x0"); + } Rc1_sd = imm; }}); 0x3: decode RC1 { @@ -137,7 +141,9 @@ decode QUADRANT default Unknown::unknown() { if (CIMM1 > 0) imm |= ~((int64_t)0x1FF); }}, {{ - assert(imm != 0); + if (imm == 0) { + fault = make_shared("immediate = 0"); + } sp_sd = sp_sd + imm; }}); default: c_lui({{ @@ -145,8 +151,12 @@ decode QUADRANT default Unknown::unknown() { if (CIMM1 > 0) imm |= ~((uint64_t)0x1FFFF); }}, {{ - assert(RC1 != 0 && RC1 != 2); - assert(imm != 0); + if (RC1 == 0 || RC1 == 2) { + fault = make_shared("source reg x0"); + } + if (imm == 0) { + fault = make_shared("immediate = 0"); + } Rc1_sd = imm; }}); } @@ -155,14 +165,18 @@ decode QUADRANT default Unknown::unknown() { format CIOp { 0x0: c_srli({{ imm = CIMM5 | (CIMM1 << 5); - assert(imm != 0); }}, {{ + if (imm == 0) { + fault = make_shared("immediate = 0"); + } Rp1 = Rp1 >> imm; }}, uint64_t); 0x1: c_srai({{ imm = CIMM5 | (CIMM1 << 5); - assert(imm != 0); }}, {{ + if (imm == 0) { + fault = make_shared("immediate = 0"); + } Rp1_sd = Rp1_sd >> imm; }}, uint64_t); 0x2: c_andi({{ @@ -230,9 +244,13 @@ decode QUADRANT default Unknown::unknown() { 0x2: decode COPCODE { 0x0: CIOp::c_slli({{ imm = CIMM5 | (CIMM1 << 5); - assert(imm != 0); }}, {{ - assert(RC1 != 0); + if (imm == 0) { + fault = make_shared("immediate = 0"); + } + if (RC1 == 0) { + fault = make_shared("source reg x0"); + } Rc1 = Rc1 << imm; }}, uint64_t); format CompressedLoad { @@ -250,7 +268,9 @@ decode QUADRANT default Unknown::unknown() { CIMM1 << 5 | CIMM5<1:0> << 6; }}, {{ - assert(RC1 != 0); + if (RC1 == 0) { + fault = make_shared("source reg x0"); + } Rc1_sd = Mem_sw; }}, {{ EA = sp + offset; @@ -260,7 +280,9 @@ decode QUADRANT default Unknown::unknown() { CIMM1 << 5 | CIMM5<2:0> << 6; }}, {{ - assert(RC1 != 0); + if (RC1 == 0) { + fault = make_shared("source reg x0"); + } Rc1_sd = Mem_sd; }}, {{ EA = sp + offset; @@ -269,22 +291,31 @@ decode QUADRANT default Unknown::unknown() { 0x4: decode CFUNCT1 { 0x0: decode RC2 { 0x0: Jump::c_jr({{ - assert(RC1 != 0); + if (RC1 == 0) { + fault = make_shared("source reg x0"); + } NPC = Rc1; }}, IsIndirectControl, IsUncondControl, IsCall); default: CROp::c_mv({{ - assert(RC1 != 0); + if (RC1 == 0) { + fault = make_shared("source reg x0"); + } Rc1 = Rc2; }}); } 0x1: decode RC1 { 0x0: SystemOp::c_ebreak({{ - assert(RC2 == 0); + if (RC2 != 0) { + fault = make_shared("source reg x1"); + } fault = make_shared(); }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); default: decode RC2 { 0x0: Jump::c_jalr({{ - assert(RC1 != 0); + if (RC1 == 0) { + fault = make_shared + ("source reg x0"); + } ra = NPC; NPC = Rc1; }}, IsIndirectControl, IsUncondControl, IsCall); @@ -1218,7 +1249,9 @@ decode QUADRANT default Unknown::unknown() { }}, FloatCmpOp); } 0x20: fcvt_s_d({{ - assert(CONV_SGN == 1); + if (CONV_SGN != 1) { + fault = make_shared("CONV_SGN != 1"); + } float fd; if (issignalingnan(Fs1)) { fd = numeric_limits::quiet_NaN(); @@ -1229,7 +1262,9 @@ decode QUADRANT default Unknown::unknown() { Fd_bits = (uint64_t)reinterpret_cast(fd); }}, FloatCvtOp); 0x21: fcvt_d_s({{ - assert(CONV_SGN == 0); + if (CONV_SGN != 0) { + fault = make_shared("CONV_SGN != 0"); + } uint32_t temp; float fs1 = reinterpret_cast(temp = Fs1_bits); @@ -1241,7 +1276,9 @@ decode QUADRANT default Unknown::unknown() { } }}, FloatCvtOp); 0x2c: fsqrt_s({{ - assert(RS2 == 0); + if (RS2 != 0) { + fault = make_shared("source reg x1"); + } uint32_t temp; float fs1 = reinterpret_cast(temp = Fs1_bits); float fd; @@ -1253,7 +1290,9 @@ decode QUADRANT default Unknown::unknown() { Fd_bits = (uint64_t)reinterpret_cast(fd); }}, FloatSqrtOp); 0x2d: fsqrt_d({{ - assert(RS2 == 0); + if (RS2 != 0) { + fault = make_shared("source reg x1"); + } Fd = sqrt(Fs1); }}, FloatSqrtOp); 0x50: decode ROUND_MODE {