From 780336fbe4089a180d1f147d6c148643057c67d0 Mon Sep 17 00:00:00 2001 From: Shadow Cat Date: Tue, 21 Jul 2026 16:22:45 -0400 Subject: [PATCH] work --- src/arch/x86_64/compile.rs | 110 ++++++++++++++++++++++++++--------- src/arch/x86_64/types/arg.rs | 6 ++ 2 files changed, 87 insertions(+), 29 deletions(-) diff --git a/src/arch/x86_64/compile.rs b/src/arch/x86_64/compile.rs index d19d82f..756bfb6 100644 --- a/src/arch/x86_64/compile.rs +++ b/src/arch/x86_64/compile.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet, VecDeque}; +use std::collections::{HashMap, HashSet}; use super::*; use crate::backend::{Body, Func, LibImport, LinkedProgram, SymImport, SymTable, Symbol, VarId}; @@ -8,8 +8,17 @@ pub struct Encoder<'a> { pub sym_tab: SymTable, pub sym_refs: HashMap>, pub program: &'a Program, + pub active: FnData, +} + +#[derive(Default)] +struct FnData { pub segs: Vec, - pub vars: HashMap, + pub seg: usize, + pub i: usize, + pub var: HashMap, + pub reg: [Option; 16], + pub reg_next: [Option; 16], } pub fn compile(p: &Program) -> Result, CompilerMsg> { @@ -59,8 +68,8 @@ pub fn compile(p: &Program) -> Result, CompilerMsg> { #[derive(Default)] pub struct SegUses { - var: HashMap>, - reg: [VecDeque; 16], + var: HashMap>, + reg: [Vec; 16], } #[derive(Clone, Copy)] @@ -75,9 +84,32 @@ impl<'a> Encoder<'a> { fn func(&mut self, f: &Func) -> ERes { let addr = self.code.bytes.len(); self.sym_tab.insert(f.sym, addr as u64); - self.segs.clear(); + self.active = Default::default(); self.calc_uses(&f.body); - for instr in &f.body { + for (i, instr) in f.body.iter().enumerate() { + self.active.i = i; + let seg = &self.active.segs[self.active.seg]; + for r in 0..self.active.reg_next.len() { + let u = self.active.reg_next[r]; + let Some(u) = u else { + continue; + }; + if u.pos != r { + continue; + } + // if there's a var currently in the reg + if let Some(var) = self.active.reg[r] { + // done if it's what's needed + if u.var.is_some_and(|v| var == v) { + continue; + } + // otherwise save it + self.save(var); + } + if let Some(var) = u.var { + if let Some(cur) = self.active.var.get(&var) {} + } + } match instr { BInstr::Asm(asm) => self.asm(asm)?, _ => todo!(), @@ -86,20 +118,21 @@ impl<'a> Encoder<'a> { Ok(()) } - pub fn calc_uses(&mut self, body: &Body) -> (usize, usize) { + fn save(&mut self, var: VarId) { + todo!() + } + + fn calc_uses(&mut self, body: &Body) -> (usize, usize) { let mut pos = 0; - let seg_i = self.segs.len(); - self.segs.push(Default::default()); + let seg_i = self.active.segs.len(); + self.active.segs.push(Default::default()); let mut uses = SegUses::default(); macro_rules! push { ($var:ident) => { push!($var, 0) }; ($var:ident, $pos:expr) => { - uses.var - .entry($var.clone()) - .or_default() - .push_back(pos + $pos) + uses.var.entry($var.clone()).or_default().push(pos + $pos) }; } for instr in body { @@ -110,12 +143,12 @@ impl<'a> Encoder<'a> { push!(dst); for ® in conv.scratch() { - uses.reg[reg as usize].push_back(RegUse { pos, var: None }); + uses.reg[reg as usize].push(RegUse { pos, var: None }); } for (i, &arg) in args.iter().enumerate() { push!(arg); if let Some(®) = conv.param().get(i) { - uses.reg[reg as usize].back_mut().unwrap().var = Some(arg); + uses.reg[reg as usize].last_mut().unwrap().var = Some(arg); } } } @@ -134,15 +167,15 @@ impl<'a> Encoder<'a> { let (seg_i1, len1) = self.calc_uses(then); let (seg_i2, len2) = self.calc_uses(else_); // insert closest usages - for (var, poss1) in &self.segs[seg_i1].var { - if let Some(poss2) = self.segs[seg_i2].var.get(var) { + for (var, poss1) in &self.active.segs[seg_i1].var { + if let Some(poss2) = self.active.segs[seg_i2].var.get(var) { push!(var, poss1[0].min(poss2[0])); } else { push!(var, poss1[0]); } } - for (var, poss2) in &self.segs[seg_i2].var { - if !self.segs[seg_i1].var.contains_key(var) { + for (var, poss2) in &self.active.segs[seg_i2].var { + if !self.active.segs[seg_i1].var.contains_key(var) { push!(var, poss2[0]); } } @@ -152,7 +185,7 @@ impl<'a> Encoder<'a> { BInstr::Loop(instrs) => { let (seg_i2, len) = self.calc_uses(instrs); // insert closest usages - for (var, poss) in &self.segs[seg_i2].var { + for (var, poss) in &self.active.segs[seg_i2].var { push!(var, poss[0]); } // during register allocation, want to insert the first use of each var @@ -183,27 +216,44 @@ impl<'a> Encoder<'a> { for &(reg, var) in &asm.args { push!(var); used.remove(®); - uses.reg[reg as usize].push_back(RegUse { + uses.reg[reg as usize].push(RegUse { pos, var: Some(var), }); } for reg in used { - uses.reg[reg as usize].push_back(RegUse { pos, var: None }); + uses.reg[reg as usize].push(RegUse { pos, var: None }); } } } pos += 1; } - self.segs[seg_i] = uses; + self.active.segs[seg_i] = uses; return (seg_i, pos); } + pub fn prep_var(&mut self, var: VarId) -> RegW { + let seg = &mut self.active.segs[self.active.seg]; + if let Some(reg) = self.active.var.get(&var) { + *reg + } else { + } + } + pub fn rvm(&mut self, input: Rvm) -> RegMem { match input { - Rvm::Reg(reg) => reg, - Rvm::Var(var_id) => todo!(), - Rvm::Mem(mem) => todo!(), + Rvm::Reg(reg) => reg.into(), + Rvm::Var(var) => self.prep_var(var).into(), + Rvm::Mem(mem) => mem.into(), + } + } + + pub fn rvmi(&mut self, input: Rvmi) -> RegMemImm { + match input { + Rvmi::Reg(reg) => reg.into(), + Rvmi::Var(var) => self.prep_var(var).into(), + Rvmi::Mem(mem) => mem.into(), + Rvmi::Imm(imm) => imm.into(), } } @@ -218,15 +268,15 @@ impl<'a> Encoder<'a> { vars.insert(var); } } - let overlap = used.intersection(&self.vars.values()); + let overlap = used.intersection(&self.active.var.values()); for var in &vars { - if let Some(reg) = self.vars.get(var) + if let Some(reg) = self.active.var.get(var) && used.contains(reg) {} } for &instr in &asm.instrs { match instr { - Instr::Mov { dst, src } => self.code.mov(dst, src)?, + Instr::Mov { dst, src } => self.code.mov(self.rvm(dst), self.rvmi(src))?, Instr::Push(rvmi) => todo!(), Instr::Pop(rvm) => todo!(), Instr::Lea { dst, src } => todo!(), @@ -247,7 +297,9 @@ impl<'a> Encoder<'a> { code: Code::default(), sym_tab: SymTable::new(program.sym_count()), sym_refs: Default::default(), + seg: 0, segs: Default::default(), + active: Default::default(), program, } } diff --git a/src/arch/x86_64/types/arg.rs b/src/arch/x86_64/types/arg.rs index 6c63c73..1748ca6 100644 --- a/src/arch/x86_64/types/arg.rs +++ b/src/arch/x86_64/types/arg.rs @@ -131,6 +131,12 @@ impl From for RegMemImm { } } +impl From for RegMemImm { + fn from(value: Imm) -> Self { + Self::Imm(value) + } +} + pub trait ModRMRM { fn rm(&self) -> u8; fn addr(&self) -> EffAddr;