1 use rustc::mir::repr as mir;
3 use error::{EvalError, EvalResult};
6 #[derive(Clone, Copy, Debug, PartialEq)]
9 I8(i8), I16(i16), I32(i32), I64(i64),
10 U8(u8), U16(u16), U32(u32), U64(u64),
16 pub fn binary_op<'tcx>(bin_op: mir::BinOp, left: PrimVal, right: PrimVal) -> EvalResult<'tcx, PrimVal> {
17 use rustc::mir::repr::BinOp::*;
20 macro_rules! int_binops {
21 ($v:ident, $l:ident, $r:ident) => ({
28 BitXor => $v($l ^ $r),
29 BitAnd => $v($l & $r),
32 // TODO(solson): Can have differently-typed RHS.
46 fn unrelated_ptr_ops<'tcx>(bin_op: mir::BinOp) -> EvalResult<'tcx, PrimVal> {
47 use rustc::mir::repr::BinOp::*;
49 Eq => Ok(Bool(false)),
51 Lt | Le | Gt | Ge => Err(EvalError::InvalidPointerMath),
52 _ => unimplemented!(),
56 let val = match (left, right) {
57 (I8(l), I8(r)) => int_binops!(I8, l, r),
58 (I16(l), I16(r)) => int_binops!(I16, l, r),
59 (I32(l), I32(r)) => int_binops!(I32, l, r),
60 (I64(l), I64(r)) => int_binops!(I64, l, r),
61 (U8(l), U8(r)) => int_binops!(U8, l, r),
62 (U16(l), U16(r)) => int_binops!(U16, l, r),
63 (U32(l), U32(r)) => int_binops!(U32, l, r),
64 (U64(l), U64(r)) => int_binops!(U64, l, r),
66 (Bool(l), Bool(r)) => {
77 Add | Sub | Mul | Div | Rem | Shl | Shr => return Err(EvalError::InvalidBoolOp(bin_op)),
81 (IntegerPtr(l), IntegerPtr(r)) => int_binops!(IntegerPtr, l, r),
83 (AbstractPtr(_), IntegerPtr(_)) | (IntegerPtr(_), AbstractPtr(_)) =>
84 return unrelated_ptr_ops(bin_op),
86 (AbstractPtr(l_ptr), AbstractPtr(r_ptr)) => {
87 if l_ptr.alloc_id != r_ptr.alloc_id {
88 return unrelated_ptr_ops(bin_op);
101 _ => return Err(EvalError::Unimplemented(format!("unimplemented ptr op: {:?}", bin_op))),
105 (l, r) => return Err(EvalError::Unimplemented(format!("unimplemented binary op: {:?}, {:?}, {:?}", l, r, bin_op))),
111 pub fn unary_op<'tcx>(un_op: mir::UnOp, val: PrimVal) -> EvalResult<'tcx, PrimVal> {
112 use rustc::mir::repr::UnOp::*;
113 use self::PrimVal::*;
115 (Not, Bool(b)) => Ok(Bool(!b)),
116 (Not, I8(n)) => Ok(I8(!n)),
117 (Neg, I8(n)) => Ok(I8(-n)),
118 (Not, I16(n)) => Ok(I16(!n)),
119 (Neg, I16(n)) => Ok(I16(-n)),
120 (Not, I32(n)) => Ok(I32(!n)),
121 (Neg, I32(n)) => Ok(I32(-n)),
122 (Not, I64(n)) => Ok(I64(!n)),
123 (Neg, I64(n)) => Ok(I64(-n)),
124 (Not, U8(n)) => Ok(U8(!n)),
125 (Not, U16(n)) => Ok(U16(!n)),
126 (Not, U32(n)) => Ok(U32(!n)),
127 (Not, U64(n)) => Ok(U64(!n)),
128 _ => Err(EvalError::Unimplemented(format!("unimplemented unary op: {:?}, {:?}", un_op, val))),