diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-05-06 18:51:25 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2009-05-06 18:51:25 +0200 |
commit | 96474f366fef95a6645cb06e5b2d30a6fce77783 (patch) | |
tree | 408fac4324b4949788943278e2152507d0838fa4 /gcc/dwarf2out.c | |
parent | 529ff44101de7c912c138994b03c7ec199ff5e93 (diff) | |
download | gcc-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.c | 48 |
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 (®_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; |