Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

o1vm/riscv32i: define registers #2743

Merged
merged 3 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions o1vm/src/interpreters/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
/// An interpreter for an optimised version of Keccak
pub mod keccak;

/// An interpreter for the MIPS instruction set.
pub mod mips;

/// An interpreter for the RISC-V 32I instruction set, following the specification
/// on
/// [riscv.org](https://riscv.org/wp-content/uploads/2019/12/riscv-spec-20191213.pdf).
pub mod riscv32i;
2 changes: 2 additions & 0 deletions o1vm/src/interpreters/riscv32i/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// All the registers used by the ISA
pub mod registers;
66 changes: 66 additions & 0 deletions o1vm/src/interpreters/riscv32i/registers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::ops::{Index, IndexMut};

use serde::{Deserialize, Serialize};

pub const N_GP_REGISTERS: usize = 32;
// FIXME:
pub const REGISTER_CURRENT_IP: usize = N_GP_REGISTERS + 1;
pub const REGISTER_NEXT_IP: usize = N_GP_REGISTERS + 2;
pub const REGISTER_HEAP_POINTER: usize = N_GP_REGISTERS + 3;

/// This represents the internal state of the virtual machine.
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct Registers<T> {
/// There are 32 general purpose registers.
/// - x0: hard-wired zero
/// - x1: return address
/// - x2: stack pointer
/// - x3: global pointer
/// - x4: thread pointer
/// - x5: temporary/alternate register
/// - x6-x7: temporaries
/// - x8: saved register/frame pointer
/// - x9: saved register
/// - x10-x11: function arguments/results
/// - x12-x17: function arguments
/// - x18-x27: saved registers
/// - x28-x31: temporaries
pub general_purpose: [T; N_GP_REGISTERS],
pub current_instruction_pointer: T,
pub next_instruction_pointer: T,
pub heap_pointer: T,
}

impl<T: Clone> Index<usize> for Registers<T> {
type Output = T;

fn index(&self, index: usize) -> &Self::Output {
if index < N_GP_REGISTERS {
&self.general_purpose[index]
} else if index == REGISTER_CURRENT_IP {
&self.current_instruction_pointer
} else if index == REGISTER_NEXT_IP {
&self.next_instruction_pointer
} else if index == REGISTER_HEAP_POINTER {
&self.heap_pointer
} else {
panic!("Index out of bounds");
}
Comment on lines +38 to +48
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nbd since ip, nip, and the heap ptr are artificial, but it is a bit awkward that 32 isn't an index in the range.

}
}

impl<T: Clone> IndexMut<usize> for Registers<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
if index < N_GP_REGISTERS {
&mut self.general_purpose[index]
} else if index == REGISTER_CURRENT_IP {
&mut self.current_instruction_pointer
} else if index == REGISTER_NEXT_IP {
&mut self.next_instruction_pointer
} else if index == REGISTER_HEAP_POINTER {
&mut self.heap_pointer
} else {
panic!("Index out of bounds");
}
}
}
Loading