about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorest31 <MTest31@outlook.com>2016-12-08 19:02:22 +0100
committerest31 <MTest31@outlook.com>2016-12-30 15:17:28 +0100
commit53ff50a94f083ec44bd6f6cb56ded6c52fcc7b8a (patch)
treecd2e2402ca74207072d4454188391b22ba2433a2 /src
parent3be141f1b46be54607277444956a211ee56a359c (diff)
downloadrust-53ff50a94f083ec44bd6f6cb56ded6c52fcc7b8a.tar.gz
rust-53ff50a94f083ec44bd6f6cb56ded6c52fcc7b8a.zip
Port to wrapping_* and unchecked_* operations
Otherwise, we codegen panic calls which create problems with debug assertions turned on.
Diffstat (limited to 'src')
-rw-r--r--src/libcompiler_builtins/lib.rs196
1 files changed, 118 insertions, 78 deletions
diff --git a/src/libcompiler_builtins/lib.rs b/src/libcompiler_builtins/lib.rs
index 818d7fb86c0..8d124b7e0aa 100644
--- a/src/libcompiler_builtins/lib.rs
+++ b/src/libcompiler_builtins/lib.rs
@@ -50,13 +50,17 @@ pub mod reimpls {
         ($a:expr, $b:expr, $ty:ty) => {{
             let (a, b) = ($a, $b);
             let bits = (::core::mem::size_of::<$ty>() * 8) as $ty;
-            let half_bits = bits / 2;
+            let half_bits = bits >> 1;
             if b & half_bits != 0 {
-                <$ty>::from_parts(0, a.low() << (b - half_bits))
+                <$ty>::from_parts(0, a.low().wrapping_shl(
+                                        b.wrapping_sub(half_bits) as u32))
             } else if b == 0 {
                 a
             } else {
-                <$ty>::from_parts(a.low() << b, (a.high() << b) | (a.low() >> (half_bits - b)))
+                <$ty>::from_parts(a.low().wrapping_shl(b as u32),
+                                  a.high().wrapping_shl(b as u32)
+                                  | a.low()
+                                     .wrapping_shr(half_bits.wrapping_sub(b) as u32))
             }
         }}
     }
@@ -72,14 +76,16 @@ pub mod reimpls {
             let bits = (::core::mem::size_of::<$ty>() * 8) as $ty;
             let half_bits = bits >> 1;
             if b & half_bits != 0 {
-                <$ty>::from_parts((a.high() >> (b - half_bits)) as <$ty as LargeInt>::LowHalf,
-                                  a.high() >> (half_bits - 1))
+                <$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32)
+                                  as <$ty as LargeInt>::LowHalf,
+                                  a.high().wrapping_shr(half_bits.wrapping_sub(1) as u32))
             } else if b == 0 {
                 a
             } else {
                 let high_unsigned = a.high() as <$ty as LargeInt>::LowHalf;
-                <$ty>::from_parts((high_unsigned << (half_bits - b)) | (a.low() >> b),
-                                  a.high() >> b)
+                <$ty>::from_parts(high_unsigned.wrapping_shl(half_bits.wrapping_sub(b) as u32)
+                                  | a.low().wrapping_shr(b as u32),
+                                  a.high().wrapping_shr(b as u32))
             }
         }}
     }
@@ -95,11 +101,13 @@ pub mod reimpls {
             let bits = (::core::mem::size_of::<$ty>() * 8) as $ty;
             let half_bits = bits >> 1;
             if b & half_bits != 0 {
-                <$ty>::from_parts(a.high() >> (b - half_bits), 0)
+                <$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32), 0)
             } else if b == 0 {
                 a
             } else {
-                <$ty>::from_parts((a.high() << (half_bits - b)) | (a.low() >> b), a.high() >> b)
+                <$ty>::from_parts(a.high().wrapping_shl(half_bits.wrapping_sub(b) as u32)
+                                  | a.low().wrapping_shr(b as u32),
+                                  a.high().wrapping_shr(b as u32))
             }
         }}
     }
