Skip to content

Commit

Permalink
[CODE GEN] implementing all ir instructions (call has #8 but i know t…
Browse files Browse the repository at this point in the history
…hat)
  • Loading branch information
Cr0a3 committed Aug 29, 2024
1 parent db2a084 commit dc28092
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/CodeGen/compilation/assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl CompilationHelper {
let mut instr = MachineInstr::new(MachineMnemonic::Move);

match location {
VarLocation::Reg(reg) => instr.add_operand(MachineOperand::Reg(reg)),
VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)),
}

match src1 {
Expand All @@ -69,7 +69,7 @@ impl CompilationHelper {
);

match location {
VarLocation::Reg(reg) => instr.add_operand(MachineOperand::Reg(reg)),
VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)),
}

mc_sink.push( instr );
Expand Down
55 changes: 52 additions & 3 deletions src/CodeGen/compilation/call.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,60 @@
use crate::prelude::Call;
use crate::{prelude::{Call, Ir}, CodeGen::{MachineMnemonic, MachineOperand}};
use crate::IR::{Block, Function, Var};
use super::CompilationHelper;
use super::{CompilationHelper, VarLocation};
use crate::CodeGen::MachineInstr;

impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_call(&mut self, node: &Call<Function, Vec<Var>, Var>, mc_sink: &mut Vec<MachineInstr>, block: &Block) {
todo!()
let boxed: Box<dyn Ir> = Box::new(node.clone());

let mut reg_args = 0;

let args = self.call.args(self.arch);

for arg in &node.inner2 {
let mut instr = MachineInstr::new(MachineMnemonic::Move);


let arg_reg = args.get(reg_args);

if let Some(arg) = arg_reg {
instr.set_out(MachineOperand::Reg(*arg));
} else {
todo!("implemt arguments which are passed over the stack");
}

let src = self.vars.get(arg).expect("expected valid variable");

match src {
VarLocation::Reg(reg) => instr.add_operand(MachineOperand::Reg(*reg)),
}

mc_sink.push( instr );

reg_args += 1;
}

mc_sink.push(MachineInstr::new(
MachineMnemonic::Call(node.inner1.name.to_string())
));

if block.isVarUsedAfterNode(&boxed, &node.inner3) {
let mut instr = MachineInstr::new(MachineMnemonic::Move);

let loc = self.alloc(&node.inner3);

instr.add_operand(
MachineOperand::Reg(
self.call.return_reg(self.arch, node.inner1.ty.ret)
)
);

match loc {
VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)),
}

mc_sink.push(instr);
}
}
}
44 changes: 40 additions & 4 deletions src/CodeGen/compilation/cast.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,46 @@
use crate::prelude::Cast;
use crate::prelude::{Cast, Ir};
use crate::IR::{Block, TypeMetadata, Var};
use super::CompilationHelper;
use crate::CodeGen::MachineInstr;
use super::{CompilationHelper, VarLocation};
use crate::CodeGen::{MachineInstr, MachineMnemonic, MachineOperand};

impl CompilationHelper {
#[allow(missing_docs)]
pub fn compile_cast(&mut self, node: &Cast<Var, TypeMetadata, Var>, mc_sink: &mut Vec<MachineInstr>, block: &Block) {
todo!()
let src1 = *self.vars.get(&node.inner1).expect("expected valid variable");

let boxed: Box<dyn Ir> = Box::new(node.clone());

if !block.isVarUsedAfterNode(&boxed, &node.inner1) {
self.free(&node.inner1)
}
if !block.isVarUsedAfterNode(&boxed, &node.inner3) {
return;
}

let out = self.alloc(&node.inner3);

let op = {

if node.inner1.ty.bitSize() > node.inner2.bitSize() {
MachineMnemonic::Zext
} else if node.inner1.ty.bitSize() < node.inner2.bitSize(){
MachineMnemonic::Downcast
} else {
return;
}

};

let mut instr = MachineInstr::new(op);

match src1 {
VarLocation::Reg(reg) => instr.add_operand(MachineOperand::Reg(reg)),
}

match out {
VarLocation::Reg(reg) => instr.set_out(MachineOperand::Reg(reg)),
}

mc_sink.push(instr);
}
}
2 changes: 1 addition & 1 deletion src/CodeGen/compilation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl CompilationHelper {
let location = if let Some(reg) = self.regs.pop(self.arch) {
VarLocation::Reg(reg)
} else {
todo!()
todo!("Registers ran out. And memory variables are currently not implemented")
};

self.vars.insert(var.clone(), location);
Expand Down
5 changes: 4 additions & 1 deletion src/CodeGen/instr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ pub enum MachineMnemonic {
Sub,
Xor,

Call,
Zext,
Downcast,

Call(String),
Return,

AdressLoad(String),
Expand Down
3 changes: 3 additions & 0 deletions src/CodeGen/reg_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use super::reg::Reg;

/// A register vector.
/// Used for getting platform specific registers
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RegVec {
regs: HashMap<Arch, Vec<Reg>>,
}
Expand All @@ -21,6 +22,8 @@ impl RegVec {
pub fn push(&mut self, arch: Arch, reg: Reg) {
if let Some(entry) = self.regs.get_mut(&arch) {
entry.push(reg);
} else {
self.regs.insert(arch, vec![reg]);
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/Target/x64/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@ pub(crate) fn construct_compilation_helper(call_conv: CallConv) -> CompilationHe
helper.regs.push(Arch::X86_64, Reg::x64(x64Reg::R14));
helper.regs.push(Arch::X86_64, Reg::x64(x64Reg::R15));

helper.regs.reverse(Arch::X86_64);

helper
}

0 comments on commit dc28092

Please sign in to comment.