diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 72a0fc2..8153295 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -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, } } } diff --git a/reid/src/codegen/intrinsics.rs b/reid/src/codegen/intrinsics.rs index 75ad663..f1a9e4c 100644 --- a/reid/src/codegen/intrinsics.rs +++ b/reid/src/codegen/intrinsics.rs @@ -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(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(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 { 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 { 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 } diff --git a/reid/src/codegen/mod.rs b/reid/src/codegen/mod.rs index cdba78d..7fcbbb6 100644 --- a/reid/src/codegen/mod.rs +++ b/reid/src/codegen/mod.rs @@ -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!(), diff --git a/reid/src/mir/fmt.rs b/reid/src/mir/fmt.rs index ba0de0b..b9a6ed4 100644 --- a/reid/src/mir/fmt.rs +++ b/reid/src/mir/fmt.rs @@ -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, "<<"), } diff --git a/reid/src/mir/implement.rs b/reid/src/mir/implement.rs index 081755b..bcf2b65 100644 --- a/reid/src/mir/implement.rs +++ b/reid/src/mir/implement.rs @@ -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), }, diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 87c463c..5eb1b6b 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -224,8 +224,8 @@ pub enum BinaryOperator { And, Or, Xor, - BitwiseOr, - BitwiseAnd, + BitOr, + BitAnd, BitshiftRight, BitshiftLeft, Cmp(CmpOperator),