@@ -178,9 +186,10 @@ pub mod reimpls {
 
             if d.high().is_power_of_two() {
                 if !rem.is_null() {
-                    *rem = u128::from_parts(n.low(), n.high() & (d.high() - 1));
+                    *rem = u128::from_parts(n.low(),
+                                            n.high() & (d.high().wrapping_sub(1)));
                 }
-                return u128::from(n.high() >> d.high().trailing_zeros());
+                return u128::from(n.high().wrapping_shr(d.high().trailing_zeros()));
             }
 
             // K K
@@ -196,11 +205,11 @@ pub mod reimpls {
                 return 0;
             }
 
-            sr += 1;
+            sr = sr.wrapping_add(1);
 
             // 1 <= sr <= u64::bits() - 1
-            q = n << (64 - sr);
-            r = n >> sr;
+            q = n.wrapping_shl(64u32.wrapping_sub(sr));
+            r = n.wrapping_shr(sr);
         } else {
             if d.high() == 0 {
                 // K X
@@ -208,22 +217,24 @@ pub mod reimpls {
                 // 0 K
                 if d.low().is_power_of_two() {
                     if !rem.is_null() {
-                        *rem = u128::from(n.low() & (d.low() - 1));
+                        *rem = u128::from(n.low() & (d.low().wrapping_sub(1)));
                     }
 
                     if d.low() == 1 {
                         return n;
                     } else {
                         let sr = d.low().trailing_zeros();
-                        return n >> sr;
+                        return n.wrapping_shr(sr);
                     };
                 }
 
-                sr = 1 + 64 + d.low().leading_zeros() - n.high().leading_zeros();
+                sr = (1 + 64u32)
+                    .wrapping_add(d.low().leading_zeros())
+                    .wrapping_sub(n.high().leading_zeros());
 
                 // 2 <= sr <= u64::bits() - 1
-                q = n << (128 - sr);
-                r = n >> sr;
+                q = n.wrapping_shl(128u32.wrapping_sub(sr));
+                r = n.wrapping_shr(sr);
                 // FIXME the C compiler-rt implementation has something here
                 // that looks like a speed optimisation.
                 // It would be worth a try to port it to Rust too and
@@ -242,11 +253,11 @@ pub mod reimpls {
                     return 0;
                 }
 
-                sr += 1;
+                sr = sr.wrapping_add(1);
 
                 // 1 <= sr <= u32::bits()
-                q = n << (128 - sr);
-                r = n >> sr;
+                q = n.wrapping_shl(128u32.wrapping_sub(sr));
+                r = n.wrapping_shr(sr);
             }
         }
 
@@ -264,24 +275,24 @@ pub mod reimpls {
         // compilation steps)
         while sr > 0 {
             // r:q = ((r:q) << 1) | carry
-            r = (r << 1) | (q >> (128 - 1));
-            q = (q << 1) | carry as u128;
+            r = r.wrapping_shl(1) | q.wrapping_shr(128 - 1);
+            q = q.wrapping_shl(1) | carry as u128;
 
             // carry = 0
             // if r >= d {
             //     r -= d;
             //     carry = 1;
             // }
-            let s = (d.wrapping_sub(r).wrapping_sub(1)) as i128 >> (128 - 1);
+            let s = ((d.wrapping_sub(r).wrapping_sub(1)) as i128).wrapping_shr(128 - 1);
             carry = (s & 1) as u64;
-            r -= d & s as u128;
-            sr -= 1;
+            r = r.wrapping_sub(d & s as u128);
+            sr = sr.wrapping_sub(1);
         }
 
         if !rem.is_null() {
             *rem = r;
         }
-        (q << 1) | carry as u128
+        (q.wrapping_shl(1)) | carry as u128
         }
     }
 
@@ -302,7 +313,7 @@ pub mod reimpls {
         unsafe {
             let mut r = ::core::mem::zeroed();
             u128_div_mod(a, b, &mut r);
-            if sa == -1 { -(r as i128_) } else { r as i128_ }
+            if sa == -1 { (r as i128_).unchecked_neg() } else { r as i128_ }
         }
     }
 
