Skip to content

Commit

Permalink
type system is better now. + i64 has been implemented.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ianyourgod committed Jul 5, 2024
1 parent 413fa88 commit 0d7e67a
Show file tree
Hide file tree
Showing 19 changed files with 912 additions and 423 deletions.
30 changes: 16 additions & 14 deletions src/code_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,42 @@ use crate::tacky;

pub mod nodes;

mod firstpass;
mod secondpass;
mod thirdpass;
mod convert_pass;
mod pseudo_replace_pass;
mod inst_fixup_pass;
mod inst_fixn2_pass;

pub struct CodeGen {
pub program: tacky::nodes::Program,
symbol_table: tacky::nodes::SymbolTable,
source: String
}

impl CodeGen {
pub fn new(program: tacky::nodes::Program, source: Option<String>) -> CodeGen {
pub fn new(program: tacky::nodes::Program, symbol_table: tacky::nodes::SymbolTable, source: Option<String>) -> CodeGen {
let src: String;
if source.is_some() {
src = source.unwrap();
} else {
src = String::new();
}

CodeGen { program, source: src }
CodeGen { program, source: src, symbol_table }
}

pub fn generate_code(&mut self) -> nodes::Program {
let fp = firstpass::Pass::new(&self.program);
let first_pass = convert_pass::Pass::new(&self.program, self.symbol_table.clone());
let first_pass_output = first_pass.run();

let first_pass_output = fp.run();
let mut second_pass = pseudo_replace_pass::Pass::new(&first_pass_output, self.symbol_table.clone());
let second_pass_output = second_pass.run();

let mut sp = secondpass::Pass::new(&first_pass_output);
let third_pass = inst_fixup_pass::Pass::new(&second_pass_output);
let third_pass_output = third_pass.run();

let second_pass_output = sp.run();
let fourth_pass = inst_fixn2_pass::Pass::new(&third_pass_output);
let fourth_pass_output = fourth_pass.run();

let tp = thirdpass::Pass::new(&second_pass_output);

let third_pass_output = tp.run();

third_pass_output
fourth_pass_output
}
}
266 changes: 153 additions & 113 deletions src/code_gen/firstpass.rs → src/code_gen/convert_pass.rs

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions src/code_gen/inst_fixn2_pass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use crate::code_gen::nodes;

// all this does is make sure that the mov doesnt have an immediate thats too big (i.e. 32 bits)

pub struct Pass {
pub program: nodes::Program,
}

impl Pass {
pub fn new(program: &nodes::Program) -> Pass {
Pass { program: program.clone() }
}

pub fn run(&self) -> nodes::Program {
let mut program = nodes::Program {
statements: Vec::new(),
};

for function in self.program.statements.clone() {
let mut instructions: Vec<nodes::Instruction> = Vec::new();

instructions.push(nodes::Instruction::AllocateStack((function.context.stack_offset + 15) & !15)); // Align stack to 16 bytes

for statement in function.instructions {
self.emit_instruction(&statement, &mut instructions);
}

program.statements.push(nodes::FunctionDefinition::new(
function.function_name.clone(),
instructions,
function.context,
function.return_type.clone(),
));
}

program
}

fn arg_is_immediate(&self, arg: &nodes::Operand) -> (bool, i64) {
match arg {
nodes::Operand::Immediate(val) => (true, *val),
_ => (false, 0),
}
}

fn emit_instruction(&self, statement: &nodes::Instruction, instructions: &mut Vec<nodes::Instruction>) {
match statement {
nodes::Instruction::Mov(ref mov) => {
let src_is_immediate = self.arg_is_immediate(&mov.src);
let dest_is_memory = match &mov.dest {
nodes::Operand::StackAllocate(_) => true,
_ => false,
};

if src_is_immediate.0 && src_is_immediate.1 > i32::MAX as i64 && dest_is_memory {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R10),
src: mov.src.clone(),
suffix: mov.suffix.clone(),
}));

instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: mov.dest.clone(),
src: nodes::Operand::Register(nodes::Reg::R10),
suffix: mov.suffix.clone(),
}));
} else {
instructions.push(statement.clone());
}
},
_ => {
instructions.push(statement.clone());
},
}
}
}
79 changes: 59 additions & 20 deletions src/code_gen/thirdpass.rs → src/code_gen/inst_fixup_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ impl Pass {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R10),
src: nodes::Operand::StackAllocate(idx2),
suffix: Some("l".to_string()),
suffix: mov.suffix.clone(),
}));
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::StackAllocate(idx1),
src: nodes::Operand::Register(nodes::Reg::R10),
suffix: Some("l".to_string()),
suffix: mov.suffix.clone(),
}));
return;
}
Expand All @@ -89,12 +89,12 @@ impl Pass {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R10),
src: nodes::Operand::StackAllocate(idx2),
suffix: Some("l".to_string()),
suffix: add.suffix.clone(),
}));
instructions.push(nodes::Instruction::Add(nodes::BinOp {
dest: nodes::Operand::StackAllocate(idx1),
src: nodes::Operand::Register(nodes::Reg::R10),
suffix: Some("l".to_string()),
suffix: add.suffix.clone(),
}));
return;
}
Expand All @@ -111,12 +111,12 @@ impl Pass {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R10),
src: nodes::Operand::StackAllocate(idx2),
suffix: Some("l".to_string()),
suffix: sub.suffix.clone(),
}));
instructions.push(nodes::Instruction::Sub(nodes::BinOp {
dest: nodes::Operand::StackAllocate(idx1),
src: nodes::Operand::Register(nodes::Reg::R10),
suffix: Some("l".to_string()),
suffix: sub.suffix.clone(),
}));
return;
}
Expand All @@ -133,22 +133,22 @@ impl Pass {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R10),
src: nodes::Operand::StackAllocate(idx2),
suffix: Some("l".to_string()),
suffix: mul.suffix.clone(),
}));
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R11),
src: nodes::Operand::StackAllocate(idx1),
suffix: Some("l".to_string()),
suffix: mul.suffix.clone(),
}));
instructions.push(nodes::Instruction::Mul(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R11),
src: nodes::Operand::Register(nodes::Reg::R10),
suffix: Some("l".to_string()),
suffix: mul.suffix.clone(),
}));
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::StackAllocate(idx1),
src: nodes::Operand::Register(nodes::Reg::R11),
suffix: Some("l".to_string()),
suffix: mul.suffix.clone(),
}));
return;
}
Expand All @@ -157,7 +157,7 @@ impl Pass {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R11),
src: nodes::Operand::StackAllocate(*idx1),
suffix: Some("l".to_string()),
suffix: mul.suffix.clone(),
}));
instructions.push(nodes::Instruction::Mul(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R11),
Expand All @@ -167,7 +167,7 @@ impl Pass {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::StackAllocate(*idx1),
src: nodes::Operand::Register(nodes::Reg::R11),
suffix: Some("l".to_string()),
suffix: mul.suffix.clone(),
}));
return;
}
Expand All @@ -183,7 +183,7 @@ impl Pass {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R10),
src: nodes::Operand::Immediate(*val),
suffix: Some("l".to_string()),
suffix: div.suffix.clone(),
}));
instructions.push(nodes::Instruction::Div(nodes::UnaryOp {
operand: nodes::Operand::Register(nodes::Reg::R10),
Expand All @@ -201,25 +201,25 @@ impl Pass {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R10),
src: nodes::Operand::StackAllocate(idx2),
suffix: Some("l".to_string()),
suffix: cmp.suffix.clone(),
}));
if dest_is_immediate {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R11),
src: nodes::Operand::StackAllocate(idx1),
suffix: Some("l".to_string()),
suffix: cmp.suffix.clone(),
}));
instructions.push(nodes::Instruction::Cmp(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R11),
src: nodes::Operand::Register(nodes::Reg::R10),
suffix: Some("l".to_string()),
suffix: cmp.suffix.clone(),
}));
return;
}
instructions.push(nodes::Instruction::Cmp(nodes::BinOp {
dest: nodes::Operand::StackAllocate(idx1),
src: nodes::Operand::Register(nodes::Reg::R10),
suffix: Some("l".to_string()),
suffix: cmp.suffix.clone(),
}));
return;
}
Expand All @@ -228,18 +228,57 @@ impl Pass {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R11),
src: cmp.src.clone(),
suffix: Some("l".to_string()),
suffix: cmp.suffix.clone(),
}));
instructions.push(nodes::Instruction::Cmp(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R11),
src: cmp.dest.clone(),
suffix: Some("l".to_string()),
suffix: cmp.suffix.clone(),
}));
return;
}

