Skip to content

Commit

Permalink
[IR] starting br condition variant
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Sep 11, 2024
1 parent 6375325 commit 697ff08
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 5 deletions.
31 changes: 29 additions & 2 deletions src/CodeGen/compilation/br.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::prelude::{Block, Br};
use crate::CodeGen::{MachineInstr, MachineMnemonic};
use crate::prelude::{Block, Br, BrCond, Ir};
use crate::CodeGen::{MachineInstr, MachineMnemonic, MachineOperand};
use crate::IR::Var;

use super::CompilationHelper;

Expand All @@ -14,4 +15,30 @@ impl CompilationHelper {

mc_sink.push( instr );
}

#[allow(missing_docs)]
pub fn compile_br_cond(&mut self, node: &BrCond<Var, Block, Block>, mc_sink: &mut Vec<MachineInstr>, block: &Block) {
let boxed: Box<dyn Ir> = Box::new(node.clone());

let iftrue = node.inner2.name.to_owned();
let iffalse = node.inner3.name.to_owned();

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

let src = *self.vars.get(&node.inner1).expect("expected valid variable");

let src = match src {
super::VarLocation::Reg(reg) => MachineOperand::Reg(reg),
};

let mut cmp = MachineInstr::new(
MachineMnemonic::Compare(iftrue, iffalse)
);
cmp.add_operand(src);
cmp.add_operand(MachineOperand::Imm(1));

mc_sink.push( cmp );
}
}
3 changes: 3 additions & 0 deletions src/CodeGen/instr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ pub enum MachineMnemonic {
Sub,
Xor,

Compare(/*if yes*/String, /*if no*/String),

Zext,
Downcast,

Expand Down Expand Up @@ -120,6 +122,7 @@ impl MachineMnemonic {
MachineMnemonic::Return => "return",
MachineMnemonic::AdressLoad(_) => "adrload",
MachineMnemonic::Br(_) => "br",
MachineMnemonic::Compare(_, _) => "compare",
}.to_string()
}
}
Expand Down
66 changes: 64 additions & 2 deletions src/IR/nodes/br.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{Support::ColorClass, IR::{Block, IRBuilder}};
use crate::{Support::ColorClass, IR::{Block, IRBuilder, Var}};

use super::{Br, Ir};
use super::{Br, BrCond, Ir};

impl Ir for Br<Box<Block>> {
fn dump(&self) -> String {
Expand Down Expand Up @@ -41,6 +41,40 @@ impl Ir for Br<Box<Block>> {
}
}

impl Ir for BrCond<Var, Block, Block> {
fn dump(&self) -> String {
format!("br cond {} {}, {}", self.inner1.name, self.inner2.name, self.inner3.name)
}

fn dumpColored(&self, profile: crate::Support::ColorProfile) -> String {
format!("{} {} {} {}, {}",
profile.markup("br", ColorClass::Instr),
profile.markup("cond", ColorClass::Instr),
profile.markup(&self.inner1.name, ColorClass::Var),
profile.markup(&self.inner2.name, ColorClass::Var),
profile.markup(&self.inner3.name, ColorClass::Var),
)
}

fn as_any(&self) -> &dyn std::any::Any {
self
}

fn verify(&self, _: crate::prelude::FunctionType) -> Result<(), crate::prelude::VerifyError> {
// TODO: Check if the blocks and the var exits

Ok(())
}

fn clone_box(&self) -> Box<dyn Ir> {
Box::from( self.clone() )
}

fn compile(&self, registry: &mut crate::Target::TargetBackendDescr) {
registry.compile_br_cond(self)
}
}

/// This trait is used for building br nodes
pub trait BuildBr<T> {
/// Builds a br node
Expand All @@ -57,4 +91,32 @@ impl BuildBr<&Block> for IRBuilder<'_> {
varCount: 0
})));
}
}

