Add intrinsic bit-operators

This commit is contained in:
Sofia 2025-07-28 12:16:14 +03:00
parent d06eff9347
commit a4e18af983
6 changed files with 74 additions and 18 deletions

View File

@ -459,8 +459,8 @@ impl ast::BinaryOperator {
ast::BinaryOperator::BitshiftRight => mir::BinaryOperator::BitshiftRight,
ast::BinaryOperator::BitshiftLeft => mir::BinaryOperator::BitshiftLeft,
ast::BinaryOperator::Xor => mir::BinaryOperator::Xor,
ast::BinaryOperator::BWAnd => mir::BinaryOperator::BitwiseAnd,
ast::BinaryOperator::BWOr => mir::BinaryOperator::BitwiseOr,
ast::BinaryOperator::BWAnd => mir::BinaryOperator::BitAnd,
ast::BinaryOperator::BWOr => mir::BinaryOperator::BitOr,
}
}
}

View File

@ -1,3 +1,5 @@
use std::ops::BitAnd;
use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type};
use crate::{
@ -84,6 +86,21 @@ where
}
}
fn complex_binop_def<T: Clone + 'static>(op: BinaryOperator, lhs: &TypeKind, rhs: &TypeKind, fun: T) -> BinopDefinition
where
T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue,
{
BinopDefinition {
lhs: ("lhs".to_owned(), lhs.clone()),
op,
rhs: ("rhs".to_owned(), rhs.clone()),
return_type: lhs.clone(),
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))),
meta: Default::default(),
exported: false,
}
}
fn boolean_binop_def<T: Clone + 'static>(op: BinaryOperator, ty: &TypeKind, fun: T) -> BinopDefinition
where
T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue,
@ -145,6 +162,39 @@ pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::LE), &ty, |scope, lhs, rhs| {
scope.block.build(Instr::ICmp(CmpPredicate::LE, lhs, rhs)).unwrap()
}));
// Bitwise operations
intrinsics.push(simple_binop_def(BitOr, &ty, |scope, lhs, rhs| {
scope.block.build(Instr::Or(lhs, rhs)).unwrap()
}));
intrinsics.push(simple_binop_def(BitAnd, &ty, |scope, lhs, rhs| {
scope.block.build(Instr::And(lhs, rhs)).unwrap()
}));
intrinsics.push(complex_binop_def(Xor, &ty, &TypeKind::U64, |scope, lhs, rhs| {
scope.block.build(Instr::XOr(lhs, rhs)).unwrap()
}));
if ty.signed() {
intrinsics.push(complex_binop_def(
BitshiftRight,
&ty,
&TypeKind::U64,
|scope, lhs, rhs| scope.block.build(Instr::ShiftRightArithmetic(lhs, rhs)).unwrap(),
));
} else {
intrinsics.push(complex_binop_def(
BitshiftRight,
&ty,
&TypeKind::U64,
|scope, lhs, rhs| scope.block.build(Instr::ShiftRightLogical(lhs, rhs)).unwrap(),
));
}
intrinsics.push(complex_binop_def(
BitshiftLeft,
&ty,
&TypeKind::U64,
|scope, lhs, rhs| scope.block.build(Instr::ShiftLeft(lhs, rhs)).unwrap(),
));
}
for ty in INTEGERS.iter().chain(&[TypeKind::Bool, TypeKind::Char]) {
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::EQ), &ty, |scope, lhs, rhs| {
@ -195,6 +245,12 @@ pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
intrinsics.push(boolean_binop_def(And, &TypeKind::Bool, |scope, lhs, rhs| {
scope.block.build(Instr::And(lhs, rhs)).unwrap()
}));
intrinsics.push(boolean_binop_def(Or, &TypeKind::Bool, |scope, lhs, rhs| {
scope.block.build(Instr::Or(lhs, rhs)).unwrap()
}));
intrinsics.push(boolean_binop_def(Xor, &TypeKind::Bool, |scope, lhs, rhs| {
scope.block.build(Instr::XOr(lhs, rhs)).unwrap()
}));
intrinsics
}

View File

@ -893,14 +893,14 @@ impl mir::Expression {
(mir::BinaryOperator::Xor, true, false) => todo!(),
(mir::BinaryOperator::Xor, false, true) => todo!(),
(mir::BinaryOperator::Xor, false, false) => todo!(),
(mir::BinaryOperator::BitwiseOr, true, true) => todo!(),
(mir::BinaryOperator::BitwiseOr, true, false) => todo!(),
(mir::BinaryOperator::BitwiseOr, false, true) => todo!(),
(mir::BinaryOperator::BitwiseOr, false, false) => todo!(),
(mir::BinaryOperator::BitwiseAnd, true, true) => todo!(),
(mir::BinaryOperator::BitwiseAnd, true, false) => todo!(),
(mir::BinaryOperator::BitwiseAnd, false, true) => todo!(),
(mir::BinaryOperator::BitwiseAnd, false, false) => todo!(),
(mir::BinaryOperator::BitOr, true, true) => todo!(),
(mir::BinaryOperator::BitOr, true, false) => todo!(),
(mir::BinaryOperator::BitOr, false, true) => todo!(),
(mir::BinaryOperator::BitOr, false, false) => todo!(),
(mir::BinaryOperator::BitAnd, true, true) => todo!(),
(mir::BinaryOperator::BitAnd, true, false) => todo!(),
(mir::BinaryOperator::BitAnd, false, true) => todo!(),
(mir::BinaryOperator::BitAnd, false, false) => todo!(),
(mir::BinaryOperator::BitshiftRight, true, true) => todo!(),
(mir::BinaryOperator::BitshiftRight, true, false) => todo!(),
(mir::BinaryOperator::BitshiftRight, false, true) => todo!(),

View File

@ -354,8 +354,8 @@ impl Display for BinaryOperator {
BinaryOperator::Mod => write!(f, "%"),
BinaryOperator::Or => write!(f, "||"),
BinaryOperator::Xor => write!(f, "^"),
BinaryOperator::BitwiseOr => write!(f, "|"),
BinaryOperator::BitwiseAnd => write!(f, "&"),
BinaryOperator::BitOr => write!(f, "|"),
BinaryOperator::BitAnd => write!(f, "&"),
BinaryOperator::BitshiftRight => write!(f, ">>"),
BinaryOperator::BitshiftLeft => write!(f, "<<"),
}

View File

@ -208,8 +208,8 @@ impl BinaryOperator {
},
BinaryOperator::Or => true,
BinaryOperator::Xor => true,
BinaryOperator::BitwiseOr => true,
BinaryOperator::BitwiseAnd => true,
BinaryOperator::BitOr => true,
BinaryOperator::BitAnd => true,
BinaryOperator::BitshiftRight => false,
BinaryOperator::BitshiftLeft => false,
}
@ -481,8 +481,8 @@ impl Expression {
}
BinaryOperator::Or => None,
BinaryOperator::Xor => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a ^ b),
BinaryOperator::BitwiseOr => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a | b),
BinaryOperator::BitwiseAnd => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a & b),
BinaryOperator::BitOr => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a | b),
BinaryOperator::BitAnd => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a & b),
BinaryOperator::BitshiftRight => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a >> b),
BinaryOperator::BitshiftLeft => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a << b),
},

View File

@ -224,8 +224,8 @@ pub enum BinaryOperator {
And,
Or,
Xor,
BitwiseOr,
BitwiseAnd,
BitOr,
BitAnd,
BitshiftRight,
BitshiftLeft,
Cmp(CmpOperator),