instructions.push(statement.clone());
}
},
nodes::Instruction::Movsx(src, dst) => {
let src_is_immediate = self.arg_is_immediate(src);
let dst_is_mem = match dst {
nodes::Operand::StackAllocate(_) => true,
_ => false,
};

if src_is_immediate {
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
dest: nodes::Operand::Register(nodes::Reg::R10),
src: src.clone(),
suffix: nodes::Suffix::L,
}));

if dst_is_mem {
instructions.push(nodes::Instruction::Movsx(nodes::Operand::Register(nodes::Reg::R10), nodes::Operand::Register(nodes::Reg::R11)));
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
src: nodes::Operand::Register(nodes::Reg::R11),
dest: dst.clone(),
suffix: nodes::Suffix::Q,
}));
return;
}

instructions.push(nodes::Instruction::Movsx(nodes::Operand::Register(nodes::Reg::R10), dst.clone()));
}

if dst_is_mem {
instructions.push(nodes::Instruction::Movsx(src.clone(), nodes::Operand::Register(nodes::Reg::R11)));
instructions.push(nodes::Instruction::Mov(nodes::BinOp {
src: nodes::Operand::Register(nodes::Reg::R11),
dest: dst.clone(),
suffix: nodes::Suffix::Q,
}));
return;
}

instructions.push(nodes::Instruction::Movsx(src.clone(), dst.clone()));
},
_ => {
instructions.push(statement.clone());
},
Expand Down
Loading

0 comments on commit 0d7e67a

Please sign in to comment.