&& tree_to_shwi (bound) == dflt)
;
- /* Otherwise represent the bound as an unsigned value with the
- precision of its type. The precision and signedness of the
- type will be necessary to re-interpret it unambiguously. */
- else if (prec < HOST_BITS_PER_WIDE_INT)
+ /* If HOST_WIDE_INT is big enough then represent the bound as
+ a constant value. We need to choose a form based on
+ whether the type is signed or unsigned. We cannot just
+ call add_AT_unsigned if the value itself is positive
+ (add_AT_unsigned might add the unsigned value encoded as
+ DW_FORM_data[1248]). Some DWARF consumers will lookup the
+ bounds type and then sign extend any unsigned values found
+ for signed types. This is needed only for
+ DW_AT_{lower,upper}_bound, since for most other attributes,
+ consumers will treat DW_FORM_data[1248] as unsigned values,
+ regardless of the underlying type. */
+ else if (prec <= HOST_BITS_PER_WIDE_INT
- || TREE_INT_CST_HIGH (bound) == 0)
++ || tree_fits_uhwi_p (bound))
{
- unsigned HOST_WIDE_INT mask
- = ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
- add_AT_unsigned (subrange_die, bound_attr,
- TREE_INT_CST_LOW (bound) & mask);
+ if (TYPE_UNSIGNED (TREE_TYPE (bound)))
+ add_AT_unsigned (subrange_die, bound_attr,
+ TREE_INT_CST_LOW (bound));
+ else
+ add_AT_int (subrange_die, bound_attr, TREE_INT_CST_LOW (bound));
}
- else if (prec == HOST_BITS_PER_WIDE_INT || tree_fits_uhwi_p (bound))
- add_AT_unsigned (subrange_die, bound_attr,
- TREE_INT_CST_LOW (bound));
else
- add_AT_double (subrange_die, bound_attr, TREE_INT_CST_HIGH (bound),
- TREE_INT_CST_LOW (bound));
+ /* Otherwise represent the bound as an unsigned value with
+ the precision of its type. The precision and signedness
+ of the type will be necessary to re-interpret it
+ unambiguously. */
+ add_AT_wide (subrange_die, bound_attr, bound);
}
break;
if (simple_type_size_in_bits (TREE_TYPE (value))
<= HOST_BITS_PER_WIDE_INT || tree_fits_shwi_p (value))
- /* DWARF2 does not provide a way of indicating whether or
- not enumeration constants are signed or unsigned. GDB
- always assumes the values are signed, so we output all
- values as if they were signed. That means that
- enumeration constants with very large unsigned values
- will appear to have negative values in the debugger.
-
- TODO: the above comment is wrong, DWARF2 does provide
- DW_FORM_sdata/DW_FORM_udata to represent signed/unsigned data.
- This should be re-worked to use correct signed/unsigned
- int/double tags for all cases, instead of always treating as
- signed. */
- add_AT_int (enum_die, DW_AT_const_value, TREE_INT_CST_LOW (value));
+ {
+ /* For constant forms created by add_AT_unsigned DWARF
+ consumers (GDB, elfutils, etc.) always zero extend
+ the value. Only when the actual value is negative
+ do we need to use add_AT_int to generate a constant
+ form that can represent negative values. */
+ HOST_WIDE_INT val = TREE_INT_CST_LOW (value);
+ if (TYPE_UNSIGNED (TREE_TYPE (value)) || val >= 0)
+ add_AT_unsigned (enum_die, DW_AT_const_value,
+ (unsigned HOST_WIDE_INT) val);
+ else
+ add_AT_int (enum_die, DW_AT_const_value, val);
+ }
else
/* Enumeration constants may be wider than HOST_WIDE_INT. Handle
- that here. */
+ that here. TODO: This should be re-worked to use correct
+ signed/unsigned double tags for all cases. */
- add_AT_double (enum_die, DW_AT_const_value,
- TREE_INT_CST_HIGH (value), TREE_INT_CST_LOW (value));
+ add_AT_wide (enum_die, DW_AT_const_value, value);
}
add_gnat_descriptive_type_attribute (type_die, type, context_die);
switch (GET_CODE (x))
{
case CONST_INT:
- {
- HOST_WIDE_INT hi = 0;
-
- if (INTVAL (x) < 0
- && !(TYPE_UNSIGNED (type)
- && (GET_MODE_BITSIZE (TYPE_MODE (type))
- < HOST_BITS_PER_WIDE_INT)))
- hi = -1;
-
- t = build_int_cst_wide (type, INTVAL (x), hi);
-
- return t;
- }
+ case CONST_WIDE_INT:
+ t = wide_int_to_tree (type, std::make_pair (x, TYPE_MODE (type)));
+ return t;
case CONST_DOUBLE:
- STATIC_ASSERT (HOST_BITS_PER_WIDE_INT * 2 <= MAX_BITSIZE_MODE_ANY_INT);
- if (GET_MODE (x) == VOIDmode)
- t = build_int_cst_wide (type,
- CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x));
++ gcc_assert (HOST_BITS_PER_WIDE_INT * 2 <= MAX_BITSIZE_MODE_ANY_INT);
+ if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (x) == VOIDmode)
+ t = wide_int_to_tree (type,
+ wide_int::from_array (&CONST_DOUBLE_LOW (x), 2,
+ HOST_BITS_PER_WIDE_INT * 2));
else
{
REAL_VALUE_TYPE d;
else
{
slsr_cand_t arg_cand = base_cand_from_table (arg);
- double_int diff = arg_cand->index - basis->index;
+ widest_int diff = arg_cand->index - basis->index;
+ basic_block pred = gimple_phi_arg_edge (phi, i)->src;
if ((incr == diff) || (!address_arithmetic_p && incr == -diff))
- ncd = ncd_for_two_cands (ncd, gimple_bb (arg_cand->cand_stmt),
- *where, arg_cand, where);
+ ncd = ncd_for_two_cands (ncd, pred, *where, NULL, where);
}
}
}
undefined, so it doesn't matter what we return, and some callers
expect to be able to use this routine for both signed and
unsigned conversions. */
- if (exp > HOST_BITS_PER_DOUBLE_INT)
+ if (exp > precision)
goto overflow;
- rshift_significand (&t, r, HOST_BITS_PER_DOUBLE_INT - exp);
- if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
+ words = (precision + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE (val); i++)
+ val[i] = 0;
+
+#if (HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG)
+ for (int i = 0; i < words; i++)
{
- high = t.sig[SIGSZ-1];
- low = t.sig[SIGSZ-2];
+ int j = SIGSZ - words + i;
+ val[i] = (j < 0) ? 0 : r->sig[j];
}
- else
+#else
+ gcc_assert (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG);
+ for (int i = 0; i < words; i++)
{
- gcc_assert (HOST_BITS_PER_WIDE_INT == 2*HOST_BITS_PER_LONG);
- high = t.sig[SIGSZ-1];
- high = high << (HOST_BITS_PER_LONG - 1) << 1;
- high |= t.sig[SIGSZ-2];
-
- low = t.sig[SIGSZ-3];
- low = low << (HOST_BITS_PER_LONG - 1) << 1;
- low |= t.sig[SIGSZ-4];
+ int j = SIGSZ - (words * 2) + (i + 2) + 1;
+ if (j < 0)
+ val[i] = 0;
+ else
+ {
+ val[i] = r->sig[j];
+ unsigned HOST_WIDE_INT v = val[i];
+ v <<= HOST_BITS_PER_LONG;
+ val[i] = v;
+ val[i] |= r->sig[j - 1];
+ }
}
- tmp = wi::lrshift (tmp, (words * HOST_BITS_PER_WIDE_INT) - exp);
+#endif
+ w = SIGSZ * HOST_BITS_PER_LONG + words * HOST_BITS_PER_WIDE_INT;
+ tmp = real_int::from_array
+ (val, (w + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT, w);
++ tmp = wi::lrshift<real_int> (tmp, (words * HOST_BITS_PER_WIDE_INT) - exp);
+ result = wide_int::from (tmp, precision, UNSIGNED);
if (r->sign)
- {
- if (low == 0)
- high = -high;
- else
- low = -low, high = ~high;
- }
- break;
+ return -result;
+ else
+ return result;
default:
gcc_unreachable ();
case MODE_INT:
case MODE_PARTIAL_INT:
{
- unsigned HOST_WIDE_INT hi = 0, lo = 0;
-
- for (i = 0;
- i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
- i += value_bit)
- lo |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
- for (; i < elem_bitsize; i += value_bit)
- hi |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask)
- << (i - HOST_BITS_PER_WIDE_INT);
-
- /* immed_double_const doesn't call trunc_int_for_mode. I don't
- know why. */
- if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
- elems[elem] = gen_int_mode (lo, outer_submode);
- else if (elem_bitsize <= HOST_BITS_PER_DOUBLE_INT)
- elems[elem] = immed_double_const (lo, hi, outer_submode);
- else
- return NULL_RTX;
+ int u;
+ int base = 0;
+ int units
+ = (GET_MODE_BITSIZE (outer_submode) + HOST_BITS_PER_WIDE_INT - 1)
+ / HOST_BITS_PER_WIDE_INT;
+ HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_WIDE_INT];
+ wide_int r;
+
+ for (u = 0; u < units; u++)
+ {
+ unsigned HOST_WIDE_INT buf = 0;
+ for (i = 0;
+ i < HOST_BITS_PER_WIDE_INT && base + i < elem_bitsize;
+ i += value_bit)
+ buf |= (unsigned HOST_WIDE_INT)(*vp++ & value_mask) << i;
+
+ tmp[u] = buf;
+ base += HOST_BITS_PER_WIDE_INT;
+ }
- gcc_assert (GET_MODE_PRECISION (outer_submode)
- <= MAX_BITSIZE_MODE_ANY_INT);
++ gcc_assert (GET_MODE_PRECISION (outer_submode) <= MAX_BITSIZE_MODE_ANY_INT);
+ r = wide_int::from_array (tmp, units,
+ GET_MODE_PRECISION (outer_submode));
+ elems[elem] = immed_wide_int_const (r, outer_submode);
}
break;
case MODE_DECIMAL_FLOAT:
{
REAL_VALUE_TYPE r;
- long tmp[MAX_BITSIZE_MODE_ANY_MODE / 32];
- long tmp[max_bitsize / 32];
++ long tmp[MAX_BITSIZE_MODE_ANY_INT / 32];
/* real_from_target wants its input in words affected by
FLOAT_WORDS_BIG_ENDIAN. However, we ignore this,