93 lines
3.2 KiB
Diff
93 lines
3.2 KiB
Diff
|
2010-05-18 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.
|
||
|
|
||
|
--- gcc/dwarf2out.c.jj 2010-05-15 08:09:16.000000000 +0200
|
||
|
+++ gcc/dwarf2out.c 2010-05-18 15:49:26.000000000 +0200
|
||
|
@@ -14364,12 +14364,12 @@ dw_loc_list_1 (tree loc, rtx varloc, int
|
||
|
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,46 @@ 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) INTVAL (MEM_SIZE (varloc))
|
||
|
+ * BITS_PER_UNIT) != bitsize)
|
||
|
+ {
|
||
|
+ unsigned HOST_WIDE_INT memsize
|
||
|
+ = INTVAL (MEM_SIZE (varloc)) * BITS_PER_UNIT;
|
||
|
+ 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 +14511,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;
|
||
|
}
|