@@ -312,9 +323,9 @@ pub mod reimpls {
         let sb = b.signum();
         let a = a.uabs();
         let b = b.uabs();
-        let sr = sa * sb; // sign of quotient
+        let sr = sa.wrapping_mul(sb); // sign of quotient
         if sr == -1 {
-            -(u128_div_mod(a, b, ptr::null_mut()) as i128_)
+            (u128_div_mod(a, b, ptr::null_mut()) as i128_).unchecked_neg()
         } else {
             u128_div_mod(a, b, ptr::null_mut()) as i128_
         }
@@ -356,7 +367,7 @@ pub mod reimpls {
                     *overflow = 1;
                 }
             } else {
-                if abs_a > unchecked_div(<$ty>::min_value(), -abs_b) {
+                if abs_a > unchecked_div(<$ty>::min_value(), abs_b.unchecked_neg()) {
                     *overflow = 1;
                 }
             }
@@ -387,10 +398,10 @@ pub mod reimpls {
             self as u32
         }
         fn high(self) -> u32 {
-            (self >> 32) as u32
+            (self.wrapping_shr(32)) as u32
         }
         fn from_parts(low: u32, high: u32) -> u64 {
-            low as u64 | ((high as u64) << 32)
+            low as u64 | (high as u64).wrapping_shl(32)
         }
     }
     impl LargeInt for i64 {
@@ -401,10 +412,10 @@ pub mod reimpls {
             self as u32
         }
         fn high(self) -> i32 {
-            (self >> 32) as i32
+            self.wrapping_shr(32) as i32
         }
         fn from_parts(low: u32, high: i32) -> i64 {
-            low as i64 | ((high as i64) << 32)
+            low as i64 | (high as i64).wrapping_shl(32)
         }
     }
     #[cfg(not(stage0))]
