Skip to content

Commit 3fcd540

Browse files
committed
Implement saturating_{add,sub} intrinsics
1 parent f99d31d commit 3fcd540

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

example/std_example.rs

+5
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ fn main() {
3838
assert_eq!(2.3f32.copysign(-1.0), -2.3f32);
3939
println!("{}", 2.3f32.powf(2.0));
4040

41+
assert_eq!(-128i8, (-128i8).saturating_sub(1));
42+
assert_eq!(127i8, 127i8.saturating_sub(-128));
43+
assert_eq!(-128i8, (-128i8).saturating_add(-128));
44+
assert_eq!(127i8, 127i8.saturating_add(1));
45+
4146
assert_eq!(0b0000000000000000000000000010000010000000000000000000000000000000_0000000000100000000000000000000000001000000000000100000000000000u128.leading_zeros(), 26);
4247
assert_eq!(0b0000000000000000000000000010000000000000000000000000000000000000_0000000000000000000000000000000000001000000000000000000010000000u128.trailing_zeros(), 7);
4348

src/intrinsics.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,8 @@ pub fn codegen_intrinsic_call<'tcx>(
487487
);
488488
ret.write_cvalue(fx, res);
489489
};
490-
_ if intrinsic.starts_with("saturating_"), <T> (c x, c y) {
491-
assert_eq!(x.layout().ty, y.layout().ty);
490+
_ if intrinsic.starts_with("saturating_"), <T> (c lhs, c rhs) {
491+
assert_eq!(lhs.layout().ty, rhs.layout().ty);
492492
let bin_op = match intrinsic {
493493
"saturating_add" => BinOp::Add,
494494
"saturating_sub" => BinOp::Sub,
@@ -500,8 +500,8 @@ pub fn codegen_intrinsic_call<'tcx>(
500500
let checked_res = crate::num::trans_checked_int_binop(
501501
fx,
502502
bin_op,
503-
x,
504-
y,
503+
lhs,
504+
rhs,
505505
);
506506

507507
let (val, has_overflow) = checked_res.load_scalar_pair(fx);
@@ -517,8 +517,18 @@ pub fn codegen_intrinsic_call<'tcx>(
517517
let val = match (intrinsic, signed) {
518518
("saturating_add", false) => codegen_select(&mut fx.bcx, has_overflow, max, val),
519519
("saturating_sub", false) => codegen_select(&mut fx.bcx, has_overflow, min, val),
520-
("saturating_add", true) => unimplemented!(),
521-
("saturating_sub", true) => unimplemented!(),
520+
("saturating_add", true) => {
521+
let rhs = rhs.load_scalar(fx);
522+
let rhs_ge_zero = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
523+
let sat_val = codegen_select(&mut fx.bcx, rhs_ge_zero, max, min);
524+
codegen_select(&mut fx.bcx, has_overflow, sat_val, val)
525+
}
526+
("saturating_sub", true) => {
527+
let rhs = rhs.load_scalar(fx);
528+
let rhs_ge_zero = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
529+
let sat_val = codegen_select(&mut fx.bcx, rhs_ge_zero, min, max);
530+
codegen_select(&mut fx.bcx, has_overflow, sat_val, val)
531+
}
522532
_ => unreachable!(),
523533
};
524534

0 commit comments

Comments
 (0)