From: amodra Date: Sun, 7 Mar 2004 23:42:37 +0000 (+0000) Subject: PR debug/11983 X-Git-Tag: upstream/4.9.2~72466 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1b6ad37661ec49431e314afafa880338e1cfc872;p=platform%2Fupstream%2Flinaro-gcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@79077 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fbd035f..b0ff6f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2004-03-08 Alan Modra + + 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 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 599b6c9..5594793 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -2344,7 +2344,7 @@ enum dw_val_class dw_val_class_const, dw_val_class_unsigned_const, dw_val_class_long_long, - dw_val_class_float, + dw_val_class_vec, dw_val_class_flag, dw_val_class_die_ref, dw_val_class_fde_ref, @@ -2363,14 +2363,15 @@ typedef struct dw_long_long_struct GTY(()) } 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 elt_size; } -dw_float_const; +dw_vec_const; /* The dw_val_node describes an attribute's value, as it is represented internally. */ @@ -2387,7 +2388,7 @@ typedef struct dw_val_struct GTY(()) HOST_WIDE_INT GTY ((default (""))) val_int; 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_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 { dw_die_ref die; @@ -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 void add_AT_long_long (dw_die_ref, enum dwarf_attribute, 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 int debug_str_eq (const void *, const void *); 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, dw_loc_descr_ref); static void add_data_member_location_attribute (dw_die_ref, tree); 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 void add_location_or_const_value_attribute (dw_die_ref, tree, enum dwarf_attribute); @@ -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. */ static inline void -add_AT_float (dw_die_ref die, enum dwarf_attribute attr_kind, - unsigned int length, long int *array) +add_AT_vec (dw_die_ref die, enum dwarf_attribute attr_kind, + unsigned int length, unsigned int elt_size, unsigned char *array) { dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node)); attr->dw_attr_next = NULL; attr->dw_attr = attr_kind; - attr->dw_attr_val.val_class = dw_val_class_float; - attr->dw_attr_val.v.val_float.length = length; - attr->dw_attr_val.v.val_float.array = array; + attr->dw_attr_val.val_class = dw_val_class_vec; + attr->dw_attr_val.v.val_vec.length = length; + 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); } @@ -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.low); break; - case dw_val_class_float: - fprintf (outfile, "floating-point constant"); + case dw_val_class_vec: + fprintf (outfile, "floating-point or vector constant"); break; case dw_val_class_flag: fprintf (outfile, "%u", AT_flag (a)); @@ -5608,8 +5614,8 @@ attr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark) case dw_val_class_long_long: CHECKSUM (at->dw_attr_val.v.val_long_long); break; - case dw_val_class_float: - CHECKSUM (at->dw_attr_val.v.val_float); + case dw_val_class_vec: + CHECKSUM (at->dw_attr_val.v.val_vec); break; case dw_val_class_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) { dw_loc_descr_ref loc1, loc2; rtx r1, r2; - unsigned i; if (v1->val_class != v2->val_class) return 0; @@ -5711,12 +5716,13 @@ same_dw_val_p (dw_val_node *v1, dw_val_node *v2, int *mark) case dw_val_class_long_long: 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; - case dw_val_class_float: - if (v1->v.val_float.length != v2->v.val_float.length) + case dw_val_class_vec: + 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; - 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; case dw_val_class_flag: return v1->v.val_flag == v2->v.val_flag; @@ -6310,8 +6316,9 @@ size_of_die (dw_die_ref die) case dw_val_class_long_long: size += 1 + 2*HOST_BITS_PER_LONG/HOST_BITS_PER_CHAR; /* block */ break; - case dw_val_class_float: - size += 1 + a->dw_attr_val.v.val_float.length * 4; /* block */ + case dw_val_class_vec: + size += 1 + (a->dw_attr_val.v.val_vec.length + * a->dw_attr_val.v.val_vec.elt_size); /* block */ break; case dw_val_class_flag: size += 1; @@ -6505,7 +6512,7 @@ value_format (dw_attr_ref a) } case dw_val_class_long_long: return DW_FORM_block1; - case dw_val_class_float: + case dw_val_class_vec: return DW_FORM_block1; case dw_val_class_flag: return DW_FORM_flag; @@ -6774,16 +6781,24 @@ output_die (dw_die_ref die) } 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 char *p; - dw2_asm_output_data (1, a->dw_attr_val.v.val_float.length * 4, - "%s", name); - - for (i = 0; i < a->dw_attr_val.v.val_float.length; i++) - dw2_asm_output_data (4, a->dw_attr_val.v.val_float.array[i], - "fp constant word %u", i); + dw2_asm_output_data (1, len * elt_size, "%s", name); + if (elt_size > sizeof (HOST_WIDE_INT)) + { + elt_size /= 2; + len *= 2; + } + 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; } @@ -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); } +/* 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 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 @@ -9345,14 +9410,11 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) if (GET_MODE_CLASS (mode) == MODE_FLOAT) { - unsigned length = GET_MODE_SIZE (mode) / 4; - long *array = ggc_alloc (sizeof (long) * length); - REAL_VALUE_TYPE rv; - - REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl); - real_to_target (array, &rv, mode); + unsigned int length = GET_MODE_SIZE (mode); + unsigned char *array = ggc_alloc (length); - 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 { @@ -9366,6 +9428,68 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) } 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: add_AT_string (die, DW_AT_const_value, XSTR (rtl, 0)); break; @@ -9739,6 +9863,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, case CONST_INT: case CONST_DOUBLE: + case CONST_VECTOR: case CONST_STRING: case SYMBOL_REF: case LABEL_REF: