diff options
| -rw-r--r-- | src/core.rs | 30 | ||||
| -rw-r--r-- | src/main.rs | 31 | ||||
| -rw-r--r-- | src/state.rs | 3 |
3 files changed, 56 insertions, 8 deletions
diff --git a/src/core.rs b/src/core.rs index 9e8e8dd..60d720b 100644 --- a/src/core.rs +++ b/src/core.rs @@ -520,3 +520,33 @@ pub fn fclass_s(state: &mut CpuState, rd: usize, rs1: usize) { } } } + +pub fn csrrw(state: &mut CpuState, rd: usize, rs1: usize, csr: usize) { + state.registers[rd] = state.csr[csr]; + state.csr[csr] = state.registers[rs1]; +} + +pub fn csrrwi(state: &mut CpuState, rd: usize, imm: u32, csr: usize) { + state.registers[rd] = state.csr[csr]; + state.csr[csr] = imm; +} + +pub fn csrrc(state: &mut CpuState, rd: usize, rs1: usize, csr: usize) { + state.registers[rd] = state.csr[csr]; + state.csr[csr] &= !state.registers[rs1]; +} + +pub fn csrrci(state: &mut CpuState, rd: usize, imm: u32, csr: usize) { + state.registers[rd] = state.csr[csr]; + state.csr[csr] &= !imm; +} + +pub fn csrrs(state: &mut CpuState, rd: usize, rs1: usize, csr: usize) { + state.registers[rd] = state.csr[csr]; + state.csr[csr] |= state.registers[rs1]; +} + +pub fn csrrsi(state: &mut CpuState, rd: usize, imm: u32, csr: usize) { + state.registers[rd] = state.csr[csr]; + state.csr[csr] |= imm; +}
\ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 3d8008d..20dde55 100644 --- a/src/main.rs +++ b/src/main.rs @@ -134,8 +134,6 @@ fn handle_instruction(state: &mut CpuState) { let imm = ((((imm_high << 5) | imm_low) as i32) << 20 >> 20) as u32; - let addr = (state.registers[rs1] + imm) as usize; - match f3 { 0 => sb(state, rs1, rs2, imm), 1 => sh(state, rs1, rs2, imm), @@ -200,11 +198,30 @@ fn handle_instruction(state: &mut CpuState) { auipc(state, rd as usize, imm); } 0b1110011 => { - // ecall - eprintln!( - "TRAP! syscall {} with gp state {:?}", - state.registers[17], pc - ); + let imm = word >> 20; + let rd = ((word >> 7) & REGISTER_NAME_WIDTH) as usize; + let rs1 = ((word >> 15) & REGISTER_NAME_WIDTH) as usize; + let f3 = (word >> 12) & 0b111; + + match f3 { + 0 => { + eprintln!( + "TRAP! syscall {} with gp state {:?}", + state.registers[17], pc + ); + + // todo: trap to CSR 0x305 + } // ecall + 1 => csrrw(state, rd, rs1, imm as usize), + 2 => csrrs(state, rd, rs1, imm as usize), + 3 => csrrc(state, rd, rs1, imm as usize), + 5 => csrrwi(state, rd, rs1 as u32, imm as usize), + 6 => csrrsi(state, rd, rs1 as u32, imm as usize), + 7 => csrrci(state, rd, rs1 as u32, imm as usize), + + _ => panic!("Illegal instruction: {:x}", word), + } + } // ecall (ebreak not implemented) 0b0101111 => { let f5 = word >> 27; diff --git a/src/state.rs b/src/state.rs index 6b1fb81..d4690bb 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,10 +1,10 @@ use crate::mem::Memory; -use std::collections::HashSet; pub struct CpuState { pub memory: Memory, pub registers: [u32; 32], pub f_registers: [f32; 32], + pub csr: [u32; 4096], pub pc: u32, pub reserved_addr: Option<usize>, } @@ -15,6 +15,7 @@ impl CpuState { memory, registers: [0u32; 32], f_registers: [0f32; 32], + csr: [0u32; 4096], pc: 0, reserved_addr: None, } |
