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::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, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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!(), | ||||
|  | ||||
| @ -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, "<<"), | ||||
|         } | ||||
|  | ||||
| @ -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), | ||||
|             }, | ||||
|  | ||||
| @ -224,8 +224,8 @@ pub enum BinaryOperator { | ||||
|     And, | ||||
|     Or, | ||||
|     Xor, | ||||
|     BitwiseOr, | ||||
|     BitwiseAnd, | ||||
|     BitOr, | ||||
|     BitAnd, | ||||
|     BitshiftRight, | ||||
|     BitshiftLeft, | ||||
|     Cmp(CmpOperator), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user