diff --git a/o1vm/resources/programs/riscv32im/bin/and b/o1vm/resources/programs/riscv32im/bin/and new file mode 100755 index 0000000000..4b645914a8 Binary files /dev/null and b/o1vm/resources/programs/riscv32im/bin/and differ diff --git a/o1vm/resources/programs/riscv32im/src/and.S b/o1vm/resources/programs/riscv32im/src/and.S new file mode 100644 index 0000000000..4bab937b9b --- /dev/null +++ b/o1vm/resources/programs/riscv32im/src/and.S @@ -0,0 +1,30 @@ +.section .text +.globl _start + +_start: + + # Simple AND + li t0, 0b1100 # t0 = 0b1100 + li t1, 0b1010 # t1 = 0b1010 + and t2, t0, t1 # t2 = t0 & t1 (Expected: t2 = 0b1000) + + # AND with zero (result always zero) + li t3, 0b1111 # t3 = 0b1111 + li t4, 0 # t4 = 0 + and t5, t3, t4 # t5 = t3 & t4 (Expected: t5 = 0) + + # AND of identical values (result same value) + li t6, 0b1010 # t6 = 0b1010 + li t0, 0b1010 # t0 = 0b1010 + and t1, t6, t0 # t1 = t6 & t0 (Expected: t1 = 0b1010) + + # 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 03e07f13c2..071df890f0 100644 --- a/o1vm/tests/test_riscv_elf.rs +++ b/o1vm/tests/test_riscv_elf.rs @@ -320,3 +320,21 @@ fn test_xor() { assert_eq!(witness.registers[T5], 0b1010); // Result: t5 = 0b1010 assert_eq!(witness.registers[T1], 0); // Result: t1 = 0 } + +#[test] +fn test_and() { + let curr_dir = std::env::current_dir().unwrap(); + let path = curr_dir.join(std::path::PathBuf::from( + "resources/programs/riscv32im/bin/and", + )); + 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[T2], 0b1000); + assert_eq!(witness.registers[T5], 0); + assert_eq!(witness.registers[T1], 0b1010); +}