Browse Source

fix(spec): small fix on RV128I emulator example

Signed-off-by: Zhouqi Jiang <[email protected]>
Zhouqi Jiang 1 month ago
parent
commit
d3035bc0b2
1 changed files with 16 additions and 11 deletions
  1. 16 11
      sbi-spec/examples/simple-rv128i-emulator.rs

+ 16 - 11
sbi-spec/examples/simple-rv128i-emulator.rs

@@ -50,6 +50,7 @@ fn main() {
 
     // --- Initialize the emulator hart ---
     let mut hart = SimpleRv128IHart::new(memory);
+    println!("Starting SimpleRv128IHart...");
 
     // Run the emulation loop, executing one instruction at a time.
     // The loop breaks when an SBI call requests to shutdown the emulator (returns a special error value).
@@ -222,13 +223,17 @@ impl<const BASE: usize, const N_INSNS: usize> InstMemory<BASE, N_INSNS> {
     /// # Parameters
     /// - `idx`: The byte offset at which to place the instructions.
     /// - `rd`: The destination register.
-    /// - `imm`: The immediate value (32-bit).
-    pub fn li(&mut self, idx: usize, rd: XReg, imm: u32) {
-        let simm20 = (imm >> 12) & 0xFFFFF;
-        let simm12 = imm & 0xFFF;
+    /// - `imm`: The immediate value (128-bit).
+    pub fn li(&mut self, idx: usize, rd: XReg, imm: u128) {
+        assert!(
+            imm <= 0xFFFFFFFF,
+            "in this example `li` only supports immediate values less than 0xFFFFFFFF"
+        );
+        let imm = imm as u32;
+        let (simm20, simm12) = (imm >> 12, imm & 0xFFF);
         if simm20 != 0 {
             self.lui(idx, rd, simm20);
-            self.addi(idx + 0x4, rd, rd, simm12);
+            self.addi(idx + 4, rd, rd, simm12);
         } else {
             self.addi(idx, rd, XReg::Zero, simm12);
         }
@@ -313,20 +318,20 @@ impl SimpleRv128IHart {
 
     /// Execute one instruction step.
     ///
-    /// This function fetches the instruction at the current program counter (PC),
-    /// decodes it, and then executes it. The PC is updated accordingly.
+    /// Fetches, decodes, and executes the instruction at the current program counter (PC),
+    /// updating the PC accordingly.
     ///
     /// # Returns
-    /// - `Ok(())` if the instruction executed normally.
-    /// - `Err(Exception::SupervisorEcall)` if an ecall instruction was encountered (SBI call).
-    /// - `Err(e)` for any other exceptions.
+    /// - `Ok(())` if executed normally.
+    /// - `Err(Exception::SupervisorEcall)` if an ecall instruction was encountered.
+    /// - `Err(e)` for other exceptions.
     pub fn stepi(&mut self) -> Result<(), Exception> {
         let raw_insn = self
             .inst_memory
             .get(self.pc)
             .ok_or(Exception::InstructionAccessFault)?;
 
-        println!("Raw insn at 0x{:x?} is 0x{:x?}", self.pc, raw_insn);
+        println!("Insn at 0x{:x}: 0x{:x}", self.pc, raw_insn);
 
         // Attempt to decode the raw instruction into one of the supported instruction variants.
         let parsed_insn =