diff --git a/src/CodeGen/compilation/assign.rs b/src/CodeGen/compilation/assign.rs index 5db4d106..327b3e29 100644 --- a/src/CodeGen/compilation/assign.rs +++ b/src/CodeGen/compilation/assign.rs @@ -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 { @@ -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 ); diff --git a/src/CodeGen/compilation/call.rs b/src/CodeGen/compilation/call.rs index 3af55725..125cf1e8 100644 --- a/src/CodeGen/compilation/call.rs +++ b/src/CodeGen/compilation/call.rs @@ -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, Var>, mc_sink: &mut Vec, block: &Block) { - todo!() + let boxed: Box = 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); + } } } \ No newline at end of file diff --git a/src/CodeGen/compilation/cast.rs b/src/CodeGen/compilation/cast.rs index 752b70e3..3b9f48b3 100644 --- a/src/CodeGen/compilation/cast.rs +++ b/src/CodeGen/compilation/cast.rs @@ -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, mc_sink: &mut Vec, block: &Block) { - todo!() + let src1 = *self.vars.get(&node.inner1).expect("expected valid variable"); + + let boxed: Box = 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); } } \ No newline at end of file diff --git a/src/CodeGen/compilation/mod.rs b/src/CodeGen/compilation/mod.rs index 6eaf5938..f04e035d 100644 --- a/src/CodeGen/compilation/mod.rs +++ b/src/CodeGen/compilation/mod.rs @@ -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); diff --git a/src/CodeGen/instr.rs b/src/CodeGen/instr.rs index 4331e0ef..8c761424 100644 --- a/src/CodeGen/instr.rs +++ b/src/CodeGen/instr.rs @@ -57,7 +57,10 @@ pub enum MachineMnemonic { Sub, Xor, - Call, + Zext, + Downcast, + + Call(String), Return, AdressLoad(String), diff --git a/src/CodeGen/reg_vec.rs b/src/CodeGen/reg_vec.rs index ecd5c3c9..6f9fa8b0 100644 --- a/src/CodeGen/reg_vec.rs +++ b/src/CodeGen/reg_vec.rs @@ -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>, } @@ -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]); } } diff --git a/src/Target/x64/compilation.rs b/src/Target/x64/compilation.rs index 304e93eb..bc4659e2 100644 --- a/src/Target/x64/compilation.rs +++ b/src/Target/x64/compilation.rs @@ -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 } \ No newline at end of file