a ton of stuff idk more ir work

This commit is contained in:
2024-10-22 02:30:50 -04:00
parent 14a4fb1ff9
commit 87f755b763
46 changed files with 1967 additions and 540 deletions

View File

@@ -7,7 +7,7 @@ use std::{
mod elf;
mod program;
mod riscv64;
pub mod riscv64;
mod target;
pub use program::*;

View File

@@ -2,34 +2,41 @@ use crate::compiler::program::{Addr, Instr, SymTable, Symbol};
use super::*;
#[derive(Debug, Clone)]
pub enum AsmInstruction {
Add(Reg, Reg, Reg),
Addi(Reg, Reg, i32),
Andi(Reg, Reg, i32),
Slli(Reg, Reg, i32),
Srli(Reg, Reg, i32),
Sd(Reg, i32, Reg),
Mv(Reg, Reg),
La(Reg, Symbol),
Jal(Reg, i32),
Add { dest: Reg, src1: Reg, src2: Reg },
Addi { dest: Reg, src: Reg, imm: i32 },
Andi { dest: Reg, src: Reg, imm: i32 },
Slli { dest: Reg, src: Reg, imm: i32 },
Srli { dest: Reg, src: Reg, imm: i32 },
Sd { src: Reg, offset: i32, base: Reg },
Mv { dest: Reg, src: Reg },
La { dest: Reg, sym: Symbol },
Jal { dest: Reg, offset: i32 },
Call(Symbol),
J(Symbol),
Ret,
Ecall,
Li(Reg, i32),
Li { dest: Reg, imm: i64 },
}
impl Instr for AsmInstruction {
fn push(&self, data: &mut Vec<u8>, sym_map: &SymTable, pos: Addr, missing: bool) -> Option<Symbol> {
fn push(
&self,
data: &mut Vec<u8>,
sym_map: &SymTable,
pos: Addr,
missing: bool,
) -> Option<Symbol> {
let last = match self {
Self::Add(dest, src1, src2) => add(*dest, *src1, *src2),
Self::Addi(dest, src, imm) => addi(*dest, *src, BitsI32::new(*imm)),
Self::Andi(dest, src, imm) => andi(*dest, *src, BitsI32::new(*imm)),
Self::Slli(dest, src, imm) => slli(*dest, *src, BitsI32::new(*imm)),
Self::Srli(dest, src, imm) => srli(*dest, *src, BitsI32::new(*imm)),
Self::Sd(src, offset, base) => sd(*src, BitsI32::new(*offset), *base),
Self::Mv(dest, src) => addi(*dest, *src, BitsI32::new(0)),
Self::La(dest, sym) => {
Self::Add { dest, src1, src2 } => add(*dest, *src1, *src2),
Self::Addi { dest, src, imm } => addi(*dest, *src, BitsI32::new(*imm)),
Self::Andi { dest, src, imm } => andi(*dest, *src, BitsI32::new(*imm)),
Self::Slli { dest, src, imm } => slli(*dest, *src, BitsI32::new(*imm)),
Self::Srli { dest, src, imm } => srli(*dest, *src, BitsI32::new(*imm)),
Self::Sd { src, offset, base } => sd(*src, BitsI32::new(*offset), *base),
Self::Mv { dest, src } => addi(*dest, *src, BitsI32::new(0)),
Self::La { dest, sym } => {
if let Some(addr) = sym_map.get(*sym) {
let offset = addr.val() as i32 - pos.val() as i32;
data.extend(auipc(*dest, BitsI32::new(0)).to_le_bytes());
@@ -39,7 +46,7 @@ impl Instr for AsmInstruction {
return Some(*sym);
}
}
Self::Jal(dest, offset) => jal(*dest, BitsI32::new(*offset)),
Self::Jal { dest, offset } => jal(*dest, BitsI32::new(*offset)),
Self::J(sym) => {
if let Some(addr) = sym_map.get(*sym) {
let offset = addr.val() as i32 - pos.val() as i32;
@@ -60,7 +67,7 @@ impl Instr for AsmInstruction {
}
Self::Ret => ret(),
Self::Ecall => ecall(),
Self::Li(reg, val) => addi(*reg, zero, BitsI32::new(*val)),
Self::Li { dest, imm } => addi(*dest, zero, BitsI32::new(*imm as i32)),
};
data.extend(last.to_le_bytes());
None

View File

@@ -2,14 +2,17 @@ mod asm;
mod base;
mod funct;
mod opcode;
mod parse;
mod reg;
mod single;
use super::{create_program, elf, SymMap};
use crate::util::BitsI32;
pub use asm::*;
use base::*;
use funct::{op::*, width};
use opcode::*;
pub use parse::*;
pub use reg::*;
use single::*;
@@ -22,23 +25,35 @@ pub fn gen() -> Vec<u8> {
let print_stuff = table.reserve();
let start = table.push_fn(vec![
I::Call(*print_stuff),
I::Li(a0, 0),
I::Li(a7, 93),
I::Li { dest: a0, imm: 0 },
I::Li { dest: a7, imm: 93 },
I::Ecall,
I::Jal(zero, 0),
I::Jal {
dest: zero,
offset: 0,
},
]);
table.write_fn(
print_stuff,
vec![
I::Li(a0, 1),
I::La(a1, msg),
I::Li(a2, len as i32),
I::Li(a7, 64),
I::Li { dest: a0, imm: 1 },
I::La { dest: a1, sym: msg },
I::Li {
dest: a2,
imm: len as i64,
},
I::Li { dest: a7, imm: 64 },
I::Ecall,
I::Li(a0, 1),
I::La(a1, msg2),
I::Li(a2, len2 as i32),
I::Li(a7, 64),
I::Li { dest: a0, imm: 1 },
I::La {
dest: a1,
sym: msg2,
},
I::Li {
dest: a2,
imm: len2 as i64,
},
I::Li { dest: a7, imm: 64 },
I::Ecall,
I::Ret,
],

View File

@@ -0,0 +1,104 @@
use super::{reg::*, AsmInstruction, Reg};
use crate::parser::{Parsable, ParseResult, ParserMsg, ParserOutput, Symbol, Token};
impl Parsable for AsmInstruction {
fn parse(
cursor: &mut crate::parser::TokenCursor,
output: &mut ParserOutput,
) -> ParseResult<Self> {
let t = cursor.expect_next()?;
let span = t.span;
match &t.token {
Token::Word(w) => ParseResult::Ok(match w.as_str() {
"ecall" => Self::Ecall,
"li" => {
let dest = Reg::parse(cursor, output)?;
cursor.expect_sym(Symbol::Comma)?;
let imm = i64::parse(cursor, output)?;
Self::Li { dest, imm }
}
_ => {
return ParseResult::Err(ParserMsg::from_span(
span,
format!("Unknown instruction {}", w),
))
}
}),
_ => return ParseResult::Err(ParserMsg::unexpected_token(&t, "assembly or }")),
}
}
}
impl Parsable for Reg {
fn parse(
cursor: &mut crate::parser::TokenCursor,
output: &mut ParserOutput,
) -> ParseResult<Self> {
let next = cursor.expect_next()?;
let Token::Word(word) = next.token else {
return ParseResult::Err(ParserMsg::unexpected_token(&next, "a riscv register"));
};
ParseResult::Ok(match word.as_str() {
"zero" => zero,
"ra" => ra,
"sp" => sp,
"gp" => gp,
"tp" => tp,
"t0" => t0,
"t1" => t1,
"t2" => t2,
"fp" => fp,
"s0" => s0,
"s1" => s1,
"a0" => a0,
"a1" => a1,
"a2" => a2,
"a3" => a3,
"a4" => a4,
"a5" => a5,
"a6" => a6,
"a7" => a7,
"s2" => s2,
"s3" => s3,
"s4" => s4,
"s5" => s5,
"s6" => s6,
"s7" => s7,
"s8" => s8,
"s9" => s9,
"s10" => s10,
"s11" => s11,
"t3" => t3,
"t4" => t4,
"t5" => t5,
"t6" => t6,
other => {
return ParseResult::Err(ParserMsg::from_span(
next.span,
format!("Unknown reg name {}", other),
));
}
})
}
}
impl Parsable for i64 {
fn parse(
cursor: &mut crate::parser::TokenCursor,
_output: &mut ParserOutput,
) -> ParseResult<Self> {
let next = cursor.expect_next()?;
let span = next.span;
let Token::Word(word) = next.token else {
return ParseResult::Err(ParserMsg::unexpected_token(&next, "an i32"));
};
let res = word.parse::<Self>();
match res {
Ok(int) => ParseResult::Ok(int),
Err(_) => ParseResult::Err(ParserMsg::from_span(
span,
format!("Expected an i32, found {}", word),
)),
}
}
}