structs r a lot more sane in code, can now actually assign & stuff

This commit is contained in:
2025-04-08 20:00:16 -04:00
parent cb9a366f43
commit 26e7a4da4a
21 changed files with 405 additions and 197 deletions
+21 -12
View File
@@ -78,6 +78,10 @@ pub fn compile(program: &IRLProgram) -> UnlinkedProgram<LI> {
stack_len += align(&f.ret_size);
}
v.push(LI::addi(sp, sp, -stack_len));
for (id, var) in &f.subvar_map {
// TODO: ALIGN DOES NOT MAKE SENSE HERE!!! need to choose to decide in lower or asm
stack.insert(id, stack[&var.id] + align(&var.offset));
}
let has_stack = stack_len > 0;
if has_stack {
if let Some(stack_ra) = stack_ra {
@@ -86,6 +90,15 @@ pub fn compile(program: &IRLProgram) -> UnlinkedProgram<LI> {
}
let mut locations = HashMap::new();
let mut irli = Vec::new();
let mut ret = Vec::new();
if has_stack {
if let Some(stack_ra) = stack_ra {
ret.push(LI::ld(ra, stack_ra, sp));
}
ret.push(LI::addi(sp, sp, stack_len));
}
ret.push(LI::Ret);
for i in &f.instructions {
irli.push((v.len(), format!("{i:?}")));
match i {
@@ -235,11 +248,14 @@ pub fn compile(program: &IRLProgram) -> UnlinkedProgram<LI> {
}
}
IRI::Ret { src } => {
let Some(rva) = stack_rva else {
panic!("no return value address on stack!")
};
v.push(LI::ld(t0, rva, sp));
mov_mem(&mut v, sp, stack[src], t0, 0, t1, align(&f.ret_size) as u32);
if let Some(src) = src {
let Some(rva) = stack_rva else {
panic!("no return value address on stack!")
};
v.push(LI::ld(t0, rva, sp));
mov_mem(&mut v, sp, stack[src], t0, 0, t1, align(&f.ret_size) as u32);
}
v.extend(&ret);
}
IRI::Jump(location) => {
v.push(LI::J(*location));
@@ -259,13 +275,6 @@ pub fn compile(program: &IRLProgram) -> UnlinkedProgram<LI> {
}
}
dbg.push_fn(irli);
if has_stack {
if let Some(stack_ra) = stack_ra {
v.push(LI::ld(ra, stack_ra, sp));
}
v.push(LI::addi(sp, sp, stack_len));
}
v.push(LI::Ret);
fns.push(UnlinkedFunction {
instrs: v,
sym: *sym,
+7 -6
View File
@@ -51,18 +51,19 @@ pub struct SectionHeader {
}
// this is currently specialized for riscv64; obviously add params later
pub fn create(program: Vec<u8>, start_offset: Addr) -> Vec<u8> {
pub fn create(program: &[u8], start_offset: Addr) -> Vec<u8> {
let addr_start = 0x1000;
let page_size = 0x1000;
let progam_size = std::mem::size_of_val(&program[..]) as u64;
// I don't know if I have to add addr_start here, idk how it maps the memory
let program_size = std::mem::size_of_val(program) as u64 + addr_start;
let program_header = ProgramHeader {
ty: 0x1, // LOAD
flags: 0b101, // executable, readable
offset: 0x0,
vaddr: addr_start,
paddr: addr_start,
filesz: progam_size,
memsz: progam_size,
filesz: program_size,
memsz: program_size,
align: page_size,
};
let header_len = (size_of::<ELF64Header>() + size_of::<ProgramHeader>()) as u64;
@@ -104,7 +105,7 @@ unsafe fn as_u8_slice<T: Sized>(p: &T) -> &[u8] {
}
impl LinkedProgram {
pub fn to_elf(self) -> Vec<u8> {
create(self.code, self.start.expect("no start found"))
pub fn to_elf(&self) -> Vec<u8> {
create(&self.code, self.start.expect("no start found"))
}
}
+2 -2
View File
@@ -2,7 +2,7 @@ use std::collections::HashMap;
use crate::{
ir::Symbol,
util::{Labelable, LabeledFmt, Labeler},
util::{Labelable, LabeledFmt},
};
use super::debug::DebugInfo;
@@ -26,7 +26,7 @@ pub struct UnlinkedFunction<I: Instr> {
pub locations: HashMap<usize, Symbol>,
}
impl<I: Instr> UnlinkedProgram<I> {
impl<I: Instr + std::fmt::Debug> UnlinkedProgram<I> {
pub fn link(self) -> LinkedProgram {
let mut data = Vec::new();
let mut sym_table = SymTable::new(self.sym_count);