aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-05-20 12:35:04 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2010-05-20 12:35:04 +0200
commitf1ca31177de94c951f65adf833c371d3f0e0a54a (patch)
treeec4c83f44e2ec052fca18a299fa98d5792122a2c
parent431043bdd73c0697871aa0698a7839df5ad55fc1 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/dwarf2out.c52
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;
}