diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/isa/funct3.rs | 3 | ||||
-rw-r--r-- | src/isa/funct7.rs | 3 | ||||
-rw-r--r-- | src/isa/mod.rs | 4 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/simulator.rs | 67 |
5 files changed, 65 insertions, 13 deletions
diff --git a/src/isa/funct3.rs b/src/isa/funct3.rs index 0612844..be2eafa 100644 --- a/src/isa/funct3.rs +++ b/src/isa/funct3.rs @@ -3,8 +3,7 @@ pub const SLLI: u32 = 0x1; pub const SLTI: u32 = 0x2; pub const SLTIU: u32 = 0x3; pub const XORI: u32 = 0x4; -pub const SRLI: u32 = 0x5; -pub const SRAI: u32 = 0x5; +pub const SRLI_SRAI: u32 = 0x5; pub const ORI: u32 = 0x6; pub const ANDI: u32 = 0x7; diff --git a/src/isa/funct7.rs b/src/isa/funct7.rs index f3446fb..f48fae8 100644 --- a/src/isa/funct7.rs +++ b/src/isa/funct7.rs @@ -1,2 +1,5 @@ pub const ADD_SRL: u32 = 0x0; pub const SUB_SRA: u32 = 0x1; + +pub const SRLI: u32 = 0x0; +pub const SRAI: u32 = 0x1; diff --git a/src/isa/mod.rs b/src/isa/mod.rs index ebfd4e8..0e3261b 100644 --- a/src/isa/mod.rs +++ b/src/isa/mod.rs @@ -110,6 +110,10 @@ impl Instruction { (self.word >> 25) & 0x7F } + pub fn shamt(&self) -> u32 { + (self.word >> 20) & 0x1F + } + pub fn rs1(&self) -> Register { Register::from_num((self.word >> 15) & 0x1F) } @@ -7,7 +7,6 @@ pub mod simulator; #[test] fn it_works() { use std::path::Path; - println!("Test"); match binary::Binary::new_from_hex_file(Path::new("../riscv/kernel.hex")) { Ok(b) => { let mut simulator = simulator::Simulator::new(1, b); diff --git a/src/simulator.rs b/src/simulator.rs index c6d9ace..a7140fe 100644 --- a/src/simulator.rs +++ b/src/simulator.rs @@ -112,14 +112,63 @@ impl Simulator { isa::opcodes::BRANCH => { }, - isa::opcodes::INTEGER_IMMEDIATE => match inst.funct3() { - isa::funct3::ADDI => { - let imm = inst.i_imm(); - let src: i32 = core.registers.read_word(inst.rs1()) as i32; - core.registers.write_word(inst.rd(), src.wrapping_add(imm) as u32); - }, - _ => { - panic!("Invalid integer-immediate funct3code: 0x{:x}", inst.funct3()); + isa::opcodes::INTEGER_IMMEDIATE => { + let imm = inst.i_imm(); + let src: i32 = core.registers.read_word(inst.rs1()) as i32; + if let Some(value) = match inst.funct3() { + isa::funct3::ADDI => { + Some(src.wrapping_add(imm) as u32) + }, + isa::funct3::SLLI => { + Some((src << inst.shamt()) as u32) + }, + isa::funct3::SLTI => { + if src < imm { + Some(1) + } + else { + Some(0) + } + }, + isa::funct3::SLTIU => { + if (src as u32) < (imm as u32) { + Some(1) + } + else { + Some(0) + } + }, + isa::funct3::XORI => { + Some((src ^ imm) as u32) + }, + isa::funct3::SRLI_SRAI => { + match inst.funct7() { + isa::funct7::SRLI => Some(((src as u32) >> inst.shamt()) as u32), + isa::funct7::SRAI => Some((src >> inst.shamt()) as u32), + _ => { + self.trap(core, Trap::IllegalInstruction { + address: pc, + instruction: inst, + }); + None + } + } + }, + isa::funct3::ORI => { + Some((src | imm) as u32) + }, + isa::funct3::ANDI => { + Some((src & imm) as u32) + }, + _ => { + self.trap(core, Trap::IllegalInstruction { + address: pc, + instruction: inst, + }); + None + } + } { + core.registers.write_word(inst.rd(), value); } }, isa::opcodes::INTEGER_REGISTER => { @@ -199,7 +248,6 @@ impl Simulator { let address = ((base as i32) + imm) as usize; if let Some(value) = self.memory.read_word(address) { core.registers.write_word(inst.rd(), value); - println!("Load to {:?}: 0x{:X}", inst.rd(), value); } else { self.trap(core, Trap::IllegalRead { @@ -220,7 +268,6 @@ impl Simulator { let val = core.registers.read_word(inst.rs2()); let address = ((base as i32) + imm) as usize; self.memory.write_word(address, val); - println!("Store to 0x{:X}: 0x{:X}", address, val); } _ => { panic!("Invalid store funct3code: 0x{:x}", inst.funct3()); |