diff options
Diffstat (limited to 'gcc/double-int.c')
-rw-r--r-- | gcc/double-int.c | 76 |
1 files changed, 11 insertions, 65 deletions
diff --git a/gcc/double-int.c b/gcc/double-int.c index aa175e89d41..924e91b6c90 100644 --- a/gcc/double-int.c +++ b/gcc/double-int.c @@ -69,71 +69,6 @@ decode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT *low, *hi = words[2] + words[3] * BASE; } -/* Force the double-word integer L1, H1 to be within the range of the - integer type TYPE. Stores the properly truncated and sign-extended - double-word integer in *LV, *HV. Returns true if the operation - overflows, that is, argument and result are different. */ - -int -fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1, - unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, const_tree type) -{ - unsigned HOST_WIDE_INT low0 = l1; - HOST_WIDE_INT high0 = h1; - unsigned int prec = TYPE_PRECISION (type); - int sign_extended_type; - - /* Size types *are* sign extended. */ - sign_extended_type = (!TYPE_UNSIGNED (type) - || (TREE_CODE (type) == INTEGER_TYPE - && TYPE_IS_SIZETYPE (type))); - - /* First clear all bits that are beyond the type's precision. */ - if (prec >= 2 * HOST_BITS_PER_WIDE_INT) - ; - else if (prec > HOST_BITS_PER_WIDE_INT) - h1 &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT)); - else - { - h1 = 0; - if (prec < HOST_BITS_PER_WIDE_INT) - l1 &= ~((HOST_WIDE_INT) (-1) << prec); - } - - /* Then do sign extension if necessary. */ - if (!sign_extended_type) - /* No sign extension */; - else if (prec >= 2 * HOST_BITS_PER_WIDE_INT) - /* Correct width already. */; - else if (prec > HOST_BITS_PER_WIDE_INT) - { - /* Sign extend top half? */ - if (h1 & ((unsigned HOST_WIDE_INT)1 - << (prec - HOST_BITS_PER_WIDE_INT - 1))) - h1 |= (HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT); - } - else if (prec == HOST_BITS_PER_WIDE_INT) - { - if ((HOST_WIDE_INT)l1 < 0) - h1 = -1; - } - else - { - /* Sign extend bottom half? */ - if (l1 & ((unsigned HOST_WIDE_INT)1 << (prec - 1))) - { - h1 = -1; - l1 |= (HOST_WIDE_INT)(-1) << prec; - } - } - - *lv = l1; - *hv = h1; - - /* If the value didn't fit, signal overflow. */ - return l1 != low0 || h1 != high0; -} - /* Add two doubleword integers with doubleword result. Return nonzero if the operation overflows according to UNSIGNED_P. Each argument is given as two `HOST_WIDE_INT' pieces. @@ -792,6 +727,17 @@ double_int_add (double_int a, double_int b) return ret; } +/* Returns A - B. */ + +double_int +double_int_sub (double_int a, double_int b) +{ + double_int ret; + neg_double (b.low, b.high, &b.low, &b.high); + add_double (a.low, a.high, b.low, b.high, &ret.low, &ret.high); + return ret; +} + /* Returns -A. */ double_int |