Add intrinsic bit-operators
This commit is contained in:
parent
d06eff9347
commit
a4e18af983
@ -459,8 +459,8 @@ impl ast::BinaryOperator {
|
|||||||
ast::BinaryOperator::BitshiftRight => mir::BinaryOperator::BitshiftRight,
|
ast::BinaryOperator::BitshiftRight => mir::BinaryOperator::BitshiftRight,
|
||||||
ast::BinaryOperator::BitshiftLeft => mir::BinaryOperator::BitshiftLeft,
|
ast::BinaryOperator::BitshiftLeft => mir::BinaryOperator::BitshiftLeft,
|
||||||
ast::BinaryOperator::Xor => mir::BinaryOperator::Xor,
|
ast::BinaryOperator::Xor => mir::BinaryOperator::Xor,
|
||||||
ast::BinaryOperator::BWAnd => mir::BinaryOperator::BitwiseAnd,
|
ast::BinaryOperator::BWAnd => mir::BinaryOperator::BitAnd,
|
||||||
ast::BinaryOperator::BWOr => mir::BinaryOperator::BitwiseOr,
|
ast::BinaryOperator::BWOr => mir::BinaryOperator::BitOr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::ops::BitAnd;
|
||||||
|
|
||||||
use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type};
|
use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type};
|
||||||
|
|
||||||
use crate::{
|
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
|
fn boolean_binop_def<T: Clone + 'static>(op: BinaryOperator, ty: &TypeKind, fun: T) -> BinopDefinition
|
||||||
where
|
where
|
||||||
T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue,
|
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| {
|
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::LE), &ty, |scope, lhs, rhs| {
|
||||||
scope.block.build(Instr::ICmp(CmpPredicate::LE, lhs, rhs)).unwrap()
|
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]) {
|
for ty in INTEGERS.iter().chain(&[TypeKind::Bool, TypeKind::Char]) {
|
||||||
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::EQ), &ty, |scope, lhs, rhs| {
|
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| {
|
intrinsics.push(boolean_binop_def(And, &TypeKind::Bool, |scope, lhs, rhs| {
|
||||||
scope.block.build(Instr::And(lhs, rhs)).unwrap()
|
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
|
intrinsics
|
||||||
}
|
}
|
||||||
|
@ -893,14 +893,14 @@ impl mir::Expression {
|
|||||||
(mir::BinaryOperator::Xor, true, false) => todo!(),
|
(mir::BinaryOperator::Xor, true, false) => todo!(),
|
||||||
(mir::BinaryOperator::Xor, false, true) => todo!(),
|
(mir::BinaryOperator::Xor, false, true) => todo!(),
|
||||||
(mir::BinaryOperator::Xor, false, false) => todo!(),
|
(mir::BinaryOperator::Xor, false, false) => todo!(),
|
||||||
(mir::BinaryOperator::BitwiseOr, true, true) => todo!(),
|
(mir::BinaryOperator::BitOr, true, true) => todo!(),
|
||||||
(mir::BinaryOperator::BitwiseOr, true, false) => todo!(),
|
(mir::BinaryOperator::BitOr, true, false) => todo!(),
|
||||||
(mir::BinaryOperator::BitwiseOr, false, true) => todo!(),
|
(mir::BinaryOperator::BitOr, false, true) => todo!(),
|
||||||
(mir::BinaryOperator::BitwiseOr, false, false) => todo!(),
|
(mir::BinaryOperator::BitOr, false, false) => todo!(),
|
||||||
(mir::BinaryOperator::BitwiseAnd, true, true) => todo!(),
|
(mir::BinaryOperator::BitAnd, true, true) => todo!(),
|
||||||
(mir::BinaryOperator::BitwiseAnd, true, false) => todo!(),
|
(mir::BinaryOperator::BitAnd, true, false) => todo!(),
|
||||||
(mir::BinaryOperator::BitwiseAnd, false, true) => todo!(),
|
(mir::BinaryOperator::BitAnd, false, true) => todo!(),
|
||||||
(mir::BinaryOperator::BitwiseAnd, false, false) => todo!(),
|
(mir::BinaryOperator::BitAnd, false, false) => todo!(),
|
||||||
(mir::BinaryOperator::BitshiftRight, true, true) => todo!(),
|
(mir::BinaryOperator::BitshiftRight, true, true) => todo!(),
|
||||||
(mir::BinaryOperator::BitshiftRight, true, false) => todo!(),
|
(mir::BinaryOperator::BitshiftRight, true, false) => todo!(),
|
||||||
(mir::BinaryOperator::BitshiftRight, false, true) => todo!(),
|
(mir::BinaryOperator::BitshiftRight, false, true) => todo!(),
|
||||||
|
@ -354,8 +354,8 @@ impl Display for BinaryOperator {
|
|||||||
BinaryOperator::Mod => write!(f, "%"),
|
BinaryOperator::Mod => write!(f, "%"),
|
||||||
BinaryOperator::Or => write!(f, "||"),
|
BinaryOperator::Or => write!(f, "||"),
|
||||||
BinaryOperator::Xor => write!(f, "^"),
|
BinaryOperator::Xor => write!(f, "^"),
|
||||||
BinaryOperator::BitwiseOr => write!(f, "|"),
|
BinaryOperator::BitOr => write!(f, "|"),
|
||||||
BinaryOperator::BitwiseAnd => write!(f, "&"),
|
BinaryOperator::BitAnd => write!(f, "&"),
|
||||||
BinaryOperator::BitshiftRight => write!(f, ">>"),
|
BinaryOperator::BitshiftRight => write!(f, ">>"),
|
||||||
BinaryOperator::BitshiftLeft => write!(f, "<<"),
|
BinaryOperator::BitshiftLeft => write!(f, "<<"),
|
||||||
}
|
}
|
||||||
|
@ -208,8 +208,8 @@ impl BinaryOperator {
|
|||||||
},
|
},
|
||||||
BinaryOperator::Or => true,
|
BinaryOperator::Or => true,
|
||||||
BinaryOperator::Xor => true,
|
BinaryOperator::Xor => true,
|
||||||
BinaryOperator::BitwiseOr => true,
|
BinaryOperator::BitOr => true,
|
||||||
BinaryOperator::BitwiseAnd => true,
|
BinaryOperator::BitAnd => true,
|
||||||
BinaryOperator::BitshiftRight => false,
|
BinaryOperator::BitshiftRight => false,
|
||||||
BinaryOperator::BitshiftLeft => false,
|
BinaryOperator::BitshiftLeft => false,
|
||||||
}
|
}
|
||||||
@ -481,8 +481,8 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
BinaryOperator::Or => None,
|
BinaryOperator::Or => None,
|
||||||
BinaryOperator::Xor => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a ^ b),
|
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::BitOr => 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::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::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),
|
BinaryOperator::BitshiftLeft => maybe(lhs.num_value()?, rhs.num_value()?, |a, b| a << b),
|
||||||
},
|
},
|
||||||
|
@ -224,8 +224,8 @@ pub enum BinaryOperator {
|
|||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
Xor,
|
Xor,
|
||||||
BitwiseOr,
|
BitOr,
|
||||||
BitwiseAnd,
|
BitAnd,
|
||||||
BitshiftRight,
|
BitshiftRight,
|
||||||
BitshiftLeft,
|
BitshiftLeft,
|
||||||
Cmp(CmpOperator),
|
Cmp(CmpOperator),
|
||||||
|
Loading…
Reference in New Issue
Block a user