]> git.lizzy.rs Git - rust.git/commitdiff
Implement overflowing_* and *_with_overflowing
authorbjorn3 <bjorn3@users.noreply.github.com>
Wed, 8 Aug 2018 07:49:42 +0000 (09:49 +0200)
committerbjorn3 <bjorn3@users.noreply.github.com>
Wed, 8 Aug 2018 07:49:42 +0000 (09:49 +0200)
src/abi.rs
src/base.rs

index c1097864bf0c5f0e305963a6b84bd1a66a0d6c49..85c6ff1e0123bdd92724abaea49bfdddca3deb61 100644 (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);
index 9d09409aa9ef23ecf8557a8e9dc77b44727c3ca7..c61e5e39c6ed972228f2cd58387417f9cc83388f 100644 (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);