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

View file

@ -5,7 +5,9 @@ edition = "2021"
[dependencies]
anyhow = "1.0.79"
bitfield = "0.14.0"
codespan-reporting = "0.11.1"
colored = "2.1.0"
itertools = "0.12.0"
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>,
labels: HashMap<String, u32>,
registers: [u32; 32],
/// EQ, LT, GT
pub cmp_flags: [bool; 3],
pub prev_stacks: Vec<Vec<u32>>,
pub stack: Vec<u32>, // TODO: Find the actual size of the stack
pub instructions: Vec<u32>,
pub pc: u32,
@ -72,7 +71,7 @@ impl Env {
register_alias,
labels: HashMap::new(),
registers: [0; 32],
cmp_flags: [false; 3],
prev_stacks: Vec::new(),
stack: Vec::from([0; 1024]), // 1024 * 64 = 64 KiB stack
instructions: Vec::new(),
pc: 0,

View file

@ -5,6 +5,11 @@ fn lui(env: &mut Env, rd: usize, imm: u32) {
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
fn jal(env: &mut Env, rd: usize, imm: u32) {
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 opcode = kind.get_opcode().unwrap();
match to_u32(opcode) {
match opcode {
0b0110111 => {
lui(env, rd, imm)
}
0b0010011 => {
addi(env, rd, ra, imm)
}
_ => todo!(),
}
}

View file

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

View file

@ -1,85 +1,111 @@
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
pub struct Pseudo(pub &'static str);
pub struct R {
pub funct7: [bool; 7],
pub rb: [bool; 5],
pub ra: [bool; 5],
pub funct3: [bool; 3],
pub rd: [bool; 5],
pub opcode: [bool; 7],
bitfield! {
pub struct R(u32);
impl Debug;
pub funct7, set_funct7: 31, 25;
pub rb, set_rb: 24, 20;
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 {
pub rc: [bool; 5],
pub funct2: [bool; 2],
pub rb: [bool; 5],
pub ra: [bool; 5],
pub funct3: [bool; 3],
pub rd: [bool; 5],
pub opcode: [bool; 7],
bitfield! {
pub struct R4(u32);
impl Debug;
pub rc, set_rc: 31, 27;
pub funct2, set_funct2: 26, 25;
pub rb, set_rb: 24, 20;
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 {
/// 11:0
pub imm: [bool; 12],
pub ra: [bool; 5],
pub funct3: [bool; 3],
pub rd: [bool; 5],
pub opcode: [bool; 7],
bitfield! {
pub struct I(u32);
impl Debug;
pub imm, set_imm: 31, 20;
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 I2 {
pub funct6: [bool; 6],
/// 5:0
pub imm: [bool; 6],
pub ra: [bool; 5],
pub funct3: [bool; 3],
pub rd: [bool; 5],
pub opcode: [bool; 7],
bitfield! {
pub struct I2(u32);
impl Debug;
pub funct6, set_funct6: 31, 26;
pub imm, set_imm: 25, 20;
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 S {
/// 11:5
pub imm: [bool; 7],
pub rb: [bool; 5],
pub ra: [bool; 5],
pub funct3: [bool; 3],
/// 4:0
pub imm2: [bool; 5],
pub opcode: [bool; 7],
bitfield! {
pub struct S(u32);
impl Debug;
pub imm_11_5, set_imm_11_5: 31, 25;
pub rb, set_rb: 24, 20;
pub ra, set_ra: 19, 15;
pub funct3, set_funct3: 14, 12;
pub imm_4_0, set_imm_4_10: 11, 7;
pub opcode, set_opcode: 6, 0;
}
pub struct B {
/// 12 | 10:5
pub imm: [bool; 7],
pub rb: [bool; 5],
pub ra: [bool; 5],
pub funct3: [bool; 3],
/// 4:1 | 11
pub imm2: [bool; 5],
pub opcode: [bool; 7],
bitfield! {
pub struct B(u32);
impl Debug;
pub imm_12, set_imm_12: 31;
pub imm_10_5, set_imm_10_5: 30, 25;
pub rb, set_rb: 24, 20;
pub ra, set_ra: 19, 15;
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 {
/// 31:12
pub imm: [bool; 20],
pub rd: [bool; 5],
pub opcode: [bool; 7],
bitfield! {
pub struct U(u32);
impl Debug;
pub imm31_12, set_imm_31_12: 31, 12;
pub rd, set_rd: 11, 7;
pub opcode, set_opcode: 6, 0;
}
pub struct J {
/// 20 | 10:1 | 11 | 19:12
pub imm: [bool; 20],
pub rd: [bool; 5],
pub opcode: [bool; 7],
bitfield! {
pub struct J(u32);
impl Debug;
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 {
@ -111,17 +137,17 @@ pub mod kind {
}
impl Kind {
pub fn get_opcode(&self) -> Option<&[bool; 7]> {
pub fn get_opcode(&self) -> Option<u32> {
match self {
Kind::Pseudo(_) => None,
Kind::R(r) => Some(&r.opcode),
Kind::R4(r4) => Some(&r4.opcode),
Kind::I(i) => Some(&i.opcode),
Kind::I2(i2) => Some(&i2.opcode),
Kind::S(s) => Some(&s.opcode),
Kind::B(b) => Some(&b.opcode),
Kind::U(u) => Some(&u.opcode),
Kind::J(j) => Some(&j.opcode),
Kind::R(r) => Some(r.opcode()),
Kind::R4(r4) => Some(r4.opcode()),
Kind::I(i) => Some(i.opcode()),
Kind::I2(i2) => Some(i2.opcode()),
Kind::S(s) => Some(s.opcode()),
Kind::B(b) => Some(b.opcode()),
Kind::U(u) => Some(u.opcode()),
Kind::J(j) => Some(j.opcode()),
}
}
@ -130,50 +156,57 @@ pub mod kind {
Kind::Pseudo(_) => None,
Kind::R(_) => None,
Kind::R4(_) => None,
Kind::I(i) => Some(to_u32(&i.imm)),
Kind::I2(i2) => Some(to_u32(&i2.imm)),
Kind::S(s) => {
let mut imm = [false; 12];
imm[0..=4].copy_from_slice(&s.imm2);
imm[5..=11].copy_from_slice(&s.imm);
Some(to_u32(&imm))
}
Kind::B(b) => {
let mut imm = [false; 13];
imm[1..=4].copy_from_slice(&b.imm2[1..=4]);
imm[5..=10].copy_from_slice(&b.imm[0..=5]);
imm[11] = b.imm2[0];
imm[12] = b.imm[6];
Some(to_u32(&imm))
}
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))
}
Kind::I(i) => Some(i.imm()),
Kind::I2(i2) => Some(i2.imm() >> 20),
Kind::S(s) => Some(s.imm_11_5() | s.imm_4_0()),
Kind::B(b) => Some(
((b.imm_12() as u32) << 12)
| ((b.imm_11() as u32) << 11)
| (b.imm_10_5() << 5)
| (b.imm_4_1() << 1),
),
Kind::U(u) => Some(u.imm31_12() << 12),
Kind::J(j) => Some(
((j.imm_20() as u32) << 20)
| ((j.imm_19_12() as u32) << 12)
| ((j.imm_11() as u32) << 11)
| (j.imm_10_1() << 1),
),
}
}
pub fn get_regs(&self) -> Option<Vec<usize>> {
match self {
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![
to_reg(&r4.rd),
to_reg(&r4.ra),
to_reg(&r4.rb),
to_reg(&r4.rc),
r4.rd() as usize,
r4.ra() as usize,
r4.rb() as usize,
r4.rc() as usize,
]),
Kind::I(i) => Some(vec![to_reg(&i.rd), to_reg(&i.ra)]),
Kind::I2(i2) => Some(vec![to_reg(&i2.rd), to_reg(&i2.ra)]),
Kind::S(s) => Some(vec![0, to_reg(&s.ra), to_reg(&s.rb)]),
Kind::B(b) => Some(vec![0, to_reg(&b.ra), to_reg(&b.rb)]),
Kind::U(u) => Some(vec![to_reg(&u.rd)]),
Kind::J(j) => Some(vec![to_reg(&j.rd)]),
Kind::I(i) => Some(vec![i.rd() as usize, i.ra() as usize, 0, 0]),
Kind::I2(i2) => Some(vec![i2.rd() as usize, i2.ra() as usize, 0, 0]),
Kind::S(s) => Some(vec![0, s.ra() as usize, s.rb() as usize, 0]),
Kind::B(b) => Some(vec![0, b.ra() as usize, b.rb() as usize, 0]),
Kind::U(u) => Some(vec![u.rd() as usize, 0, 0, 0]),
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!(
f,
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.funct7),
to_u32(&self.rb),
to_u32(&self.ra),
to_u32(&self.funct3),
to_u32(&self.rd),
to_u32(&self.opcode),
self.funct7(),
self.rb(),
self.ra(),
self.funct3(),
self.rd(),
self.opcode()
)
}
}
@ -202,13 +235,13 @@ pub mod kind {
write!(
f,
"{:05b}{:02b}{:05b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.rc),
to_u32(&self.funct2),
to_u32(&self.rb),
to_u32(&self.ra),
to_u32(&self.funct3),
to_u32(&self.rd),
to_u32(&self.opcode),
self.rc(),
self.funct2(),
self.rb(),
self.ra(),
self.funct3(),
self.rd(),
self.opcode()
)
}
}
@ -217,11 +250,11 @@ pub mod kind {
write!(
f,
"{:012b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.imm),
to_u32(&self.ra),
to_u32(&self.funct3),
to_u32(&self.rd),
to_u32(&self.opcode),
self.imm(),
self.ra(),
self.funct3(),
self.rd(),
self.opcode()
)
}
}
@ -230,12 +263,12 @@ pub mod kind {
write!(
f,
"{:06b}{:06b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.funct6),
to_u32(&self.imm),
to_u32(&self.ra),
to_u32(&self.funct3),
to_u32(&self.rd),
to_u32(&self.opcode),
self.funct6(),
self.imm(),
self.ra(),
self.funct3(),
self.rd(),
self.opcode()
)
}
}
@ -244,12 +277,12 @@ pub mod kind {
write!(
f,
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.imm),
to_u32(&self.rb),
to_u32(&self.ra),
to_u32(&self.funct3),
to_u32(&self.imm2),
to_u32(&self.opcode),
self.imm_11_5(),
self.rb(),
self.ra(),
self.funct3(),
self.imm_4_0(),
self.opcode()
)
}
}
@ -257,13 +290,15 @@ pub mod kind {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}",
to_u32(&self.imm),
to_u32(&self.rb),
to_u32(&self.ra),
to_u32(&self.funct3),
to_u32(&self.imm2),
to_u32(&self.opcode),
"{}{:06b}{:05b}{:05b}{:03b}{:04b}{}{:07b}",
self.imm_12() as u32,
self.imm_10_5(),
self.rb(),
self.ra(),
self.funct3(),
self.imm_4_1(),
self.imm_11() as u32,
self.opcode()
)
}
}
@ -272,9 +307,9 @@ pub mod kind {
write!(
f,
"{:020b}{:05b}{:07b}",
to_u32(&self.imm),
to_u32(&self.rd),
to_u32(&self.opcode),
self.imm31_12(),
self.rd(),
self.opcode()
)
}
}
@ -282,10 +317,13 @@ pub mod kind {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"{:020b}{:05b}{:07b}",
to_u32(&self.imm),
to_u32(&self.rd),
to_u32(&self.opcode),
"{}{:09b}{}{:08b}{:05b}{:07b}",
self.imm_20() as u32,
self.imm_10_1(),
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],
),
"lui" => (
Kind::U(U {
imm: to_bits(0),
rd: to_bits(0),
opcode: to_bits(0b0110111),
Kind::U({
let mut u = U(0);
u.set_opcode(0b0110111);
u
}),
vec![Arg::Register(0), Arg::Immediate],
),
// Memory
"sb" => (
Kind::S(S {
imm: to_bits(0),
rb: to_bits(0),
ra: to_bits(0),
funct3: to_bits(0b000),
imm2: to_bits(0),
opcode: to_bits(0b0100011),
Kind::S({
let mut s = S(0);
s.set_funct3(0b000);
s.set_opcode(0b0100011);
s
}),
vec![Arg::Register(2), Arg::Memory],
),
// Arithmetic, Logic, Shift
"add" => (
Kind::R(R {
funct7: to_bits(0b0000000),
rb: to_bits(0),
ra: to_bits(0),
funct3: to_bits(0b000),
rd: to_bits(0),
opcode: to_bits(0b0110011),
Kind::R({
let mut r = R(0);
r.set_funct7(0b0000000);
r.set_funct3(0b000);
r.set_opcode(0b0110011);
r
}),
vec![Arg::Register(0), Arg::Register(1), Arg::Register(2)],
),
"addi" => (
Kind::I(I {
imm: to_bits(0),
ra: to_bits(0),
funct3: to_bits(0b000),
rd: to_bits(0),
opcode: to_bits(0b0010011),
Kind::I({
let mut i = I(0);
i.set_funct3(0b000);
i.set_opcode(0b0010011);
i
}),
vec![Arg::Register(0), Arg::Register(1), Arg::Immediate],
),
// Multiply, Divide
"mul" => (
Kind::R(R {
funct7: to_bits(0b0000001),
rb: to_bits(0),
ra: to_bits(0),
funct3: to_bits(0b000),
rd: to_bits(0),
opcode: to_bits(0b0110011),
Kind::R({
let mut r = R(0);
r.set_funct7(0b0000001);
r.set_funct3(0b000);
r.set_opcode(0b0110011);
r
}),
vec![Arg::Register(0), Arg::Register(1), Arg::Register(2)],
),
"div" => (
Kind::R(R {
funct7: to_bits(0b0000001),
rb: to_bits(0),
ra: to_bits(0),
funct3: to_bits(0b100),
rd: to_bits(0),
opcode: to_bits(0b0110011),
Kind::R({
let mut r = R(0);
r.set_funct7(0b0000001);
r.set_funct3(0b100);
r.set_opcode(0b0110011);
r
}),
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)
"beq" => (
Kind::B(B {
imm: to_bits(0),
rb: to_bits(0),
ra: to_bits(0),
funct3: to_bits(0b000),
imm2: to_bits(0),
opcode: to_bits(0b1100011),
Kind::B({
let mut b = B(0);
b.set_funct3(0b000);
b.set_opcode(0b1100011);
b
}),
vec![Arg::Register(1), Arg::Register(2), Arg::Immediate],
),
"bne" => (
Kind::B(B {
imm: to_bits(0),
rb: to_bits(0),
ra: to_bits(0),
funct3: to_bits(0b001),
imm2: to_bits(0),
opcode: to_bits(0b1100011),
Kind::B({
let mut b = B(0);
b.set_funct3(0b001);
b.set_opcode(0b1100011);
b
}),
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]),
"jal" => (
Kind::J(J {
imm: to_bits(0),
rd: to_bits(0),
opcode: to_bits(0b1101111),
Kind::J({
let mut j = J(0);
j.set_opcode(0b1101111);
j
}),
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>) {
match kind {
Kind::Pseudo(_) => (kind, args),
Kind::R(r) => (
Kind::R(R {
funct7: r.funct7,
rb: reg_bits(regs[2]),
ra: reg_bits(regs[1]),
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::R(mut r) => {
r.set_rd(regs[0] as u32);
r.set_ra(regs[1] as u32);
r.set_rb(regs[2] as u32);
(Kind::R(r), args)
}
Kind::B(b) => {
let bits = to_bits::<32>(imm);
(
Kind::B(B {
imm: {
let mut imm = [false; 7];
imm[6] = bits[12];
imm[0..=5].copy_from_slice(&bits[5..=10]);
imm
},
rb: reg_bits(regs[2]),
ra: reg_bits(regs[1]),
funct3: b.funct3,
imm2: {
let mut imm2 = [false; 5];
imm2[1..=4].copy_from_slice(&bits[1..=4]);
imm2[0] = bits[11];
imm2
},
opcode: b.opcode,
}),
args,
)
Kind::R4(mut r4) => {
r4.set_rd(regs[0] as u32);
r4.set_ra(regs[1] as u32);
r4.set_rb(regs[2] as u32);
r4.set_rc(regs[3] as u32);
(Kind::R4(r4), args)
}
Kind::I(mut i) => {
i.set_rd(regs[0] as u32);
i.set_ra(regs[1] as u32);
i.set_imm(imm);
(Kind::I(i), args)
}
Kind::I2(mut i2) => {
i2.set_rd(regs[0] as u32);
i2.set_ra(regs[1] as u32);
i2.set_imm(imm);
(Kind::I2(i2), args)
}
Kind::S(mut s) => {
s.set_ra(regs[1] as u32);
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(effects)]
pub mod colorizer;
pub mod env;
pub mod err;
pub mod execution;

View file

@ -8,7 +8,7 @@ use codespan_reporting::{
},
};
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<()> {
@ -20,64 +20,76 @@ fn main() -> anyhow::Result<()> {
let mut env = Env::new();
let mut ops: Vec<(Kind, String)> = Vec::new();
match parse(&env, &input) {
Ok(tokens) => {
let lines: Vec<&str> = input.lines().collect();
let size = lines.iter().map(|l| l.len()).max().unwrap();
let mut i = 0;
env.handle_mem_offsets(tokens).iter().for_each(|(token, loc)| {
let token = token.clone();
env.handle_mem_offsets(tokens)
.iter()
.for_each(|(token, loc)| {
let token = token.clone();
match token.clone() {
Token::Op(..) => match env.assemble_op((token, loc.clone())) {
Ok(op) => {
let mut formatted = format!(
"{:<1$} {3:02x}: {2:032b}",
lines[loc.line - 1],
size + 3,
op[0],
i
);
i += 4;
match token.clone() {
Token::Op(name, _) => match env.assemble_op((token, loc.clone())) {
Ok(op) => {
let mut formatted = format!(
"{:<1$} {3:02x}: {2:032b}",
lines[loc.line - 1],
size + 3,
op[0],
loc.mem_offset
);
ops.push(Kind::to_op(op[0].clone()));
if op.len() > 1 {
for op in op[1..].iter() {
formatted +=
&format!("\n{:<1$} {3:02x}: {2:032b}", "", size + 3, op, i);
i += 4;
}
}
println!("{}", formatted);
}
Err(err) => {
let diagnostic = Diagnostic::error()
.with_message("Runtime Error")
.with_labels(vec![Label::primary((), err.1.start..(err.1.end + 1))
.with_message(err.0.to_string())])
.with_notes({
let mut notes = Vec::new();
if let Some(note) = &err.2 {
notes.push(note.to_string());
if op.len() > 1 {
for op in op[1..].iter() {
formatted += &format!(
"\n{:<1$} {3:02x}: {2:032b}",
"",
size + 3,
op,
loc.mem_offset
);
ops.push(Kind::to_op(op.clone()));
}
notes.push(err.0.note());
notes
});
}
println!("{}", formatted);
}
Err(err) => {
let diagnostic = Diagnostic::error()
.with_message("Runtime Error")
.with_labels(vec![Label::primary(
(),
err.1.start..(err.1.end + 1),
)
.with_message(err.0.to_string())])
.with_notes({
let mut notes = Vec::new();
if let Some(note) = &err.2 {
notes.push(note.to_string());
}
notes.push(err.0.note());
notes
});
term::emit(&mut writer.lock(), &config, &file, &diagnostic).unwrap();
term::emit(&mut writer.lock(), &config, &file, &diagnostic)
.unwrap();
}
},
Token::Label(name) => {
println!(
"{:<1$} <{2:02x}>",
name.clone() + ":",
size + 3,
env.get_label(&name).unwrap()
);
}
},
Token::Label(name) => {
println!(
"{:<1$} <{2:02x}>",
name.clone() + ":",
size + 3,
env.get_label(&name).unwrap()
);
_ => unreachable!(),
}
_ => unreachable!(),
}
});
});
}
Err(errs) => {
let err = errs.first().unwrap();
@ -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(())
}