From f1ca31177de94c951f65adf833c371d3f0e0a54a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 20 May 2010 12:35:04 +0200 Subject: [PATCH] dwarf2out.c (new_loc_descr_op_bit_piece): Add offset argument. * dwarf2out.c (new_loc_descr_op_bit_piece): Add offset argument. Don't use DW_OP_piece if offset is non-zero, put offset into second DW_OP_bit_piece argument. (dw_sra_loc_expr): Adjust callers. For memory expressions compute offset. From-SVN: r159623 --- gcc/ChangeLog | 8 ++++++++ gcc/dwarf2out.c | 52 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cde189eed40..ee86787de69 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-05-20 Jakub Jelinek + + * dwarf2out.c (new_loc_descr_op_bit_piece): Add offset + argument. Don't use DW_OP_piece if offset is non-zero, + put offset into second DW_OP_bit_piece argument. + (dw_sra_loc_expr): Adjust callers. For memory expressions + compute offset. + 2010-05-20 Hans-Peter Nilsson PR target/44202 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index e68065b2c1e..1f6e9021d16 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -14364,12 +14364,12 @@ dw_loc_list_1 (tree loc, rtx varloc, int want_address, if it is not possible. */ static dw_loc_descr_ref -new_loc_descr_op_bit_piece (HOST_WIDE_INT bitsize) +new_loc_descr_op_bit_piece (HOST_WIDE_INT bitsize, HOST_WIDE_INT offset) { - if ((bitsize % BITS_PER_UNIT) == 0) + if ((bitsize % BITS_PER_UNIT) == 0 && offset == 0) return new_loc_descr (DW_OP_piece, bitsize / BITS_PER_UNIT, 0); else if (dwarf_version >= 3 || !dwarf_strict) - return new_loc_descr (DW_OP_bit_piece, bitsize, 0); + return new_loc_descr (DW_OP_bit_piece, bitsize, offset); else return NULL; } @@ -14448,7 +14448,7 @@ dw_sra_loc_expr (tree decl, rtx loc) if (padsize > decl_size) return NULL; decl_size -= padsize; - *descr_tail = new_loc_descr_op_bit_piece (padsize); + *descr_tail = new_loc_descr_op_bit_piece (padsize, 0); if (*descr_tail == NULL) return NULL; descr_tail = &(*descr_tail)->dw_loc_next; @@ -14461,7 +14461,47 @@ dw_sra_loc_expr (tree decl, rtx loc) decl_size -= bitsize; if (last == NULL) { - *descr_tail = new_loc_descr_op_bit_piece (bitsize); + HOST_WIDE_INT offset = 0; + if (GET_CODE (varloc) == VAR_LOCATION + && GET_CODE (PAT_VAR_LOCATION_LOC (varloc)) != PARALLEL) + { + varloc = PAT_VAR_LOCATION_LOC (varloc); + if (GET_CODE (varloc) == EXPR_LIST) + varloc = XEXP (varloc, 0); + } + do + { + if (GET_CODE (varloc) == CONST + || GET_CODE (varloc) == SIGN_EXTEND + || GET_CODE (varloc) == ZERO_EXTEND) + varloc = XEXP (varloc, 0); + else if (GET_CODE (varloc) == SUBREG) + varloc = SUBREG_REG (varloc); + else + break; + } + while (1); + /* DW_OP_bit_size offset should be zero for register + or implicit location descriptions and empty location + descriptions, but for memory addresses needs big endian + adjustment. */ + if (MEM_P (varloc)) + { + unsigned HOST_WIDE_INT memsize + = INTVAL (MEM_SIZE (varloc)) * BITS_PER_UNIT; + if (memsize != bitsize) + { + if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN + && (memsize > BITS_PER_WORD || bitsize > BITS_PER_WORD)) + return NULL; + if (memsize < bitsize) + return NULL; + if (BITS_BIG_ENDIAN) + offset = memsize - bitsize; + } + } + + *descr_tail = new_loc_descr_op_bit_piece (bitsize, offset); if (*descr_tail == NULL) return NULL; descr_tail = &(*descr_tail)->dw_loc_next; @@ -14472,7 +14512,7 @@ dw_sra_loc_expr (tree decl, rtx loc) the decl. */ if (descr != NULL && decl_size != 0) { - *descr_tail = new_loc_descr_op_bit_piece (decl_size); + *descr_tail = new_loc_descr_op_bit_piece (decl_size, 0); if (*descr_tail == NULL) return NULL; } -- 2.30.2