diff --git a/o1vm/resources/programs/riscv32im/bin/addi_negative b/o1vm/resources/programs/riscv32im/bin/addi_negative new file mode 100755 index 0000000000..f610f7df86 Binary files /dev/null and b/o1vm/resources/programs/riscv32im/bin/addi_negative differ diff --git a/o1vm/resources/programs/riscv32im/src/addi_negative.S b/o1vm/resources/programs/riscv32im/src/addi_negative.S new file mode 100644 index 0000000000..5ef1bfda36 --- /dev/null +++ b/o1vm/resources/programs/riscv32im/src/addi_negative.S @@ -0,0 +1,22 @@ +.section .text +.globl _start + +_start: + li t0, 100 # t0 = 100 + + # Subtract 50 using addi (addi with negative immediate) + addi t1, t0, -50 # t1 = t0 + (-50) (Expected: t1 = 50) + + # Subtract 100 using addi (addi with negative immediate) + addi t2, t1, -100 # t2 = t1 + (-100) (Expected: t2 = -50) + + # Custom exit syscall + li a0, 0 + li a1, 0 + li a2, 0 + li a3, 0 + li a4, 0 + li a5, 0 + li a6, 0 + li a7, 42 + ecall diff --git a/o1vm/tests/test_riscv_elf.rs b/o1vm/tests/test_riscv_elf.rs index 7d3d7be7d2..2cef90f069 100644 --- a/o1vm/tests/test_riscv_elf.rs +++ b/o1vm/tests/test_riscv_elf.rs @@ -178,3 +178,21 @@ fn test_add_overflow() { assert_eq!(witness.registers[T3], 0b11111111111111111111111111111111); assert_eq!(witness.registers[T4], 0b00000000000000000000000000000000); } + +#[test] +fn test_addi_negative() { + let curr_dir = std::env::current_dir().unwrap(); + let path = curr_dir.join(std::path::PathBuf::from( + "resources/programs/riscv32im/bin/addi_negative", + )); + let state = o1vm::elf_loader::parse_riscv32(&path).unwrap(); + let mut witness = Env::::create(PAGE_SIZE.try_into().unwrap(), state); + + while !witness.halt { + witness.step(); + } + + assert_eq!(witness.registers[T0], 100); + assert_eq!(witness.registers[T1], 50); + assert_eq!(witness.registers[T2], (-50_i32) as u32); +}