From 8ca42acf1a92ac0d811bbeecf8aed25a8c2d5a30 Mon Sep 17 00:00:00 2001
From: David Li
Date: Sat, 19 Dec 2015 09:27:18 -0500
Subject: Implement RV32I integer-immediate instructions
---
src/isa/funct3.rs | 3 +--
src/isa/funct7.rs | 3 +++
src/isa/mod.rs | 4 ++++
src/lib.rs | 1 -
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)
}
diff --git a/src/lib.rs b/src/lib.rs
index 8a607db..b3d29aa 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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());
--
cgit v1.2.3