OSDN Git Service

* dwarf2out.c (new_reg_loc_descr): Don't ever create DW_OP_regX.
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 May 2009 16:51:25 +0000 (16:51 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 May 2009 16:51:25 +0000 (16:51 +0000)
(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*.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147187 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dwarf2out.c

index f6ec862..7b3d41e 100644 (file)
@@ -1,3 +1,11 @@
+2009-05-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * 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*.
+
 2009-05-06  Michael Matz  <matz@suse.de>
 
        PR middle-end/40021
index 73a31ec..0d308c9 100644 (file)
@@ -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;