Pack the Instruction Kind structs to 32b

This commit is contained in:
Lumi Kalt 2024-01-24 13:52:38 +00:00
parent e410fe0069
commit 96202c0d1a
9 changed files with 423 additions and 373 deletions

24
Cargo.lock generated
View file

@ -8,6 +8,12 @@ version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
[[package]]
name = "bitfield"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac"
[[package]] [[package]]
name = "codespan-reporting" name = "codespan-reporting"
version = "0.11.1" version = "0.11.1"
@ -74,6 +80,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.8.1" version = "1.8.1"
@ -99,10 +111,22 @@ name = "riscv_interpreter"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bitfield",
"codespan-reporting", "codespan-reporting",
"colored", "colored",
"itertools", "itertools",
"rayon", "rayon",
"term_size",
]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
] ]
[[package]] [[package]]

View file

@ -5,7 +5,9 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.79" anyhow = "1.0.79"
bitfield = "0.14.0"
codespan-reporting = "0.11.1" codespan-reporting = "0.11.1"
colored = "2.1.0" colored = "2.1.0"
itertools = "0.12.0" itertools = "0.12.0"
rayon = "1.8.1" rayon = "1.8.1"
term_size = "0.3.2"

28
src/colorizer.rs Normal file
View file

@ -0,0 +1,28 @@
use std::collections::HashMap;
use colored::Colorize;
fn add_color(input: String) -> String {
let map = [
("number", "magenta"),
("green", "blue"),
].iter().cloned().collect::<HashMap<&str, &str>>();
let mut colored = String::new();
for word in input.split(' ') {
if let Some(num) = word.parse::<i32>().ok() {
colored.push_str(&format!("{:032b}", num));
}
}
colored
}
fn handle_color(input: &str, color: &str) -> String {
match color {
"magenta" => input.magenta().to_string(),
"blue" => input.blue().to_string(),
_ => input.to_string(),
}
}

View file

