Commit e7ee3914 by Alan Modra Committed by Alan Modra

re PR debug/11983 (ICE in dwarf-2 on code using altivec)

	PR debug/11983
	* dwarf2out.c (enum dw_val_class): Rename dw_val_class_float to
	dw_val_class_vec.  Replace use throughout file.
	(dw_float_const): Delete.
	(dw_vec_const): New.
	(dw_val_struct_union): Rename val_float to val_vec.  Replace use
	throughout file.
	(add_AT_vec): Rename from add_AT_float.  Add elt_size param.
	(same_dw_val_p): Adjust vec comparison.  Use memcmp.
	(size_of_die): Adjust dw_val_class_vec sizing.
	(output_die): Output dw_val_class_vec.
	(insert_int, extract_int, insert_float): New functions.
	(add_const_value_attribute): Use insert_float for CONST_DOUBLE.
	Handle CONST_VECTOR.
	(add_location_or_const_value_attribute): Handle CONST_VECTOR.

From-SVN: r79077
parent 5cc73f91
2004-03-08 Alan Modra <amodra@bigpond.net.au>
PR debug/11983
* dwarf2out.c (enum dw_val_class): Rename dw_val_class_float to
dw_val_class_vec. Replace use throughout file.
(dw_float_const): Delete.
(dw_vec_const): New.
(dw_val_struct_union): Rename val_float to val_vec. Replace use
throughout file.
(add_AT_vec): Rename from add_AT_float. Add elt_size param.
(same_dw_val_p): Adjust vec comparison. Use memcmp.
(size_of_die): Adjust dw_val_class_vec sizing.
(output_die): Output dw_val_class_vec.
(insert_int, extract_int, insert_float): New functions.
(add_const_value_attribute): Use insert_float for CONST_DOUBLE.
Handle CONST_VECTOR.
(add_location_or_const_value_attribute): Handle CONST_VECTOR.
2004-03-07 Aldy Hernandez <aldyh@redhat.com> 2004-03-07 Aldy Hernandez <aldyh@redhat.com>
......
...@@ -2344,7 +2344,7 @@ enum dw_val_class ...@@ -2344,7 +2344,7 @@ enum dw_val_class
dw_val_class_const, dw_val_class_const,
dw_val_class_unsigned_const, dw_val_class_unsigned_const,
dw_val_class_long_long, dw_val_class_long_long,
dw_val_class_float, dw_val_class_vec,
dw_val_class_flag, dw_val_class_flag,
dw_val_class_die_ref, dw_val_class_die_ref,
dw_val_class_fde_ref, dw_val_class_fde_ref,
...@@ -2363,14 +2363,15 @@ typedef struct dw_long_long_struct GTY(()) ...@@ -2363,14 +2363,15 @@ typedef struct dw_long_long_struct GTY(())
} }
dw_long_long_const; dw_long_long_const;
/* Describe a floating point constant value. */ /* Describe a floating point constant value, or a vector constant value. */
typedef struct dw_fp_struct GTY(()) typedef struct dw_vec_struct GTY(())
{ {
long * GTY((length ("%h.length"))) array; unsigned char * GTY((length ("%h.length"))) array;
unsigned length; unsigned length;
unsigned elt_size;
} }
dw_float_const; dw_vec_const;
/* The dw_val_node describes an attribute's value, as it is /* The dw_val_node describes an attribute's value, as it is
represented internally. */ represented internally. */
...@@ -2387,7 +2388,7 @@ typedef struct dw_val_struct GTY(()) ...@@ -2387,7 +2388,7 @@ typedef struct dw_val_struct GTY(())
HOST_WIDE_INT GTY ((default (""))) val_int; HOST_WIDE_INT GTY ((default (""))) val_int;
unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned; unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned;
dw_long_long_const GTY ((tag ("dw_val_class_long_long"))) val_long_long; dw_long_long_const GTY ((tag ("dw_val_class_long_long"))) val_long_long;
dw_float_const GTY ((tag ("dw_val_class_float"))) val_float; dw_vec_const GTY ((tag ("dw_val_class_vec"))) val_vec;
struct dw_val_die_union struct dw_val_die_union
{ {
dw_die_ref die; dw_die_ref die;
...@@ -3635,7 +3636,8 @@ static void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned HOST_WID ...@@ -3635,7 +3636,8 @@ static void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned HOST_WID
static inline unsigned HOST_WIDE_INT AT_unsigned (dw_attr_ref); static inline unsigned HOST_WIDE_INT AT_unsigned (dw_attr_ref);
static void add_AT_long_long (dw_die_ref, enum dwarf_attribute, unsigned long, static void add_AT_long_long (dw_die_ref, enum dwarf_attribute, unsigned long,
unsigned long); unsigned long);
static void add_AT_float (dw_die_ref, enum dwarf_attribute, unsigned, long *); static inline void add_AT_vec (dw_die_ref, enum dwarf_attribute, unsigned int,
unsigned int, unsigned char *);
static hashval_t debug_str_do_hash (const void *); static hashval_t debug_str_do_hash (const void *);
static int debug_str_eq (const void *, const void *); static int debug_str_eq (const void *, const void *);
static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *);
...@@ -3770,6 +3772,9 @@ static void add_AT_location_description (dw_die_ref, enum dwarf_attribute, ...@@ -3770,6 +3772,9 @@ static void add_AT_location_description (dw_die_ref, enum dwarf_attribute,
dw_loc_descr_ref); dw_loc_descr_ref);
static void add_data_member_location_attribute (dw_die_ref, tree); static void add_data_member_location_attribute (dw_die_ref, tree);
static void add_const_value_attribute (dw_die_ref, rtx); static void add_const_value_attribute (dw_die_ref, rtx);
static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
static HOST_WIDE_INT extract_int (const unsigned char *, unsigned);
static void insert_float (rtx, unsigned char *);
static rtx rtl_for_decl_location (tree); static rtx rtl_for_decl_location (tree);
static void add_location_or_const_value_attribute (dw_die_ref, tree, static void add_location_or_const_value_attribute (dw_die_ref, tree,
enum dwarf_attribute); enum dwarf_attribute);
...@@ -4605,16 +4610,17 @@ add_AT_long_long (dw_die_ref die, enum dwarf_attribute attr_kind, ...@@ -4605,16 +4610,17 @@ add_AT_long_long (dw_die_ref die, enum dwarf_attribute attr_kind,
/* Add a floating point attribute value to a DIE and return it. */ /* Add a floating point attribute value to a DIE and return it. */
static inline void static inline void
add_AT_float (dw_die_ref die, enum dwarf_attribute attr_kind, add_AT_vec (dw_die_ref die, enum dwarf_attribute attr_kind,
unsigned int length, long int *array) unsigned int length, unsigned int elt_size, unsigned char *array)
{ {
dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL; attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind; attr->dw_attr = attr_kind;
attr->dw_attr_val.val_class = dw_val_class_float; attr->dw_attr_val.val_class = dw_val_class_vec;
attr->dw_attr_val.v.val_float.length = length; attr->dw_attr_val.v.val_vec.length = length;
attr->dw_attr_val.v.val_float.array = array; attr->dw_attr_val.v.val_vec.elt_size = elt_size;
attr->dw_attr_val.v.val_vec.array = array;
add_dwarf_attr (die, attr); add_dwarf_attr (die, attr);
} }
...@@ -5407,8 +5413,8 @@ print_die (dw_die_ref die, FILE *outfile) ...@@ -5407,8 +5413,8 @@ print_die (dw_die_ref die, FILE *outfile)
a->dw_attr_val.v.val_long_long.hi, a->dw_attr_val.v.val_long_long.hi,
a->dw_attr_val.v.val_long_long.low); a->dw_attr_val.v.val_long_long.low);
break; break;
case dw_val_class_float: case dw_val_class_vec:
fprintf (outfile, "floating-point constant"); fprintf (outfile, "floating-point or vector constant");
break; break;
case dw_val_class_flag: case dw_val_class_flag:
fprintf (outfile, "%u", AT_flag (a)); fprintf (outfile, "%u", AT_flag (a));
...@@ -5608,8 +5614,8 @@ attr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark) ...@@ -5608,8 +5614,8 @@ attr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark)
case dw_val_class_long_long: case dw_val_class_long_long:
CHECKSUM (at->dw_attr_val.v.val_long_long); CHECKSUM (at->dw_attr_val.v.val_long_long);
break; break;
case dw_val_class_float: case dw_val_class_vec:
CHECKSUM (at->dw_attr_val.v.val_float); CHECKSUM (at->dw_attr_val.v.val_vec);
break; break;
case dw_val_class_flag: case dw_val_class_flag:
CHECKSUM (at->dw_attr_val.v.val_flag); CHECKSUM (at->dw_attr_val.v.val_flag);
...@@ -5697,7 +5703,6 @@ same_dw_val_p (dw_val_node *v1, dw_val_node *v2, int *mark) ...@@ -5697,7 +5703,6 @@ same_dw_val_p (dw_val_node *v1, dw_val_node *v2, int *mark)
{ {
dw_loc_descr_ref loc1, loc2; dw_loc_descr_ref loc1, loc2;
rtx r1, r2; rtx r1, r2;
unsigned i;
if (v1->val_class != v2->val_class) if (v1->val_class != v2->val_class)
return 0; return 0;
...@@ -5711,12 +5716,13 @@ same_dw_val_p (dw_val_node *v1, dw_val_node *v2, int *mark) ...@@ -5711,12 +5716,13 @@ same_dw_val_p (dw_val_node *v1, dw_val_node *v2, int *mark)
case dw_val_class_long_long: case dw_val_class_long_long:
return v1->v.val_long_long.hi == v2->v.val_long_long.hi return v1->v.val_long_long.hi == v2->v.val_long_long.hi
&& v1->v.val_long_long.low == v2->v.val_long_long.low; && v1->v.val_long_long.low == v2->v.val_long_long.low;
case dw_val_class_float: case dw_val_class_vec:
if (v1->v.val_float.length != v2->v.val_float.length) if (v1->v.val_vec.length != v2->v.val_vec.length
|| v1->v.val_vec.elt_size != v2->v.val_vec.elt_size)
return 0;
if (memcmp (v1->v.val_vec.array, v2->v.val_vec.array,
v1->v.val_vec.length * v1->v.val_vec.elt_size))
return 0; return 0;
for (i = 0; i < v1->v.val_float.length; i++)
if (v1->v.val_float.array[i] != v2->v.val_float.array[i])
return 0;
return 1; return 1;
case dw_val_class_flag: case dw_val_class_flag:
return v1->v.val_flag == v2->v.val_flag; return v1->v.val_flag == v2->v.val_flag;
...@@ -6310,8 +6316,9 @@ size_of_die (dw_die_ref die) ...@@ -6310,8 +6316,9 @@ size_of_die (dw_die_ref die)
case dw_val_class_long_long: case dw_val_class_long_long:
size += 1 + 2*HOST_BITS_PER_LONG/HOST_BITS_PER_CHAR; /* block */ size += 1 + 2*HOST_BITS_PER_LONG/HOST_BITS_PER_CHAR; /* block */
break; break;
case dw_val_class_float: case dw_val_class_vec:
size += 1 + a->dw_attr_val.v.val_float.length * 4; /* block */ size += 1 + (a->dw_attr_val.v.val_vec.length
* a->dw_attr_val.v.val_vec.elt_size); /* block */
break; break;
case dw_val_class_flag: case dw_val_class_flag:
size += 1; size += 1;
...@@ -6505,7 +6512,7 @@ value_format (dw_attr_ref a) ...@@ -6505,7 +6512,7 @@ value_format (dw_attr_ref a)
} }
case dw_val_class_long_long: case dw_val_class_long_long:
return DW_FORM_block1; return DW_FORM_block1;
case dw_val_class_float: case dw_val_class_vec:
return DW_FORM_block1; return DW_FORM_block1;
case dw_val_class_flag: case dw_val_class_flag:
return DW_FORM_flag; return DW_FORM_flag;
...@@ -6774,16 +6781,24 @@ output_die (dw_die_ref die) ...@@ -6774,16 +6781,24 @@ output_die (dw_die_ref die)
} }
break; break;
case dw_val_class_float: case dw_val_class_vec:
{ {
unsigned int elt_size = a->dw_attr_val.v.val_vec.elt_size;
unsigned int len = a->dw_attr_val.v.val_vec.length;
unsigned int i; unsigned int i;
unsigned char *p;
dw2_asm_output_data (1, a->dw_attr_val.v.val_float.length * 4, dw2_asm_output_data (1, len * elt_size, "%s", name);
"%s", name); if (elt_size > sizeof (HOST_WIDE_INT))
{
for (i = 0; i < a->dw_attr_val.v.val_float.length; i++) elt_size /= 2;
dw2_asm_output_data (4, a->dw_attr_val.v.val_float.array[i], len *= 2;
"fp constant word %u", i); }
for (i = 0, p = a->dw_attr_val.v.val_vec.array;
i < len;
i++, p += elt_size)
dw2_asm_output_data (elt_size, extract_int (p, elt_size),
"fp or vector constant word %u", i);
break; break;
} }
...@@ -9313,6 +9328,56 @@ add_data_member_location_attribute (dw_die_ref die, tree decl) ...@@ -9313,6 +9328,56 @@ add_data_member_location_attribute (dw_die_ref die, tree decl)
add_AT_loc (die, DW_AT_data_member_location, loc_descr); add_AT_loc (die, DW_AT_data_member_location, loc_descr);
} }
/* Writes integer values to dw_vec_const array. */
static void
insert_int (HOST_WIDE_INT val, unsigned int size, unsigned char *dest)
{
while (size != 0)
{
*dest++ = val & 0xff;
val >>= 8;
--size;
}
}
/* Reads integers from dw_vec_const array. Inverse of insert_int. */
static HOST_WIDE_INT
extract_int (const unsigned char *src, unsigned int size)
{
HOST_WIDE_INT val = 0;
src += size;
while (size != 0)
{
val <<= 8;
val |= *--src & 0xff;
--size;
}
return val;
}
/* Writes floating point values to dw_vec_const array. */
static void
insert_float (rtx rtl, unsigned char *array)
{
REAL_VALUE_TYPE rv;
long val[4];
int i;
REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl);
real_to_target (val, &rv, GET_MODE (rtl));
/* real_to_target puts 32-bit pieces in each long. Pack them. */
for (i = 0; i < GET_MODE_SIZE (GET_MODE (rtl)) / 4; i++)
{
insert_int (val[i], 4, array);
array += 4;
}
}
/* Attach a DW_AT_const_value attribute for a variable or a parameter which /* Attach a DW_AT_const_value attribute for a variable or a parameter which
does not have a "location" either in memory or in a register. These does not have a "location" either in memory or in a register. These
things can arise in GNU C when a constant is passed as an actual parameter things can arise in GNU C when a constant is passed as an actual parameter
...@@ -9345,14 +9410,11 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) ...@@ -9345,14 +9410,11 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
if (GET_MODE_CLASS (mode) == MODE_FLOAT) if (GET_MODE_CLASS (mode) == MODE_FLOAT)
{ {
unsigned length = GET_MODE_SIZE (mode) / 4; unsigned int length = GET_MODE_SIZE (mode);
long *array = ggc_alloc (sizeof (long) * length); unsigned char *array = ggc_alloc (length);
REAL_VALUE_TYPE rv;
REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl);
real_to_target (array, &rv, mode);
add_AT_float (die, DW_AT_const_value, length, array); insert_float (rtl, array);
add_AT_vec (die, DW_AT_const_value, length / 4, 4, array);
} }
else else
{ {
...@@ -9366,6 +9428,68 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) ...@@ -9366,6 +9428,68 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
} }
break; break;
case CONST_VECTOR:
{
enum machine_mode mode = GET_MODE (rtl);
unsigned int elt_size = GET_MODE_UNIT_SIZE (mode);
unsigned int length = CONST_VECTOR_NUNITS (rtl);
unsigned char *array = ggc_alloc (length * elt_size);
unsigned int i;
unsigned char *p;
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
{
for (i = 0, p = array; i < length; i++, p += elt_size)
{
rtx elt = CONST_VECTOR_ELT (rtl, i);
HOST_WIDE_INT lo, hi;
if (GET_CODE (elt) == CONST_INT)
{
lo = INTVAL (elt);
hi = -(lo < 0);
}
else if (GET_CODE (elt) == CONST_DOUBLE)
{
lo = CONST_DOUBLE_LOW (elt);
hi = CONST_DOUBLE_HIGH (elt);
}
else
abort ();
if (elt_size <= sizeof (HOST_WIDE_INT))
insert_int (lo, elt_size, p);
else if (elt_size == 2 * sizeof (HOST_WIDE_INT))
{
unsigned char *p0 = p;
unsigned char *p1 = p + sizeof (HOST_WIDE_INT);
if (WORDS_BIG_ENDIAN)
{
p0 = p1;
p1 = p;
}
insert_int (lo, sizeof (HOST_WIDE_INT), p0);
insert_int (hi, sizeof (HOST_WIDE_INT), p1);
}
else
abort ();
}
}
else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
{
for (i = 0, p = array; i < length; i++, p += elt_size)
{
rtx elt = CONST_VECTOR_ELT (rtl, i);
insert_float (elt, p);
}
}
else
abort ();
add_AT_vec (die, DW_AT_const_value, length, elt_size, array);
}
break;
case CONST_STRING: case CONST_STRING:
add_AT_string (die, DW_AT_const_value, XSTR (rtl, 0)); add_AT_string (die, DW_AT_const_value, XSTR (rtl, 0));
break; break;
...@@ -9739,6 +9863,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, ...@@ -9739,6 +9863,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
case CONST_INT: case CONST_INT:
case CONST_DOUBLE: case CONST_DOUBLE:
case CONST_VECTOR:
case CONST_STRING: case CONST_STRING:
case SYMBOL_REF: case SYMBOL_REF:
case LABEL_REF: case LABEL_REF:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment