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

Module: ppl/ppl Branch: master Commit: 685ee646b27f9f757e912ff3ae53610332292c35 URL: http://www.cs.unipr.it/git/gitweb.cgi?p=ppl/ppl.git;a=commit;h=685ee646b27f9...
Author: Abramo Bagnara abramo.bagnara@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; }
participants (1)
-
Abramo Bagnara