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