@@ -442,20 +453,23 @@ pub mod reimpls {
     macro_rules! mul {
         ($a:expr, $b:expr, $ty: ty, $tyh: ty) => {{
             let (a, b) = ($a, $b);
-            let half_bits = (::core::mem::size_of::<$tyh>() * 8) / 2;
-            let lower_mask = !0 >> half_bits;
-            let mut low = (a.low() & lower_mask) * (b.low() & lower_mask);
-            let mut t = low >> half_bits;
+            let half_bits = ((::core::mem::size_of::<$tyh>() * 8) / 2) as u32;
+            let lower_mask = (!0u64).wrapping_shr(half_bits);
+            let mut low = (a.low() & lower_mask).wrapping_mul(b.low() & lower_mask);
+            let mut t = low.wrapping_shr(half_bits);
             low &= lower_mask;
-            t += (a.low() >> half_bits) * (b.low() & lower_mask);
-            low += (t & lower_mask) << half_bits;
-            let mut high = (t >> half_bits) as $tyh;
-            t = low >> half_bits;
+            t = t.wrapping_add(a.low().wrapping_shr(half_bits)
+                                      .wrapping_mul(b.low() & lower_mask));
+            low = low.wrapping_add((t & lower_mask).wrapping_shl(half_bits));
+            let mut high = t.wrapping_shr(half_bits) as $tyh;
+            t = low.wrapping_shr(half_bits);
             low &= lower_mask;
-            t += (b.low() >> half_bits) * (a.low() & lower_mask);
-            low += (t & lower_mask) << half_bits;
-            high += (t >> half_bits) as $tyh;
-            high += ((a.low() >> half_bits) * (b.low() >> half_bits)) as $tyh;
+            t = t.wrapping_add(b.low().wrapping_shr(half_bits)
+                                      .wrapping_mul(a.low() & lower_mask));
+            low = low.wrapping_add((t & lower_mask).wrapping_shl(half_bits));
+            high = high.wrapping_add(t.wrapping_shr(half_bits) as $tyh);
+            high = high.wrapping_add(a.low().wrapping_shr(half_bits)
+                           .wrapping_mul(b.low().wrapping_shr(half_bits)) as $tyh);
             high = high
                 .wrapping_add(a.high()
                 .wrapping_mul(b.low() as $tyh))
@@ -468,7 +482,7 @@ pub mod reimpls {
     #[cfg(stage0)]
     #[export_name="__multi3"]
     pub extern "C" fn u128_mul(a: i128_, b: i128_) -> i128_ {
-        (a as i64 * b as i64) as i128_
+        (a as i64).wrapping_mul(b as i64) as i128_
     }
 
     #[cfg(not(stage0))]
@@ -491,6 +505,16 @@ pub mod reimpls {
         }
     }
 
+    trait NegExt: Sized {
+        fn unchecked_neg(self) -> i128_;
+    }
+
+    impl NegExt for i128_ {
+        fn unchecked_neg(self) -> i128_ {
+            (!self).wrapping_add(1)
+        }
+    }
+
     trait FloatStuff: Sized {
         type ToBytes;
 
@@ -514,7 +538,8 @@ pub mod reimpls {
 
         fn to_bytes(self) -> u32 { unsafe { ::core::mem::transmute(self) } }
         fn get_exponent(self) -> i32 {
-            (((self.to_bytes() & Self::EXP_MASK) >> Self::MANTISSA_BITS) as i32) - Self::MAX_EXP
+            ((self.to_bytes() & Self::EXP_MASK).wrapping_shr(Self::MANTISSA_BITS) as i32)
+            .wrapping_sub(Self::MAX_EXP)
         }
     }
 
@@ -528,7 +553,8 @@ pub mod reimpls {
 
         fn to_bytes(self) -> u64 { unsafe { ::core::mem::transmute(self) } }
         fn get_exponent(self) -> i32 {
-            (((self.to_bytes() & Self::EXP_MASK) >> Self::MANTISSA_BITS) as i32) - Self::MAX_EXP
+            ((self.to_bytes() & Self::EXP_MASK).wrapping_shr(Self::MANTISSA_BITS) as i32)
+            .wrapping_sub(Self::MAX_EXP)
         }
     }
 
@@ -545,9 +571,11 @@ pub mod reimpls {
                 return !0;
             }
             if exponent < (<$fromty as FloatStuff>::MANTISSA_BITS) as i32 {
-                mantissa as $outty >> (<$fromty as FloatStuff>::MANTISSA_BITS as i32 - exponent)
+                (mantissa as $outty)
+                    .wrapping_shr((<$fromty as FloatStuff>::MANTISSA_BITS as i32).wrapping_sub(exponent) as u32)
             } else {
-                mantissa as $outty << (exponent - <$fromty as FloatStuff>::MANTISSA_BITS as i32)
+                (mantissa as $outty)
+                    .wrapping_shl(exponent.wrapping_sub(<$fromty as FloatStuff>::MANTISSA_BITS as i32) as u32)
             }
         } }
     }
@@ -576,11 +604,13 @@ pub mod reimpls {
                 return if sign > 0.0 { <$outty>::max_value() } else { <$outty>::min_value() };
             }
             let r = if exponent < (<$fromty as FloatStuff>::MANTISSA_BITS) as i32 {
-                mantissa as $outty >> (<$fromty as FloatStuff>::MANTISSA_BITS as i32 - exponent)
+                (mantissa as $outty)
+                    .wrapping_shr((<$fromty as FloatStuff>::MANTISSA_BITS as i32).wrapping_sub(exponent) as u32)
             } else {
-                mantissa as $outty << (exponent - <$fromty as FloatStuff>::MANTISSA_BITS as i32)
+                (mantissa as $outty)
+                    .wrapping_shl(exponent.wrapping_sub(<$fromty as FloatStuff>::MANTISSA_BITS as i32) as u32)
             };
-            if sign >= 0.0 { r } else { -r }
+            if sign >= 0.0 { r } else { r.unchecked_neg() }
         }}
     }
 
