aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-05-06 18:51:25 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2009-05-06 18:51:25 +0200
commit96474f366fef95a6645cb06e5b2d30a6fce77783 (patch)
tree408fac4324b4949788943278e2152507d0838fa4 /gcc/dwarf2out.c
parent529ff44101de7c912c138994b03c7ec199ff5e93 (diff)
downloadgcc-96474f366fef95a6645cb06e5b2d30a6fce77783.zip
gcc-96474f366fef95a6645cb06e5b2d30a6fce77783.tar.gz
gcc-96474f366fef95a6645cb06e5b2d30a6fce77783.tar.bz2
dwarf2out.c (new_reg_loc_descr): Don't ever create DW_OP_regX.
* dwarf2out.c (new_reg_loc_descr): Don't ever create DW_OP_regX. (one_reg_loc_descriptor): Create DW_OP_regX here instead of calling new_reg_loc_descr. (loc_by_reference): If loc is DW_OP_regX, change it into DW_OP_bregX 0 instead of appending DW_OP_deref*. From-SVN: r147187
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c48
1 files changed, 36 insertions, 12 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 73a31ec..0d308c9 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3851,18 +3851,11 @@ new_loc_descr (enum dwarf_location_atom op, unsigned HOST_WIDE_INT oprnd1,
static inline dw_loc_descr_ref
new_reg_loc_descr (unsigned int reg, unsigned HOST_WIDE_INT offset)
{
- if (offset)
- {
- if (reg <= 31)
- return new_loc_descr ((enum dwarf_location_atom) (DW_OP_breg0 + reg),
- offset, 0);
- else
- return new_loc_descr (DW_OP_bregx, reg, offset);
- }
- else if (reg <= 31)
- return new_loc_descr ((enum dwarf_location_atom) (DW_OP_reg0 + reg), 0, 0);
+ if (reg <= 31)
+ return new_loc_descr ((enum dwarf_location_atom) (DW_OP_breg0 + reg),
+ offset, 0);
else
- return new_loc_descr (DW_OP_regx, reg, 0);
+ return new_loc_descr (DW_OP_bregx, reg, offset);
}
/* Add a location description term to a location description expression. */
@@ -9702,7 +9695,13 @@ reg_loc_descriptor (rtx rtl, enum var_init_status initialized)
static dw_loc_descr_ref
one_reg_loc_descriptor (unsigned int regno, enum var_init_status initialized)
{
- dw_loc_descr_ref reg_loc_descr = new_reg_loc_descr (regno, 0);
+ dw_loc_descr_ref reg_loc_descr;
+
+ if (regno <= 31)
+ reg_loc_descr
+ = new_loc_descr ((enum dwarf_location_atom) (DW_OP_reg0 + regno), 0, 0);
+ else
+ reg_loc_descr = new_loc_descr (DW_OP_regx, regno, 0);
if (initialized == VAR_INIT_STATUS_UNINITIALIZED)
add_loc_descr (&reg_loc_descr, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
@@ -11719,6 +11718,31 @@ loc_by_reference (dw_loc_descr_ref loc, tree decl)
|| !DECL_BY_REFERENCE (decl))
return loc;
+ /* If loc is DW_OP_reg{0...31,x}, don't add DW_OP_deref, instead
+ change it into corresponding DW_OP_breg{0...31,x} 0. Then the
+ location expression is considered to be address of a memory location,
+ rather than the register itself. */
+ if (((loc->dw_loc_opc >= DW_OP_reg0 && loc->dw_loc_opc <= DW_OP_reg31)
+ || loc->dw_loc_opc == DW_OP_regx)
+ && (loc->dw_loc_next == NULL
+ || (loc->dw_loc_next->dw_loc_opc == DW_OP_GNU_uninit
+ && loc->dw_loc_next->dw_loc_next == NULL)))
+ {
+ if (loc->dw_loc_opc == DW_OP_regx)
+ {
+ loc->dw_loc_opc = DW_OP_bregx;
+ loc->dw_loc_oprnd2.v.val_int = 0;
+ }
+ else
+ {
+ loc->dw_loc_opc
+ = (enum dwarf_location_atom)
+ (loc->dw_loc_opc + (DW_OP_breg0 - DW_OP_reg0));
+ loc->dw_loc_oprnd1.v.val_int = 0;
+ }
+ return loc;
+ }
+
size = int_size_in_bytes (TREE_TYPE (decl));
if (size > DWARF2_ADDR_SIZE || size == -1)
return 0;