Skip to content

Commit

Permalink
Implement saturating_{add,sub} intrinsics
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorn3 committed Aug 20, 2019
1 parent f99d31d commit 3fcd540
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
5 changes: 5 additions & 0 deletions example/std_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ fn main() {
assert_eq!(2.3f32.copysign(-1.0), -2.3f32);
println!("{}", 2.3f32.powf(2.0));

assert_eq!(-128i8, (-128i8).saturating_sub(1));
assert_eq!(127i8, 127i8.saturating_sub(-128));
assert_eq!(-128i8, (-128i8).saturating_add(-128));
assert_eq!(127i8, 127i8.saturating_add(1));

assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26);
assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7);

Expand Down
22 changes: 16 additions & 6 deletions src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,8 @@ pub fn codegen_intrinsic_call<'tcx>(
);
ret.write_cvalue(fx, res);
};
_ if intrinsic.starts_with("saturating_"), <T> (c x, c y) {
assert_eq!(x.layout().ty, y.layout().ty);
_ if intrinsic.starts_with("saturating_"), <T> (c lhs, c rhs) {
assert_eq!(lhs.layout().ty, rhs.layout().ty);
let bin_op = match intrinsic {
"saturating_add" => BinOp::Add,
"saturating_sub" => BinOp::Sub,
Expand All @@ -500,8 +500,8 @@ pub fn codegen_intrinsic_call<'tcx>(
let checked_res = crate::num::trans_checked_int_binop(
fx,
bin_op,
x,
y,
lhs,
rhs,
);

let (val, has_overflow) = checked_res.load_scalar_pair(fx);
Expand All @@ -517,8 +517,18 @@ pub fn codegen_intrinsic_call<'tcx>(
let val = match (intrinsic, signed) {
("saturating_add", false) => codegen_select(&mut fx.bcx, has_overflow, max, val),
("saturating_sub", false) => codegen_select(&mut fx.bcx, has_overflow, min, val),
("saturating_add", true) => unimplemented!(),
("saturating_sub", true) => unimplemented!(),
("saturating_add", true) => {
let rhs = rhs.load_scalar(fx);
let rhs_ge_zero = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
let sat_val = codegen_select(&mut fx.bcx, rhs_ge_zero, max, min);
codegen_select(&mut fx.bcx, has_overflow, sat_val, val)
}
("saturating_sub", true) => {
let rhs = rhs.load_scalar(fx);
let rhs_ge_zero = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
let sat_val = codegen_select(&mut fx.bcx, rhs_ge_zero, min, max);
codegen_select(&mut fx.bcx, has_overflow, sat_val, val)
}
_ => unreachable!(),
};

Expand Down

0 comments on commit 3fcd540

Please sign in to comment.