[PPL-devel] [GIT] ppl/ppl(master): Avoided user defined and implementation define behaviors of left and right shift .

Abramo Bagnara abramo.bagnara at bugseng.com
Sat Aug 25 11:46:11 CEST 2012


Module: ppl/ppl
Branch: master
Commit: 685ee646b27f9f757e912ff3ae53610332292c35
URL:    http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=685ee646b27f9f757e912ff3ae53610332292c35

Author: Abramo Bagnara <abramo.bagnara at bugseng.com>
Date:   Sat Aug 25 11:46:06 2012 +0200

Avoided user defined and implementation define behaviors of left and right shift.

---

 src/checked_int_inlines.hh |  113 +++++++++++++++++++++-----------------------
 1 files changed, 54 insertions(+), 59 deletions(-)

diff --git a/src/checked_int_inlines.hh b/src/checked_int_inlines.hh
index f88677e..e92d806 100644
--- a/src/checked_int_inlines.hh
+++ b/src/checked_int_inlines.hh
@@ -1213,45 +1213,40 @@ template <typename To_Policy, typename From_Policy, typename Type>
 inline Result
 div_2exp_signed_int(Type& to, const Type x, unsigned int exp,
                     Rounding_Dir dir) {
-  if (exp > sizeof_to_bits(sizeof(Type)) - 1) {
-  zero:
-    to = 0;
+  if (x < 0) {
+    if (exp >= sizeof_to_bits(sizeof(Type))) {
+      to = 0;
+      if (round_not_requested(dir))
+        return V_LE;
+      return round_lt_int_no_overflow<To_Policy>(to, dir);
+    }
+    typedef typename C_Integer<Type>::other_type UType;
+    UType ux = x;
+    ux = -ux;
+    to = ~Type(~-(ux >> exp));
     if (round_not_requested(dir))
-      return V_LGE;
-    if (x < 0)
+      return V_LE;
+    if (ux & ((UType(1) << exp) -1))
       return round_lt_int_no_overflow<To_Policy>(to, dir);
-    else if (x > 0)
+    return V_EQ;
+  }
+  else {
+    if (exp >= sizeof_to_bits(sizeof(Type)) - 1) {
+      to = 0;
+      if (round_not_requested(dir))
+        return V_GE;
+      if (x == 0)
+        return V_EQ;
+      return round_gt_int_no_overflow<To_Policy>(to, dir);
+    }
+    to = x >> exp;
+    if (round_not_requested(dir))
+      return V_GE;
+    if (x & ((Type(1) << exp) - 1))
       return round_gt_int_no_overflow<To_Policy>(to, dir);
     else
       return V_EQ;
   }
-  if (exp == sizeof_to_bits(sizeof(Type)) - 1) {
-    if (x == C_Integer<Type>::min) {
-      to = -1;
-      return V_EQ;
-    }
-    goto zero;
-  }
-#if 0
-  to = x / (Type(1) << exp);
-  if (round_not_requested(dir))
-    return V_GE;
-  Type r = x % (Type(1) << exp);
-  if (r < 0)
-    return round_lt_int_no_overflow<To_Policy>(to, dir);
-  else if (r > 0)
-    return round_gt_int_no_overflow<To_Policy>(to, dir);
-  else
-    return V_EQ;
-#else
-  // Faster but compiler implementation dependent (see C++98 5.8.3)
-  to = x >> exp;
-  if (round_not_requested(dir))
-    return V_GE;
-  if (x & ((Type(1) << exp) - 1))
-    return round_gt_int_no_overflow<To_Policy>(to, dir);
-  return V_EQ;
-#endif
 }
 
 template <typename To_Policy, typename From_Policy, typename Type>
@@ -1337,12 +1332,9 @@ mul_2exp_unsigned_int(Type& to, const Type x, unsigned int exp,
     }
     return set_pos_overflow_int<To_Policy>(to, dir);
   }
-  if (x & (((Type(1) << exp) - 1) << (sizeof_to_bits(sizeof(Type)) - exp)))
-    return set_pos_overflow_int<To_Policy>(to, dir);
-  Type n = x << exp;
-  if (PPL_GT_SILENT(n, (Extended_Int<To_Policy, Type>::max)))
+  if (x > Extended_Int<To_Policy, Type>::max >> exp)
     return set_pos_overflow_int<To_Policy>(to, dir);
-  to = n;
+  to = x << exp;
   return V_EQ;
 }
 
@@ -1350,37 +1342,40 @@ template <typename To_Policy, typename From_Policy, typename Type>
 inline Result
 mul_2exp_signed_int(Type& to, const Type x, unsigned int exp,
                     Rounding_Dir dir) {
-  if (!To_Policy::check_overflow) {
-    to = x << exp;
-    return V_EQ;
-  }
-  if (exp >= sizeof_to_bits(sizeof(Type)) - 1) {
-    if (x < 0)
-      return set_neg_overflow_int<To_Policy>(to, dir);
-    else if (x > 0)
-      return set_pos_overflow_int<To_Policy>(to, dir);
-    else {
-      to = 0;
+  if (x < 0) {
+    if (!To_Policy::check_overflow) {
+      to = x * (Type(1) << exp);
       return V_EQ;
     }
-  }
-  Type mask = ((Type(1) << exp) - 1) << ((sizeof_to_bits(sizeof(Type)) - 1) - exp);
-  Type n;
-  if (x < 0) {
-    if ((x & mask) != mask)
+    if (exp >= sizeof_to_bits(sizeof(Type)))
+      return set_neg_overflow_int<To_Policy>(to, dir);
+    typedef typename C_Integer<Type>::other_type UType;
+    UType mask = UType(-1) << (sizeof_to_bits(sizeof(Type)) - exp - 1);
+    UType ux = x;
+    if ((ux & mask) != mask)
       return set_neg_overflow_int<To_Policy>(to, dir);
-    n = x << exp;
+    ux <<= exp;
+    Type n = ~(Type(~ux));
     if (PPL_LT_SILENT(n, (Extended_Int<To_Policy, Type>::min)))
       return set_neg_overflow_int<To_Policy>(to, dir);
+    to = n;
   }
   else {
-    if (x & mask)
+    if (!To_Policy::check_overflow) {
+      to = x << exp;
+      return V_EQ;
+    }
+    if (exp >= sizeof_to_bits(sizeof(Type)) - 1) {
+      if (x == 0) {
+        to = 0;
+        return V_EQ;
+      }
       return set_pos_overflow_int<To_Policy>(to, dir);
-    n = x << exp;
-    if (PPL_GT_SILENT(n, (Extended_Int<To_Policy, Type>::max)))
+    }
+    if (x > Extended_Int<To_Policy, Type>::max >> exp)
       return set_pos_overflow_int<To_Policy>(to, dir);
+    to = x << exp;
   }
-  to = n;
   return V_EQ;
 }
 




More information about the PPL-devel mailing list