Skip to content

Commit

Permalink
Change NVM Syscall Specification (nexus-xyz#150)
Browse files Browse the repository at this point in the history
* Change NVM to use rd as part of syscalls for easier circuit constraint generation.

* Clippy
  • Loading branch information
sjudson authored Apr 23, 2024
1 parent 0f8da4d commit b173cd4
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 10 deletions.
2 changes: 1 addition & 1 deletion riscv/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ pub fn eval_inst(vm: &mut VM) -> Result<()> {
}
FENCE | EBREAK => {}
ECALL => {
vm.syscalls.syscall(vm.regs.pc, vm.regs.x, &vm.mem)?;
vm.Z = vm.syscalls.syscall(vm.regs.pc, vm.regs.x, &vm.mem)?;
}
UNIMP => {
PC = vm.inst.pc;
Expand Down
8 changes: 8 additions & 0 deletions riscv/src/nvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ fn translate_inst(rv: RVInst) -> (u32, Inst) {
}
RV32::ECALL => {
inst.opcode = SYS;
// Per the RISC-V spec, for an ecall `rd = 0` and the system determines
// how to return a value, e.g. by modifying register `x10` (aka `a0`).
//
// For the NVM, we formalize this by setting `rd = 10` and having each
// ecall modify `x10`, even if to just write zero. By doing so, we know
// that `rd` points to the modified register, and so we will always
// generate the R1CS circuit constraints correctly.
inst.rd = 10;
}
RV32::FENCE | RV32::EBREAK => {
inst.opcode = NOP;
Expand Down
5 changes: 3 additions & 2 deletions vm/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ pub fn eval_step(vm: &mut NexusVM<impl Memory>) -> Result<()> {
HALT => {
PC = vm.pc;
}
SYS => vm.syscalls.syscall(vm.pc, vm.regs, &vm.memory)?,

SYS => {
vm.Z = vm.syscalls.syscall(vm.pc, vm.regs, &vm.memory)?;
}
JAL => {
vm.Z = add32(vm.pc, 8);
let XI = add32(X, I);
Expand Down
18 changes: 11 additions & 7 deletions vm/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,30 @@ impl Syscalls {
self.input = slice.to_owned().into();
}

pub fn syscall(&mut self, pc: u32, mut regs: [u32; 32], memory: &impl Memory) -> Result<()> {
pub fn syscall(&mut self, pc: u32, regs: [u32; 32], memory: &impl Memory) -> Result<u32> {
let num = regs[18]; // s2 = x18 syscall number
let a0 = regs[10]; // a0 = x10
let a1 = regs[11]; // a1 = x11
let inp1 = regs[10]; // a0 = x10
let inp2 = regs[11]; // a1 = x11

let mut out = 0x0;

if num == 1 {
// write_log
let mut stdout = std::io::stdout();
for addr in a0..a0 + a1 {
for addr in inp1..inp1 + inp2 {
let b = memory.load(Width::BU, addr)?.0;
stdout.write_all(&[b as u8])?;
}
let _ = stdout.flush();
} else if num == 2 {
match self.input.pop_front() {
Some(b) => regs[10] = b as u32,
None => regs[10] = u32::MAX,
Some(b) => out = b as u32,
None => out = u32::MAX,
}
} else {
return Err(UnknownSyscall(pc, num));
}
Ok(())

Ok(out)
}
}

0 comments on commit b173cd4

Please sign in to comment.