Fix some assembling bugs

This commit is contained in:
Lumi Kalt 2024-01-23 15:46:30 +00:00
parent 78165b9b4e
commit 385278d8e9
6 changed files with 83 additions and 36 deletions

View file

@ -6,7 +6,7 @@ use crate::{
parser::{Loc, Token}, parser::{Loc, Token},
}; };
pub enum SymbolValue { pub enum Variables {
Byte(u8), Byte(u8),
Half(u16), Half(u16),
Word(u32), Word(u32),
@ -16,12 +16,14 @@ pub enum SymbolValue {
#[derive(Debug)] #[derive(Debug)]
pub struct Env { pub struct Env {
pub register_alias: HashMap<String, u32>, register_alias: HashMap<String, u32>,
labels: HashMap<String, u32>, labels: HashMap<String, u32>,
registers: [u32; 32], registers: [u32; 32],
pub stack: Vec<u32>, // TODO: Find the size of the stack /// EQ, LT, GT
pub cmp_flags: [bool; 3],
pub stack: Vec<u32>, // TODO: Find the actual size of the stack
pub instructions: Vec<u32>, pub instructions: Vec<u32>,
pc: u32, pub pc: u32,
} }
impl Env { impl Env {
@ -70,6 +72,7 @@ impl Env {
register_alias, register_alias,
labels: HashMap::new(), labels: HashMap::new(),
registers: [0; 32], registers: [0; 32],
cmp_flags: [false; 3],
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,
@ -197,7 +200,7 @@ impl Env {
Arg::Symbol => { Arg::Symbol => {
if let Token::Symbol(s) = &args[k].0 { if let Token::Symbol(s) = &args[k].0 {
if let Some(v) = self.get_label(&s) { if let Some(v) = self.get_label(&s) {
imm = v; imm = (v).wrapping_sub(loc.mem_offset as u32);
Ok(()) Ok(())
} else { } else {
Err(( Err((
@ -236,29 +239,55 @@ impl Env {
} }
} }
pub fn handle_labels(&mut self, tokens: Vec<(Token, Loc)>) { pub fn handle_mem_offsets(&mut self, mut tokens: Vec<(Token, Loc)>) -> Vec<(Token, Loc)> {
let mut i = 0; let mut i = 0;
// Calculate the instruction position for all opcodes to // Calculate the instruction position for all opcodes to
// allow for labels to be used before they are defined // allow for labels to be used before they are defined
tokens.into_iter().for_each(|(token, _)| match token { tokens
.clone()
.into_iter()
.enumerate()
.for_each(|(id, (token, _))| match token {
Token::Op(name, _) => { Token::Op(name, _) => {
if let Some((kind, args)) = instruction(&name) { if let Some((kind, args)) = instruction(&name) {
if let Kind::Pseudo(_) = kind { if let Kind::Pseudo(_) = kind {
tokens[id].1.mem_offset = i + 4;
handle_pseudo((kind, args), 0, vec![0; 4]) handle_pseudo((kind, args), 0, vec![0; 4])
.into_iter() .into_iter()
.for_each(|_| i += 1); .for_each(|_| i += 4);
} else { } else {
i += 1; i += 4;
} }
} }
} }
Token::Label(name) => { Token::Label(name) => {
self.add_label(&name, (i + 1) * 4); self.add_label(&name, (i + 4) as u32);
} }
other => { other => {
dbg!(other); dbg!(other);
unreachable!() unreachable!()
} }
}); });
tokens
}
/// Assume memory offsets have been handled
pub fn exec_op(&mut self, (op, loc): (Token, Loc)) -> Result<(), (RuntimeErr, Loc, Option<String>)> {
let (i, args) = if let Token::Op(name, args) = op {
if let Some(i) = instruction(&name) {
(i, args.clone())
} else {
return Err((
RuntimeErr::InvalidOp,
loc,
Some("no implementation exists".to_string()),
));
}
} else {
unreachable!()
};
todo!()
} }
} }

0
src/execution.rs Normal file
View file

View file

@ -444,7 +444,7 @@ pub fn with((kind, args): (Kind, Vec<Arg>), imm: u32, regs: Vec<u32>) -> (Kind,
Kind::S(S { Kind::S(S {
imm: { imm: {
let mut imm = [false; 7]; let mut imm = [false; 7];
imm.copy_from_slice(&bits[5..=11]); //.into_iter().rev().map(|&b| b).collect::<Vec<_>>()[..]); imm.copy_from_slice(&bits[5..=11]);
imm imm
}, },
rb: to_bits(regs[2]), rb: to_bits(regs[2]),
@ -452,7 +452,7 @@ pub fn with((kind, args): (Kind, Vec<Arg>), imm: u32, regs: Vec<u32>) -> (Kind,
funct3: s.funct3, funct3: s.funct3,
imm2: { imm2: {
let mut imm2 = [false; 5]; let mut imm2 = [false; 5];
imm2.copy_from_slice(&bits[0..=4]); //.into_iter().rev().map(|&b| b).collect::<Vec<_>>()[..]); imm2.copy_from_slice(&bits[0..=4]);
imm2 imm2
}, },
opcode: s.opcode, opcode: s.opcode,
@ -547,15 +547,15 @@ pub fn handle_pseudo(
} }
"beqz" => vec![ "beqz" => vec![
// beq ra, x0, imm // beq ra, x0, imm
with(get_instruction("beq"), imm, vec![0, regs[0], 0]), with(get_instruction("beq"), imm, regs),
], ],
"bnez" => vec![ "bnez" => vec![
// bne ra, x0, imm // bne ra, x0, imm
with(get_instruction("bne"), imm, vec![0, regs[0], 0]), with(get_instruction("bne"), imm, regs),
], ],
"j" => vec![ "j" => vec![
// jal x0, imm // jal x0, imm
with(get_instruction("jal"), imm, vec![0]), with(get_instruction("jal"), imm, regs),
], ],
other => { other => {
dbg!(other); dbg!(other);
@ -564,7 +564,7 @@ pub fn handle_pseudo(
} }
} }
fn to_bits<const N: usize>(val: u32) -> [bool; N] { const 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 {
bits[i] = (val >> i) & 1 == 1; bits[i] = (val >> i) & 1 == 1;
@ -572,7 +572,7 @@ fn to_bits<const N: usize>(val: u32) -> [bool; N] {
bits bits
} }
fn to_u32<const N: usize>(bits: &[bool; N]) -> u32 { const fn to_u32<const N: usize>(bits: &[bool; N]) -> u32 {
let mut val = 0; let mut val = 0;
for i in 0..N { for i in 0..N {
if bits[i] { if bits[i] {

View file

@ -1,5 +1,11 @@
#![feature(const_for)]
#![feature(const_mut_refs)]
#![feature(const_trait_impl)]
#![feature(effects)]
pub mod env; pub mod env;
pub mod err; pub mod err;
pub mod execution;
pub mod instructions; pub mod instructions;
pub mod parser; pub mod parser;
pub mod tests; pub mod tests;

View file

@ -27,14 +27,12 @@ fn main() -> anyhow::Result<()> {
let size = lines.iter().map(|l| l.len()).max().unwrap(); let size = lines.iter().map(|l| l.len()).max().unwrap();
let mut i = 0; let mut i = 0;
tokens.iter().for_each(|(token, loc)| { env.handle_mem_offsets(tokens).iter().for_each(|(token, loc)| {
let token = token.clone(); let token = token.clone();
env.handle_labels(tokens.clone());
match token.clone() { match token.clone() {
Token::Op(..) => match env.assemble_op((token, loc.clone())) { Token::Op(..) => match env.assemble_op((token, loc.clone())) {
Ok(op) => { Ok(op) => {
let addr = (loc.line - 1) * 4;
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],
@ -46,7 +44,8 @@ fn main() -> anyhow::Result<()> {
if op.len() > 1 { if op.len() > 1 {
for op in op[1..].iter() { for op in op[1..].iter() {
formatted += &format!("\n{:<1$} {3:02x}: {2:032b}", "", size + 3, op, i); formatted +=
&format!("\n{:<1$} {3:02x}: {2:032b}", "", size + 3, op, i);
i += 4; i += 4;
} }
} }

View file

@ -51,6 +51,18 @@ pub struct Loc {
pub line: usize, pub line: usize,
pub start: usize, pub start: usize,
pub end: usize, pub end: usize,
pub mem_offset: usize,
}
impl Default for Loc {
fn default() -> Self {
Self {
line: 0,
start: 0,
end: 0,
mem_offset: 0,
}
}
} }
fn parse_line(env: &Env, input: &str, loc: &mut Loc) -> Result<Vec<(Token, Loc)>, ParseErr> { fn parse_line(env: &Env, input: &str, loc: &mut Loc) -> Result<Vec<(Token, Loc)>, ParseErr> {
@ -83,9 +95,9 @@ fn parse_line(env: &Env, input: &str, loc: &mut Loc) -> Result<Vec<(Token, Loc)>
let err = Err(( let err = Err((
SyntaxErr::UnexpectedChar, SyntaxErr::UnexpectedChar,
Loc { Loc {
line: loc.line,
start: loc.end + 1, start: loc.end + 1,
end: loc.end + 1, end: loc.end + 1,
..*loc
}, },
tokens.clone(), tokens.clone(),
None, None,
@ -134,9 +146,9 @@ fn parse_line(env: &Env, input: &str, loc: &mut Loc) -> Result<Vec<(Token, Loc)>
let err = Err(( let err = Err((
SyntaxErr::InvalidRegister, SyntaxErr::InvalidRegister,
Loc { Loc {
line: loc.line,
start, start,
end, end,
..*loc
}, },
tokens.clone(), tokens.clone(),
None, None,
@ -282,6 +294,7 @@ pub fn parse(env: &Env, input: &str) -> Result<Vec<(Token, Loc)>, Vec<ParseErr>>
line: 0, line: 0,
start: 0, start: 0,
end: 0, end: 0,
mem_offset: 0,
}; };
let parsed_lines = input let parsed_lines = input