@@ -616,30 +646,35 @@ pub mod reimpls {
     pub extern "C" fn u128_as_f64(mut a: u128_) -> f64 {
         use ::core::f64::MANTISSA_DIGITS;
         if a == 0 { return 0.0; }
-        let sd = 128 - a.leading_zeros();
-        let mut e = sd - 1;
+        let sd = 128u32.wrapping_sub(a.leading_zeros());
+        let mut e = sd.wrapping_sub(1);
         const MD1 : u32 = MANTISSA_DIGITS + 1;
         const MD2 : u32 = MANTISSA_DIGITS + 2;
 
+        // SNAP: replace this with !0u128
+        let negn :u128_ = !0;
+
         if sd > MANTISSA_DIGITS {
             a = match sd {
-                MD1 => a << 1,
+                MD1 => a.wrapping_shl(1),
                 MD2 => a,
-                _ => (a >> (sd - (MANTISSA_DIGITS + 2))) |
-                     (if (a & (!0 >> (128 + MANTISSA_DIGITS + 2) - sd)) == 0 { 0 } else { 1 })
+                _ => a.wrapping_shr(sd.wrapping_sub(MANTISSA_DIGITS + 2)) |
+                     (if (a & (negn.wrapping_shr(128 + MANTISSA_DIGITS + 2)
+                                   .wrapping_sub(sd as u128_))) == 0 { 0 } else { 1 })
             };
             a |= if (a & 4) == 0 { 0 } else { 1 };
-            a += 1;
-            a >>= 2;
+            a = a.wrapping_add(1);
+            a = a.wrapping_shr(2);
             if a & (1 << MANTISSA_DIGITS) != 0 {
-                a >>= 1;
-                e += 1;
+                a = a.wrapping_shr(1);
+                e = e.wrapping_add(1);
             }
         } else {
-            a <<= MANTISSA_DIGITS - sd;
+            a = a.wrapping_shl(MANTISSA_DIGITS.wrapping_sub(sd));
         }
         unsafe {
-            ::core::mem::transmute(((e as u64 + 1023) << 52) | (a as u64 & 0x000f_ffff_ffff_ffff))
+            ::core::mem::transmute((e as u64).wrapping_add(1023).wrapping_shl(52)
+                                   | (a as u64 & 0x000f_ffff_ffff_ffff))
         }
     }
 
@@ -647,30 +682,35 @@ pub mod reimpls {
     pub extern "C" fn u128_as_f32(mut a: u128_) -> f32 {
         use ::core::f32::MANTISSA_DIGITS;
         if a == 0 { return 0.0; }
-        let sd = 128 - a.leading_zeros();
-        let mut e = sd - 1;
+        let sd = 128u32.wrapping_sub(a.leading_zeros());
+        let mut e = sd.wrapping_sub(1);
         const MD1 : u32 = MANTISSA_DIGITS + 1;
         const MD2 : u32 = MANTISSA_DIGITS + 2;
 
+        // SNAP: replace this with !0u128
+        let negn :u128_ = !0;
+
         if sd > MANTISSA_DIGITS {
             a = match sd {
-                MD1 => a << 1,
+                MD1 => a.wrapping_shl(1),
                 MD2 => a,
-                _ => (a >> (sd - (MANTISSA_DIGITS + 2))) |
-                     (if (a & (!0 >> (128 + MANTISSA_DIGITS + 2) - sd)) == 0 { 0 } else { 1 })
+                _ => a.wrapping_shr(sd.wrapping_sub(MANTISSA_DIGITS + 2)) |
+                     (if (a & (negn.wrapping_shr(128 + MANTISSA_DIGITS + 2)
+                                   .wrapping_sub(sd as u128_))) == 0 { 0 } else { 1 })
             };
             a |= if (a & 4) == 0 { 0 } else { 1 };
-            a += 1;
-            a >>= 2;
+            a = a.wrapping_add(1);
+            a = a.wrapping_shr(2);
             if a & (1 << MANTISSA_DIGITS) != 0 {
-                a >>= 1;
-                e += 1;
+                a = a.wrapping_shr(1);
+                e = e.wrapping_add(1);
             }
         } else {
-            a <<= MANTISSA_DIGITS - sd;
+            a = a.wrapping_shl(MANTISSA_DIGITS.wrapping_sub(sd));
         }
         unsafe {
-            ::core::mem::transmute(((e + 127) << 23) | (a as u32 & 0x007f_ffff))
+            ::core::mem::transmute((e as u32).wrapping_add(127).wrapping_shl(23)
+                                   | (a as u32 & 0x007f_ffff))
         }
     }
 }