diff --git a/resources/hello_world.dsa b/resources/hello_world.dsa new file mode 100644 index 0000000..e99752d --- /dev/null +++ b/resources/hello_world.dsa @@ -0,0 +1,5 @@ +fn main() { +__main_0: + _ = print::print(v_0) + return +} diff --git a/resources/main.dsa b/resources/main.dsa index 36908c3..73ea3ff 100644 --- a/resources/main.dsa +++ b/resources/main.dsa @@ -1,5 +1,5 @@ // GENERATED BY DSC COMPILER -// Generated at 2026-08-20 11:13:23 +// Generated at 2026-08-21 19:34:30 // Imports include alloc: "./lib/memory/block_alloc.dsa" @@ -30,7 +30,7 @@ _ret: pop bpr ret -db str_4: "successful free of ptr" +db str_8: "successful free of ptr" // fn main() -> u32 main: push bpr @@ -121,18 +121,18 @@ main: ldw spr, rg2, 8 lli 0, rg4 ieq rg2, rg4, rg5 - jez rg5, _else_2 -_then_1: - lwi str_4, rg4 + jez rg5, _else_6 +_then_5: + lwi str_8, rg4 stw rg2, spr, 8 // push arg 0 push rg4 call print::print pop zero - jmp _end_3 -_else_2: + jmp _end_7 +_else_6: nop -_end_3: +_end_7: lli 0, rg4 stw rg4, bpr, 8 jmp _ret \ No newline at end of file diff --git a/resources/main_ir.dsa b/resources/main_ir.dsa new file mode 100644 index 0000000..0299159 --- /dev/null +++ b/resources/main_ir.dsa @@ -0,0 +1,44 @@ +fn main() { +__main_0: + v_1 = literal 64 + v_2 = literal 32 + v_0 = alloc::init(v_1, v_2) + v_3 = copy v_0 + _ = print::print_hex_word(v_3) + _ = print::print_newline() + v_5 = copy v_0 + v_4 = alloc::alloc(v_5) + v_6 = copy v_4 + _ = print::print_hex_word(v_6) + v_7 = copy v_4 + v_8 = literal 200 + store v_7, v_8 + _ = print::print_newline() + v_10 = copy v_0 + v_9 = alloc::alloc(v_10) + v_11 = copy v_9 + _ = print::print_hex_word(v_11) + _ = print::print_newline() + _ = print::print_num(v_12) + v_13 = copy v_0 + _ = alloc::free(v_13, v_14) + v_16 = copy v_0 + v_15 = alloc::alloc(v_16) + _ = print::print_newline() + v_17 = copy v_15 + _ = print::print_hex_word(v_17) + _ = print::print_newline() + v_18 = copy v_4 + _ = print::print_hex_word(v_18) + if v_19 then __then_2 else __else_2 +__then_2: + _ = print::print(v_20) + jump __endif_2 +__else_2: + jump __endif_2 +__endif_2: + v_21 = literal 0 + return v_21 +__unreachable_3: + return +} diff --git a/tooling/dscs_compiler/src/backend/codegen.rs b/tooling/dscs_compiler/src/backend/codegen.rs index 0fd59c2..1e8de30 100644 --- a/tooling/dscs_compiler/src/backend/codegen.rs +++ b/tooling/dscs_compiler/src/backend/codegen.rs @@ -1,12 +1,15 @@ -use super::instruction::{InsBlock as IB, Instruction as I, Label}; -use super::registers::{Register, RegisterAllocator}; -use crate::backend::instruction::Comparison::{ +use super::instruction::InsBlock as IB; +use super::registers::RegisterAllocator; +use crate::model::CompilerError; +use crate::model::ast::{ + AssignmentOperator, BinaryOperator, Call, ConstExpr, Declaration, Dependency, Expression, + Number, Program, Statement, TypeId, UnaryOperator, Variable, +}; +use crate::model::instruction::Comparison::{ Equal, Greater, GreaterEqual, Less, LessEqual, NotEqual, }; -use crate::model::{ - AssignmentOperator, BinaryOperator, Call, CompilerError, ConstExpr, Declaration, Dependency, - Expression, Number, Program, Statement, TypeId, UnaryOperator, Variable, -}; +use crate::model::instruction::{Instruction as I, Label}; +use crate::model::register::Register; use chrono::{DateTime, Local}; use dsa_tasks::ProcessAgent; use std::collections::HashMap; diff --git a/tooling/dscs_compiler/src/backend/instruction.rs b/tooling/dscs_compiler/src/backend/instruction.rs index b5407fc..afe33e6 100644 --- a/tooling/dscs_compiler/src/backend/instruction.rs +++ b/tooling/dscs_compiler/src/backend/instruction.rs @@ -1,6 +1,4 @@ -use std::fmt; - -use crate::backend::registers::Register; +use crate::model::instruction::Instruction; pub struct InsBlock { instructions: Vec, @@ -55,804 +53,3 @@ impl From for InsBlock { } } } - -pub enum Comparison { - Greater, - GreaterEqual, - Equal, - NotEqual, - Less, - LessEqual, -} - -#[derive(Debug, Clone)] -pub enum Instruction { - // Labels and comments - Label(Label), - Comment { - text: String, - top_level: bool, - }, - Newline, - - // Data Directives - Db { - label: String, - data: Vec, - }, - Dh { - label: String, - data: Vec, - }, - Dw { - label: String, - data: Vec, - }, - DString { - // alias for db. - label: String, - data: String, - }, - - Resx { - label: String, - size: u32, - }, - - // Include - Include { - name: String, - path: String, - }, - - // Data movement - Mov { - src: Register, - dest: Register, - }, - Movs { - src: Register, - dest: Register, - }, - - // Memory operations - Ldb { - src: MemOperand, - dest: Register, - }, - Ldh { - src: MemOperand, - dest: Register, - }, - Ldw { - src: MemOperand, - dest: Register, - }, - Stb { - src: Register, - dest: MemOperand, - }, - Sth { - src: Register, - dest: MemOperand, - }, - Stw { - src: Register, - dest: MemOperand, - }, - - // Immediate loads - Lli { - imm: Imm, - dest: Register, - }, - Lui { - imm: Imm, - dest: Register, - }, - Lwi { - imm: Imm, - dest: Register, - }, - LwiLabel { - label: String, - dest: Register, - }, - - // Arithmetic - Add { - src1: Register, - src2: Register, - dest: Register, - }, - Sub { - src1: Register, - src2: Register, - dest: Register, - }, - - AddI { - src: Register, - imm: Imm, - dest: Option, - }, - SubI { - src: Register, - imm: Imm, - dest: Option, - }, - - // 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, - r_shamt: Register, - i_shamt: u16, - dest: Register, - }, - - Ieq { - src1: Register, - src2: Register, - dest: Register, - }, - Ine { - src1: Register, - src2: Register, - dest: Register, - }, - Ilt { - src1: Register, - src2: Register, - dest: Register, - }, - Ile { - src1: Register, - src2: Register, - dest: Register, - }, - Igt { - src1: Register, - src2: Register, - dest: Register, - }, - Ige { - src1: Register, - src2: Register, - dest: Register, - }, - - // Jumps - Jmp { - target: Label, - }, - - Jnz { - src: Register, - target: Label, - }, - Jez { - src: Register, - target: Label, - }, - - Jic { - target: Label, - }, - Jnc { - target: Label, - }, - - // Stack - Push { - reg: Register, - }, - Pop { - reg: Register, - }, - - // Function calls - Call { - target: String, - }, // namespace::function - Return, - - // System - Hlt, - Nop, - Int { - code: u8, - }, -} - -pub enum DataDirective { - U8(Vec), - U16(Vec), - U32(Vec), - String(String), - Char(char), -} - -impl fmt::Display for Instruction { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::Label(l) => write!(f, "{}:", l), - Self::Newline => write!(f, ""), /* empty string as newlines are inserted */ - // automatically. - Self::Comment { text, top_level } => write!( - f, - "{}", - text.lines() - .map(|line| format!( - "{}// {}", - if *top_level { "" } else { " " }, - line.trim(), - )) - .collect::>() - .join("\n") - ), - - Self::Include { name, path } => write!(f, "include {name}: \"{}\"", path), - - Self::Db { label, data } => write!( - f, - "db {}: {}", - label, - data.iter() - .map(|&b| format!("{:#04X}", b)) - .collect::>() - .join(", ") - ), - Self::Dh { label, data } => write!( - f, - "dh {}: {}", - label, - data.iter() - .map(|&b| format!("{:#06X}", b)) - .collect::>() - .join(", ") - ), - Self::Dw { label, data } => write!( - f, - "dw {}: {}", - label, - data.iter() - .map(|&b| format!("{:#08X}", b)) - .collect::>() - .join(", ") - ), - Self::DString { label, data } => write!(f, "db {}: \"{}\"", label, data), - - Self::Resx { label, size } => write!(f, "resx {}: {}", label, size), - - Self::Mov { src, dest } => write!(f, " mov {}, {}", src, dest), - Self::Movs { src, dest } => write!(f, " movs {}, {}", src, dest), - - Self::Ldb { src: addr, dest } => { - let (reg, offset) = reg_and_offset(addr); - write!(f, " ldb {}, {}, {}", reg, dest, offset) - } - Self::Ldh { src: addr, dest } => { - let (reg, offset) = reg_and_offset(addr); - write!(f, " ldh {}, {}, {}", reg, dest, offset) - } - Self::Ldw { src, dest } => { - let (reg, offset) = reg_and_offset(src); - write!(f, " ldw {}, {}, {}", reg, dest, offset) - } - // 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, dest: addr } => { - let (reg, offset) = reg_and_offset(addr); - write!(f, " stb {}, {}, {}", src, reg, offset) - } - Self::Sth { src, dest: addr } => { - let (reg, offset) = reg_and_offset(addr); - write!(f, " sth {}, {}, {}", src, reg, offset) - } - Self::Stw { src, dest: addr } => { - let (reg, offset) = reg_and_offset(addr); - write!(f, " stw {}, {}, {}", src, reg, offset) - } - - Self::Lli { imm, dest } => write!(f, " lli {}, {}", imm, dest), - Self::Lui { imm, dest } => write!(f, " lui {}, {}", imm, dest), - Self::Lwi { imm, dest } => write!(f, " lwi {}, {}", imm, dest), - Self::LwiLabel { label, dest } => write!(f, " lwi {}, {}", label, 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::AddI { src, imm, dest } => { - if let Some(d) = dest { - write!(f, " addi {}, {}, {}", src, imm, d) - } else { - write!(f, " addi {}, {}", src, imm) - } - } - Self::SubI { src, imm, dest } => { - if let Some(d) = dest { - write!(f, " subi {}, {}, {}", src, imm, d) - } else { - write!(f, " subi {}, {}", src, imm) - } - } - - // shift instructions - Self::Shl { - src1, - r_shamt, - i_shamt, - dest, - } => { - write!(f, " shl {}, {}, {}, {}", src1, r_shamt, i_shamt, dest) - } - Self::Shr { - src1, - r_shamt, - i_shamt, - dest, - } => { - write!(f, " shl {}, {}, {}, {}", src1, r_shamt, i_shamt, dest) - } - - Self::Ieq { src1, src2, dest } => write!(f, " ieq {}, {}, {}", src1, src2, dest), - Self::Ine { src1, src2, dest } => write!(f, " ine {}, {}, {}", src1, src2, dest), - Self::Ilt { src1, src2, dest } => write!(f, " ilt {}, {}, {}", src1, src2, dest), - Self::Ile { src1, src2, dest } => write!(f, " ile {}, {}, {}", src1, src2, dest), - Self::Igt { src1, src2, dest } => write!(f, " igt {}, {}, {}", src1, src2, dest), - Self::Ige { src1, src2, dest } => write!(f, " ige {}, {}, {}", src1, src2, dest), - - // jump instructions - Self::Jmp { target } => write!(f, " jmp {}", target), - Self::Jic { target } => write!(f, " jic {}", target), - Self::Jnc { target } => write!(f, " jnc {}", target), - Self::Jez { src, target } => write!(f, " jez {}, {}", src, target), - Self::Jnz { src, target } => write!(f, " jnz {}, {}", src, target), - - // stack instructions - Self::Push { reg } => write!(f, " push {}", reg), - Self::Pop { reg } => write!(f, " pop {}", reg), - - // call & return instructions - Self::Call { target } => write!(f, " call {}", target), - Self::Return => write!(f, " ret"), - - // misc instructions - Self::Int { code } => write!(f, " int {}", code), - Self::Hlt => write!(f, " hlt"), - Self::Nop => write!(f, " nop"), - } - } -} - -impl Instruction { - // data directives - pub fn db_string(label: impl Into, data: impl Into) -> Self { - Self::DString { - label: label.into(), - data: data.into(), - } - } - - pub fn db_word(label: impl Into, data: u32) -> Self { - Self::Dw { - label: label.into(), - data: vec![data], - } - } - - pub fn db_bytes(label: impl Into, data: &[u8]) -> Self { - Self::Db { - label: label.into(), - data: data.to_vec(), - } - } - - // Movement - pub fn mov(src: R1, dest: R2) -> Self - where - R1: Into, - R2: Into, - { - Self::Mov { - src: src.into(), - dest: dest.into(), - } - } - - // Memory loads - pub fn ldw_reg(base: R, dest: Register) -> Self - where - R: Into, - { - Self::Ldw { - src: MemOperand::RegIndirect(base.into()), - dest, - } - } - - pub fn ldw_reg_offset(base: R, dest: Register, offset: i32) -> Self - where - R: Into, - { - Self::Ldw { - src: MemOperand::RegOffset(base.into(), offset), - dest, - } - } - - pub fn ldw_label(label: impl Into