a ton of stuff idk more ir work
This commit is contained in:
@@ -7,7 +7,7 @@ use std::{
|
||||
|
||||
mod elf;
|
||||
mod program;
|
||||
mod riscv64;
|
||||
pub mod riscv64;
|
||||
mod target;
|
||||
|
||||
pub use program::*;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
],
|
||||
|
||||
104
src/compiler/riscv64/parse.rs
Normal file
104
src/compiler/riscv64/parse.rs
Normal 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),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user