aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2015-12-16 17:13:38 -0500
committerDavid Li <li.davidm96@gmail.com>2015-12-16 17:13:38 -0500
commit6dd313d2024c8a0c7a512eca90988ce95b63c6f3 (patch)
treeaa52843967d8068231038a3e607adea529b3a570 /src
parent55a9ca94d64249280438da9b90186e0a4973f90d (diff)
Implement ADDI
Diffstat (limited to 'src')
-rw-r--r--src/isa/mod.rs71
-rw-r--r--src/simulator.rs31
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<T: Into<isa::Register>>(&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<T: Into<isa::Register>>(&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());