implement bit masks as the compiler would translate them

This commit is contained in:
Oliver Schneider 2016-06-20 17:16:45 +02:00
parent 0821a15476
commit 3e3aeab0ed
No known key found for this signature in database
GPG Key ID: 56D6EEA0FC67AC46
2 changed files with 20 additions and 9 deletions

View File

@ -69,7 +69,7 @@ impl<'tcx> Error for EvalError<'tcx> {
EvalError::Math(..) =>
"mathematical operation failed",
EvalError::InvalidBitShiftRhs(..) =>
"bit shift rhs negative or not an int",
"bit shift rhs not an int",
}
}

View File

@ -69,15 +69,26 @@ pub fn binary_op<'tcx>(bin_op: mir::BinOp, left: PrimVal, right: PrimVal) -> Eva
match bin_op {
// can have rhs with a different numeric type
Shl | Shr => {
let mask_bits = match left {
I8(_) => 3,
I16(_) => 4,
I32(_) => 5,
I64(_) => 6,
U8(_) => 3,
U16(_) => 4,
U32(_) => 5,
U64(_) => 6,
_ => unreachable!(),
};
let r = match right {
I8(i) if i >= 0 => i as u32,
I16(i) if i >= 0 => i as u32,
I32(i) if i >= 0 => i as u32,
I64(i) if i >= 0 && i as i32 as i64 == i => i as u32,
U8(i) => i as u32,
U16(i) => i as u32,
U32(i) => i,
U64(i) if i as u32 as u64 == i => i as u32,
I8(i) => (i & ((1 << mask_bits) - 1)) as u32,
I16(i) => (i & ((1 << mask_bits) - 1)) as u32,
I32(i) => (i & ((1 << mask_bits) - 1)) as u32,
I64(i) => (i & ((1 << mask_bits) - 1)) as u32,
U8(i) => (i & ((1 << mask_bits) - 1)) as u32,
U16(i) => (i & ((1 << mask_bits) - 1)) as u32,
U32(i) => (i & ((1 << mask_bits) - 1)) as u32,
U64(i) => (i & ((1 << mask_bits) - 1)) as u32,
_ => return Err(EvalError::InvalidBitShiftRhs(right)),
};
macro_rules! shift {