From 3241d6a62f9c70db645dabc5e17fae9c408683f0 Mon Sep 17 00:00:00 2001 From: Neelay Sant Date: Wed, 5 Feb 2025 16:39:44 +0000 Subject: [PATCH 1/5] RISC-V: Deduplicate Addi OpCode --- src/riscv/lib/src/interpreter/rv32a.rs | 3 +- src/riscv/lib/src/interpreter/rv32c.rs | 12 +++++- src/riscv/lib/src/interpreter/rv32i.rs | 24 +++++------ src/riscv/lib/src/machine_state.rs | 15 +++---- .../lib/src/machine_state/instruction.rs | 13 +++--- .../machine_state/instruction/constructors.rs | 40 +++++++++++++++++-- .../instruction/tagged_instruction.rs | 15 ++++--- src/riscv/lib/src/parser.rs | 27 +++++++------ src/riscv/lib/src/parser/instruction.rs | 10 ++++- .../lib/tests/expected/jstz/state_hash_final | 2 +- 10 files changed, 107 insertions(+), 54 deletions(-) diff --git a/src/riscv/lib/src/interpreter/rv32a.rs b/src/riscv/lib/src/interpreter/rv32a.rs index a26cf1409a27..a699646474e8 100644 --- a/src/riscv/lib/src/interpreter/rv32a.rs +++ b/src/riscv/lib/src/interpreter/rv32a.rs @@ -234,6 +234,7 @@ mod test { macro_rules! test_lrsc { ($name:ident, $lr: ident, $sc: ident, $align: expr, $t: ident) => { backend_test!($name, F, { + use $crate::machine_state::registers::nz; let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); @@ -256,7 +257,7 @@ mod test { // Correct sequence of LR.x / SC.y instructions // SC.x succeeds and stores the expected value state.$lr(a0, a1, a2, false, false)?; - state.hart.xregisters.run_addi(imm, a2, a1); + state.hart.xregisters.run_addi(imm, nz::a2, nz::a1); state.$sc(a0, a1, a2, false, false)?; let res = state.hart.xregisters.read(a2); let val: $t = state.read_from_address(r1_addr)?; diff --git a/src/riscv/lib/src/interpreter/rv32c.rs b/src/riscv/lib/src/interpreter/rv32c.rs index 0ef6d48ce5d2..01921cd4275b 100644 --- a/src/riscv/lib/src/interpreter/rv32c.rs +++ b/src/riscv/lib/src/interpreter/rv32c.rs @@ -122,7 +122,11 @@ where /// encoded in the instruction (see U:C-16.5). pub fn run_caddi16sp(&mut self, imm: i64) { debug_assert!(imm != 0 && imm % 16 == 0); - self.run_addi(imm, sp, sp) + // Return the lower XLEN (64 bits in our case) bits of the addition + // Irrespective of sign, the result is the same, casting to u64 for addition + let rval = self.read(sp); + let result = rval.wrapping_add(imm as u64); + self.write(sp, result) } /// `C.ADDI4SPN` CIW-type compressed instruction @@ -133,7 +137,11 @@ where /// encoded in the instruction (see U:C-16.5). pub fn run_caddi4spn(&mut self, imm: i64, rd: XRegister) { debug_assert!(imm > 0 && imm % 4 == 0); - self.run_addi(imm, sp, rd) + // Return the lower XLEN (64 bits in our case) bits of the addition + // Irrespective of sign, the result is the same, casting to u64 for addition + let rval = self.read(sp); + let result = rval.wrapping_add(imm as u64); + self.write(rd, result) } /// `C.SLLI` CI-type compressed instruction diff --git a/src/riscv/lib/src/interpreter/rv32i.rs b/src/riscv/lib/src/interpreter/rv32i.rs index eac17756e78c..a47e3460fdb4 100644 --- a/src/riscv/lib/src/interpreter/rv32i.rs +++ b/src/riscv/lib/src/interpreter/rv32i.rs @@ -26,12 +26,12 @@ where /// `ADDI` I-type instruction /// /// Add `imm` to val(rs1) and store the result in `rd` - pub fn run_addi(&mut self, imm: i64, rs1: XRegister, rd: XRegister) { + pub fn run_addi(&mut self, imm: i64, rs1: NonZeroXRegister, rd: NonZeroXRegister) { // Return the lower XLEN (64 bits in our case) bits of the addition // Irrespective of sign, the result is the same, casting to u64 for addition - let rval = self.read(rs1); + let rval = self.read_nz(rs1); let result = rval.wrapping_add(imm as u64); - self.write(rd, result) + self.write_nz(rd, result) } /// `SUB` R-type instruction @@ -396,7 +396,7 @@ mod tests { main_memory::{tests::T1K, Address}, mode::Mode, registers::{ - a0, a1, a2, a3, a4, fa0, nz, t0, t1, t2, t3, t4, XRegisters, XRegistersLayout, + a0, a1, a2, a3, a4, fa0, nz, t0, t1, t2, t3, XRegisters, XRegistersLayout, }, MachineCoreState, MachineCoreStateLayout, ProgramCounterUpdate, }, @@ -410,20 +410,20 @@ mod tests { backend_test!(test_add_sub, F, { let imm_rs1_rd_res = [ - (0_i64, 0_u64, t3, 0_u64), - (0, 0xFFF0_0420, t2, 0xFFF0_0420), - (-1, 0, t4, 0xFFFF_FFFF_FFFF_FFFF), + (0_i64, 0_u64, nz::t3, 0_u64), + (0, 0xFFF0_0420, nz::t2, 0xFFF0_0420), + (-1, 0, nz::t4, 0xFFFF_FFFF_FFFF_FFFF), ( 1_000_000, -123_000_987_i64 as u64, - a2, + nz::a2, -122_000_987_i64 as u64, ), - (1_000_000, 123_000_987, a2, 124_000_987), + (1_000_000, 123_000_987, nz::a2, 124_000_987), ( -1, -321_000_000_000_i64 as u64, - a1, + nz::a1, -321_000_000_001_i64 as u64, ), ]; @@ -433,8 +433,8 @@ mod tests { state.hart.xregisters.write(a0, rs1); state.hart.xregisters.write(t0, imm as u64); - state.hart.xregisters.run_addi(imm, a0, rd); - assert_eq!(state.hart.xregisters.read(rd), res); + state.hart.xregisters.run_addi(imm, nz::a0, rd); + assert_eq!(state.hart.xregisters.read_nz(rd), res); run_add(&mut state, nz::a0, nz::t0, nz::a0); assert_eq!(state.hart.xregisters.read(a0), res); // test sub with: res - imm = rs1 and res - rs1 = imm diff --git a/src/riscv/lib/src/machine_state.rs b/src/riscv/lib/src/machine_state.rs index b981f5a9a6af..8b7e6382effb 100644 --- a/src/riscv/lib/src/machine_state.rs +++ b/src/riscv/lib/src/machine_state.rs @@ -687,9 +687,10 @@ mod tests { }, parser::{ instruction::{ - CIBNZTypeArgs, ITypeArgs, Instr, InstrCacheable, InstrWidth, SBTypeArgs, + CIBNZTypeArgs, Instr, InstrCacheable, InstrWidth, SBTypeArgs, SplitITypeArgs, }, parse_block, + XRegisterParsed::*, }, state_backend::{ test_helpers::{assert_eq_struct, copy_via_serde, TestBackendFactory}, @@ -884,9 +885,9 @@ mod tests { const I_LOAD_6_INTO_T2: u32 = 0b11000000000001110010011; assert_eq!( parse_block(&I_LOAD_6_INTO_T2.to_le_bytes()), - [Instr::Cacheable(InstrCacheable::Addi(ITypeArgs { - rd: t2, - rs1: zero, + [Instr::Cacheable(InstrCacheable::Addi(SplitITypeArgs { + rd: NonZero(nz::t2), + rs1: X0, imm: 6, }))] ); @@ -895,9 +896,9 @@ mod tests { const I_LOAD_5_INTO_T2: u32 = 0b10100000000001110010011; assert_eq!( parse_block(&I_LOAD_5_INTO_T2.to_le_bytes()), - [Instr::Cacheable(InstrCacheable::Addi(ITypeArgs { - rd: t2, - rs1: zero, + [Instr::Cacheable(InstrCacheable::Addi(SplitITypeArgs { + rd: NonZero(nz::t2), + rs1: X0, imm: 5, }))] ); diff --git a/src/riscv/lib/src/machine_state/instruction.rs b/src/riscv/lib/src/machine_state/instruction.rs index bf1d84b1a03d..0fb5aec066df 100644 --- a/src/riscv/lib/src/machine_state/instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction.rs @@ -708,14 +708,16 @@ macro_rules! impl_r_type { } macro_rules! impl_i_type { - ($fn: ident) => { + ($fn: ident, non_zero) => { // SAFETY: This function must only be called on an `Args` belonging // to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, ) -> Result { - core.hart.xregisters.$fn(self.imm, self.rs1.x, self.rd.x); + core.hart + .xregisters + .$fn(self.imm, self.rs1.nzx, self.rd.nzx); Ok(Next(self.width)) } }; @@ -1087,7 +1089,7 @@ impl Args { impl_r_type!(run_sraw, non_zero_rd); // RV64I I-type instructions - impl_i_type!(run_addi); + impl_i_type!(run_addi, non_zero); impl_i_type!(run_addiw, non_zero_rd); impl_i_type!(run_xori, non_zero_rd); impl_i_type!(run_ori, non_zero_rd); @@ -1422,10 +1424,7 @@ impl From<&InstrCacheable> for Instruction { }, // RV64I I-type instructions - InstrCacheable::Addi(args) => Instruction { - opcode: OpCode::Addi, - args: args.to_args(InstrWidth::Uncompressed), - }, + InstrCacheable::Addi(args) => Instruction::from_ic_addi(args), InstrCacheable::Addiw(args) => Instruction { opcode: OpCode::Addiw, args: args.to_args(InstrWidth::Uncompressed), diff --git a/src/riscv/lib/src/machine_state/instruction/constructors.rs b/src/riscv/lib/src/machine_state/instruction/constructors.rs index c5d6b8249b7a..25a857cef28b 100644 --- a/src/riscv/lib/src/machine_state/instruction/constructors.rs +++ b/src/riscv/lib/src/machine_state/instruction/constructors.rs @@ -7,7 +7,7 @@ use crate::{ default::ConstDefault, machine_state::registers::NonZeroXRegister, parser::{ - instruction::{InstrWidth, NonZeroRdRTypeArgs}, + instruction::{InstrWidth, NonZeroRdRTypeArgs, SplitITypeArgs}, split_x0, XRegisterParsed, }, }; @@ -54,7 +54,7 @@ impl Instruction { opcode: OpCode::Li, args: Args { rd: rd.into(), - // We are adding a default values for rs1 and rs2 as NonZeroXRegister::x1 + // We are adding default values for rs1 and rs2 as NonZeroXRegister::x1 // to be explicit that it is of NonZeroXRegister type. rs1: NonZeroXRegister::x1.into(), rs2: NonZeroXRegister::x1.into(), @@ -70,7 +70,7 @@ impl Instruction { Self { opcode: OpCode::Nop, args: Args { - // We are adding a default values for rd, rs1 and rs2 as NonZeroXRegister::x1 + // We are adding default values for rd, rs1 and rs2 as NonZeroXRegister::x1 // to be explicit that they are of NonZeroXRegister type. rd: NonZeroXRegister::x1.into(), rs1: NonZeroXRegister::x1.into(), @@ -80,6 +80,28 @@ impl Instruction { }, } } + + /// Create a new [`Instruction`] with the appropriate [`ArgsShape`] for the `Addi` [`OpCode`]. + pub(crate) fn new_addi( + rd: NonZeroXRegister, + rs1: NonZeroXRegister, + imm: i64, + width: InstrWidth, + ) -> Self { + Self { + opcode: OpCode::Addi, + args: Args { + rd: rd.into(), + rs1: rs1.into(), + // We are adding a default value for rs2 as NonZeroXRegister::x1 + // to be explicit that it is of NonZeroXRegister type. + rs2: NonZeroXRegister::x1.into(), + imm, + width, + ..Args::DEFAULT + }, + } + } } impl Instruction { @@ -96,4 +118,16 @@ impl Instruction { } } } + + /// Convert [`InstrCacheable::Addi`] according to whether registers are non-zero. + pub(super) fn from_ic_addi(args: &SplitITypeArgs) -> Instruction { + use XRegisterParsed as X; + match (args.rd, args.rs1) { + (X::X0, _) => Instruction::new_nop(InstrWidth::Uncompressed), + (X::NonZero(rd), X::X0) => Instruction::new_li(rd, args.imm, InstrWidth::Uncompressed), + (X::NonZero(rd), X::NonZero(rs1)) => { + Instruction::new_addi(rd, rs1, args.imm, InstrWidth::Uncompressed) + } + } + } } diff --git a/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs b/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs index eeb77fa39ff0..ff2cf618f787 100644 --- a/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs @@ -329,11 +329,11 @@ pub enum ArgsShape { pub fn opcode_to_argsshape(opcode: &OpCode) -> ArgsShape { use OpCode::*; match opcode { - Addi | Lb | Lh | Lw | Lbu | Lhu | Lwu | Ld | Sb | Sh | Sw | Sd | Beq | Bne | Blt | Bge - | Bltu | Bgeu | Jal | Jalr | Lrw | Scw | Amoswapw | Amoaddw | Amoxorw | Amoandw - | Amoorw | Amominw | Amomaxw | Amominuw | Amomaxuw | Lrd | Scd | Amoswapd | Amoaddd - | Amoxord | Amoandd | Amoord | Amomind | Amomaxd | Amominud | Amomaxud | Rem | Remu - | Remw | Remuw | Div | Divu | Divw | Divuw | Mul | Mulh | Mulhsu | Mulhu | Mulw | Csrrw + Lb | Lh | Lw | Lbu | Lhu | Lwu | Ld | Sb | Sh | Sw | Sd | Beq | Bne | Blt | Bge | Bltu + | Bgeu | Jal | Jalr | Lrw | Scw | Amoswapw | Amoaddw | Amoxorw | Amoandw | Amoorw + | Amominw | Amomaxw | Amominuw | Amomaxuw | Lrd | Scd | Amoswapd | Amoaddd | Amoxord + | Amoandd | Amoord | Amomind | Amomaxd | Amominud | Amomaxud | Rem | Remu | Remw + | Remuw | Div | Divu | Divw | Divuw | Mul | Mulh | Mulhsu | Mulhu | Mulw | Csrrw | Csrrs | Csrrc | Csrrwi | Csrrsi | Csrrci | CLw | CSw | CSwsp | CAddi16sp | CAddi4spn | CAnd | COr | CXor | CSub | CAddw | CSubw | CLd | CSd | CSdsp | Unknown | Beqz | Bnez | J => ArgsShape::XSrcXDest, @@ -351,9 +351,8 @@ pub fn opcode_to_argsshape(opcode: &OpCode) -> ArgsShape { Fsw | Fsd | CFsd | CFsdsp => ArgsShape::XSrcFSrc, - Add | Mv | CJr | CJalr | CAddi | CAddiw | Li | CLui | CSlli | CLdsp | CLwsp | Nop => { - ArgsShape::NZXSrcNZXDest - } + Addi | Add | Mv | CJr | CJalr | CAddi | CAddiw | Li | CLui | CSlli | CLdsp | CLwsp + | Nop => ArgsShape::NZXSrcNZXDest, Andi | Ori | Xori | Addiw | Sub | And | Or | Xor | Sll | Srl | Sra | Addw | Subw | Sllw | Srlw | Sraw | Slti | Sltiu | Slli | Srli | Srai | Slliw | Srliw | Sraiw | Slt | Sltu diff --git a/src/riscv/lib/src/parser.rs b/src/riscv/lib/src/parser.rs index a32eaafbc827..13bda6e2d5cf 100644 --- a/src/riscv/lib/src/parser.rs +++ b/src/riscv/lib/src/parser.rs @@ -508,7 +508,6 @@ pub const fn parse_uncompressed_instruction(instr: u32) -> Instr { // RV64I (Chapter 5.4) and RV64C (Chapter 16.7) describe the code points associated // with HINT instructions. We do not implement any HINT logic, but decode all these // as `Hint` or `HintCompresssed` opcodes, which we translate to NOPs in `machine_state`. - // TODO: RV-422: Pass known NonZero `rd` values to Args constructors. use XRegisterParsed::*; let i = match opcode(instr) { // R-type instructions @@ -612,10 +611,13 @@ pub const fn parse_uncompressed_instruction(instr: u32) -> Instr { OP_ARITH_I => match (funct3(instr), split_x0(rd(instr))) { (F3_0, X0) => match (split_x0(rs1(instr)), i_imm(instr)) { (X0, _) | (_, 0) => Hint { instr }, - (_rs1, _imm) => i_instr!(Addi, instr), + (rs1, imm) => Addi(instruction::SplitITypeArgs { rd: X0, rs1, imm }), }, - // TODO: RV-427 Deduplicate Addi and introduce specific constructor for its cases. - (F3_0, _rd) => i_instr!(Addi, instr), + (F3_0, rd) => Addi(instruction::SplitITypeArgs { + rd, + rs1: split_x0(rs1(instr)), + imm: i_imm(instr), + }), (F3_4, X0) => Hint { instr }, (F3_4, NonZero(rd)) => i_instr!(Xori, instr, rd), (F3_6, X0) => Hint { instr }, @@ -1403,10 +1405,10 @@ mod tests { use super::{ instruction::{ - CsrArgs, ITypeArgs, Instr, InstrCacheable::*, NonZeroRdITypeArgs, SBTypeArgs, - UJTypeArgs, + CsrArgs, Instr, InstrCacheable::*, NonZeroRdITypeArgs, SBTypeArgs, UJTypeArgs, }, parse_block, + XRegisterParsed::*, }; use crate::{ machine_state::{ @@ -1416,6 +1418,7 @@ mod tests { parser::{ instruction::{CIBNZTypeArgs, CIBTypeArgs, InstrUncacheable}, parse_compressed_instruction, parse_compressed_instruction_inner, NonZeroRdUJTypeArgs, + SplitITypeArgs, }, }; @@ -1439,9 +1442,9 @@ mod tests { rs1: x0, csr: mcause, })), - Instr::Cacheable(Addi(ITypeArgs { - rd: x31, - rs1: x0, + Instr::Cacheable(Addi(SplitITypeArgs { + rd: NonZero(NonZeroXRegister::x31), + rs1: X0, imm: 0x8, })), ]; @@ -1465,9 +1468,9 @@ mod tests { 0x0, 0x9b, 0x83, 0x3, 0x34, 0x63, 0x10, 0x74, 0x12, ]; let expected = [ - Instr::Cacheable(Addi(ITypeArgs { - rd: x3, - rs1: x0, + Instr::Cacheable(Addi(SplitITypeArgs { + rd: NonZero(NonZeroXRegister::x3), + rs1: X0, imm: 21, })), Instr::Cacheable(CLui(CIBNZTypeArgs { diff --git a/src/riscv/lib/src/parser/instruction.rs b/src/riscv/lib/src/parser/instruction.rs index 67a9c35933e2..9e540b2ac77b 100644 --- a/src/riscv/lib/src/parser/instruction.rs +++ b/src/riscv/lib/src/parser/instruction.rs @@ -3,6 +3,7 @@ // // SPDX-License-Identifier: MIT +use super::XRegisterParsed; use crate::{ default::ConstDefault, interpreter::float::RoundingMode, @@ -37,6 +38,13 @@ pub struct ITypeArgs { pub imm: i64, } +/// Intermediate representation of Args for I-type instructions with parsed split of registers. +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, serde::Serialize, serde::Deserialize)] +pub struct SplitITypeArgs { + pub(crate) rd: XRegisterParsed, + pub(crate) rs1: XRegisterParsed, + pub imm: i64, +} /// Intermediate representation of Args for I-type instructions with guaranteed `rd` != `x0`. #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, serde::Serialize, serde::Deserialize)] pub struct NonZeroRdITypeArgs { @@ -288,7 +296,7 @@ pub enum InstrCacheable { Sraw(NonZeroRdRTypeArgs), // RV64I I-type instructions - Addi(ITypeArgs), + Addi(SplitITypeArgs), Addiw(NonZeroRdITypeArgs), Xori(NonZeroRdITypeArgs), Ori(NonZeroRdITypeArgs), diff --git a/src/riscv/lib/tests/expected/jstz/state_hash_final b/src/riscv/lib/tests/expected/jstz/state_hash_final index 300e3c9e7524..08f070e489af 100644 --- a/src/riscv/lib/tests/expected/jstz/state_hash_final +++ b/src/riscv/lib/tests/expected/jstz/state_hash_final @@ -1 +1 @@ -Hash { digest: [134, 251, 171, 73, 20, 75, 244, 189, 12, 157, 121, 210, 196, 228, 1, 77, 175, 210, 206, 24, 56, 72, 50, 136, 90, 128, 142, 191, 126, 255, 140, 95] } +Hash { digest: [45, 231, 182, 200, 166, 106, 111, 34, 141, 100, 207, 181, 240, 205, 143, 76, 221, 222, 103, 8, 60, 82, 190, 242, 155, 242, 103, 212, 26, 142, 24, 121] } -- GitLab From 08ce157d5ca837a4ef402937bef0347b2c553240 Mon Sep 17 00:00:00 2001 From: Neelay Sant Date: Wed, 5 Feb 2025 11:28:45 +0000 Subject: [PATCH 2/5] RISC-V: Deduplicate C.Addi OpCode into Addi --- src/riscv/lib/src/interpreter/rv32c.rs | 30 ------------------- src/riscv/lib/src/interpreter/rv32i.rs | 6 ++-- .../lib/src/machine_state/instruction.rs | 10 ++----- .../instruction/tagged_instruction.rs | 5 ++-- src/riscv/lib/src/parser/instruction.rs | 3 ++ .../lib/tests/expected/jstz/state_hash_final | 2 +- 6 files changed, 14 insertions(+), 42 deletions(-) diff --git a/src/riscv/lib/src/interpreter/rv32c.rs b/src/riscv/lib/src/interpreter/rv32c.rs index 01921cd4275b..74f0b58d892a 100644 --- a/src/riscv/lib/src/interpreter/rv32c.rs +++ b/src/riscv/lib/src/interpreter/rv32c.rs @@ -103,18 +103,6 @@ impl XRegisters where M: backend::ManagerReadWrite, { - /// `C.ADDI` CI-type compressed instruction - /// - /// Adds the non-zero sign-extended 6-bit `imm` to the value in `rd_rs1` then - /// writes the result to `rd_rs1`. - pub fn run_caddi(&mut self, imm: i64, rd_rs1: NonZeroXRegister) { - // Return the lower XLEN (64 bits in our case) bits of the addition - // Irrespective of sign, the result is the same, casting to u64 for addition - let rval = self.read_nz(rd_rs1); - let result = rval.wrapping_add(imm as u64); - self.write_nz(rd_rs1, result) - } - /// `C.ADDI16SP` CI-type compressed instruction /// /// Adds the non-zero immediate to the value in the stack pointer. @@ -338,24 +326,6 @@ mod tests { } }); - backend_test!(run_caddi, F, { - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); - let state_cell = std::cell::RefCell::new(state); - - proptest!(|( - rd_val in any::(), - imm in any::(), - )| { - let mut state = state_cell.borrow_mut(); - state.reset(); - - state.hart.xregisters.write_nz(nz::a1, rd_val); - state.hart.xregisters.run_caddi(imm, nz::a1); - let res = state.hart.xregisters.read_nz(nz::a1); - prop_assert_eq!(res, rd_val.wrapping_add(imm as u64)); - }); - }); - backend_test!(test_run_cli, F, { let imm_rdrs1_res = [ (0_i64, nz::t3, 0_u64), diff --git a/src/riscv/lib/src/interpreter/rv32i.rs b/src/riscv/lib/src/interpreter/rv32i.rs index a47e3460fdb4..17d1bb0135c6 100644 --- a/src/riscv/lib/src/interpreter/rv32i.rs +++ b/src/riscv/lib/src/interpreter/rv32i.rs @@ -23,9 +23,11 @@ impl XRegisters where M: backend::ManagerReadWrite, { - /// `ADDI` I-type instruction - /// /// Add `imm` to val(rs1) and store the result in `rd` + /// + /// Relevant RISC-V opcodes: + /// - `ADDI` + /// - `C.ADDI` pub fn run_addi(&mut self, imm: i64, rs1: NonZeroXRegister, rd: NonZeroXRegister) { // Return the lower XLEN (64 bits in our case) bits of the addition // Irrespective of sign, the result is the same, casting to u64 for addition diff --git a/src/riscv/lib/src/machine_state/instruction.rs b/src/riscv/lib/src/machine_state/instruction.rs index 0fb5aec066df..ff37ec6b6f80 100644 --- a/src/riscv/lib/src/machine_state/instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction.rs @@ -335,7 +335,6 @@ pub enum OpCode { CJr, CJalr, CLui, - CAddi, CAddi16sp, CAddi4spn, CSlli, @@ -543,7 +542,6 @@ impl OpCode { Self::Bnez => Args::run_bnez, Self::Li => Args::run_li, Self::CLui => Args::run_clui, - Self::CAddi => Args::run_caddi, Self::CAddi16sp => Args::run_caddi16spn, Self::CAddi4spn => Args::run_caddi4spn, Self::CSlli => Args::run_cslli, @@ -1288,7 +1286,6 @@ impl Args { impl_cb_type!(run_bnez); impl_ci_type!(run_li, non_zero); impl_ci_type!(run_clui, non_zero); - impl_ci_type!(run_caddi, non_zero); impl_ci_type!(run_caddi4spn); impl_ci_type!(run_cslli, non_zero); impl_cr_type!(run_cand); @@ -2031,10 +2028,9 @@ impl From<&InstrCacheable> for Instruction { opcode: OpCode::CLui, args: args.into(), }, - InstrCacheable::CAddi(args) => Instruction { - opcode: OpCode::CAddi, - args: args.into(), - }, + InstrCacheable::CAddi(args) => { + Instruction::new_addi(args.rd_rs1, args.rd_rs1, args.imm, InstrWidth::Compressed) + } InstrCacheable::CAddi16sp(args) => Instruction { opcode: OpCode::CAddi16sp, args: args.into(), diff --git a/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs b/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs index ff2cf618f787..ca9bd84ff5b3 100644 --- a/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs @@ -351,8 +351,9 @@ pub fn opcode_to_argsshape(opcode: &OpCode) -> ArgsShape { Fsw | Fsd | CFsd | CFsdsp => ArgsShape::XSrcFSrc, - Addi | Add | Mv | CJr | CJalr | CAddi | CAddiw | Li | CLui | CSlli | CLdsp | CLwsp - | Nop => ArgsShape::NZXSrcNZXDest, + Addi | Add | Mv | CJr | CJalr | CAddiw | Li | CLui | CSlli | CLdsp | CLwsp | Nop => { + ArgsShape::NZXSrcNZXDest + } Andi | Ori | Xori | Addiw | Sub | And | Or | Xor | Sll | Srl | Sra | Addw | Subw | Sllw | Srlw | Sraw | Slti | Sltiu | Slli | Srli | Srai | Slliw | Srliw | Sraiw | Slt | Sltu diff --git a/src/riscv/lib/src/parser/instruction.rs b/src/riscv/lib/src/parser/instruction.rs index 9e540b2ac77b..dc46fbc0f989 100644 --- a/src/riscv/lib/src/parser/instruction.rs +++ b/src/riscv/lib/src/parser/instruction.rs @@ -296,6 +296,7 @@ pub enum InstrCacheable { Sraw(NonZeroRdRTypeArgs), // RV64I I-type instructions + /// `ADDI` - Add `imm` to val(rs1) and store the result in `rd`. Addi(SplitITypeArgs), Addiw(NonZeroRdITypeArgs), Xori(NonZeroRdITypeArgs), @@ -465,6 +466,8 @@ pub enum InstrCacheable { /// `C.LI` - Loads the sign-extended 6-bit immediate into register `rd_rs1`. CLi(CIBNZTypeArgs), CLui(CIBNZTypeArgs), + /// `C.ADDI` - Adds the non-zero sign-extended 6-bit `imm` + /// to the value in `rd_rs1` then writes the result to `rd_rs1`. CAddi(CIBNZTypeArgs), CAddi16sp(CJTypeArgs), CAddi4spn(CIBTypeArgs), diff --git a/src/riscv/lib/tests/expected/jstz/state_hash_final b/src/riscv/lib/tests/expected/jstz/state_hash_final index 08f070e489af..0f837b8585c7 100644 --- a/src/riscv/lib/tests/expected/jstz/state_hash_final +++ b/src/riscv/lib/tests/expected/jstz/state_hash_final @@ -1 +1 @@ -Hash { digest: [45, 231, 182, 200, 166, 106, 111, 34, 141, 100, 207, 181, 240, 205, 143, 76, 221, 222, 103, 8, 60, 82, 190, 242, 155, 242, 103, 212, 26, 142, 24, 121] } +Hash { digest: [1, 5, 167, 194, 3, 18, 227, 80, 95, 88, 246, 172, 220, 217, 22, 234, 144, 51, 57, 202, 54, 10, 95, 5, 163, 120, 56, 169, 88, 81, 2, 127] } -- GitLab From 57b80d052a749b7af0f565c539ea6e95309f0e38 Mon Sep 17 00:00:00 2001 From: Neelay Sant Date: Wed, 5 Feb 2025 15:18:22 +0000 Subject: [PATCH 3/5] RISC-V: Deduplicate C.Addi4spn OpCode into Addi --- src/riscv/lib/src/interpreter/rv32c.rs | 15 --------------- src/riscv/lib/src/interpreter/rv32i.rs | 1 + src/riscv/lib/src/machine_state/instruction.rs | 8 +------- .../src/machine_state/instruction/constructors.rs | 15 +++++++++++++-- .../instruction/tagged_instruction.rs | 7 ++++--- src/riscv/lib/src/machine_state/registers.rs | 1 - src/riscv/lib/src/parser/instruction.rs | 3 +++ .../lib/tests/expected/jstz/state_hash_final | 2 +- 8 files changed, 23 insertions(+), 29 deletions(-) diff --git a/src/riscv/lib/src/interpreter/rv32c.rs b/src/riscv/lib/src/interpreter/rv32c.rs index 74f0b58d892a..4db934ce9da6 100644 --- a/src/riscv/lib/src/interpreter/rv32c.rs +++ b/src/riscv/lib/src/interpreter/rv32c.rs @@ -117,21 +117,6 @@ where self.write(sp, result) } - /// `C.ADDI4SPN` CIW-type compressed instruction - /// - /// Adds the non-zero immediate to the stack pointer and writes the result - /// to `rd`. - /// The immediate is obtained by zero-extending and scaling by 4 the value - /// encoded in the instruction (see U:C-16.5). - pub fn run_caddi4spn(&mut self, imm: i64, rd: XRegister) { - debug_assert!(imm > 0 && imm % 4 == 0); - // Return the lower XLEN (64 bits in our case) bits of the addition - // Irrespective of sign, the result is the same, casting to u64 for addition - let rval = self.read(sp); - let result = rval.wrapping_add(imm as u64); - self.write(rd, result) - } - /// `C.SLLI` CI-type compressed instruction /// /// Performs a logical left shift of the value in register `rd_rs1` diff --git a/src/riscv/lib/src/interpreter/rv32i.rs b/src/riscv/lib/src/interpreter/rv32i.rs index 17d1bb0135c6..f22c3b49195f 100644 --- a/src/riscv/lib/src/interpreter/rv32i.rs +++ b/src/riscv/lib/src/interpreter/rv32i.rs @@ -28,6 +28,7 @@ where /// Relevant RISC-V opcodes: /// - `ADDI` /// - `C.ADDI` + /// - `C.ADDI4SPN` pub fn run_addi(&mut self, imm: i64, rs1: NonZeroXRegister, rd: NonZeroXRegister) { // Return the lower XLEN (64 bits in our case) bits of the addition // Irrespective of sign, the result is the same, casting to u64 for addition diff --git a/src/riscv/lib/src/machine_state/instruction.rs b/src/riscv/lib/src/machine_state/instruction.rs index ff37ec6b6f80..dc6274bd558d 100644 --- a/src/riscv/lib/src/machine_state/instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction.rs @@ -336,7 +336,6 @@ pub enum OpCode { CJalr, CLui, CAddi16sp, - CAddi4spn, CSlli, CAnd, COr, @@ -543,7 +542,6 @@ impl OpCode { Self::Li => Args::run_li, Self::CLui => Args::run_clui, Self::CAddi16sp => Args::run_caddi16spn, - Self::CAddi4spn => Args::run_caddi4spn, Self::CSlli => Args::run_cslli, Self::Mv => Args::run_mv, Self::CAnd => Args::run_cand, @@ -1286,7 +1284,6 @@ impl Args { impl_cb_type!(run_bnez); impl_ci_type!(run_li, non_zero); impl_ci_type!(run_clui, non_zero); - impl_ci_type!(run_caddi4spn); impl_ci_type!(run_cslli, non_zero); impl_cr_type!(run_cand); impl_cr_type!(run_cxor); @@ -2035,10 +2032,7 @@ impl From<&InstrCacheable> for Instruction { opcode: OpCode::CAddi16sp, args: args.into(), }, - InstrCacheable::CAddi4spn(args) => Instruction { - opcode: OpCode::CAddi4spn, - args: args.into(), - }, + InstrCacheable::CAddi4spn(args) => Instruction::from_ic_caddi4spn(args), InstrCacheable::CSlli(args) => Instruction { opcode: OpCode::CSlli, args: args.into(), diff --git a/src/riscv/lib/src/machine_state/instruction/constructors.rs b/src/riscv/lib/src/machine_state/instruction/constructors.rs index 25a857cef28b..c993571090bc 100644 --- a/src/riscv/lib/src/machine_state/instruction/constructors.rs +++ b/src/riscv/lib/src/machine_state/instruction/constructors.rs @@ -5,9 +5,9 @@ use super::{Args, Instruction, OpCode}; use crate::{ default::ConstDefault, - machine_state::registers::NonZeroXRegister, + machine_state::registers::{nz, NonZeroXRegister}, parser::{ - instruction::{InstrWidth, NonZeroRdRTypeArgs, SplitITypeArgs}, + instruction::{CIBTypeArgs, InstrWidth, NonZeroRdRTypeArgs, SplitITypeArgs}, split_x0, XRegisterParsed, }, }; @@ -130,4 +130,15 @@ impl Instruction { } } } + + /// Convert [`InstrCacheable::CAddi4spn`] according to whether register is non-zero. + pub(super) fn from_ic_caddi4spn(args: &CIBTypeArgs) -> Instruction { + use XRegisterParsed as X; + match split_x0(args.rd_rs1) { + X::X0 => Instruction::new_nop(InstrWidth::Compressed), + X::NonZero(rd_rs1) => { + Instruction::new_addi(rd_rs1, nz::sp, args.imm, InstrWidth::Compressed) + } + } + } } diff --git a/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs b/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs index ca9bd84ff5b3..ab92e5207883 100644 --- a/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs @@ -334,9 +334,10 @@ pub fn opcode_to_argsshape(opcode: &OpCode) -> ArgsShape { | Amominw | Amomaxw | Amominuw | Amomaxuw | Lrd | Scd | Amoswapd | Amoaddd | Amoxord | Amoandd | Amoord | Amomind | Amomaxd | Amominud | Amomaxud | Rem | Remu | Remw | Remuw | Div | Divu | Divw | Divuw | Mul | Mulh | Mulhsu | Mulhu | Mulw | Csrrw - | Csrrs | Csrrc | Csrrwi | Csrrsi | Csrrci | CLw | CSw | CSwsp | CAddi16sp | CAddi4spn - | CAnd | COr | CXor | CSub | CAddw | CSubw | CLd | CSd | CSdsp | Unknown | Beqz | Bnez - | J => ArgsShape::XSrcXDest, + | Csrrs | Csrrc | Csrrwi | Csrrsi | Csrrci | CLw | CSw | CSwsp | CAddi16sp | CAnd | COr + | CXor | CSub | CAddw | CSubw | CLd | CSd | CSdsp | Unknown | Beqz | Bnez | J => { + ArgsShape::XSrcXDest + } Fadds | Fsubs | Fmuls | Fdivs | Fsqrts | Fmins | Fmaxs | Fsgnjs | Fsgnjns | Fsgnjxs | Fmadds | Fmsubs | Fnmsubs | Fnmadds | Faddd | Fsubd | Fmuld | Fdivd | Fsqrtd | Fmind diff --git a/src/riscv/lib/src/machine_state/registers.rs b/src/riscv/lib/src/machine_state/registers.rs index 7590f2de1224..26fa52f9bc81 100644 --- a/src/riscv/lib/src/machine_state/registers.rs +++ b/src/riscv/lib/src/machine_state/registers.rs @@ -333,7 +333,6 @@ impl NonZeroXRegister { } /// ABI register names for NonZeroXRegister types used in backend tests. -#[cfg(test)] pub mod nz { use super::NonZeroXRegister; diff --git a/src/riscv/lib/src/parser/instruction.rs b/src/riscv/lib/src/parser/instruction.rs index dc46fbc0f989..cdc6e34c9efc 100644 --- a/src/riscv/lib/src/parser/instruction.rs +++ b/src/riscv/lib/src/parser/instruction.rs @@ -470,6 +470,9 @@ pub enum InstrCacheable { /// to the value in `rd_rs1` then writes the result to `rd_rs1`. CAddi(CIBNZTypeArgs), CAddi16sp(CJTypeArgs), + /// `C.ADDI4SPN`- Adds the non-zero immediate to the stack pointer and writes the result + /// to `rd`. The immediate is obtained by zero-extending and scaling by 4 the value + /// encoded in the instruction (see U:C-16.5). CAddi4spn(CIBTypeArgs), CSlli(CIBNZTypeArgs), CSrli(CIBTypeArgs), diff --git a/src/riscv/lib/tests/expected/jstz/state_hash_final b/src/riscv/lib/tests/expected/jstz/state_hash_final index 0f837b8585c7..ca78d498e114 100644 --- a/src/riscv/lib/tests/expected/jstz/state_hash_final +++ b/src/riscv/lib/tests/expected/jstz/state_hash_final @@ -1 +1 @@ -Hash { digest: [1, 5, 167, 194, 3, 18, 227, 80, 95, 88, 246, 172, 220, 217, 22, 234, 144, 51, 57, 202, 54, 10, 95, 5, 163, 120, 56, 169, 88, 81, 2, 127] } +Hash { digest: [70, 152, 60, 231, 9, 48, 55, 164, 98, 135, 77, 217, 3, 221, 186, 219, 186, 220, 236, 124, 51, 128, 18, 60, 126, 154, 36, 194, 37, 205, 75, 119] } -- GitLab From 77296e8dd58d5231b3aaad9d84ddd254aa1b9866 Mon Sep 17 00:00:00 2001 From: Neelay Sant Date: Wed, 5 Feb 2025 15:21:58 +0000 Subject: [PATCH 4/5] RISC-V: Deduplicate C.Addi16sp OpCode into Addi --- src/riscv/lib/src/interpreter/rv32c.rs | 14 ------------ src/riscv/lib/src/interpreter/rv32i.rs | 1 + .../lib/src/machine_state/instruction.rs | 22 +++++-------------- .../instruction/tagged_instruction.rs | 4 ++-- src/riscv/lib/src/parser/instruction.rs | 3 +++ .../lib/tests/expected/jstz/state_hash_final | 2 +- 6 files changed, 13 insertions(+), 33 deletions(-) diff --git a/src/riscv/lib/src/interpreter/rv32c.rs b/src/riscv/lib/src/interpreter/rv32c.rs index 4db934ce9da6..a7b33946122f 100644 --- a/src/riscv/lib/src/interpreter/rv32c.rs +++ b/src/riscv/lib/src/interpreter/rv32c.rs @@ -103,20 +103,6 @@ impl XRegisters where M: backend::ManagerReadWrite, { - /// `C.ADDI16SP` CI-type compressed instruction - /// - /// Adds the non-zero immediate to the value in the stack pointer. - /// The immediate is obtained by sign-extending and scaling by 16 the value - /// encoded in the instruction (see U:C-16.5). - pub fn run_caddi16sp(&mut self, imm: i64) { - debug_assert!(imm != 0 && imm % 16 == 0); - // Return the lower XLEN (64 bits in our case) bits of the addition - // Irrespective of sign, the result is the same, casting to u64 for addition - let rval = self.read(sp); - let result = rval.wrapping_add(imm as u64); - self.write(sp, result) - } - /// `C.SLLI` CI-type compressed instruction /// /// Performs a logical left shift of the value in register `rd_rs1` diff --git a/src/riscv/lib/src/interpreter/rv32i.rs b/src/riscv/lib/src/interpreter/rv32i.rs index f22c3b49195f..136cf2127f2a 100644 --- a/src/riscv/lib/src/interpreter/rv32i.rs +++ b/src/riscv/lib/src/interpreter/rv32i.rs @@ -29,6 +29,7 @@ where /// - `ADDI` /// - `C.ADDI` /// - `C.ADDI4SPN` + /// - `C.ADDI16SP` pub fn run_addi(&mut self, imm: i64, rs1: NonZeroXRegister, rd: NonZeroXRegister) { // Return the lower XLEN (64 bits in our case) bits of the addition // Irrespective of sign, the result is the same, casting to u64 for addition diff --git a/src/riscv/lib/src/machine_state/instruction.rs b/src/riscv/lib/src/machine_state/instruction.rs index dc6274bd558d..cf9950fb5774 100644 --- a/src/riscv/lib/src/machine_state/instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction.rs @@ -335,7 +335,6 @@ pub enum OpCode { CJr, CJalr, CLui, - CAddi16sp, CSlli, CAnd, COr, @@ -541,7 +540,6 @@ impl OpCode { Self::Bnez => Args::run_bnez, Self::Li => Args::run_li, Self::CLui => Args::run_clui, - Self::CAddi16sp => Args::run_caddi16spn, Self::CSlli => Args::run_cslli, Self::Mv => Args::run_mv, Self::CAnd => Args::run_cand, @@ -1291,16 +1289,6 @@ impl Args { impl_cr_type!(run_csub); impl_css_type!(run_cswsp); - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. - unsafe fn run_caddi16spn( - &self, - core: &mut MachineCoreState, - ) -> Result { - core.hart.xregisters.run_caddi16sp(self.imm); - Ok(Next(self.width)) - } - fn run_j( &self, core: &mut MachineCoreState, @@ -2028,10 +2016,12 @@ impl From<&InstrCacheable> for Instruction { InstrCacheable::CAddi(args) => { Instruction::new_addi(args.rd_rs1, args.rd_rs1, args.imm, InstrWidth::Compressed) } - InstrCacheable::CAddi16sp(args) => Instruction { - opcode: OpCode::CAddi16sp, - args: args.into(), - }, + InstrCacheable::CAddi16sp(args) => Instruction::new_addi( + NonZeroXRegister::x2, + NonZeroXRegister::x2, + args.imm, + InstrWidth::Compressed, + ), InstrCacheable::CAddi4spn(args) => Instruction::from_ic_caddi4spn(args), InstrCacheable::CSlli(args) => Instruction { opcode: OpCode::CSlli, diff --git a/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs b/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs index ab92e5207883..fa2515688e94 100644 --- a/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction/tagged_instruction.rs @@ -334,8 +334,8 @@ pub fn opcode_to_argsshape(opcode: &OpCode) -> ArgsShape { | Amominw | Amomaxw | Amominuw | Amomaxuw | Lrd | Scd | Amoswapd | Amoaddd | Amoxord | Amoandd | Amoord | Amomind | Amomaxd | Amominud | Amomaxud | Rem | Remu | Remw | Remuw | Div | Divu | Divw | Divuw | Mul | Mulh | Mulhsu | Mulhu | Mulw | Csrrw - | Csrrs | Csrrc | Csrrwi | Csrrsi | Csrrci | CLw | CSw | CSwsp | CAddi16sp | CAnd | COr - | CXor | CSub | CAddw | CSubw | CLd | CSd | CSdsp | Unknown | Beqz | Bnez | J => { + | Csrrs | Csrrc | Csrrwi | Csrrsi | Csrrci | CLw | CSw | CSwsp | CAnd | COr | CXor + | CSub | CAddw | CSubw | CLd | CSd | CSdsp | Unknown | Beqz | Bnez | J => { ArgsShape::XSrcXDest } diff --git a/src/riscv/lib/src/parser/instruction.rs b/src/riscv/lib/src/parser/instruction.rs index cdc6e34c9efc..7041955b22e8 100644 --- a/src/riscv/lib/src/parser/instruction.rs +++ b/src/riscv/lib/src/parser/instruction.rs @@ -469,6 +469,9 @@ pub enum InstrCacheable { /// `C.ADDI` - Adds the non-zero sign-extended 6-bit `imm` /// to the value in `rd_rs1` then writes the result to `rd_rs1`. CAddi(CIBNZTypeArgs), + /// `C.ADDI16SP` - Adds the non-zero immediate to the value in the stack pointer. + /// The immediate is obtained by sign-extending and scaling by 16 the value + /// encoded in the instruction (see U:C-16.5). CAddi16sp(CJTypeArgs), /// `C.ADDI4SPN`- Adds the non-zero immediate to the stack pointer and writes the result /// to `rd`. The immediate is obtained by zero-extending and scaling by 4 the value diff --git a/src/riscv/lib/tests/expected/jstz/state_hash_final b/src/riscv/lib/tests/expected/jstz/state_hash_final index ca78d498e114..a0f1a1470324 100644 --- a/src/riscv/lib/tests/expected/jstz/state_hash_final +++ b/src/riscv/lib/tests/expected/jstz/state_hash_final @@ -1 +1 @@ -Hash { digest: [70, 152, 60, 231, 9, 48, 55, 164, 98, 135, 77, 217, 3, 221, 186, 219, 186, 220, 236, 124, 51, 128, 18, 60, 126, 154, 36, 194, 37, 205, 75, 119] } +Hash { digest: [18, 125, 128, 4, 255, 142, 132, 177, 117, 110, 101, 2, 209, 79, 113, 172, 197, 114, 30, 60, 227, 163, 136, 60, 53, 99, 101, 63, 133, 57, 51, 177] } -- GitLab From 617ed2f06733327b7a58ccfb90b9946ca333b35a Mon Sep 17 00:00:00 2001 From: Neelay Sant Date: Wed, 5 Feb 2025 16:41:19 +0000 Subject: [PATCH 5/5] RISC-V: Convert safety comments into docstrings --- .../lib/src/machine_state/instruction.rs | 144 +++++++++--------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/src/riscv/lib/src/machine_state/instruction.rs b/src/riscv/lib/src/machine_state/instruction.rs index cf9950fb5774..fede7d369dbb 100644 --- a/src/riscv/lib/src/machine_state/instruction.rs +++ b/src/riscv/lib/src/machine_state/instruction.rs @@ -666,8 +666,8 @@ impl ConstDefault for Args { macro_rules! impl_r_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -678,8 +678,8 @@ macro_rules! impl_r_type { }; ($fn: ident, non_zero_rd) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -692,8 +692,8 @@ macro_rules! impl_r_type { }; ($impl: path, $fn: ident, non_zero) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn(&self, icb: &mut I) -> ::IResult { $impl(icb, self.rs1.nzx, self.rs2.nzx, self.rd.nzx); icb.ok(Next(self.width)) @@ -703,8 +703,8 @@ macro_rules! impl_r_type { macro_rules! impl_i_type { ($fn: ident, non_zero) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -717,8 +717,8 @@ macro_rules! impl_i_type { }; ($fn: ident, non_zero_rd) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -731,8 +731,8 @@ macro_rules! impl_i_type { macro_rules! impl_fload_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -744,8 +744,8 @@ macro_rules! impl_fload_type { } macro_rules! impl_load_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -757,8 +757,8 @@ macro_rules! impl_load_type { } macro_rules! impl_cload_sp_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -769,8 +769,8 @@ macro_rules! impl_cload_sp_type { } macro_rules! impl_cfload_sp_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -782,8 +782,8 @@ macro_rules! impl_cfload_sp_type { macro_rules! impl_store_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -795,8 +795,8 @@ macro_rules! impl_store_type { } macro_rules! impl_fstore_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -809,8 +809,8 @@ macro_rules! impl_fstore_type { macro_rules! impl_b_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -822,8 +822,8 @@ macro_rules! impl_b_type { macro_rules! impl_amo_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -836,8 +836,8 @@ macro_rules! impl_amo_type { macro_rules! impl_ci_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -848,8 +848,8 @@ macro_rules! impl_ci_type { }; ($fn: ident, non_zero) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -862,8 +862,8 @@ macro_rules! impl_ci_type { macro_rules! impl_cr_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -876,8 +876,8 @@ macro_rules! impl_cr_type { macro_rules! impl_cr_nz_type { ($impl: path, $fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn(&self, icb: &mut I) -> ::IResult { $impl(icb, self.rd.nzx, self.rs2.nzx); icb.ok(Next(self.width)) @@ -887,8 +887,8 @@ macro_rules! impl_cr_nz_type { macro_rules! impl_cb_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -900,8 +900,8 @@ macro_rules! impl_cb_type { macro_rules! impl_css_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -913,8 +913,8 @@ macro_rules! impl_css_type { macro_rules! impl_fcss_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -926,8 +926,8 @@ macro_rules! impl_fcss_type { macro_rules! impl_csr_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -941,8 +941,8 @@ macro_rules! impl_csr_type { macro_rules! impl_csr_imm_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -956,8 +956,8 @@ macro_rules! impl_csr_imm_type { macro_rules! impl_f_x_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -969,8 +969,8 @@ macro_rules! impl_f_x_type { }; ($fn:ident, rm) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -984,8 +984,8 @@ macro_rules! impl_f_x_type { macro_rules! impl_x_f_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -997,8 +997,8 @@ macro_rules! impl_x_f_type { }; ($fn:ident, rm) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -1012,8 +1012,8 @@ macro_rules! impl_x_f_type { macro_rules! impl_f_r_type { ($fn: ident) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -1025,8 +1025,8 @@ macro_rules! impl_f_r_type { }; ($fn: ident, (rd, x)) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -1038,8 +1038,8 @@ macro_rules! impl_f_r_type { }; ($fn: ident, rm) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -1051,8 +1051,8 @@ macro_rules! impl_f_r_type { }; ($fn: ident, (rs2, f), $($field: ident),+) => { - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn $fn( &self, core: &mut MachineCoreState, @@ -1120,8 +1120,8 @@ impl Args { // RV64I U-type instructions // - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn run_lui( &self, core: &mut MachineCoreState, @@ -1130,8 +1130,8 @@ impl Args { Ok(Next(self.width)) } - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn run_auipc( &self, core: &mut MachineCoreState, @@ -1142,8 +1142,8 @@ impl Args { // RV64I jump instructions // - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn run_jal( &self, core: &mut MachineCoreState, @@ -1151,8 +1151,8 @@ impl Args { Ok(Set(core.hart.run_jal(self.imm, self.rd.x))) } - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn run_jalr( &self, core: &mut MachineCoreState, @@ -1296,8 +1296,8 @@ impl Args { Ok(Set(core.hart.run_j(self.imm))) } - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn run_cjr( &self, core: &mut MachineCoreState, @@ -1305,8 +1305,8 @@ impl Args { Ok(Set(core.hart.run_cjr(self.rs1.nzx))) } - // SAFETY: This function must only be called on an `Args` belonging - // to the same OpCode as the OpCode used to derive this function. + /// SAFETY: This function must only be called on an `Args` belonging + /// to the same OpCode as the OpCode used to derive this function. unsafe fn run_cjalr( &self, core: &mut MachineCoreState, -- GitLab