From 6dd313d2024c8a0c7a512eca90988ce95b63c6f3 Mon Sep 17 00:00:00 2001 From: David Li Date: Wed, 16 Dec 2015 17:13:38 -0500 Subject: Implement ADDI --- src/isa/mod.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/simulator.rs | 31 +++++++++++++++++++------ 2 files changed, 95 insertions(+), 7 deletions(-) diff --git a/src/isa/mod.rs b/src/isa/mod.rs index ac8ce45..b34d701 100644 --- a/src/isa/mod.rs +++ b/src/isa/mod.rs @@ -1,6 +1,7 @@ pub mod opcodes; pub mod funct3; +#[derive(Debug, PartialEq)] pub enum Register { X0 = 0, X1 = 1, @@ -14,12 +15,70 @@ pub enum Register { X9 = 9, X10 = 10, X11 = 11, + X12 = 12, + X13 = 13, + X14 = 14, + X15 = 15, + X16 = 16, + X17 = 17, + X18 = 18, + X19 = 19, + X20 = 20, + X21 = 21, + X22 = 22, + X23 = 23, + X24 = 24, + X25 = 25, + X26 = 26, + X27 = 27, + X28 = 28, + X29 = 29, + X30 = 30, + X31 = 31, } impl Register { pub fn as_num(self) -> usize { self as usize } + + pub fn from_num(num: u32) -> Register { + match num { + 0 => Register::X0, + 1 => Register::X1, + 2 => Register::X2, + 3 => Register::X3, + 4 => Register::X4, + 5 => Register::X5, + 6 => Register::X6, + 7 => Register::X7, + 8 => Register::X8, + 9 => Register::X9, + 10 => Register::X10, + 11 => Register::X11, + 12 => Register::X12, + 13 => Register::X13, + 14 => Register::X14, + 15 => Register::X15, + 16 => Register::X16, + 17 => Register::X17, + 18 => Register::X18, + 19 => Register::X19, + 20 => Register::X20, + 21 => Register::X21, + 22 => Register::X22, + 23 => Register::X23, + 24 => Register::X24, + 25 => Register::X25, + 26 => Register::X26, + 27 => Register::X27, + 28 => Register::X28, + 29 => Register::X29, + 30 => Register::X30, + 31 => Register::X31, + _ => panic!("Invalid register number: {}", num), + } + } } pub struct Instruction { @@ -37,7 +96,19 @@ impl Instruction { self.word & 0x7F } + pub fn rd(&self) -> Register { + Register::from_num((self.word >> 7) & 0x1F) + } + pub fn funct3(&self) -> u32 { (self.word >> 12) & 0x3 } + + pub fn rs1(&self) -> Register { + Register::from_num((self.word >> 15) & 0x1F) + } + + pub fn i_imm(&self) -> i32 { + (self.word as i32) >> 20 + } } diff --git a/src/simulator.rs b/src/simulator.rs index 8ecf6e7..a258ac1 100644 --- a/src/simulator.rs +++ b/src/simulator.rs @@ -8,18 +8,32 @@ pub struct Simulator { } #[derive(Clone)] -struct Core { - pc: usize, -} - struct RegisterFile { registers: [u32; 32], } +#[derive(Clone)] +struct Core { + pc: usize, + registers: RegisterFile, +} + impl RegisterFile { + fn new() -> RegisterFile { + RegisterFile { + registers: [0; 32], + } + } + fn write_word>(&mut self, reg: T, value: u32) { // TODO: should be safe to use unchecked index - self.registers[reg.into().as_num()] = value; + let reg = reg.into(); + if reg == isa::Register::X0 { return; } + self.registers[reg.as_num()] = value; + } + + fn read_word>(&mut self, reg: T) -> u32 { + self.registers[reg.into().as_num()] } } @@ -34,7 +48,7 @@ impl Simulator { } pub fn run(&mut self) { - let mut cores = vec![Core { pc: 0x10000, }; self.num_cores]; + let mut cores = vec![Core { pc: 0x10000, registers: RegisterFile::new() }; self.num_cores]; loop { for core in cores.iter_mut() { self.step_core(core); @@ -50,7 +64,10 @@ impl Simulator { }, isa::opcodes::INTEGER_IMMEDIATE => match inst.funct3() { isa::funct3::ADDI => { - println!("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); + println!("After ADDI: {:?} = {}", inst.rd(), core.registers.read_word(inst.rd()) as i32); } _ => { panic!("Invalid integer-immediate funct3code: 0x{:x}", inst.funct3()); -- cgit v1.2.3