Skip to content

Commit 0980596

Browse files
committed
Extract codegen_saturating_int_binop function
1 parent f200fbc commit 0980596

File tree

2 files changed

+37
-31
lines changed

2 files changed

+37
-31
lines changed

src/intrinsics/mod.rs

+1-31
Original file line numberDiff line numberDiff line change
@@ -507,37 +507,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
507507
_ => unreachable!(),
508508
};
509509

510-
let signed = type_sign(lhs.layout().ty);
511-
512-
let checked_res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs);
513-
514-
let (val, has_overflow) = checked_res.load_scalar_pair(fx);
515-
let clif_ty = fx.clif_type(lhs.layout().ty).unwrap();
516-
517-
let (min, max) = type_min_max_value(&mut fx.bcx, clif_ty, signed);
518-
519-
let val = match (intrinsic, signed) {
520-
(sym::saturating_add, false) => fx.bcx.ins().select(has_overflow, max, val),
521-
(sym::saturating_sub, false) => fx.bcx.ins().select(has_overflow, min, val),
522-
(sym::saturating_add, true) => {
523-
let rhs = rhs.load_scalar(fx);
524-
let rhs_ge_zero =
525-
fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
526-
let sat_val = fx.bcx.ins().select(rhs_ge_zero, max, min);
527-
fx.bcx.ins().select(has_overflow, sat_val, val)
528-
}
529-
(sym::saturating_sub, true) => {
530-
let rhs = rhs.load_scalar(fx);
531-
let rhs_ge_zero =
532-
fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
533-
let sat_val = fx.bcx.ins().select(rhs_ge_zero, min, max);
534-
fx.bcx.ins().select(has_overflow, sat_val, val)
535-
}
536-
_ => unreachable!(),
537-
};
538-
539-
let res = CValue::by_val(val, lhs.layout());
540-
510+
let res = crate::num::codegen_saturating_int_binop(fx, bin_op, lhs, rhs);
541511
ret.write_cvalue(fx, res);
542512
}
543513
sym::rotate_left => {

src/num.rs

+36
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,42 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
309309
CValue::by_val_pair(res, has_overflow, out_layout)
310310
}
311311

312+
pub(crate) fn codegen_saturating_int_binop<'tcx>(
313+
fx: &mut FunctionCx<'_, '_, 'tcx>,
314+
bin_op: BinOp,
315+
lhs: CValue<'tcx>,
316+
rhs: CValue<'tcx>,
317+
) -> CValue<'tcx> {
318+
assert_eq!(lhs.layout().ty, rhs.layout().ty);
319+
320+
let signed = type_sign(lhs.layout().ty);
321+
let clif_ty = fx.clif_type(lhs.layout().ty).unwrap();
322+
let (min, max) = type_min_max_value(&mut fx.bcx, clif_ty, signed);
323+
324+
let checked_res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs);
325+
let (val, has_overflow) = checked_res.load_scalar_pair(fx);
326+
327+
let val = match (bin_op, signed) {
328+
(BinOp::Add, false) => fx.bcx.ins().select(has_overflow, max, val),
329+
(BinOp::Sub, false) => fx.bcx.ins().select(has_overflow, min, val),
330+
(BinOp::Add, true) => {
331+
let rhs = rhs.load_scalar(fx);
332+
let rhs_ge_zero = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
333+
let sat_val = fx.bcx.ins().select(rhs_ge_zero, max, min);
334+
fx.bcx.ins().select(has_overflow, sat_val, val)
335+
}
336+
(BinOp::Sub, true) => {
337+
let rhs = rhs.load_scalar(fx);
338+
let rhs_ge_zero = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
339+
let sat_val = fx.bcx.ins().select(rhs_ge_zero, min, max);
340+
fx.bcx.ins().select(has_overflow, sat_val, val)
341+
}
342+
_ => unreachable!(),
343+
};
344+
345+
CValue::by_val(val, lhs.layout())
346+
}
347+
312348
pub(crate) fn codegen_float_binop<'tcx>(
313349
fx: &mut FunctionCx<'_, '_, 'tcx>,
314350
bin_op: BinOp,

0 commit comments

Comments
 (0)