aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2015-12-20 14:59:22 -0500
committerDavid Li <li.davidm96@gmail.com>2015-12-20 14:59:22 -0500
commit80c073a5c4a992598ecaf36c58d2294f6aa766d0 (patch)
tree416a845f3055e38005545f9c87b2b6445c878cf9
parent8ca42acf1a92ac0d811bbeecf8aed25a8c2d5a30 (diff)
Implement JAL, JALR
-rw-r--r--src/isa/mod.rs15
-rw-r--r--src/isa/opcodes.rs2
-rw-r--r--src/simulator.rs9
3 files changed, 21 insertions, 5 deletions
diff --git a/src/isa/mod.rs b/src/isa/mod.rs
index 0e3261b..c8aa290 100644
--- a/src/isa/mod.rs
+++ b/src/isa/mod.rs
@@ -127,9 +127,18 @@ impl Instruction {
}
pub fn s_imm(&self) -> i32 {
- let word = self.word as i32;
- let low = (word >> 7) & 0x1F;
- let high = (word >> 25) & 0x7F;
+ let low = (self.word >> 7) & 0x1F;
+ let high = ((self.word as i32) >> 25) & 0x7F;
(high << 7) | low
}
+
+ pub fn uj_imm(&self) -> i32 {
+ // Want zero-extension
+ let low1 = (self.word >> 21) & 0x3FF;
+ let low11 = (self.word >> 19) & 0x1;
+ let low12 = (self.word >> 12) & 0xFF;
+ // Want sign-extension
+ let low20 = ((self.word as i32) >> 30) & 0x1;
+ (low20 << 20) | (low12 << 12) | (low11 << 11) | (low1 << 1)
+ }
}
diff --git a/src/isa/opcodes.rs b/src/isa/opcodes.rs
index e5763e3..56b9568 100644
--- a/src/isa/opcodes.rs
+++ b/src/isa/opcodes.rs
@@ -1,6 +1,6 @@
pub const BRANCH: u32 = 0x63;
pub const JALR: u32 = 0x67;
-pub const JAL: u32 = 0x68;
+pub const JAL: u32 = 0x6F;
pub const INTEGER_IMMEDIATE: u32 = 0x13;
pub const INTEGER_REGISTER: u32 = 0x33;
pub const LOAD: u32 = 0x3;
diff --git a/src/simulator.rs b/src/simulator.rs
index a7140fe..607a3b5 100644
--- a/src/simulator.rs
+++ b/src/simulator.rs
@@ -105,9 +105,16 @@ impl Simulator {
// ret
core.running = false;
}
+ else {
+ let target = ((pc as i32) + inst.i_imm()) as usize;
+ core.registers.write_word(inst.rd(), pc + 4);
+ core.pc = target;
+ }
},
isa::opcodes::JAL => {
-
+ let target = ((pc as i32) + inst.uj_imm()) as usize;
+ core.registers.write_word(inst.rd(), pc + 4);
+ core.pc = target;
}
isa::opcodes::BRANCH => {