Encode imm, needs further testing
This commit is contained in:
parent
746d33b0b9
commit
ef87cbefc2
3 changed files with 187 additions and 67 deletions
22
src/env.rs
22
src/env.rs
|
@ -4,8 +4,8 @@ use crate::{err::RuntimeErr, parser::{Loc, Token}};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Env {
|
pub struct Env {
|
||||||
pub register_alias: HashMap<String, usize>,
|
pub register_alias: HashMap<String, u32>,
|
||||||
labels: HashMap<String, usize>,
|
labels: HashMap<String, u32>,
|
||||||
registers: [i64; 32],
|
registers: [i64; 32],
|
||||||
pub stack: Vec<i64>, // TODO: Find the size of the stack
|
pub stack: Vec<i64>, // TODO: Find the size of the stack
|
||||||
pub instructions: Vec<u32>,
|
pub instructions: Vec<u32>,
|
||||||
|
@ -61,22 +61,22 @@ impl Env {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_register(&mut self, reg: usize, value: i64) {
|
pub fn set_register(&mut self, reg: u32, value: i64) {
|
||||||
self.registers[reg] = value;
|
self.registers[reg as usize] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_register(&self, reg: usize) -> i64 {
|
pub fn get_register(&self, reg: u32) -> i64 {
|
||||||
self.registers[reg]
|
self.registers[reg as usize]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alias_to_register(&self, reg: &str) -> Option<usize> {
|
pub fn alias_to_register(&self, reg: &str) -> Option<u32> {
|
||||||
self.register_alias.get(reg).copied()
|
self.register_alias.get(reg).copied()
|
||||||
}
|
}
|
||||||
pub fn xn_to_register(&self, reg: &str) -> Option<usize> {
|
pub fn xn_to_register(&self, reg: &str) -> Option<u32> {
|
||||||
if reg == "x0" {
|
if reg == "x0" {
|
||||||
Some(0)
|
Some(0)
|
||||||
} else if reg.starts_with("x") && !reg[1..].starts_with("0") {
|
} else if reg.starts_with("x") && !reg[1..].starts_with("0") {
|
||||||
match reg[1..].parse::<usize>() {
|
match reg[1..].parse::<u32>() {
|
||||||
Ok(n) if n < 32 => Some(n),
|
Ok(n) if n < 32 => Some(n),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -90,11 +90,11 @@ impl Env {
|
||||||
.is_some()
|
.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_label(&mut self, label: &str, value: usize) {
|
pub fn add_label(&mut self, label: &str, value: u32) {
|
||||||
self.labels.insert(label.to_string(), value);
|
self.labels.insert(label.to_string(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_label(&self, label: &str) -> Option<usize> {
|
pub fn get_label(&self, label: &str) -> Option<u32> {
|
||||||
self.labels.get(label).copied()
|
self.labels.get(label).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ pub mod kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct I {
|
pub struct I {
|
||||||
pub imm: [bool; 12], // 11:0
|
/// 11:0
|
||||||
|
pub imm: [bool; 12],
|
||||||
pub ra: [bool; 5],
|
pub ra: [bool; 5],
|
||||||
pub funct3: [bool; 3],
|
pub funct3: [bool; 3],
|
||||||
pub rd: [bool; 5],
|
pub rd: [bool; 5],
|
||||||
|
@ -35,7 +36,8 @@ pub mod kind {
|
||||||
|
|
||||||
pub struct I2 {
|
pub struct I2 {
|
||||||
pub funct6: [bool; 6],
|
pub funct6: [bool; 6],
|
||||||
pub imm: [bool; 6], // 5:0
|
/// 5:0
|
||||||
|
pub imm: [bool; 6],
|
||||||
pub ra: [bool; 5],
|
pub ra: [bool; 5],
|
||||||
pub funct3: [bool; 3],
|
pub funct3: [bool; 3],
|
||||||
pub rd: [bool; 5],
|
pub rd: [bool; 5],
|
||||||
|
@ -43,31 +45,37 @@ pub mod kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct S {
|
pub struct S {
|
||||||
pub imm: [bool; 7], // 11:5
|
/// 11:5
|
||||||
|
pub imm: [bool; 7],
|
||||||
pub rb: [bool; 5],
|
pub rb: [bool; 5],
|
||||||
pub ra: [bool; 5],
|
pub ra: [bool; 5],
|
||||||
pub funct3: [bool; 3],
|
pub funct3: [bool; 3],
|
||||||
pub imm2: [bool; 5], // 4:0
|
/// 4:0
|
||||||
|
pub imm2: [bool; 5],
|
||||||
pub opcode: [bool; 7],
|
pub opcode: [bool; 7],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct B {
|
pub struct B {
|
||||||
pub imm: [bool; 7], // 12 | 10:5
|
/// 12 | 10:5
|
||||||
|
pub imm: [bool; 7],
|
||||||
pub rb: [bool; 5],
|
pub rb: [bool; 5],
|
||||||
pub ra: [bool; 5],
|
pub ra: [bool; 5],
|
||||||
pub funct3: [bool; 3],
|
pub funct3: [bool; 3],
|
||||||
pub imm2: [bool; 5], // 4:1 | 11
|
/// 4:1 | 11
|
||||||
|
pub imm2: [bool; 5],
|
||||||
pub opcode: [bool; 7],
|
pub opcode: [bool; 7],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct U {
|
pub struct U {
|
||||||
pub imm: [bool; 20], // 31:12
|
/// 31:12
|
||||||
|
pub imm: [bool; 20],
|
||||||
pub rd: [bool; 5],
|
pub rd: [bool; 5],
|
||||||
pub opcode: [bool; 7],
|
pub opcode: [bool; 7],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct J {
|
pub struct J {
|
||||||
pub imm: [bool; 20], // 20 | 10:1 | 11 | 19:12
|
/// 20 | 10:1 | 11 | 19:12
|
||||||
|
pub imm: [bool; 20],
|
||||||
pub rd: [bool; 5],
|
pub rd: [bool; 5],
|
||||||
pub opcode: [bool; 7],
|
pub opcode: [bool; 7],
|
||||||
}
|
}
|
||||||
|
@ -111,12 +119,12 @@ pub mod kind {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}",
|
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}",
|
||||||
to_u32(&self.opcode),
|
|
||||||
to_u32(&self.rd),
|
|
||||||
to_u32(&self.funct3),
|
|
||||||
to_u32(&self.ra),
|
|
||||||
to_u32(&self.rb),
|
|
||||||
to_u32(&self.funct7),
|
to_u32(&self.funct7),
|
||||||
|
to_u32(&self.rb),
|
||||||
|
to_u32(&self.ra),
|
||||||
|
to_u32(&self.funct3),
|
||||||
|
to_u32(&self.rd),
|
||||||
|
to_u32(&self.opcode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,15 +132,14 @@ 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}{:02b}{:05b}{:07b}",
|
"{:05b}{:02b}{:05b}{:05b}{:03b}{:05b}{:07b}",
|
||||||
to_u32(&self.opcode),
|
|
||||||
to_u32(&self.rd),
|
|
||||||
to_u32(&self.funct3),
|
|
||||||
to_u32(&self.ra),
|
|
||||||
to_u32(&self.rb),
|
|
||||||
to_u32(&self.funct2),
|
|
||||||
to_u32(&self.rc),
|
to_u32(&self.rc),
|
||||||
to_u32(&[false; 7]),
|
to_u32(&self.funct2),
|
||||||
|
to_u32(&self.rb),
|
||||||
|
to_u32(&self.ra),
|
||||||
|
to_u32(&self.funct3),
|
||||||
|
to_u32(&self.rd),
|
||||||
|
to_u32(&self.opcode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,12 +147,12 @@ 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}{:03b}{:05b}{:012b}",
|
"{:012b}{:05b}{:03b}{:05b}{:07b}",
|
||||||
to_u32(&self.opcode),
|
|
||||||
to_u32(&self.rd),
|
|
||||||
to_u32(&self.funct3),
|
|
||||||
to_u32(&self.ra),
|
|
||||||
to_u32(&self.imm),
|
to_u32(&self.imm),
|
||||||
|
to_u32(&self.ra),
|
||||||
|
to_u32(&self.funct3),
|
||||||
|
to_u32(&self.rd),
|
||||||
|
to_u32(&self.opcode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,13 +160,13 @@ 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}{:03b}{:05b}{:05b}{:06b}",
|
"{:06b}{:06b}{:05b}{:03b}{:05b}{:07b}",
|
||||||
to_u32(&self.opcode),
|
|
||||||
to_u32(&self.rd),
|
|
||||||
to_u32(&self.funct3),
|
|
||||||
to_u32(&self.ra),
|
|
||||||
to_u32(&self.imm),
|
|
||||||
to_u32(&self.funct6),
|
to_u32(&self.funct6),
|
||||||
|
to_u32(&self.imm),
|
||||||
|
to_u32(&self.ra),
|
||||||
|
to_u32(&self.funct3),
|
||||||
|
to_u32(&self.rd),
|
||||||
|
to_u32(&self.opcode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,13 +174,13 @@ 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}{:03b}{:05b}{:07b}{:05b}",
|
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}",
|
||||||
to_u32(&self.opcode),
|
|
||||||
to_u32(&self.imm2),
|
|
||||||
to_u32(&self.funct3),
|
|
||||||
to_u32(&self.ra),
|
|
||||||
to_u32(&self.rb),
|
|
||||||
to_u32(&self.imm),
|
to_u32(&self.imm),
|
||||||
|
to_u32(&self.rb),
|
||||||
|
to_u32(&self.ra),
|
||||||
|
to_u32(&self.funct3),
|
||||||
|
to_u32(&self.imm2),
|
||||||
|
to_u32(&self.opcode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,13 +188,13 @@ 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}{:03b}{:05b}{:07b}{:05b}",
|
"{:07b}{:05b}{:05b}{:03b}{:05b}{:07b}",
|
||||||
to_u32(&self.opcode),
|
|
||||||
to_u32(&self.imm2),
|
|
||||||
to_u32(&self.funct3),
|
|
||||||
to_u32(&self.ra),
|
|
||||||
to_u32(&self.rb),
|
|
||||||
to_u32(&self.imm),
|
to_u32(&self.imm),
|
||||||
|
to_u32(&self.rb),
|
||||||
|
to_u32(&self.ra),
|
||||||
|
to_u32(&self.funct3),
|
||||||
|
to_u32(&self.imm2),
|
||||||
|
to_u32(&self.opcode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,10 +202,10 @@ 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}{:020b}",
|
"{:020b}{:05b}{:07b}",
|
||||||
to_u32(&self.opcode),
|
|
||||||
to_u32(&self.rd),
|
|
||||||
to_u32(&self.imm),
|
to_u32(&self.imm),
|
||||||
|
to_u32(&self.rd),
|
||||||
|
to_u32(&self.opcode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,10 +213,10 @@ 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}{:020b}",
|
"{:020b}{:05b}{:07b}",
|
||||||
to_u32(&self.opcode),
|
|
||||||
to_u32(&self.rd),
|
|
||||||
to_u32(&self.imm),
|
to_u32(&self.imm),
|
||||||
|
to_u32(&self.rd),
|
||||||
|
to_u32(&self.opcode),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,10 +273,6 @@ pub fn instruction(op: &str) -> (Kind, Vec<Value>) {
|
||||||
|
|
||||||
/// Order: rd, ra, rb, rc
|
/// Order: rd, ra, rb, rc
|
||||||
pub fn with_reg_args((kind, args): (Kind, Vec<Value>), regs: Vec<u32>) -> (Kind, Vec<Value>) {
|
pub fn with_reg_args((kind, args): (Kind, Vec<Value>), regs: Vec<u32>) -> (Kind, Vec<Value>) {
|
||||||
let arity = args.len();
|
|
||||||
// The engine will have already checked that the arity is correct
|
|
||||||
debug_assert!(arity == regs.len());
|
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
Kind::Pseudo(_) => (kind, args),
|
Kind::Pseudo(_) => (kind, args),
|
||||||
Kind::R(r) => (
|
Kind::R(r) => (
|
||||||
|
@ -357,6 +360,110 @@ pub fn with_reg_args((kind, args): (Kind, Vec<Value>), regs: Vec<u32>) -> (Kind,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_imm((kind, args): (Kind, Vec<Value>), imm: u32) -> (Kind, Vec<Value>) {
|
||||||
|
match kind {
|
||||||
|
Kind::Pseudo(_) => (kind, args),
|
||||||
|
Kind::R(r) => (Kind::R(r), args),
|
||||||
|
Kind::R4(r4) => (Kind::R4(r4), args),
|
||||||
|
Kind::I(i) => (
|
||||||
|
Kind::I(I {
|
||||||
|
imm: to_bits(imm),
|
||||||
|
ra: i.ra,
|
||||||
|
funct3: i.funct3,
|
||||||
|
rd: i.rd,
|
||||||
|
opcode: i.opcode,
|
||||||
|
}),
|
||||||
|
args,
|
||||||
|
),
|
||||||
|
Kind::I2(i2) => (
|
||||||
|
Kind::I2(I2 {
|
||||||
|
funct6: i2.funct6,
|
||||||
|
imm: to_bits(imm),
|
||||||
|
ra: i2.ra,
|
||||||
|
funct3: i2.funct3,
|
||||||
|
rd: i2.rd,
|
||||||
|
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[11..=5]);
|
||||||
|
imm
|
||||||
|
},
|
||||||
|
rb: s.rb,
|
||||||
|
ra: s.ra,
|
||||||
|
funct3: s.funct3,
|
||||||
|
imm2: {
|
||||||
|
let mut imm2 = [false; 5];
|
||||||
|
imm2.copy_from_slice(&bits[4..=0]);
|
||||||
|
imm2
|
||||||
|
},
|
||||||
|
opcode: s.opcode,
|
||||||
|
}),
|
||||||
|
args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Kind::B(b) => {
|
||||||
|
let bits = to_bits::<32>(imm);
|
||||||
|
(
|
||||||
|
Kind::B(B {
|
||||||
|
imm: {
|
||||||
|
let mut imm = [false; 7];
|
||||||
|
imm[6] = bits[12];
|
||||||
|
imm[5..=0].copy_from_slice(&bits[10..=5]);
|
||||||
|
imm
|
||||||
|
},
|
||||||
|
rb: b.rb,
|
||||||
|
ra: b.ra,
|
||||||
|
funct3: b.funct3,
|
||||||
|
imm2: {
|
||||||
|
let mut imm2 = [false; 5];
|
||||||
|
imm2[4..=1].copy_from_slice(&bits[4..=1]);
|
||||||
|
imm2[0] = bits[11];
|
||||||
|
imm2
|
||||||
|
},
|
||||||
|
opcode: b.opcode,
|
||||||
|
}),
|
||||||
|
args,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Kind::U(u) => (
|
||||||
|
Kind::U(U {
|
||||||
|
imm: {
|
||||||
|
let bits = to_bits::<32>(imm);
|
||||||
|
let mut imm = [false; 20];
|
||||||
|
imm.copy_from_slice(&bits[31..=12]);
|
||||||
|
imm
|
||||||
|
},
|
||||||
|
rd: u.rd,
|
||||||
|
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[18..=9].copy_from_slice(&bits[10..=1]);
|
||||||
|
imm[8] = bits[11];
|
||||||
|
imm[7..=0].copy_from_slice(&bits[19..=12]);
|
||||||
|
imm
|
||||||
|
},
|
||||||
|
rd: j.rd,
|
||||||
|
opcode: j.opcode,
|
||||||
|
}),
|
||||||
|
args,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn to_bits<const N: usize>(val: u32) -> [bool; N] {
|
fn to_bits<const N: usize>(val: u32) -> [bool; N] {
|
||||||
let mut bits = [false; N];
|
let mut bits = [false; N];
|
||||||
for i in 0..N {
|
for i in 0..N {
|
||||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -9,7 +9,7 @@ use codespan_reporting::{
|
||||||
};
|
};
|
||||||
use riscv_interpreter::{
|
use riscv_interpreter::{
|
||||||
env::Env,
|
env::Env,
|
||||||
instructions::{instruction, with_reg_args},
|
instructions::{instruction, with_imm, with_reg_args},
|
||||||
parser::parse,
|
parser::parse,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,7 +61,20 @@ fn main() -> anyhow::Result<()> {
|
||||||
env.alias_to_register("a1").unwrap() as u32
|
env.alias_to_register("a1").unwrap() as u32
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
.0
|
.0 // 011001101010000001010010110000000
|
||||||
|
// Ripes: 011001101010000001010010110000000
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"addi a0 a0 1: {}",
|
||||||
|
with_imm(with_reg_args(
|
||||||
|
instruction("addi"),
|
||||||
|
vec![
|
||||||
|
env.alias_to_register("a0").unwrap() as u32,
|
||||||
|
env.alias_to_register("a0").unwrap() as u32
|
||||||
|
]
|
||||||
|
), 1)
|
||||||
|
.0 // 00000000000101010000010100010011
|
||||||
|
// Ripes: 00000000000101010000010100010011
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in a new issue