diff options
author | Jakub Jelinek <jakub@redhat.com> | 2010-05-20 12:35:04 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-05-20 12:35:04 +0200 |
commit | f1ca31177de94c951f65adf833c371d3f0e0a54a (patch) | |
tree | ec4c83f44e2ec052fca18a299fa98d5792122a2c | |
parent | 431043bdd73c0697871aa0698a7839df5ad55fc1 (diff) | |
download | gcc-f1ca31177de94c951f65adf833c371d3f0e0a54a.zip gcc-f1ca31177de94c951f65adf833c371d3f0e0a54a.tar.gz gcc-f1ca31177de94c951f65adf833c371d3f0e0a54a.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 52 |
2 files changed, 54 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cde189e..ee86787 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-05-20 Jakub Jelinek <jakub@redhat.com> + + * 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 <hp@axis.com> PR target/44202 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index e68065b..1f6e902 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; } |