wip
This commit is contained in:
commit
7a6e4b31bd
10 changed files with 989 additions and 0 deletions
122
src/main.rs
Normal file
122
src/main.rs
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#[repr(C)]
|
||||
struct MachineState<'a> {
|
||||
memory: &'a [u8]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct CoreState {
|
||||
// Integer registers
|
||||
x: [i64; 32],
|
||||
|
||||
// Floating point registers
|
||||
// f32 values get... NaN-boxed into f64 values? wild
|
||||
// probably most efficiently treated like a union so can
|
||||
// do f32-native loads and stores and also update the top
|
||||
// bytes separately
|
||||
f: [f64; 32],
|
||||
|
||||
// 4096 csrs? no we're not gonna store them all
|
||||
|
||||
// do we need pc? we're passing it around as active state
|
||||
pc: i64,
|
||||
|
||||
// * fflags, accrued exceptions: bits 0-4
|
||||
// * nx: bit 0
|
||||
// * uf: bit 1
|
||||
// * of: bit 2
|
||||
// * dz: bit 3
|
||||
// * nv: bit 4
|
||||
// * frm, rounding mode: bits 5-7
|
||||
// * reserved: bits 8-31
|
||||
fcsr: i32,
|
||||
}
|
||||
|
||||
// R-type
|
||||
// * opcode: bits 0-6
|
||||
// * rd: bits 7-11
|
||||
// * funct3: bits 12-14
|
||||
// * rs1: bits 15-19
|
||||
// * rs2: bits 20-24
|
||||
// * func7: bits 25-31
|
||||
|
||||
// I-type
|
||||
// * opcode: bits 0-6
|
||||
// * rd: bits 7-11
|
||||
// * funct3: bits 12-14
|
||||
// * rs1: bits 15-19
|
||||
// * imm[0:11]: bits 20-31
|
||||
|
||||
// S-type
|
||||
// * opcode: bits 0-6
|
||||
// * imm[0:4]: bits 7-11
|
||||
// * funct3: bits 12-14
|
||||
// * rs1: bits 15-19
|
||||
// * rs2: bits 20-24
|
||||
// * imm[5:11]: bits 25-31
|
||||
|
||||
// B-type
|
||||
// * opcode: bits 0-6
|
||||
// * imm[11]: bit 7
|
||||
// * imm[1:4]: bits 8-11
|
||||
// * funct3: bits 12-14
|
||||
// * rs1: bits 15-19
|
||||
// * rs2: bits 20-24
|
||||
// * imm[5:10]: bits 25-30
|
||||
// * imm[12]: bit 31
|
||||
|
||||
// U-type
|
||||
// * opcode: bits 0-6
|
||||
// * rd: bits 7-11
|
||||
// * imm[12:31]
|
||||
|
||||
// J-type
|
||||
// * opcode: bits 0-6
|
||||
// * rd: bits 7-11
|
||||
// * imm[12:19]: bits 12-19
|
||||
// * imm[11]: bit 20
|
||||
// * imm[1:10]: bits 21-30
|
||||
// * imm[20]: bit 31
|
||||
|
||||
// sequential path is expected to be the common case on conditional branches
|
||||
// this aligns nicely with encoding forward to the next unconditional branch
|
||||
// but if possible unconditional jumps within a compilation unit may be doable
|
||||
|
||||
// memory ordering instructions -- how can any of this be done? :D
|
||||
|
||||
// FENCE.I could tell us to clear JIT caches :D
|
||||
|
||||
|
||||
|
||||
extern "C" fn interpreter(
|
||||
_machine: *mut MachineState,
|
||||
_state: *mut CoreState,
|
||||
pc: i64) -> i64
|
||||
{
|
||||
println!("Hello, world!");
|
||||
return pc;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let size = 128 * 1024 * 1024;
|
||||
let mut memory = vec![0u8; size];
|
||||
let mut machine = MachineState {
|
||||
memory: &mut memory[..]
|
||||
};
|
||||
let mut core = CoreState {
|
||||
x: [
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
],
|
||||
f: [
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
||||
pc: 0,
|
||||
fcsr: 0,
|
||||
};
|
||||
let pc = interpreter(&mut machine, &mut core, 0);
|
||||
println!("Ended with PC {}", pc);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue