This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

dwarf2out.c bugfix


The PA64 work is using dwarf2 debug records (death to stabs!)  Not
unexpectedly this has exposed a problem or two.  Nothing nearly has fun to
track down as the code gen problems from the last few days :-)  Just a 
simple abort and the straightfoward fix.

Basically mem_loc_descriptor did not handle autoincrement addressing modes.

POST_INC, POST_DEC are trivial -- the autoincrement happens after the memory
reference, so we can just strip off the autoincrement and handle it like any
other register address.

PRE_INC, PRE_DEC are slightly more complex since we have to account for the
autoincrement side effect in the memory reference.  This required us to pass
in the mode of the memory reference so that we would know its size.  Given
that information it's easy to cons up a PLUS expression for the memory
address.


	* dwarf2out.c (mem_loc_descriptor): New argument MODE.  All callers
	changed.  Handle autoincrement addressing modes.

Index: dwarf2out.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/dwarf2out.c,v
retrieving revision 1.115
diff -c -3 -p -r1.115 dwarf2out.c
*** dwarf2out.c	1999/08/27 03:46:39	1.115
--- dwarf2out.c	1999/08/30 07:26:54
*************** static int type_is_enum			PROTO((tree));
*** 2571,2577 ****
  static dw_loc_descr_ref reg_loc_descriptor PROTO((rtx));
  static dw_loc_descr_ref based_loc_descr	PROTO((unsigned, long));
  static int is_based_loc			PROTO((rtx));
! static dw_loc_descr_ref mem_loc_descriptor PROTO((rtx));
  static dw_loc_descr_ref concat_loc_descriptor PROTO((rtx, rtx));
  static dw_loc_descr_ref loc_descriptor	PROTO((rtx));
  static unsigned ceiling			PROTO((unsigned, unsigned));
--- 2571,2577 ----
  static dw_loc_descr_ref reg_loc_descriptor PROTO((rtx));
  static dw_loc_descr_ref based_loc_descr	PROTO((unsigned, long));
  static int is_based_loc			PROTO((rtx));
! static dw_loc_descr_ref mem_loc_descriptor PROTO((rtx, enum machine_mode 
mode));
  static dw_loc_descr_ref concat_loc_descriptor PROTO((rtx, rtx));
  static dw_loc_descr_ref loc_descriptor	PROTO((rtx));
  static unsigned ceiling			PROTO((unsigned, unsigned));
*************** is_based_loc (rtl)
*** 6574,6584 ****
     When creating memory location descriptors, we are effectively transforming
     the RTL for a memory-resident object into its Dwarf postfix expression
     equivalent.  This routine recursively descends an RTL tree, turning
!    it into Dwarf postfix code as it goes.  */
  
  static dw_loc_descr_ref
! mem_loc_descriptor (rtl)
       register rtx rtl;
  {
    dw_loc_descr_ref mem_loc_result = NULL;
    /* Note that for a dynamically sized array, the location we will generate 
a
--- 6574,6588 ----
     When creating memory location descriptors, we are effectively transforming
     the RTL for a memory-resident object into its Dwarf postfix expression
     equivalent.  This routine recursively descends an RTL tree, turning
!    it into Dwarf postfix code as it goes.
  
+    MODE is the mode of the memory reference, needed to handle some
+    autoincrement addressing modes.  */
+ 
  static dw_loc_descr_ref
! mem_loc_descriptor (rtl, mode)
       register rtx rtl;
+      enum machine_mode mode;
  {
    dw_loc_descr_ref mem_loc_result = NULL;
    /* Note that for a dynamically sized array, the location we will generate 
a
*************** mem_loc_descriptor (rtl)
*** 6588,6593 ****
--- 6592,6604 ----
  
    switch (GET_CODE (rtl))
      {
+     case POST_INC:
+     case POST_DEC:
+       /* POST_INC and POST_DEC can be handled just like a SUBREG.  So we
+ 	 just fall into the SUBREG code.  */
+ 
+       /* ... fall through ... */
+ 
      case SUBREG:
        /* The case of a subreg may arise when we have a local (register)
           variable or a formal (register) parameter which doesn't quite fill
*************** mem_loc_descriptor (rtl)
*** 6616,6622 ****
        break;
  
      case MEM:
!       mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0));
        add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
        break;
  
--- 6627,6633 ----
        break;
  
      case MEM:
!       mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode);
        add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
        break;
  
*************** mem_loc_descriptor (rtl)
*** 6631,6644 ****
        mem_loc_result->dw_loc_oprnd1.v.val_addr = addr_to_string (rtl);
        break;
  
      case PLUS:
        if (is_based_loc (rtl))
  	mem_loc_result = based_loc_descr (reg_number (XEXP (rtl, 0)),
  					  INTVAL (XEXP (rtl, 1)));
        else
  	{
! 	  add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0)));
! 	  add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1)));
  	  add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_plus, 0, 0));
  	}
        break;
--- 6642,6668 ----
        mem_loc_result->dw_loc_oprnd1.v.val_addr = addr_to_string (rtl);
        break;
  
+     case PRE_INC:
+     case PRE_DEC:
+       /* Turn these into a PLUS expression and fall into the PLUS code
+ 	 below.  */
+       rtl = gen_rtx_PLUS (word_mode, XEXP (rtl, 0),
+ 			  GEN_INT (GET_CODE (rtl) == PRE_INC
+ 				   ? GET_MODE_UNIT_SIZE (mode) 
+ 				   : - GET_MODE_UNIT_SIZE (mode)));
+ 			  
+       /* ... fall through ... */
+ 
      case PLUS:
        if (is_based_loc (rtl))
  	mem_loc_result = based_loc_descr (reg_number (XEXP (rtl, 0)),
  					  INTVAL (XEXP (rtl, 1)));
        else
  	{
! 	  add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0),
! 							      mode));
! 	  add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1),
! 							      mode));
  	  add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_plus, 0, 0));
  	}
        break;
*************** mem_loc_descriptor (rtl)
*** 6646,6653 ****
      case MULT:
        /* If a pseudo-reg is optimized away, it is possible for it to
  	 be replaced with a MEM containing a multiply.  */
!       add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0)));
!       add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1)));
        add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
        break;
  
--- 6670,6677 ----
      case MULT:
        /* If a pseudo-reg is optimized away, it is possible for it to
  	 be replaced with a MEM containing a multiply.  */
!       add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0), 
mode));
!       add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1), 
mode));
        add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
        break;
  
*************** loc_descriptor (rtl)
*** 6714,6720 ****
        break;
  
      case MEM:
!       loc_result = mem_loc_descriptor (XEXP (rtl, 0));
        break;
  
      case CONCAT:
--- 6738,6744 ----
        break;
  
      case MEM:
!       loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
        break;
  
      case CONCAT:





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]