From 75ad04cf9535bf4852de7b8c8c8d9326255fbb54 Mon Sep 17 00:00:00 2001 From: zxq5 Date: Tue, 10 Feb 2026 16:37:33 +0000 Subject: [PATCH] forgot to commit these --- compiler/src/backend/dsa/instruction.rs | 610 ++++++++++++++++++++++++ compiler/src/backend/dsa/scope.rs | 7 + compiler/src/backend/dsa/variable.rs | 186 ++++++++ 3 files changed, 803 insertions(+) create mode 100644 compiler/src/backend/dsa/instruction.rs create mode 100644 compiler/src/backend/dsa/scope.rs create mode 100644 compiler/src/backend/dsa/variable.rs diff --git a/compiler/src/backend/dsa/instruction.rs b/compiler/src/backend/dsa/instruction.rs new file mode 100644 index 0000000..e419b62 --- /dev/null +++ b/compiler/src/backend/dsa/instruction.rs @@ -0,0 +1,610 @@ +use std::fmt; + +use crate::{ + backend::dsa::registers::Register, + model::{CompilerError, Expression}, +}; + +pub struct CodeGen { + // For building the final program + program: InsBlock, + + // For generating temporary blocks + label_counter: usize, + stack_offset: i32, +} + +impl CodeGen { + pub fn new() -> Self { + Self { + program: InsBlock::new(), + label_counter: 0, + stack_offset: 0, + } + } + + /// Emit directly to program (for top-level constructs) + pub fn emit(&mut self, instr: Instruction) { + self.program.push(instr); + } + + /// Emit a block to program + pub fn emit_block(&mut self, block: InsBlock) { + self.program.append(block); + } + + /// Build expression (returns block for composition) + pub fn build_expr(&mut self, expr: &Expression) -> Result { + // ... returns InstrBlock + todo!() + } + + /// Get final output + pub fn finish(mut self) -> String { + // Optimize before final output + // self.program.remove_dead_code(); + // self.program.optimize_peephole(); + + self.program + .instructions + .iter() + .map(|i| i.to_string()) + .collect::>() + .join("\n") + } +} + +pub struct InsBlock { + instructions: Vec, +} + +impl InsBlock { + pub fn new() -> Self { + Self { + instructions: vec![], + } + } + + pub fn push(&mut self, instr: Instruction) { + self.instructions.push(instr); + } + + pub fn append(&mut self, mut other: Self) { + self.instructions.append(&mut other.instructions); + } + + pub fn extend(&mut self, instrs: impl IntoIterator) { + self.instructions.extend(instrs); + } + + pub fn is_empty(&self) -> bool { + self.instructions.is_empty() + } + + pub fn len(&self) -> usize { + self.instructions.len() + } + + pub fn iter(&self) -> impl Iterator { + self.instructions.iter() + } +} + +pub enum Instruction { + // Labels and comments + Label(Label), + Comment(String), + + // Data movement + Mov { + src: Register, + dest: Register, + }, + Movs { + src: Register, + dest: Register, + }, + + // Memory operations + Ldb { + addr: MemOperand, + dest: Register, + }, + Ldh { + addr: MemOperand, + dest: Register, + }, + Ldw { + addr: MemOperand, + dest: Register, + }, + Stb { + src: Register, + addr: MemOperand, + }, + Sth { + src: Register, + addr: MemOperand, + }, + Stw { + src: Register, + addr: MemOperand, + }, + + // Immediate loads + Lli { + imm: Imm, + dest: Register, + }, + Lui { + imm: Imm, + dest: Register, + }, + + // Arithmetic + Add { + src1: Register, + src2: Register, + dest: Register, + }, + Sub { + src1: Register, + src2: Register, + dest: Register, + }, + IAdd { + src: Register, + imm: Imm, + dest: Option, + }, + ISub { + src: Register, + imm: Imm, + dest: Option, + }, + Inc { + reg: Register, + }, + Dec { + reg: Register, + }, + + // Bitwise + And { + src1: Register, + src2: Register, + dest: Register, + }, + Or { + src1: Register, + src2: Register, + dest: Register, + }, + Xor { + src1: Register, + src2: Register, + dest: Register, + }, + Not { + src: Register, + dest: Register, + }, + Nand { + src1: Register, + src2: Register, + dest: Register, + }, + Nor { + src1: Register, + src2: Register, + dest: Register, + }, + Xnor { + src1: Register, + src2: Register, + dest: Register, + }, + + // Shifts + Shl { + src1: Register, + r_shamt: Register, + i_shamt: u16, + dest: Register, + }, + Shr { + src1: Register, + rsh: Register, + ish: u16, + dest: Register, + }, + + // Comparison + Cmp { + reg1: Register, + reg2: Register, + }, + + // Jumps + Jmp { + target: Label, + }, + Jeq { + target: Label, + }, + Jne { + target: Label, + }, + Jgt { + target: Label, + }, + Jge { + target: Label, + }, + Jlt { + target: Label, + }, + Jle { + target: Label, + }, + + // Stack + Push { + reg: Register, + }, + Pop { + reg: Register, + }, + + // Function calls + Call { + target: String, + }, // namespace::function + Return, + + // System + Hlt, + Nop, + Int { + code: u8, + }, +} + +impl fmt::Display for Instruction { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Label(l) => write!(f, "{}:", l), + Self::Comment(c) => write!(f, "; {}", c), + + Self::Mov { src, dest } => write!(f, " mov {}, {}", src, dest), + Self::Movs { src, dest } => write!(f, " movs {}, {}", src, dest), + + Self::Ldb { addr, dest } => { + write!(f, " ldb {}, {}", format_mem_operand(addr), dest) + } + Self::Ldh { addr, dest } => { + write!(f, " ldh {}, {}", format_mem_operand(addr), dest) + } + Self::Ldw { addr, dest } => { + write!(f, " ldw {}, {}", format_mem_operand(addr), dest) + } + // Self::Ldbs { addr, dest } => { + // write!(f, " ldbs {}, {}", format_mem_operand(addr), dest) + // } + // Self::Ldhs { addr, dest } => { + // write!(f, " ldhs {}, {}", format_mem_operand(addr), dest) + // } + // Self::Ldws { addr, dest } => { + // write!(f, " ldws {}, {}", format_mem_operand(addr), dest) + // } + Self::Stb { src, addr } => { + write!(f, " stb {}, {}", src, format_mem_operand(addr)) + } + Self::Sth { src, addr } => { + write!(f, " sth {}, {}", src, format_mem_operand(addr)) + } + Self::Stw { src, addr } => { + write!(f, " stw {}, {}", src, format_mem_operand(addr)) + } + + Self::Lli { imm, dest } => write!(f, " lli {}, {}", imm, dest), + Self::Lui { imm, dest } => write!(f, " lui {}, {}", imm, dest), + + // arithmetic + Self::Add { src1, src2, dest } => { + write!(f, " add {}, {}, {}", src1, src2, dest) + } + Self::Sub { src1, src2, dest } => { + write!(f, " sub {}, {}, {}", src1, src2, dest) + } + Self::And { src1, src2, dest } => { + write!(f, " and {}, {}, {}", src1, src2, dest) + } + Self::Or { src1, src2, dest } => { + write!(f, " or {}, {}, {}", src1, src2, dest) + } + Self::Nand { src1, src2, dest } => { + write!(f, " nand {}, {}, {}", src1, src2, dest) + } + Self::Xor { src1, src2, dest } => { + write!(f, " xor {}, {}, {}", src1, src2, dest) + } + Self::Nor { src1, src2, dest } => { + write!(f, " nor {}, {}, {}", src1, src2, dest) + } + Self::Not { src, dest } => { + write!(f, " not {} {}", src, dest) + } + Self::Xnor { src1, src2, dest } => { + write!(f, " xnor {}, {}, {}", src1, src2, dest) + } + Self::IAdd { src, imm, dest } => { + if let Some(d) = dest { + write!(f, " iadd {}, {}, {}", src, imm, d) + } else { + write!(f, " iadd {}, {}", src, imm) + } + } + Self::ISub { src, imm, dest } => { + if let Some(d) = dest { + write!(f, " isub {}, {}, {}", src, imm, d) + } else { + write!(f, " isub {}, {}", src, imm) + } + } + + // shift instructions + Self::Shl { + src1, + r_shamt, + i_shamt, + dest, + } => { + write!(f, " shl {}, {}, {}, {}", src1, r_shamt, i_shamt, dest) + } + Self::Shr { + src1, + rsh: r_shamt, + ish: i_shamt, + dest, + } => { + write!(f, " shl {}, {}, {}, {}", src1, r_shamt, i_shamt, dest) + } + + // increment instructions + Self::Inc { reg } => write!(f, " inc {}", reg), + Self::Dec { reg } => write!(f, " dec {}", reg), + + Self::Cmp { reg1, reg2 } => write!(f, " cmp {}, {}", reg1, reg2), + + // jump instructions + Self::Jmp { target } => write!(f, " jmp {}", target), + Self::Jeq { target } => write!(f, " jeq {}", target), + Self::Jne { target } => write!(f, " jne {}", target), + Self::Jgt { target } => write!(f, " jgt {}", target), + Self::Jge { target } => write!(f, " jge {}", target), + Self::Jlt { target } => write!(f, " jlt {}", target), + Self::Jle { target } => write!(f, " jle {}", target), + + // stack pseudoinstructions + Self::Push { reg } => write!(f, " push {}", reg), + Self::Pop { reg } => write!(f, " pop {}", reg), + + // call & return pseudoinstructions + Self::Call { target } => write!(f, " call {}", target), + Self::Return => write!(f, " return"), + + // misc instructions + Self::Int { code } => write!(f, " int {}", code), + Self::Hlt => write!(f, " hlt"), + Self::Nop => write!(f, " nop"), + } + } +} + +impl Instruction { + // Movement + pub fn mov(src: Register, dest: Register) -> Self { + Self::Mov { src, dest } + } + + // Memory loads + pub fn ldw_reg(base: Register, dest: Register) -> Self { + Self::Ldw { + addr: MemOperand::RegIndirect(base), + dest, + } + } + + pub fn ldw_reg_offset(base: Register, offset: i32, dest: Register) -> Self { + Self::Ldw { + addr: MemOperand::RegOffset(base, offset), + dest, + } + } + + pub fn ldw_label(label: impl Into