summaryrefslogtreecommitdiff
path: root/riscv/riscv.sail
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/riscv.sail')
-rw-r--r--riscv/riscv.sail355
1 files changed, 216 insertions, 139 deletions
diff --git a/riscv/riscv.sail b/riscv/riscv.sail
index a40ec53f..ed640ad3 100644
--- a/riscv/riscv.sail
+++ b/riscv/riscv.sail
@@ -293,12 +293,16 @@ function process_load(rd, addr, value, is_unsigned) =
}
function clause execute(LOAD(imm, rs1, rd, is_unsigned, width, aq, rl)) =
- let addr : xlenbits = X(rs1) + EXTS(imm) in
- match width {
- BYTE => process_load(rd, addr, mem_read(addr, 1, aq, rl, false), is_unsigned),
- HALF => process_load(rd, addr, mem_read(addr, 2, aq, rl, false), is_unsigned),
- WORD => process_load(rd, addr, mem_read(addr, 4, aq, rl, false), is_unsigned),
- DOUBLE => process_load(rd, addr, mem_read(addr, 8, aq, rl, false), is_unsigned)
+ let vaddr : xlenbits = X(rs1) + EXTS(imm) in
+ match translateAddr(vaddr, Read, Data) {
+ TR_Failure(e) => handle_mem_exception(vaddr, e),
+ TR_Address(addr) =>
+ match width {
+ BYTE => process_load(rd, vaddr, mem_read(addr, 1, aq, rl, false), is_unsigned),
+ HALF => process_load(rd, vaddr, mem_read(addr, 2, aq, rl, false), is_unsigned),
+ WORD => process_load(rd, vaddr, mem_read(addr, 4, aq, rl, false), is_unsigned),
+ DOUBLE => process_load(rd, vaddr, mem_read(addr, 8, aq, rl, false), is_unsigned)
+ }
}
/* FIXME: aq/rl are getting dropped */
@@ -311,7 +315,8 @@ function clause print_insn (LOAD(imm, rs1, rd, is_unsigned, width, aq, rl)) =
(HALF, true) => "lhu ",
(WORD, false) => "lw ",
(WORD, true) => "lwu ",
- (_, _) => "ld.bad "
+ (DOUBLE, false) => "ld ",
+ (DOUBLE, true) => "ldu "
} in
insn ^ rd ^ ", " ^ rs1 ^ ", " ^ BitStr(imm)
@@ -323,29 +328,35 @@ function clause decode imm7 : bits(7) @ rs2 : regbits @ rs1 : regbits @ 0b001 @
function clause decode imm7 : bits(7) @ rs2 : regbits @ rs1 : regbits @ 0b010 @ imm5 : bits(5) @ 0b0100011 = Some(STORE(imm7 @ imm5, rs2, rs1, WORD, false, false))
function clause decode imm7 : bits(7) @ rs2 : regbits @ rs1 : regbits @ 0b011 @ imm5 : bits(5) @ 0b0100011 = Some(STORE(imm7 @ imm5, rs2, rs1, DOUBLE, false, false))
+/* NOTE: Currently, we only EA if address translation is successful.
+ This may need revisiting. */
function clause execute (STORE(imm, rs2, rs1, width, aq, rl)) =
- let addr : xlenbits = X(rs1) + EXTS(imm) in
- let eares : MemoryOpResult(unit) = match width {
- BYTE => mem_write_ea(addr, 1, aq, rl, false),
- HALF => mem_write_ea(addr, 2, aq, rl, false),
- WORD => mem_write_ea(addr, 4, aq, rl, false),
- DOUBLE => mem_write_ea(addr, 8, aq, rl, false)
- } in
- match (eares) {
- MemException(e) => handle_mem_exception(addr, e),
- MemValue(_) => {
- let rs2_val = X(rs2) in
- let res : MemoryOpResult(unit) = match width {
- BYTE => mem_write_value(addr, 1, rs2_val[7..0], aq, rl, false),
- HALF => mem_write_value(addr, 2, rs2_val[15..0], aq, rl, false),
- WORD => mem_write_value(addr, 4, rs2_val[31..0], aq, rl, false),
- DOUBLE => mem_write_value(addr, 8, rs2_val, aq, rl, false)
+ let vaddr : xlenbits = X(rs1) + EXTS(imm) in
+ match translateAddr(vaddr, Write, Data) {
+ TR_Failure(e) => handle_mem_exception(vaddr, e),
+ TR_Address(addr) =>
+ let eares : MemoryOpResult(unit) = match width {
+ BYTE => mem_write_ea(addr, 1, aq, rl, false),
+ HALF => mem_write_ea(addr, 2, aq, rl, false),
+ WORD => mem_write_ea(addr, 4, aq, rl, false),
+ DOUBLE => mem_write_ea(addr, 8, aq, rl, false)
} in
- match (res) {
- MemValue(_) => (),
- MemException(e) => handle_mem_exception(addr, e)
+ match (eares) {
+ MemException(e) => handle_mem_exception(addr, e),
+ MemValue(_) => {
+ let rs2_val = X(rs2) in
+ let res : MemoryOpResult(unit) = match width {
+ BYTE => mem_write_value(addr, 1, rs2_val[7..0], aq, rl, false),
+ HALF => mem_write_value(addr, 2, rs2_val[15..0], aq, rl, false),
+ WORD => mem_write_value(addr, 4, rs2_val[31..0], aq, rl, false),
+ DOUBLE => mem_write_value(addr, 8, rs2_val, aq, rl, false)
+ } in
+ match (res) {
+ MemValue(_) => (),
+ MemException(e) => handle_mem_exception(addr, e)
+ }
+ }
}
- }
}
/* FIXME: aq/rl are getting dropped */
@@ -581,7 +592,7 @@ function clause execute ECALL() =
Machine => E_M_EnvCall
},
excinfo = (None() : option(xlenbits)) } in
- nextPC = handle_exception_ctl(cur_privilege, CTL_TRAP(t), PC)
+ nextPC = handle_exception(cur_privilege, CTL_TRAP(t), PC)
function clause print_insn (ECALL()) =
"ecall"
@@ -591,8 +602,12 @@ union clause ast = MRET : unit
function clause decode 0b0011000 @ 0b00010 @ 0b00000 @ 0b000 @ 0b00000 @ 0b1110011 = Some(MRET())
-function clause execute MRET() =
- nextPC = handle_exception_ctl(cur_privilege, CTL_MRET(), PC)
+function clause execute MRET() = {
+ if cur_privilege == Machine then
+ nextPC = handle_exception(cur_privilege, CTL_MRET(), PC)
+ else
+ handle_illegal()
+}
function clause print_insn (MRET()) =
"mret"
@@ -600,10 +615,16 @@ function clause print_insn (MRET()) =
/* ****************************************************************** */
union clause ast = SRET : unit
-function clause decode 0b0001000 @ 0b00010 @ 0b00000 @ 0b000 @ 0b00000 @ 0b1110011 = Some(MRET())
+function clause decode 0b0001000 @ 0b00010 @ 0b00000 @ 0b000 @ 0b00000 @ 0b1110011 = Some(SRET())
function clause execute SRET() =
- nextPC = handle_exception_ctl(cur_privilege, CTL_SRET(), PC)
+ match cur_privilege {
+ User => handle_illegal(),
+ Supervisor => if mstatus.TSR() == true
+ then handle_illegal()
+ else nextPC = handle_exception(cur_privilege, CTL_SRET(), PC),
+ Machine => nextPC = handle_exception(cur_privilege, CTL_SRET(), PC)
+ }
function clause print_insn (SRET()) =
"sret"
@@ -619,6 +640,48 @@ function clause print_insn (EBREAK()) =
"ebreak"
/* ****************************************************************** */
+union clause ast = WFI : unit
+
+function clause decode 0b000100000101 @ 0b00000 @ 0b000 @ 0b00000 @ 0b1110011 = Some(WFI())
+
+function clause execute WFI() = {
+ match cur_privilege {
+ Machine => (),
+ Supervisor => if mstatus.TW() == true
+ then handle_illegal()
+ else (),
+ User => handle_illegal()
+ }
+}
+
+function clause print_insn (WFI()) =
+ "wfi"
+
+/* ****************************************************************** */
+union clause ast = SFENCE_VMA : (regbits, regbits)
+
+function clause decode 0b0001001 @ rs2 : regbits @ rs1 : regbits @ 0b000 @ 0b00000 @ 0b1110011 = Some(SFENCE_VMA(rs1, rs2))
+
+function clause execute SFENCE_VMA(rs1, rs2) = {
+ /* FIXME: spec leaves unspecified what happens if this is executed in M-mode.
+ We assume it is the same as S-mode, which is definitely wrong.
+ */
+ if cur_privilege == User then handle_illegal()
+ else match (architecture(mstatus.SXL()), mstatus.TVM()) {
+ (Some(RV64), true) => handle_illegal(),
+ (Some(RV64), false) => {
+ let addr : option(vaddr39) = if rs1 == 0 then None() else Some(X(rs1)[38 .. 0]);
+ let asid : option(asid64) = if rs2 == 0 then None() else Some(X(rs2)[15 .. 0]);
+ flushTLB(asid, addr)
+ },
+ (_, _) => internal_error("unimplemented sfence architecture")
+ }
+}
+
+function clause print_insn (SFENCE_VMA(rs1, rs2)) =
+ "sfence.vma " ^ rs1 ^ ", " ^ rs2
+
+/* ****************************************************************** */
union clause ast = LOADRES : (bool, bool, regbits, word_width, regbits)
function clause decode 0b00010 @ [aq] @ [rl] @ 0b00000 @ rs1 : regbits @ 0b010 @ rd : regbits @ 0b0101111 = Some(LOADRES(aq, rl, rs1, WORD, rd))
@@ -627,11 +690,15 @@ function clause decode 0b00010 @ [aq] @ [rl] @ 0b00000 @ rs1 : regbits @ 0b011 @
val process_loadres : forall 'n, 0 < 'n <= 8. (regbits, xlenbits, MemoryOpResult(bits(8 * 'n)), bool) -> unit
function clause execute(LOADRES(aq, rl, rs1, width, rd)) =
- let addr : xlenbits = X(rs1) in
- match width {
- WORD => process_load(rd, addr, mem_read(addr, 4, aq, rl, true), false),
- DOUBLE => process_load(rd, addr, mem_read(addr, 8, aq, rl, true), false),
- _ => internal_error("LOADRES expected WORD or DOUBLE")
+ let vaddr : xlenbits = X(rs1) in
+ match translateAddr(vaddr, Read, Data) {
+ TR_Failure(e) => handle_mem_exception(vaddr, e),
+ TR_Address(addr) =>
+ match width {
+ WORD => process_load(rd, addr, mem_read(addr, 4, aq, rl, true), false),
+ DOUBLE => process_load(rd, addr, mem_read(addr, 8, aq, rl, true), false),
+ _ => internal_error("LOADRES expected WORD or DOUBLE")
+ }
}
/* FIXME */
@@ -650,29 +717,36 @@ union clause ast = STORECON : (bool, bool, regbits, regbits, word_width, regbits
function clause decode 0b00011 @ [aq] @ [rl] @ rs2 : regbits @ rs1 : regbits @ 0b010 @ rd : regbits @ 0b0101111 = Some(STORECON(aq, rl, rs2, rs1, WORD, rd))
function clause decode 0b00011 @ [aq] @ [rl] @ rs2 : regbits @ rs1 : regbits @ 0b011 @ rd : regbits @ 0b0101111 = Some(STORECON(aq, rl, rs2, rs1, DOUBLE, rd))
+/* NOTE: Currently, we only EA if address translation is successful.
+ This may need revisiting. */
function clause execute (STORECON(aq, rl, rs2, rs1, width, rd)) = {
status : bits(1) = if speculate_conditional_success() then 0b0 else 0b1;
X(rd) = EXTZ(status);
if status == 0b1 then () else {
- addr : xlenbits = X(rs1);
- let eares : MemoryOpResult(unit) = match width {
- WORD => mem_write_ea(addr, 4, aq, rl, true),
- DOUBLE => mem_write_ea(addr, 8, aq, rl, true),
- _ => internal_error("STORECON expected word or double")
- };
- match (eares) {
- MemException(e) => handle_mem_exception(addr, e),
- MemValue(_) => {
- rs2_val = X(rs2);
- let res : MemoryOpResult(unit) = match width {
- WORD => mem_write_value(addr, 4, rs2_val[31..0], aq, rl, true),
- DOUBLE => mem_write_value(addr, 8, rs2_val, aq, rl, true),
+ vaddr : xlenbits = X(rs1);
+ match translateAddr(vaddr, Write, Data) {
+ TR_Failure(e) => handle_mem_exception(vaddr, e),
+ TR_Address(addr) => {
+ let eares : MemoryOpResult(unit) = match width {
+ WORD => mem_write_ea(addr, 4, aq, rl, true),
+ DOUBLE => mem_write_ea(addr, 8, aq, rl, true),
_ => internal_error("STORECON expected word or double")
- } in
- match (res) {
- MemValue(_) => (),
- MemException(e) => handle_mem_exception(addr, e)
+ };
+ match (eares) {
+ MemException(e) => handle_mem_exception(addr, e),
+ MemValue(_) => {
+ rs2_val = X(rs2);
+ let res : MemoryOpResult(unit) = match width {
+ WORD => mem_write_value(addr, 4, rs2_val[31..0], aq, rl, true),
+ DOUBLE => mem_write_value(addr, 8, rs2_val, aq, rl, true),
+ _ => internal_error("STORECON expected word or double")
+ } in
+ match (res) {
+ MemValue(_) => (),
+ MemException(e) => handle_mem_exception(addr, e)
+ }
+ }
}
}
}
@@ -711,49 +785,55 @@ function clause decode 0b11000 @ [aq] @ [rl] @ rs2 : regbits @ rs1 : regbits @ 0
function clause decode 0b11100 @ [aq] @ [rl] @ rs2 : regbits @ rs1 : regbits @ 0b010 @ rd : regbits @ 0b0101111 = Some(AMO(AMOMAXU, aq, rl, rs2, rs1, WORD, rd))
function clause decode 0b11100 @ [aq] @ [rl] @ rs2 : regbits @ rs1 : regbits @ 0b011 @ rd : regbits @ 0b0101111 = Some(AMO(AMOMAXU, aq, rl, rs2, rs1, DOUBLE, rd))
+/* NOTE: Currently, we only EA if address translation is successful.
+ This may need revisiting. */
function clause execute (AMO(op, aq, rl, rs2, rs1, width, rd)) = {
- addr : xlenbits = X(rs1);
-
- let eares : MemoryOpResult(unit) = match width {
- WORD => mem_write_ea(addr, 4, aq & rl, rl, true),
- DOUBLE => mem_write_ea(addr, 8, aq & rl, rl, true),
- _ => internal_error ("AMO expected WORD or DOUBLE")
- };
- match (eares) {
- MemException(e) => handle_mem_exception(addr, e),
- MemValue(_) => {
- let rval : MemoryOpResult(xlenbits) = match width {
- WORD => extend_value(false, mem_read(addr, 4, aq, aq & rl, true)),
- DOUBLE => extend_value(false, mem_read(addr, 8, aq, aq & rl, true)),
- _ => internal_error ("AMO expected WORD or DOUBLE")
+ vaddr : xlenbits = X(rs1);
+ match translateAddr(vaddr, ReadWrite, Data) {
+ TR_Failure(e) => handle_mem_exception(vaddr, e),
+ TR_Address(addr) => {
+ let eares : MemoryOpResult(unit) = match width {
+ WORD => mem_write_ea(addr, 4, aq & rl, rl, true),
+ DOUBLE => mem_write_ea(addr, 8, aq & rl, rl, true),
+ _ => internal_error ("AMO expected WORD or DOUBLE")
};
- match (rval) {
+ match (eares) {
MemException(e) => handle_mem_exception(addr, e),
- MemValue(loaded) => {
- rs2_val : xlenbits = X(rs2);
- result : xlenbits =
- match op {
- AMOSWAP => rs2_val,
- AMOADD => rs2_val + loaded,
- AMOXOR => rs2_val ^ loaded,
- AMOAND => rs2_val & loaded,
- AMOOR => rs2_val | loaded,
-
- /* Have to convert number to vector here. Check this */
- AMOMIN => vector64(min(signed(rs2_val), signed(loaded))),
- AMOMAX => vector64(max(signed(rs2_val), signed(loaded))),
- AMOMINU => vector64(min(unsigned(rs2_val), unsigned(loaded))),
- AMOMAXU => vector64(max(unsigned(rs2_val), unsigned(loaded)))
- };
-
- let wval : MemoryOpResult(unit) = match width {
- WORD => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),
- DOUBLE => mem_write_value(addr, 8, result, aq & rl, rl, true),
- _ => internal_error("AMO expected WORD or DOUBLE")
+ MemValue(_) => {
+ let rval : MemoryOpResult(xlenbits) = match width {
+ WORD => extend_value(false, mem_read(addr, 4, aq, aq & rl, true)),
+ DOUBLE => extend_value(false, mem_read(addr, 8, aq, aq & rl, true)),
+ _ => internal_error ("AMO expected WORD or DOUBLE")
};
- match (wval) {
- MemValue(_) => X(rd) = loaded,
- MemException(e) => handle_mem_exception(addr, e)
+ match (rval) {
+ MemException(e) => handle_mem_exception(addr, e),
+ MemValue(loaded) => {
+ rs2_val : xlenbits = X(rs2);
+ result : xlenbits =
+ match op {
+ AMOSWAP => rs2_val,
+ AMOADD => rs2_val + loaded,
+ AMOXOR => rs2_val ^ loaded,
+ AMOAND => rs2_val & loaded,
+ AMOOR => rs2_val | loaded,
+
+ /* Have to convert number to vector here. Check this */
+ AMOMIN => vector64(min(signed(rs2_val), signed(loaded))),
+ AMOMAX => vector64(max(signed(rs2_val), signed(loaded))),
+ AMOMINU => vector64(min(unsigned(rs2_val), unsigned(loaded))),
+ AMOMAXU => vector64(max(unsigned(rs2_val), unsigned(loaded)))
+ };
+
+ let wval : MemoryOpResult(unit) = match width {
+ WORD => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),
+ DOUBLE => mem_write_value(addr, 8, result, aq & rl, rl, true),
+ _ => internal_error("AMO expected WORD or DOUBLE")
+ };
+ match (wval) {
+ MemValue(_) => X(rd) = loaded,
+ MemException(e) => handle_mem_exception(addr, e)
+ }
+ }
}
}
}
@@ -796,7 +876,7 @@ function clause decode csr : bits(12) @ rs1 : regbits @ 0b101 @ rd : regbits @ 0
function clause decode csr : bits(12) @ rs1 : regbits @ 0b110 @ rd : regbits @ 0b1110011 = Some(CSR (csr, rs1, rd, true, CSRRS))
function clause decode csr : bits(12) @ rs1 : regbits @ 0b111 @ rd : regbits @ 0b1110011 = Some(CSR (csr, rs1, rd, true, CSRRC))
-function readCSR csr: bits(12) -> xlenbits =
+function readCSR csr : csreg -> xlenbits =
match csr {
/* machine mode */
0xF11 => mvendorid,
@@ -804,6 +884,7 @@ function readCSR csr: bits(12) -> xlenbits =
0xF13 => mimpid,
0xF14 => mhartid,
0x300 => mstatus.bits(),
+ 0x301 => misa.bits(),
0x302 => medeleg.bits(),
0x303 => mideleg.bits(),
0x304 => mie.bits(),
@@ -832,60 +913,60 @@ function readCSR csr: bits(12) -> xlenbits =
0xC01 => mtime,
0xC02 => minstret,
+ /* trigger/debug */
+ 0x7a0 => ~(tselect), /* this indicates we don't have any trigger support */
+
_ => { print_bits("unhandled read to CSR ", csr);
0x0000_0000_0000_0000 }
}
-function writeCSR (csr : bits(12), value : xlenbits) -> unit =
+function writeCSR (csr : csreg, value : xlenbits) -> unit =
+ let res : option(xlenbits) =
match csr {
/* machine mode */
- 0x300 => mstatus = legalize_mstatus(mstatus, value),
- 0x302 => medeleg = legalize_medeleg(medeleg, value),
- 0x303 => mideleg = legalize_mideleg(mideleg, value),
- 0x304 => mie = legalize_mie(mie, value),
- 0x305 => mtvec = legalize_tvec(mtvec, value),
- 0x340 => mscratch = value,
- 0x341 => mepc = legalize_xepc(value),
- 0x342 => mcause->bits() = value,
- 0x343 => mtval = value,
- 0x344 => mip = legalize_mip(mip, value),
+ 0x300 => { mstatus = legalize_mstatus(mstatus, value); Some(mstatus.bits()) },
+ 0x302 => { medeleg = legalize_medeleg(medeleg, value); Some(medeleg.bits()) },
+ 0x303 => { mideleg = legalize_mideleg(mideleg, value); Some(mideleg.bits()) },
+ 0x304 => { mie = legalize_mie(mie, value); Some(mie.bits()) },
+ 0x305 => { mtvec = legalize_tvec(mtvec, value); Some(mtvec.bits()) },
+ 0x340 => { mscratch = value; Some(mscratch) },
+ 0x341 => { mepc = legalize_xepc(value); Some(mepc) },
+ 0x342 => { mcause->bits() = value; Some(mcause.bits()) },
+ 0x343 => { mtval = value; Some(mtval) },
+ 0x344 => { mip = legalize_mip(mip, value); Some(mip.bits()) },
/* supervisor mode */
- 0x100 => mstatus = legalize_sstatus(mstatus, value),
- 0x102 => sedeleg = legalize_sedeleg(sedeleg, value),
- 0x103 => sideleg->bits() = value, /* TODO: does this need legalization? */
- 0x104 => mie = legalize_sie(mie, mideleg, value),
- 0x105 => stvec = legalize_tvec(stvec, value),
- 0x140 => sscratch = value,
- 0x141 => sepc = legalize_xepc(value),
- 0x142 => scause->bits() = value,
- 0x143 => stval = value,
- 0x144 => mip = legalize_sip(mip, mideleg, value),
- 0x180 => satp = legalize_satp(cur_Architecture(), satp, value),
-
- _ => print_bits("unhandled write to CSR ", csr)
+ 0x100 => { mstatus = legalize_sstatus(mstatus, value); Some(mstatus.bits()) },
+ 0x102 => { sedeleg = legalize_sedeleg(sedeleg, value); Some(sedeleg.bits()) },
+ 0x103 => { sideleg->bits() = value; Some(sideleg.bits()) }, /* TODO: does this need legalization? */
+ 0x104 => { mie = legalize_sie(mie, mideleg, value); Some(mie.bits()) },
+ 0x105 => { stvec = legalize_tvec(stvec, value); Some(stvec.bits()) },
+ 0x140 => { sscratch = value; Some(sscratch) },
+ 0x141 => { sepc = legalize_xepc(value); Some(sepc) },
+ 0x142 => { scause->bits() = value; Some(scause.bits()) },
+ 0x143 => { stval = value; Some(stval) },
+ 0x144 => { mip = legalize_sip(mip, mideleg, value); Some(mip.bits()) },
+ 0x180 => { satp = legalize_satp(cur_Architecture(), satp, value); Some(satp) },
+
+ /* trigger/debug */
+ 0x7a0 => { tselect = value; Some(tselect) },
+
+ _ => None()
+ } in
+ match res {
+ Some(v) => print("CSR " ^ csr ^ " <- " ^ BitStr(v) ^ " (input: " ^ BitStr(value) ^ ")"),
+ None() => print_bits("unhandled write to CSR ", csr)
}
-function haveCSRPriv (csr : bits(12), isWrite : bool) -> bool =
- let isRO = csr[11..10] == 0b11 in
- ~ (isRO & isWrite) /* XXX TODO check priv */
-
-val signalIllegalInstruction : unit -> unit effect {escape}
-function signalIllegalInstruction () = not_implemented ("illegal instruction")
-
function clause execute CSR(csr, rs1, rd, is_imm, op) =
let rs1_val : xlenbits = if is_imm then EXTZ(rs1) else X(rs1) in
let isWrite : bool = match op {
CSRRW => true,
_ => if is_imm then unsigned(rs1_val) != 0 else unsigned(rs1) != 0
} in
- if ~ (check_CSR(csr, cur_privilege, isWrite)) then {
- let instr : xlenbits = cur_inst;
- let t : sync_exception =
- struct { trap = E_Illegal_Instr,
- excinfo = Some (instr) } in
- nextPC = handle_exception_ctl(cur_privilege, CTL_TRAP(t), PC)
- } else {
+ if ~ (check_CSR(csr, cur_privilege, isWrite))
+ then handle_illegal()
+ else {
let csr_val = readCSR(csr); /* could have side-effects, so technically shouldn't perform for CSRW[I] with rd == 0 */
if isWrite then {
let new_val : xlenbits = match op {
@@ -908,7 +989,8 @@ function clause print_insn (CSR(csr, rs1, rd, is_imm, op)) =
(CSRRC, true) => "csrrci ",
(CSRRC, false) => "csrrc "
} in
- insn ^ rd ^ ", " ^ rs1 ^ ", " ^ csr_name(csr)
+ let rs1_str : string = if is_imm then BitStr(rs1) else reg_name_abi(rs1) in
+ insn ^ rd ^ ", " ^ rs1_str ^ ", " ^ csr_name(csr)
/* ****************************************************************** */
union clause ast = NOP : unit
@@ -928,12 +1010,7 @@ union clause ast = ILLEGAL : unit
function clause decodeCompressed (0b0000 @ 0b00000 @ 0b00000 @ 0b00) : bits(16) = Some(ILLEGAL())
-function clause execute ILLEGAL() = {
- let t : sync_exception =
- struct { trap = E_Illegal_Instr,
- excinfo = Some (EXTZ(0b0)) } in
- nextPC = handle_exception_ctl(cur_privilege, CTL_TRAP(t), PC)
-}
+function clause execute ILLEGAL() = handle_illegal ()
function clause print_insn (ILLEGAL()) =
"illegal"