/// This trait is used for building br condition nodes
pub trait BuildBrCond<T, U, Z> {
/// Builds a br condition node
///
/// ```no_run
/// br condition iftrue, iffalse
/// ```
///
/// Jumps to iftrue if the value is not 0 else to iffalse
fn BuildBr(&mut self, val: T, iftrue: U, iffalse: Z);
}

impl BuildBrCond<Var, &Block, &Block> for IRBuilder<'_> {
fn BuildBr(&mut self, val: Var, iftrue: &Block, iffalse: &Block) {
let block = self.blocks.get_mut(self.curr).expect("the IRBuilder needs to have an current block\nConsider creating one");

block.push_ir( BrCond::new(val, Block {
name: iftrue.name.to_owned(),
nodes: vec![],
varCount: 0,
}, Block {
name: iffalse.name.to_owned(),
nodes: vec![],
varCount: 0,
}) );
}
}
1 change: 1 addition & 0 deletions src/IR/nodes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ IrTypeWith3!(Mul, T, U, Z);
IrTypeWith3!(Div, T, U, Z);

IrTypeWith1!(Br, T);
IrTypeWith3!(BrCond, T, U, Z);

use crate::Support::{ColorClass, ColorProfile};

Expand Down
3 changes: 2 additions & 1 deletion src/Target/target_descr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,5 @@ compile_func!(compile_assign_var_type, compile_assign_var_type, Assign<Var, Type
compile_func!(compile_assign_var_var, compile_assign_var_var, Assign<Var, Var>);
compile_func!(compile_assign_var_const, compile_assign_var_const, Assign<Var, Const>);

compile_func!(compile_br, compile_br, Br<Box<Block>>);
compile_func!(compile_br, compile_br, Br<Box<Block>>);
compile_func!(compile_br_cond, compile_br_cond, BrCond<Var, Block, Block>);
25 changes: 25 additions & 0 deletions src/Target/x64/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ fn x64_lower_instr(conv: CallConv, sink: &mut Vec<X64MCInstr>, instr: MachineIns
MachineMnemonic::Return => x64_lower_return(sink, &instr),
MachineMnemonic::AdressLoad(to) => x64_lower_adr_load(sink, &instr, to),
MachineMnemonic::Br(to) => x64_lower_br(sink, &instr, to),
MachineMnemonic::Compare(iftrue, iffalse) => x64_lower_cond_br(sink, &instr, iftrue, iffalse),
}
}

Expand Down Expand Up @@ -219,6 +220,30 @@ fn x64_lower_br(sink: &mut Vec<X64MCInstr>, _: &MachineInstr, symbol: &String) {
X64MCInstr::with1(Mnemonic::Link, target)
);
}
fn x64_lower_cond_br(sink: &mut Vec<X64MCInstr>, instr: &MachineInstr, iftrue: &String, iffalse: &String) {
let src = instr.operands.get(0).expect("expected valid src operand at 1. place");
let value = instr.operands.get(1).expect("expected valid value to compare at 1. place");

let src = match src {
crate::CodeGen::MachineOperand::Imm(_) => unreachable!(),
crate::CodeGen::MachineOperand::Reg(reg) => match *reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(x64),
},
};

let value = match value {
crate::CodeGen::MachineOperand::Imm(imm) => Operand::Imm(*imm),
crate::CodeGen::MachineOperand::Reg(reg) => match *reg {
crate::CodeGen::Reg::x64(x64) => Operand::Reg(x64),
},
};

X64MCInstr::with2(Mnemonic::Cmp, src, value);
X64MCInstr::with1(Mnemonic::Jne, Operand::Imm(0));
X64MCInstr::with1(Mnemonic::Link, Operand::BlockLinkDestination(iffalse.to_owned(), -4));
X64MCInstr::with1(Mnemonic::Jmp, Operand::Imm(0));
X64MCInstr::with1(Mnemonic::Link, Operand::BlockLinkDestination(iftrue.to_owned(), -4));
}

macro_rules! LowerSimpleMath {
($func:ident, $mnemonic:expr) => {
Expand Down

0 comments on commit 697ff08

Please sign in to comment.