refactor/cleanup of mir generation for arithmetic ops and preloading of constant lhs
This commit is contained in:
parent
06b1ec1763
commit
eba0edb9e4
368
src/triples.rs
368
src/triples.rs
|
@ -26,7 +26,37 @@ enum Type2 {
|
|||
Pointer,
|
||||
}
|
||||
|
||||
impl Into<mir::Type> for Type2 {
|
||||
fn into(self) -> mir::Type {
|
||||
self.mir_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl Type2 {
|
||||
fn mir_type(self) -> mir::Type {
|
||||
match self {
|
||||
Type2::Integral(_, bits) => mir::Type::from_bitsize_int(bits as u32),
|
||||
Type2::Binary32 => mir::Type::SinglePrecision,
|
||||
Type2::Binary64 => mir::Type::DoublePrecision,
|
||||
Type2::Bool => mir::Type::from_bitsize_int(1),
|
||||
Type2::Pointer => mir::Type::QWord,
|
||||
}
|
||||
}
|
||||
fn is_signed(self) -> bool {
|
||||
match self {
|
||||
Type2::Integral(signed, _) => signed,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
fn mir_unalignment(self) -> Option<(bool, u16)> {
|
||||
match self {
|
||||
Type2::Integral(signed, bits) => match bits {
|
||||
8 | 16 | 32 | 64 => None,
|
||||
bits => Some((signed, bits)),
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn size(&self) -> u32 {
|
||||
match self {
|
||||
Type2::Integral(_signed, bits) => bits.div_ceil(8) as u32,
|
||||
|
@ -100,7 +130,7 @@ enum Inst {
|
|||
/// ptr, index,
|
||||
GetElementPtr(Type2),
|
||||
/// size, align
|
||||
Parameter,
|
||||
Parameter(Type2),
|
||||
/// lhs, rhs
|
||||
Add(Type2),
|
||||
/// lhs, rhs
|
||||
|
@ -129,6 +159,16 @@ enum Inst {
|
|||
Return,
|
||||
}
|
||||
|
||||
impl Inst {
|
||||
fn is_constant(self) -> bool {
|
||||
match self {
|
||||
Inst::ConstantU32 | Inst::ConstantU64 | Inst::ConstantMultiByte => true,
|
||||
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Data {
|
||||
lhs: u32,
|
||||
|
@ -242,10 +282,11 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
|
|||
for param in parameters {
|
||||
variant!(Tag::Parameter { ty, .. } = self.tree.nodes.get_node(*param));
|
||||
let ty = self.tree.type_of_node(*ty);
|
||||
let ir = self.ir.push(
|
||||
Inst::Parameter,
|
||||
Some(Data::new(ty.size_of(), ty.align_of())),
|
||||
);
|
||||
let size = ty.size_of();
|
||||
let align = ty.align_of();
|
||||
let ir = self
|
||||
.ir
|
||||
.push(Inst::Parameter(ty.into()), Some(Data::new(size, align)));
|
||||
|
||||
self.lookup.insert(*param, NodeOrList::Node(ir));
|
||||
}
|
||||
|
@ -456,12 +497,12 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
|
|||
let label = self.tree.strings.get_str(data.as_index());
|
||||
writeln_indented!(indent - 1, w, "%{} = func {label}:", node)?;
|
||||
}
|
||||
Inst::Parameter => {
|
||||
Inst::Parameter(ty) => {
|
||||
let (size, align) = data.as_lhs_rhs();
|
||||
writeln_indented!(
|
||||
indent,
|
||||
w,
|
||||
"%{} = Param(size: {}, align: {})",
|
||||
"%{} = param {ty} (size: {}, align: {})",
|
||||
node,
|
||||
size,
|
||||
align
|
||||
|
@ -1065,7 +1106,7 @@ impl<'a> Assembler<'a> {
|
|||
}
|
||||
registers.insert(dst_reg, node);
|
||||
}
|
||||
Inst::Parameter => {
|
||||
Inst::Parameter(_) => {
|
||||
let param_reg = Registers::sysv_param_idx(param_count).unwrap();
|
||||
param_count += 1;
|
||||
register_store.force_take(param_reg);
|
||||
|
@ -1312,10 +1353,9 @@ impl<'a> MirBuilder<'a> {
|
|||
let src = *mapping.get(&ptr).unwrap();
|
||||
mir.gen_get_element_ptr(ty, src, idx)
|
||||
}
|
||||
Inst::Parameter => {
|
||||
let (size, _) = data.unwrap().as_lhs_rhs();
|
||||
let ty = mir::Type::from_bytesize_int(size);
|
||||
mir.gen_param(ty)
|
||||
Inst::Parameter(ty) => {
|
||||
// let (size, _) = data.unwrap().as_lhs_rhs();
|
||||
mir.gen_param(ty.into())
|
||||
}
|
||||
Inst::Add(ty) => {
|
||||
let (src, dst) = data.unwrap().as_lhs_rhs();
|
||||
|
@ -1349,188 +1389,156 @@ impl<'a> MirBuilder<'a> {
|
|||
let lhs = *mapping.get(&src).unwrap();
|
||||
let rhs = *mapping.get(&dst).unwrap();
|
||||
|
||||
match ty {
|
||||
Type2::Integral(signed, bits) => match bits {
|
||||
8 => mir.gen_sub(mir::Type::Byte, lhs, rhs),
|
||||
16 => mir.gen_sub(mir::Type::Word, lhs, rhs),
|
||||
32 => mir.gen_sub(mir::Type::DWord, lhs, rhs),
|
||||
64 => mir.gen_sub(mir::Type::QWord, lhs, rhs),
|
||||
64.. => {
|
||||
unimplemented!()
|
||||
}
|
||||
bits => {
|
||||
let ty = mir::Type::from_bitsize_int(bits as u32);
|
||||
let unalignment = ty.mir_unalignment();
|
||||
let ty = ty.mir_type();
|
||||
|
||||
let sum = mir.gen_sub(ty, lhs, rhs);
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
}
|
||||
},
|
||||
Type2::Binary32 => mir.gen_sub(mir::Type::SinglePrecision, lhs, rhs),
|
||||
Type2::Binary64 => mir.gen_sub(mir::Type::DoublePrecision, lhs, rhs),
|
||||
Type2::Pointer => mir.gen_sub(mir::Type::QWord, lhs, rhs),
|
||||
_ => unreachable!(),
|
||||
let const_lhs = self.ir.ir.nodes[src as usize].is_constant();
|
||||
let lhs = if const_lhs {
|
||||
mir.gen_load_const(ty, src)
|
||||
} else {
|
||||
lhs
|
||||
};
|
||||
|
||||
let sum = mir.gen_sub(ty, lhs, rhs);
|
||||
if let Some((signed, bits)) = unalignment {
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
}
|
||||
Inst::Mul(ty) => {
|
||||
let (src, dst) = data.unwrap().as_lhs_rhs();
|
||||
let lhs = *mapping.get(&src).unwrap();
|
||||
let rhs = *mapping.get(&dst).unwrap();
|
||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||
|
||||
match ty {
|
||||
Type2::Integral(signed, bits) => match bits {
|
||||
8 => mir.gen_mul(mir::Type::Byte, signed, lhs, rhs),
|
||||
16 => mir.gen_mul(mir::Type::Word, signed, lhs, rhs),
|
||||
32 => mir.gen_mul(mir::Type::DWord, signed, lhs, rhs),
|
||||
64 => mir.gen_mul(mir::Type::QWord, signed, lhs, rhs),
|
||||
64.. => {
|
||||
unimplemented!()
|
||||
}
|
||||
bits => {
|
||||
let ty = mir::Type::from_bitsize_int(bits as u32);
|
||||
let unalignment = ty.mir_unalignment();
|
||||
let signed = ty.is_signed();
|
||||
let ty = ty.mir_type();
|
||||
|
||||
let sum = mir.gen_mul(ty, signed, lhs, rhs);
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
}
|
||||
},
|
||||
Type2::Binary32 => {
|
||||
mir.gen_mul_unsigned(mir::Type::SinglePrecision, lhs, rhs)
|
||||
}
|
||||
Type2::Binary64 => {
|
||||
mir.gen_mul_unsigned(mir::Type::DoublePrecision, lhs, rhs)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() {
|
||||
(rhs, lhs)
|
||||
} else {
|
||||
(lhs, rhs)
|
||||
};
|
||||
|
||||
let lhs = *mapping.get(&lhs).unwrap();
|
||||
let rhs = *mapping.get(&rhs).unwrap();
|
||||
|
||||
let sum = mir.gen_mul(ty, signed, lhs, rhs);
|
||||
if let Some((signed, bits)) = unalignment {
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
}
|
||||
Inst::Div(ty) => {
|
||||
let (src, dst) = data.unwrap().as_lhs_rhs();
|
||||
let lhs = *mapping.get(&src).unwrap();
|
||||
let rhs = *mapping.get(&dst).unwrap();
|
||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||
|
||||
match ty {
|
||||
Type2::Integral(signed, bits) => match bits {
|
||||
8 => mir.gen_div(mir::Type::Byte, signed, lhs, rhs),
|
||||
16 => mir.gen_div(mir::Type::Word, signed, lhs, rhs),
|
||||
32 => mir.gen_div(mir::Type::DWord, signed, lhs, rhs),
|
||||
64 => mir.gen_div(mir::Type::QWord, signed, lhs, rhs),
|
||||
64.. => {
|
||||
unimplemented!()
|
||||
}
|
||||
bits => {
|
||||
let ty = mir::Type::from_bitsize_int(bits as u32);
|
||||
let unalignment = ty.mir_unalignment();
|
||||
let signed = ty.is_signed();
|
||||
let ty = ty.mir_type();
|
||||
|
||||
let sum = mir.gen_div(ty, signed, lhs, rhs);
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
}
|
||||
},
|
||||
Type2::Binary32 => {
|
||||
mir.gen_div_unsigned(mir::Type::SinglePrecision, lhs, rhs)
|
||||
}
|
||||
Type2::Binary64 => {
|
||||
mir.gen_div_unsigned(mir::Type::DoublePrecision, lhs, rhs)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
let lhs = if self.ir.ir.nodes[lhs as usize].is_constant() {
|
||||
mir.gen_load_const(ty, lhs)
|
||||
} else {
|
||||
lhs
|
||||
};
|
||||
|
||||
let lhs = *mapping.get(&lhs).unwrap();
|
||||
let rhs = *mapping.get(&rhs).unwrap();
|
||||
|
||||
let sum = mir.gen_div(ty, signed, lhs, rhs);
|
||||
if let Some((signed, bits)) = unalignment {
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
}
|
||||
Inst::Rem(ty) => {
|
||||
let (src, dst) = data.unwrap().as_lhs_rhs();
|
||||
let lhs = *mapping.get(&src).unwrap();
|
||||
let rhs = *mapping.get(&dst).unwrap();
|
||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||
|
||||
match ty {
|
||||
Type2::Integral(signed, bits) => match bits {
|
||||
8 => mir.gen_rem(mir::Type::Byte, signed, lhs, rhs),
|
||||
16 => mir.gen_rem(mir::Type::Word, signed, lhs, rhs),
|
||||
32 => mir.gen_rem(mir::Type::DWord, signed, lhs, rhs),
|
||||
64 => mir.gen_rem(mir::Type::QWord, signed, lhs, rhs),
|
||||
64.. => {
|
||||
unimplemented!()
|
||||
}
|
||||
bits => {
|
||||
let ty = mir::Type::from_bitsize_int(bits as u32);
|
||||
let unalignment = ty.mir_unalignment();
|
||||
let signed = ty.is_signed();
|
||||
let ty = ty.mir_type();
|
||||
|
||||
let sum = mir.gen_rem(ty, signed, lhs, rhs);
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
}
|
||||
},
|
||||
Type2::Binary32 => {
|
||||
mir.gen_rem_unsigned(mir::Type::SinglePrecision, lhs, rhs)
|
||||
}
|
||||
Type2::Binary64 => {
|
||||
mir.gen_rem_unsigned(mir::Type::DoublePrecision, lhs, rhs)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
let lhs = if self.ir.ir.nodes[lhs as usize].is_constant() {
|
||||
mir.gen_load_const(ty, lhs)
|
||||
} else {
|
||||
lhs
|
||||
};
|
||||
|
||||
let lhs = *mapping.get(&lhs).unwrap();
|
||||
let rhs = *mapping.get(&rhs).unwrap();
|
||||
|
||||
let sum = mir.gen_rem(ty, signed, lhs, rhs);
|
||||
if let Some((signed, bits)) = unalignment {
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
}
|
||||
Inst::BitAnd(ty) => {
|
||||
let (src, dst) = data.unwrap().as_lhs_rhs();
|
||||
let lhs = *mapping.get(&src).unwrap();
|
||||
let rhs = *mapping.get(&dst).unwrap();
|
||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||
|
||||
match ty {
|
||||
Type2::Integral(signed, bits) => match bits {
|
||||
8 => mir.gen_bitand(mir::Type::Byte, lhs, rhs),
|
||||
16 => mir.gen_bitand(mir::Type::Word, lhs, rhs),
|
||||
32 => mir.gen_bitand(mir::Type::DWord, lhs, rhs),
|
||||
64 => mir.gen_bitand(mir::Type::QWord, lhs, rhs),
|
||||
64.. => {
|
||||
unimplemented!()
|
||||
}
|
||||
bits => {
|
||||
let ty = mir::Type::from_bitsize_int(bits as u32);
|
||||
let unalignment = ty.mir_unalignment();
|
||||
let ty = ty.mir_type();
|
||||
|
||||
let sum = mir.gen_bitand(ty, lhs, rhs);
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() {
|
||||
(rhs, lhs)
|
||||
} else {
|
||||
(lhs, rhs)
|
||||
};
|
||||
|
||||
let lhs = *mapping.get(&lhs).unwrap();
|
||||
let rhs = *mapping.get(&rhs).unwrap();
|
||||
|
||||
let sum = mir.gen_bitand(ty, lhs, rhs);
|
||||
if let Some((signed, bits)) = unalignment {
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
}
|
||||
Inst::BitOr(ty) => {
|
||||
let (src, dst) = data.unwrap().as_lhs_rhs();
|
||||
let lhs = *mapping.get(&src).unwrap();
|
||||
let rhs = *mapping.get(&dst).unwrap();
|
||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||
|
||||
match ty {
|
||||
Type2::Integral(signed, bits) => match bits {
|
||||
8 => mir.gen_bitor(mir::Type::Byte, lhs, rhs),
|
||||
16 => mir.gen_bitor(mir::Type::Word, lhs, rhs),
|
||||
32 => mir.gen_bitor(mir::Type::DWord, lhs, rhs),
|
||||
64 => mir.gen_bitor(mir::Type::QWord, lhs, rhs),
|
||||
64.. => {
|
||||
unimplemented!()
|
||||
}
|
||||
bits => {
|
||||
let ty = mir::Type::from_bitsize_int(bits as u32);
|
||||
let unalignment = ty.mir_unalignment();
|
||||
let ty = ty.mir_type();
|
||||
|
||||
let sum = mir.gen_bitor(ty, lhs, rhs);
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() {
|
||||
(rhs, lhs)
|
||||
} else {
|
||||
(lhs, rhs)
|
||||
};
|
||||
|
||||
let lhs = *mapping.get(&lhs).unwrap();
|
||||
let rhs = *mapping.get(&rhs).unwrap();
|
||||
|
||||
let sum = mir.gen_bitor(ty, lhs, rhs);
|
||||
if let Some((signed, bits)) = unalignment {
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
}
|
||||
Inst::BitXOr(ty) => {
|
||||
let (src, dst) = data.unwrap().as_lhs_rhs();
|
||||
let lhs = *mapping.get(&src).unwrap();
|
||||
let rhs = *mapping.get(&dst).unwrap();
|
||||
let (lhs, rhs) = data.unwrap().as_lhs_rhs();
|
||||
|
||||
match ty {
|
||||
Type2::Integral(signed, bits) => match bits {
|
||||
8 => mir.gen_bitxor(mir::Type::Byte, lhs, rhs),
|
||||
16 => mir.gen_bitxor(mir::Type::Word, lhs, rhs),
|
||||
32 => mir.gen_bitxor(mir::Type::DWord, lhs, rhs),
|
||||
64 => mir.gen_bitxor(mir::Type::QWord, lhs, rhs),
|
||||
64.. => {
|
||||
unimplemented!()
|
||||
}
|
||||
bits => {
|
||||
let ty = mir::Type::from_bitsize_int(bits as u32);
|
||||
let unalignment = ty.mir_unalignment();
|
||||
let ty = ty.mir_type();
|
||||
|
||||
let sum = mir.gen_bitxor(ty, lhs, rhs);
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() {
|
||||
(rhs, lhs)
|
||||
} else {
|
||||
(lhs, rhs)
|
||||
};
|
||||
|
||||
let lhs = *mapping.get(&lhs).unwrap();
|
||||
let rhs = *mapping.get(&rhs).unwrap();
|
||||
|
||||
let sum = mir.gen_bitxor(ty, lhs, rhs);
|
||||
if let Some((signed, bits)) = unalignment {
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
}
|
||||
Inst::ShiftLeft(ty) => {
|
||||
|
@ -1591,26 +1599,24 @@ impl<'a> MirBuilder<'a> {
|
|||
}
|
||||
}
|
||||
Inst::Negate(ty) => {
|
||||
let src = data.unwrap().as_u32();
|
||||
let src = *mapping.get(&src).unwrap();
|
||||
let lhs = data.unwrap().as_u32();
|
||||
|
||||
match ty {
|
||||
Type2::Integral(signed, bits) => match bits {
|
||||
8 => mir.gen_negate(mir::Type::Byte, src),
|
||||
16 => mir.gen_negate(mir::Type::Word, src),
|
||||
32 => mir.gen_negate(mir::Type::DWord, src),
|
||||
64 => mir.gen_negate(mir::Type::QWord, src),
|
||||
64.. => {
|
||||
unimplemented!()
|
||||
}
|
||||
bits => {
|
||||
let ty = mir::Type::from_bitsize_int(bits as u32);
|
||||
let unalignment = ty.mir_unalignment();
|
||||
let ty = ty.mir_type();
|
||||
|
||||
let sum = mir.gen_negate(ty, src);
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
}
|
||||
},
|
||||
_ => unreachable!(),
|
||||
let lhs = if self.ir.ir.nodes[lhs as usize].is_constant() {
|
||||
mir.gen_load_const(ty, lhs)
|
||||
} else {
|
||||
lhs
|
||||
};
|
||||
|
||||
let lhs = *mapping.get(&lhs).unwrap();
|
||||
|
||||
let sum = mir.gen_negate(ty, lhs);
|
||||
if let Some((signed, bits)) = unalignment {
|
||||
mir.gen_truncate(sum, ty, signed, bits)
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
}
|
||||
Inst::ReturnValue => {
|
||||
|
|
Loading…
Reference in a new issue