Implement overflowing_* and *_with_overflowing

This commit is contained in:
bjorn3 2018-08-08 09:49:42 +02:00
parent 0f73b8fb4c
commit 018612cf22
2 changed files with 62 additions and 1 deletions

View File

@ -411,6 +411,66 @@ pub fn codegen_call<'a, 'tcx: 'a>(
};
ret.write_cvalue(fx, res);
}
_ if intrinsic.ends_with("_with_overflow") => {
assert_eq!(args.len(), 2);
assert_eq!(args[0].layout().ty, args[1].layout().ty);
let bin_op = match intrinsic {
"add_with_overflow" => BinOp::Add,
"sub_with_overflow" => BinOp::Sub,
"mul_with_overflow" => BinOp::Mul,
_ => unimplemented!("intrinsic {}", intrinsic),
};
let res = match args[0].layout().ty.sty {
TypeVariants::TyUint(_) => crate::base::trans_checked_int_binop(
fx,
bin_op,
args[0],
args[1],
ret.layout().ty,
false,
),
TypeVariants::TyInt(_) => crate::base::trans_checked_int_binop(
fx,
bin_op,
args[0],
args[1],
ret.layout().ty,
true,
),
_ => panic!(),
};
ret.write_cvalue(fx, res);
}
_ if intrinsic.starts_with("overflowing_") => {
assert_eq!(args.len(), 2);
assert_eq!(args[0].layout().ty, args[1].layout().ty);
let bin_op = match intrinsic {
"overflowing_add" => BinOp::Add,
"overflowing_sub" => BinOp::Sub,
"overflowing_mul" => BinOp::Mul,
_ => unimplemented!("intrinsic {}", intrinsic),
};
let res = match args[0].layout().ty.sty {
TypeVariants::TyUint(_) => crate::base::trans_int_binop(
fx,
bin_op,
args[0],
args[1],
ret.layout().ty,
false,
),
TypeVariants::TyInt(_) => crate::base::trans_int_binop(
fx,
bin_op,
args[0],
args[1],
ret.layout().ty,
true,
),
_ => panic!(),
};
ret.write_cvalue(fx, res);
}
"offset" => {
assert_eq!(args.len(), 2);
let base = args[0].load_value(fx);

View File

@ -621,7 +621,7 @@ pub fn trans_int_binop<'a, 'tcx: 'a>(
}
}
fn trans_checked_int_binop<'a, 'tcx: 'a>(
pub fn trans_checked_int_binop<'a, 'tcx: 'a>(
fx: &mut FunctionCx<'a, 'tcx>,
bin_op: BinOp,
lhs: CValue<'tcx>,
@ -661,6 +661,7 @@ fn trans_checked_int_binop<'a, 'tcx: 'a>(
Offset (_) bug;
};
// TODO: check for overflow
let has_overflow = CValue::const_val(fx, fx.tcx.types.bool, 0);
let out_place = CPlace::temp(fx, out_ty);