@ -19,8 +19,7 @@ pub struct Env {
register_alias: HashMap<String, usize>, register_alias: HashMap<String, usize>,
labels: HashMap<String, u32>, labels: HashMap<String, u32>,
registers: [u32; 32], registers: [u32; 32],
/// EQ, LT, GT pub prev_stacks: Vec<Vec<u32>>,
pub cmp_flags: [bool; 3],
pub stack: Vec<u32>, // TODO: Find the actual size of the stack pub stack: Vec<u32>, // TODO: Find the actual size of the stack
pub instructions: Vec<u32>, pub instructions: Vec<u32>,
pub pc: u32, pub pc: u32,
@ -72,7 +71,7 @@ impl Env {
register_alias, register_alias,
labels: HashMap::new(), labels: HashMap::new(),
registers: [0; 32], registers: [0; 32],
cmp_flags: [false; 3], prev_stacks: Vec::new(),
stack: Vec::from([0; 1024]), // 1024 * 64 = 64 KiB stack stack: Vec::from([0; 1024]), // 1024 * 64 = 64 KiB stack
instructions: Vec::new(), instructions: Vec::new(),
pc: 0, pc: 0,

View file

@ -5,6 +5,11 @@ fn lui(env: &mut Env, rd: usize, imm: u32) {
env.set_register(rd, imm); env.set_register(rd, imm);
} }
/// addi rd, ra, imm
fn addi(env: &mut Env, rd: usize, ra: usize, imm: u32) {
env.set_register(rd, env.get_register(ra) + imm);
}
/// jal rd, imm /// jal rd, imm
fn jal(env: &mut Env, rd: usize, imm: u32) { fn jal(env: &mut Env, rd: usize, imm: u32) {
env.set_register(rd, env.pc); env.set_register(rd, env.pc);
@ -29,10 +34,13 @@ pub fn run_instruction(env: &mut Env, kind: Kind) {
let imm = kind.get_imm().unwrap(); let imm = kind.get_imm().unwrap();
let opcode = kind.get_opcode().unwrap(); let opcode = kind.get_opcode().unwrap();
match to_u32(opcode) { match opcode {
0b0110111 => { 0b0110111 => {
lui(env, rd, imm) lui(env, rd, imm)
} }
0b0010011 => {
addi(env, rd, ra, imm)
}
_ => todo!(), _ => todo!(),
} }
} }

View file

@ -13,7 +13,7 @@ pub fn info(env: &Env, op: &str, args: Vec<String>) -> Vec<String> {
.collect::<String>(); .collect::<String>();
vec![ vec![
format!( format!(
"load the upper 20 bits of {} into the register {}", "load the upper 20 bits of {} into {}",
args[1], args[0] args[1], args[0]
), ),
format!( format!(
@ -22,7 +22,7 @@ pub fn info(env: &Env, op: &str, args: Vec<String>) -> Vec<String> {
imm[12..32].to_string().red(), imm[12..32].to_string().red(),
imm[0..12].to_string() imm[0..12].to_string()
), ),
format!("{:>1$} = {2}{3:0>12}", args[0], args[1].to_string().len(), imm[12..32].to_string(), "0".to_string().bold()), format!("{:>1$} <- {2}{3:0>12}", args[0], args[1].to_string().len() - 1, imm[12..32].to_string(), "0".to_string().bold()),
] ]
} }
_ => todo!(), _ => todo!(),

View file

@ -1,85 +1,111 @@
pub mod kind { pub mod kind {
use std::fmt::{self, Display, Formatter}; use std::{
fmt::{self, Display, Formatter},
mem,
};
use crate::instructions::to_u32; use bitfield::bitfield;
use super::to_reg; use crate::instructions::{instruction, to_u32};
use super::{to_bits, to_reg};
/// will be converted by the engine to a real instruction /// will be converted by the engine to a real instruction
pub struct Pseudo(pub &'static str); pub struct Pseudo(pub &'static str);
pub struct R { bitfield! {
pub funct7: [bool; 7], pub struct R(u32);
pub rb: [bool; 5], impl Debug;
pub ra: [bool; 5],
pub funct3: [bool; 3], pub funct7, set_funct7: 31, 25;
pub rd: [bool; 5], pub rb, set_rb: 24, 20;
pub opcode: [bool; 7], pub ra, set_ra: 19, 15;
pub funct3, set_funct3: 14, 12;
pub rd, set_rd: 11, 7;
pub opcode, set_opcode: 6, 0;
} }
pub struct R4 { bitfield! {
pub rc: [bool; 5], pub struct R4(u32);
pub funct2: [bool; 2], impl Debug;
pub rb: [bool; 5],
pub ra: [bool; 5], pub rc, set_rc: 31, 27;
pub funct3: [bool; 3], pub funct2, set_funct2: 26, 25;
pub rd: [bool; 5], pub rb, set_rb: 24, 20;
pub opcode: [bool; 7], pub ra, set_ra: 19, 15;
pub funct3, set_funct3: 14, 12;
pub rd, set_rd: 11, 7;
pub opcode, set_opcode: 6, 0;
} }
pub struct I { bitfield! {
/// 11:0 pub struct I(u32);
pub imm: [bool; 12], impl Debug;
pub ra: [bool; 5],
pub funct3: [bool; 3], pub imm, set_imm: 31, 20;
pub rd: [bool; 5], pub ra, set_ra: 19, 15;
pub opcode: [bool; 7], pub funct3, set_funct3: 14, 12;
pub rd, set_rd: 11, 7;
pub opcode, set_opcode: 6, 0;
} }
pub struct I2 { bitfield! {
pub funct6: [bool; 6], pub struct I2(u32);
/// 5:0 impl Debug;
pub imm: [bool; 6],
pub ra: [bool; 5], pub funct6, set_funct6: 31, 26;
pub funct3: [bool; 3], pub imm, set_imm: 25, 20;
pub rd: [bool; 5], pub ra, set_ra: 19, 15;
pub opcode: [bool; 7], pub funct3, set_funct3: 14, 12;
pub rd, set_rd: 11, 7;
pub opcode, set_opcode: 6, 0;
} }
pub struct S { bitfield! {
/// 11:5 pub struct S(u32);
pub imm: [bool; 7], impl Debug;
pub rb: [bool; 5],
pub ra: [bool; 5], pub imm_11_5, set_imm_11_5: 31, 25;
pub funct3: [bool; 3], pub rb, set_rb: 24, 20;
/// 4:0 pub ra, set_ra: 19, 15;
pub imm2: [bool; 5], pub funct3, set_funct3: 14, 12;
pub opcode: [bool; 7], pub imm_4_0, set_imm_4_10: 11, 7;
pub opcode, set_opcode: 6, 0;
} }
pub struct B { bitfield! {
/// 12 | 10:5 pub struct B(u32);
pub imm: [bool; 7], impl Debug;
pub rb: [bool; 5],
pub ra: [bool; 5], pub imm_12, set_imm_12: 31;
pub funct3: [bool; 3], pub imm_10_5, set_imm_10_5: 30, 25;
/// 4:1 | 11 pub rb, set_rb: 24, 20;
pub imm2: [bool; 5], pub ra, set_ra: 19, 15;
pub opcode: [bool; 7], pub funct3, set_funct3: 14, 12;
pub imm_4_1, set_imm_4_1: 11, 8;
pub imm_11, set_imm_11: 7;
pub opcode, set_opcode: 6, 0;
} }
pub struct U { bitfield! {
/// 31:12 pub struct U(u32);
pub imm: [bool; 20], impl Debug;
pub rd: [bool; 5],
pub opcode: [bool; 7], pub imm31_12, set_imm_31_12: 31, 12;
pub rd, set_rd: 11, 7;
pub opcode, set_opcode: 6, 0;
} }
pub struct J { bitfield! {
/// 20 | 10:1 | 11 | 19:12 pub struct J(u32);
pub imm: [bool; 20], impl Debug;
pub rd: [bool; 5],
pub opcode: [bool; 7], pub imm_20, set_imm_20: 31;
pub imm_10_1, set_imm_10_1: 30, 21;
pub imm_11, set_imm_11: 20;
pub imm_19_12, set_imm_19_12: 19, 12;
pub rd, set_rd: 11, 7;
pub opcode, set_opcode: 6, 0;
} }
pub enum Kind { pub enum Kind {
@ -111,17 +137,17 @@ pub mod kind {
} }
impl Kind { impl Kind {
pub fn get_opcode(&self) -> Option<&[bool; 7]> { pub fn get_opcode(&self) -> Option<u32> {
match self { match self {
Kind::Pseudo(_) => None, Kind::Pseudo(_) => None,
Kind::R(r) => Some(&r.opcode), Kind::R(r) => Some(r.opcode()),
Kind::R4(r4) => Some(&r4.opcode), Kind::R4(r4) => Some(r4.opcode()),
Kind::I(i) => Some(&i.opcode), Kind::I(i) => Some(i.opcode()),
Kind::I2(i2) => Some(&i2.opcode), Kind::I2(i2) => Some(i2.opcode()),
Kind::S(s) => Some(&s.opcode), Kind::S(s) => Some(s.opcode()),
Kind::B(b) => Some(&b.opcode), Kind::B(b) => Some(b.opcode()),
Kind::U(u) => Some(&u.opcode), Kind::U(u) => Some(u.opcode()),
Kind::J(j) => Some(&j.opcode), Kind::J(j) => Some(j.opcode()),
} }
} }
@ -130,50 +156,57 @@ pub mod kind {
Kind::Pseudo(_) => None, Kind::Pseudo(_) => None,
Kind::R(_) => None, Kind::R(_) => None,
Kind::R4(_) => None, Kind::R4(_) => None,
Kind::I(i) => Some(to_u32(&i.imm)), Kind::I(i) => Some(i.imm()),
Kind::I2(i2) => Some(to_u32(&i2.imm)), Kind::I2(i2) => Some(i2.imm() >> 20),
Kind::S(s) => { Kind::S(s) => Some(s.imm_11_5() | s.imm_4_0()),
let mut imm = [false; 12]; Kind::B(b) => Some(
imm[0..=4].copy_from_slice(&s.imm2); ((b.imm_12() as u32) << 12)
imm[5..=11].copy_from_slice(&s.imm); | ((b.imm_11() as u32) << 11)
Some(to_u32(&imm)) | (b.imm_10_5() << 5)
} | (b.imm_4_1() << 1),
Kind::B(b) => { ),
let mut imm = [false; 13]; Kind::U(u) => Some(u.imm31_12() << 12),
imm[1..=4].copy_from_slice(&b.imm2[1..=4]); Kind::J(j) => Some(
imm[5..=10].copy_from_slice(&b.imm[0..=5]); ((j.imm_20() as u32) << 20)
imm[11] = b.imm2[0]; | ((j.imm_19_12() as u32) << 12)
imm[12] = b.imm[6]; | ((j.imm_11() as u32) << 11)
Some(to_u32(&imm)) | (j.imm_10_1() << 1),
} ),
Kind::U(u) => Some(to_u32(&u.imm) << 12),
Kind::J(j) => {
let mut imm = [false; 21];
imm[1..=10].copy_from_slice(&j.imm[9..=18]);
imm[11] = j.imm[8];
imm[12..=19].copy_from_slice(&j.imm[0..=7]);
imm[20] = j.imm[19];
Some(to_u32(&imm))
}
} }
} }
pub fn get_regs(&self) -> Option<Vec<usize>> { pub fn get_regs(&self) -> Option<Vec<usize>> {
match self { match self {
Kind::Pseudo(_) => None, Kind::Pseudo(_) => None,
Kind::R(r) => Some(vec![to_reg(&r.rd), to_reg(&r.ra), to_reg(&r.rb)]), Kind::R(r) => Some(vec![r.rd() as usize, r.ra() as usize, r.rb() as usize, 0]),
Kind::R4(r4) => Some(vec![ Kind::R4(r4) => Some(vec![
to_reg(&r4.rd), r4.rd() as usize,
to_reg(&r4.ra), r4.ra() as usize,
to_reg(&r4.rb), r4.rb() as usize,
to_reg(&r4.rc), r4.rc() as usize,
]), ]),
Kind::I(i) => Some(vec![to_reg(&i.rd), to_reg(&i.ra)]), Kind::I(i) => Some(vec![i.rd() as usize, i.ra() as usize, 0, 0]),
Kind::I2(i2) => Some(vec![to_reg(&i2.rd), to_reg(&i2.ra)]), Kind::I2(i2) => Some(vec![i2.rd() as usize, i2.ra() as usize, 0, 0]),
Kind::S(s) => Some(vec![0, to_reg(&s.ra), to_reg(&s.rb)]), Kind::S(s) => Some(vec![0, s.ra() as usize, s.rb() as usize, 0]),
Kind::B(b) => Some(vec![0, to_reg(&b.ra), to_reg(&b.rb)]), Kind::B(b) => Some(vec![0, b.ra() as usize, b.rb() as usize, 0]),
Kind::U(u) => Some(vec![to_reg(&u.rd)]), Kind::U(u) => Some(vec![u.rd() as usize, 0, 0, 0]),
Kind::J(j) => Some(vec![to_reg(&j.rd)]), Kind::J(j) => Some(vec![j.rd() as usize, 0, 0, 0]),
}
}
pub fn to_op(instruction: u32) -> (Kind, String) {
let opcode = instruction & 0b00000000000000000000000001111111;
match opcode {
0b0110111 => (
Kind::U(unsafe { mem::transmute_copy(&instruction) }),
"lui".into(),
),
0b0010011 => (
Kind::I(unsafe { mem::transmute_copy(&instruction) }),
"addi".into(),
),
_ => todo!(),
} }
} }
} }
@ -188,12 +221,12 @@ pub mod kind {
write!( write!(
f, f,
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}", "{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.funct7), self.funct7(),
to_u32(&self.rb), self.rb(),
to_u32(&self.ra), self.ra(),
to_u32(&self.funct3), self.funct3(),
to_u32(&self.rd), self.rd(),
to_u32(&self.opcode), self.opcode()
) )
} }
} }
@ -202,13 +235,13 @@ pub mod kind {
write!( write!(
f, f,
"{:05b}{:02b}{:05b}{:05b}{:03b}{:05b}{:07b}", "{:05b}{:02b}{:05b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.rc), self.rc(),
to_u32(&self.funct2), self.funct2(),
to_u32(&self.rb), self.rb(),
to_u32(&self.ra), self.ra(),
to_u32(&self.funct3), self.funct3(),
to_u32(&self.rd), self.rd(),
to_u32(&self.opcode), self.opcode()
) )
} }
} }
@ -217,11 +250,11 @@ pub mod kind {
write!( write!(
f, f,
"{:012b}{:05b}{:03b}{:05b}{:07b}", "{:012b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.imm), self.imm(),
to_u32(&self.ra), self.ra(),
to_u32(&self.funct3), self.funct3(),
to_u32(&self.rd), self.rd(),
to_u32(&self.opcode), self.opcode()
) )
} }
} }
@ -230,12 +263,12 @@ pub mod kind {
write!( write!(
f, f,
"{:06b}{:06b}{:05b}{:03b}{:05b}{:07b}", "{:06b}{:06b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.funct6), self.funct6(),
to_u32(&self.imm), self.imm(),
to_u32(&self.ra), self.ra(),
to_u32(&self.funct3), self.funct3(),
to_u32(&self.rd), self.rd(),
to_u32(&self.opcode), self.opcode()
) )
} }
} }
@ -244,12 +277,12 @@ pub mod kind {
write!( write!(
f, f,
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}", "{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.imm), self.imm_11_5(),
to_u32(&self.rb), self.rb(),
to_u32(&self.ra), self.ra(),
to_u32(&self.funct3), self.funct3(),
to_u32(&self.imm2), self.imm_4_0(),
to_u32(&self.opcode), self.opcode()
) )
} }
} }
@ -257,13 +290,15 @@ pub mod kind {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}", "{}{:06b}{:05b}{:05b}{:03b}{:04b}{}{:07b}",
to_u32(&self.imm), self.imm_12() as u32,
to_u32(&self.rb), self.imm_10_5(),
to_u32(&self.ra), self.rb(),
to_u32(&self.funct3), self.ra(),
to_u32(&self.imm2), self.funct3(),
to_u32(&self.opcode), self.imm_4_1(),
self.imm_11() as u32,
self.opcode()
) )
} }
} }
@ -272,9 +307,9 @@ pub mod kind {
write!( write!(
f, f,
"{:020b}{:05b}{:07b}", "{:020b}{:05b}{:07b}",
to_u32(&self.imm), self.imm31_12(),
to_u32(&self.rd), self.rd(),
to_u32(&self.opcode), self.opcode()
) )
} }
} }
@ -282,10 +317,13 @@ pub mod kind {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
"{:020b}{:05b}{:07b}", "{}{:09b}{}{:08b}{:05b}{:07b}",
to_u32(&self.imm), self.imm_20() as u32,
to_u32(&self.rd), self.imm_10_1(),
to_u32(&self.opcode), self.imm_11() as u32,
self.imm_19_12(),
self.rd(),
self.opcode()
) )
} }
} }
@ -342,70 +380,64 @@ pub fn instruction(op: &str) -> Option<(Kind, Vec<Arg>)> {
vec![Arg::Register(0), Arg::Immediate], vec![Arg::Register(0), Arg::Immediate],
), ),
"lui" => ( "lui" => (
Kind::U(U { Kind::U({
imm: to_bits(0), let mut u = U(0);
rd: to_bits(0), u.set_opcode(0b0110111);
opcode: to_bits(0b0110111), u
}), }),
vec![Arg::Register(0), Arg::Immediate], vec![Arg::Register(0), Arg::Immediate],
), ),
// Memory // Memory
"sb" => ( "sb" => (
Kind::S(S { Kind::S({
imm: to_bits(0), let mut s = S(0);
rb: to_bits(0), s.set_funct3(0b000);
ra: to_bits(0), s.set_opcode(0b0100011);
funct3: to_bits(0b000), s
imm2: to_bits(0),
opcode: to_bits(0b0100011),
}), }),
vec![Arg::Register(2), Arg::Memory], vec![Arg::Register(2), Arg::Memory],
), ),
// Arithmetic, Logic, Shift // Arithmetic, Logic, Shift
"add" => ( "add" => (
Kind::R(R { Kind::R({
funct7: to_bits(0b0000000), let mut r = R(0);
rb: to_bits(0), r.set_funct7(0b0000000);
ra: to_bits(0), r.set_funct3(0b000);
funct3: to_bits(0b000), r.set_opcode(0b0110011);
rd: to_bits(0), r
opcode: to_bits(0b0110011),
}), }),
vec![Arg::Register(0), Arg::Register(1), Arg::Register(2)], vec![Arg::Register(0), Arg::Register(1), Arg::Register(2)],
), ),
"addi" => ( "addi" => (
Kind::I(I { Kind::I({
imm: to_bits(0), let mut i = I(0);
ra: to_bits(0), i.set_funct3(0b000);
funct3: to_bits(0b000), i.set_opcode(0b0010011);
rd: to_bits(0), i
opcode: to_bits(0b0010011),
}), }),
vec![Arg::Register(0), Arg::Register(1), Arg::Immediate], vec![Arg::Register(0), Arg::Register(1), Arg::Immediate],
), ),
// Multiply, Divide // Multiply, Divide
"mul" => ( "mul" => (
Kind::R(R { Kind::R({
funct7: to_bits(0b0000001), let mut r = R(0);
rb: to_bits(0), r.set_funct7(0b0000001);
ra: to_bits(0), r.set_funct3(0b000);
funct3: to_bits(0b000), r.set_opcode(0b0110011);
rd: to_bits(0), r
opcode: to_bits(0b0110011),
}), }),
vec![Arg::Register(0), Arg::Register(1), Arg::Register(2)], vec![Arg::Register(0), Arg::Register(1), Arg::Register(2)],
), ),
"div" => ( "div" => (
Kind::R(R { Kind::R({
funct7: to_bits(0b0000001), let mut r = R(0);
rb: to_bits(0), r.set_funct7(0b0000001);
ra: to_bits(0), r.set_funct3(0b100);
funct3: to_bits(0b100), r.set_opcode(0b0110011);
rd: to_bits(0), r
opcode: to_bits(0b0110011),
}), }),
vec![Arg::Register(0), Arg::Register(1), Arg::Register(2)], vec![Arg::Register(0), Arg::Register(1), Arg::Register(2)],
), ),
@ -414,24 +446,20 @@ pub fn instruction(op: &str) -> Option<(Kind, Vec<Arg>)> {
// Flow control (branch, jump, call, ret) // Flow control (branch, jump, call, ret)
"beq" => ( "beq" => (
Kind::B(B { Kind::B({
imm: to_bits(0), let mut b = B(0);
rb: to_bits(0), b.set_funct3(0b000);
ra: to_bits(0), b.set_opcode(0b1100011);
funct3: to_bits(0b000), b
imm2: to_bits(0),
opcode: to_bits(0b1100011),
}), }),
vec![Arg::Register(1), Arg::Register(2), Arg::Immediate], vec![Arg::Register(1), Arg::Register(2), Arg::Immediate],
), ),
"bne" => ( "bne" => (
Kind::B(B { Kind::B({
imm: to_bits(0), let mut b = B(0);
rb: to_bits(0), b.set_funct3(0b001);
ra: to_bits(0), b.set_opcode(0b1100011);
funct3: to_bits(0b001), b
imm2: to_bits(0),
opcode: to_bits(0b1100011),
}), }),
vec![Arg::Register(1), Arg::Register(2), Arg::Immediate], vec![Arg::Register(1), Arg::Register(2), Arg::Immediate],
), ),
@ -445,10 +473,10 @@ pub fn instruction(op: &str) -> Option<(Kind, Vec<Arg>)> {
), ),
"j" => (Kind::Pseudo(Pseudo("j")), vec![Arg::Symbol]), "j" => (Kind::Pseudo(Pseudo("j")), vec![Arg::Symbol]),
"jal" => ( "jal" => (
Kind::J(J { Kind::J({
imm: to_bits(0), let mut j = J(0);
rd: to_bits(0), j.set_opcode(0b1101111);
opcode: to_bits(0b1101111), j
}), }),
vec![Arg::Register(0), Arg::Symbol], vec![Arg::Register(0), Arg::Symbol],
), ),
@ -464,120 +492,60 @@ pub fn get_instruction(op: &str) -> (Kind, Vec<Arg>) {
pub fn with((kind, args): (Kind, Vec<Arg>), imm: u32, regs: Vec<usize>) -> (Kind, Vec<Arg>) { pub fn with((kind, args): (Kind, Vec<Arg>), imm: u32, regs: Vec<usize>) -> (Kind, Vec<Arg>) {
match kind { match kind {
Kind::Pseudo(_) => (kind, args), Kind::Pseudo(_) => (kind, args),
Kind::R(r) => ( Kind::R(mut r) => {
Kind::R(R { r.set_rd(regs[0] as u32);
funct7: r.funct7, r.set_ra(regs[1] as u32);
rb: reg_bits(regs[2]), r.set_rb(regs[2] as u32);
ra: reg_bits(regs[1]), (Kind::R(r), args)
funct3: r.funct3,
rd: reg_bits(regs[0]),
opcode: r.opcode,
}),
args,
),
Kind::R4(r4) => (
Kind::R4(R4 {
rc: reg_bits(regs[3]),
funct2: r4.funct2,
rb: reg_bits(regs[2]),
ra: reg_bits(regs[1]),
funct3: r4.funct3,
rd: reg_bits(regs[0]),
opcode: r4.opcode,
}),
args,
),
Kind::I(i) => (
Kind::I(I {
imm: to_bits(imm),
ra: reg_bits(regs[1]),
funct3: i.funct3,
rd: reg_bits(regs[0]),
opcode: i.opcode,
}),
args,
),
Kind::I2(i2) => (
Kind::I2(I2 {
funct6: i2.funct6,
imm: to_bits(imm),
ra: reg_bits(regs[1]),
funct3: i2.funct3,
rd: reg_bits(regs[0]),
opcode: i2.opcode,
}),
args,
),
Kind::S(s) => {
let bits = to_bits::<32>(imm);
(
Kind::S(S {
imm: {
let mut imm = [false; 7];
imm.copy_from_slice(&bits[5..=11]);
imm
},
rb: reg_bits(regs[2]),
ra: reg_bits(regs[1]),
funct3: s.funct3,
imm2: {
let mut imm2 = [false; 5];
imm2.copy_from_slice(&bits[0..=4]);
imm2
},
opcode: s.opcode,
}),
args,
)
} }
Kind::B(b) => { Kind::R4(mut r4) => {
let bits = to_bits::<32>(imm); r4.set_rd(regs[0] as u32);
( r4.set_ra(regs[1] as u32);
Kind::B(B { r4.set_rb(regs[2] as u32);
imm: { r4.set_rc(regs[3] as u32);
let mut imm = [false; 7]; (Kind::R4(r4), args)
imm[6] = bits[12]; }
imm[0..=5].copy_from_slice(&bits[5..=10]); Kind::I(mut i) => {
imm i.set_rd(regs[0] as u32);
}, i.set_ra(regs[1] as u32);
rb: reg_bits(regs[2]), i.set_imm(imm);
ra: reg_bits(regs[1]), (Kind::I(i), args)
funct3: b.funct3, }
imm2: { Kind::I2(mut i2) => {
let mut imm2 = [false; 5]; i2.set_rd(regs[0] as u32);
imm2[1..=4].copy_from_slice(&bits[1..=4]); i2.set_ra(regs[1] as u32);
imm2[0] = bits[11]; i2.set_imm(imm);
imm2 (Kind::I2(i2), args)
}, }
opcode: b.opcode, Kind::S(mut s) => {
}), s.set_ra(regs[1] as u32);
args, s.set_rb(regs[2] as u32);
) s.set_imm_11_5(imm >> 5);
s.set_imm_4_10(imm);
(Kind::S(s), args)
}
Kind::B(mut b) => {
b.set_ra(regs[1] as u32);
b.set_rb(regs[2] as u32);
b.set_imm_12(to_bits::<1>(imm >> 12)[0]);
b.set_imm_11(to_bits::<1>(imm >> 11)[0]);
b.set_imm_10_5(imm >> 5);
b.set_imm_4_1(imm);
(Kind::B(b), args)
}
Kind::U(mut u) => {
u.set_rd(regs[0] as u32);
u.set_imm_31_12(imm >> 12);
(Kind::U(u), args)
}
Kind::J(mut j) => {
j.set_rd(regs[0] as u32);
j.set_imm_20(to_bits::<1>(imm >> 20)[0]);
j.set_imm_19_12(imm >> 12);
j.set_imm_11(to_bits::<1>(imm >> 11)[0]);
j.set_imm_10_1(imm >> 1);
(Kind::J(j), args)
} }
Kind::U(u) => (
Kind::U(U {
imm: to_bits(imm >> 12), // 31:12
rd: reg_bits(regs[0]),
opcode: u.opcode,
}),
args,
),
Kind::J(j) => (
Kind::J(J {
imm: {
let bits = to_bits::<32>(imm);
let mut imm = [false; 20];
imm[19] = bits[20];
imm[9..=18].copy_from_slice(&bits[1..=10]);
imm[8] = bits[11];
imm[0..=7].copy_from_slice(&bits[12..=19]);
imm
},
rd: reg_bits(regs[0]),
opcode: j.opcode,
}),
args,
),
} }
} }

View file

@ -3,6 +3,7 @@
#![feature(const_trait_impl)] #![feature(const_trait_impl)]
#![feature(effects)] #![feature(effects)]
pub mod colorizer;
pub mod env; pub mod env;
pub mod err; pub mod err;
pub mod execution; pub mod execution;

View file

@ -8,7 +8,7 @@ use codespan_reporting::{
}, },
}; };
use riscv_interpreter::{ use riscv_interpreter::{
env::Env, info::info, parser::{parse, Token} env::Env, execution::run_instruction, info::info, instructions::{instruction, kind::Kind}, parser::{parse, Token}
}; };
fn main() -> anyhow::Result<()> { fn main() -> anyhow::Result<()> {
@ -20,32 +20,40 @@ fn main() -> anyhow::Result<()> {
let mut env = Env::new(); let mut env = Env::new();
let mut ops: Vec<(Kind, String)> = Vec::new();
match parse(&env, &input) { match parse(&env, &input) {
Ok(tokens) => { Ok(tokens) => {
let lines: Vec<&str> = input.lines().collect(); let lines: Vec<&str> = input.lines().collect();
let size = lines.iter().map(|l| l.len()).max().unwrap(); let size = lines.iter().map(|l| l.len()).max().unwrap();
let mut i = 0;
env.handle_mem_offsets(tokens).iter().for_each(|(token, loc)| { env.handle_mem_offsets(tokens)
.iter()
.for_each(|(token, loc)| {
let token = token.clone(); let token = token.clone();
match token.clone() { match token.clone() {
Token::Op(..) => match env.assemble_op((token, loc.clone())) { Token::Op(name, _) => match env.assemble_op((token, loc.clone())) {
Ok(op) => { Ok(op) => {
let mut formatted = format!( let mut formatted = format!(
"{:<1$} {3:02x}: {2:032b}", "{:<1$} {3:02x}: {2:032b}",
lines[loc.line - 1], lines[loc.line - 1],
size + 3, size + 3,
op[0], op[0],
i loc.mem_offset
); );
i += 4; ops.push(Kind::to_op(op[0].clone()));
if op.len() > 1 { if op.len() > 1 {
for op in op[1..].iter() { for op in op[1..].iter() {
formatted += formatted += &format!(
&format!("\n{:<1$} {3:02x}: {2:032b}", "", size + 3, op, i); "\n{:<1$} {3:02x}: {2:032b}",
i += 4; "",
size + 3,
op,
loc.mem_offset
);
ops.push(Kind::to_op(op.clone()));
} }
} }
println!("{}", formatted); println!("{}", formatted);
@ -53,7 +61,10 @@ fn main() -> anyhow::Result<()> {
Err(err) => { Err(err) => {
let diagnostic = Diagnostic::error() let diagnostic = Diagnostic::error()
.with_message("Runtime Error") .with_message("Runtime Error")
.with_labels(vec![Label::primary((), err.1.start..(err.1.end + 1)) .with_labels(vec![Label::primary(
(),
err.1.start..(err.1.end + 1),
)
.with_message(err.0.to_string())]) .with_message(err.0.to_string())])
.with_notes({ .with_notes({
let mut notes = Vec::new(); let mut notes = Vec::new();
@ -64,7 +75,8 @@ fn main() -> anyhow::Result<()> {
notes notes
}); });
term::emit(&mut writer.lock(), &config, &file, &diagnostic).unwrap(); term::emit(&mut writer.lock(), &config, &file, &diagnostic)
.unwrap();
} }
}, },
Token::Label(name) => { Token::Label(name) => {
@ -104,7 +116,15 @@ fn main() -> anyhow::Result<()> {
} }
}; };
println!("{}", info(&env, "lui", vec!["a0".to_string(), "573498".to_string()]).join("\n")); for op in ops {
run_instruction(&mut env, op.0);
println!(
"{:<1$} <{2:02x}>",
op.1,
32,
env.get_register(10));
}
Ok(()) Ok(())
} }