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]

Re: egcs-1.1.1 issues



law@cygnus.com said:
> We should be thinking about what bugs we want/need to address for
> egcs-1.1.1. 

I've just installed the following two ARM-related patches on the trunk.  I 
think both should go into an egcs-1.1.1 release.  The first fixes passing 
constants by reference in the Fortran compiler (generated bad assembly 
code).  The second fixes handling of some memory addresses when compiling 
for ARM architecture 4 when the address isn't in standard canonical form.

Sat Sep 19 07:33:36 1998  Richard Earnshaw (rearnsha@arm.com)

	* arm.c (add_constant): New parameter address_only, change caller.
	Set it non-zero if taking the address of an item in the pool.
	(arm_reorg): Handle cases where we need the address of an item in
	the pool.

	* arm.c (bad_signed_byte_operand): Check both arms of a sum in
	a memory address.
	* arm.md (splits for *extendqihi_insn and *extendqisi_insn): Handle
	memory addresses that are not in standard canonical form.


Index: arm.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/arm/arm.c,v
retrieving revision 1.12
diff -p -r1.12 arm.c
*** arm.c	1998/08/19 08:33:48	1.12
--- arm.c	1998/09/19 14:28:10
*************** static int arm_naked_function_p PROTO ((
*** 55,61 ****
  static void init_fpa_table PROTO ((void));
  static enum machine_mode select_dominance_cc_mode PROTO ((enum rtx_code, rtx,
  							  rtx, HOST_WIDE_INT));
! static HOST_WIDE_INT add_constant PROTO ((rtx, enum machine_mode));
  static void dump_table PROTO ((rtx));
  static int fixit PROTO ((rtx, enum machine_mode, int));
  static rtx find_barrier PROTO ((rtx, int));
--- 55,61 ----
  static void init_fpa_table PROTO ((void));
  static enum machine_mode select_dominance_cc_mode PROTO ((enum rtx_code, rtx,
  							  rtx, HOST_WIDE_INT));
! static HOST_WIDE_INT add_constant PROTO ((rtx, enum machine_mode, int *));
  static void dump_table PROTO ((rtx));
  static int fixit PROTO ((rtx, enum machine_mode, int));
  static rtx find_barrier PROTO ((rtx, int));
*************** typedef struct
*** 3445,3463 ****
  static pool_node pool_vector[MAX_POOL_SIZE];
  static int pool_size;
  static rtx pool_vector_label;
  
! /* Add a constant to the pool and return its label.  */
  static HOST_WIDE_INT
! add_constant (x, mode)
       rtx x;
       enum machine_mode mode;
  {
    int i;
    HOST_WIDE_INT offset;
  
    if (mode == SImode && GET_CODE (x) == MEM && CONSTANT_P (XEXP (x, 0))
        && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
      x = get_pool_constant (XEXP (x, 0));
  #ifndef AOF_ASSEMBLER
    else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == 3)
      x = XVECEXP (x, 0, 0);
--- 3483,3513 ----
  static pool_node pool_vector[MAX_POOL_SIZE];
  static int pool_size;
  static rtx pool_vector_label;
+ 
+ /* Add a constant to the pool and return its offset within the current
+    pool.
  
!    X is the rtx we want to replace. MODE is its mode.  On return,
!    ADDRESS_ONLY will be non-zero if we really want the address of such
!    a constant, not the constant itself.  */
  static HOST_WIDE_INT
! add_constant (x, mode, address_only)
       rtx x;
       enum machine_mode mode;
+      int *address_only;
  {
    int i;
    HOST_WIDE_INT offset;
  
+   *address_only = 0;
    if (mode == SImode && GET_CODE (x) == MEM && CONSTANT_P (XEXP (x, 0))
        && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
      x = get_pool_constant (XEXP (x, 0));
+   else if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P(x))
+     {
+       *address_only = 1;
+       x = get_pool_constant (x);
+     }
  #ifndef AOF_ASSEMBLER
    else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == 3)
      x = XVECEXP (x, 0, 0);
*************** arm_reorg (first)
*** 3709,3714 ****
--- 3759,3765 ----
  		  rtx newsrc;
  		  rtx addr;
  		  int scratch;
+ 		  int address_only;
  
  		  /* If this is an HImode constant load, convert it into
  		     an SImode constant load.  Since the register is always
*************** arm_reorg (first)
*** 3722,3760 ****
  		      PUT_MODE (dst, SImode);
  		    }
  
! 		  offset = add_constant (src, mode);
  		  addr = plus_constant (gen_rtx (LABEL_REF, VOIDmode,
  						 pool_vector_label),
  					offset);
  
! 		  /* For wide moves to integer regs we need to split the
! 		     address calculation off into a separate insn, so that
! 		     the load can then be done with a load-multiple.  This is
! 		     safe, since we have already noted the length of such
! 		     insns to be 8, and we are immediately over-writing the
! 		     scratch we have grabbed with the final result.  */
! 		  if (GET_MODE_SIZE (mode) > 4
  		      && (scratch = REGNO (dst)) < 16)
  		    {
! 		      rtx reg = gen_rtx (REG, SImode, scratch);
  		      newinsn = emit_insn_after (gen_movaddr (reg, addr),
  						 newinsn);
  		      addr = reg;
  		    }
  
! 		  newsrc = gen_rtx (MEM, mode, addr);
  
! 		  /* Build a jump insn wrapper around the move instead
! 		     of an ordinary insn, because we want to have room for
! 		     the target label rtx in fld[7], which an ordinary
! 		     insn doesn't have. */
! 		  newinsn = emit_jump_insn_after (gen_rtx (SET, VOIDmode,
! 							   dst, newsrc),
! 						  newinsn);
! 		  JUMP_LABEL (newinsn) = pool_vector_label;
  
! 		  /* But it's still an ordinary insn */
! 		  PUT_CODE (newinsn, INSN);
  
  		  /* Kill old insn */
  		  delete_insn (scan);
--- 3773,3822 ----
  		      PUT_MODE (dst, SImode);
  		    }
  
! 		  offset = add_constant (src, mode, &address_only);
  		  addr = plus_constant (gen_rtx (LABEL_REF, VOIDmode,
  						 pool_vector_label),
  					offset);
  
! 		  /* If we only want the address of the pool entry, or
! 		     for wide moves to integer regs we need to split
! 		     the address calculation off into a separate insn.
! 		     If necessary, the load can then be done with a
! 		     load-multiple.  This is safe, since we have
! 		     already noted the length of such insns to be 8,
! 		     and we are immediately over-writing the scratch
! 		     we have grabbed with the final result.  */
! 		  if ((address_only || GET_MODE_SIZE (mode) > 4)
  		      && (scratch = REGNO (dst)) < 16)
  		    {
! 		      rtx reg;
! 
! 		      if (mode == SImode)
! 			reg = dst;
! 		      else 
! 			reg = gen_rtx (REG, SImode, scratch);
! 
  		      newinsn = emit_insn_after (gen_movaddr (reg, addr),
  						 newinsn);
  		      addr = reg;
  		    }
  
! 		  if (! address_only)
! 		    {
! 		      newsrc = gen_rtx (MEM, mode, addr);
  
! 		      /* XXX Fixme -- I think the following is bogus.  */
! 		      /* Build a jump insn wrapper around the move instead
! 			 of an ordinary insn, because we want to have room for
! 			 the target label rtx in fld[7], which an ordinary
! 			 insn doesn't have. */
! 		      newinsn = emit_jump_insn_after
! 			(gen_rtx (SET, VOIDmode, dst, newsrc), newinsn);
! 		      JUMP_LABEL (newinsn) = pool_vector_label;
  
! 		      /* But it's still an ordinary insn */
! 		      PUT_CODE (newinsn, INSN);
! 		    }
  
  		  /* Kill old insn */
  		  delete_insn (scan);
Index: arm.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/arm/arm.c,v
retrieving revision 1.12
diff -p -r1.12 arm.c
*** arm.c	1998/08/19 08:33:48	1.12
--- arm.c	1998/09/18 15:45:15
*************** bad_signed_byte_operand (op, mode)
*** 1769,1775 ****
  
    /* A sum of anything more complex than reg + reg or reg + const is bad */
    if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
!       && ! s_register_operand (XEXP (op, 0), VOIDmode))
      return 1;
  
    /* Big constants are also bad */
--- 1785,1793 ----
  
    /* A sum of anything more complex than reg + reg or reg + const is bad */
    if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
!       && (! s_register_operand (XEXP (op, 0), VOIDmode)
! 	  || (! s_register_operand (XEXP (op, 1), VOIDmode)
! 	      && GET_CODE (XEXP (op, 1)) != CONST_INT)))
      return 1;
  
    /* Big constants are also bad */
Index: arm.md
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/arm/arm.md,v
retrieving revision 1.6
diff -p -r1.6 arm.md
*** arm.md	1998/07/11 03:04:39	1.6
--- arm.md	1998/09/18 15:45:17
***************
*** 2399,2404 ****
--- 2434,2445 ----
  	XEXP (operands[2], 0) = plus_constant (operands[3], low);
  	operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
        }
+     /* Ensure the sum is in correct canonical form */
+     else if (GET_CODE (operands[1]) == PLUS
+ 	     && GET_CODE (XEXP (operands[1], 1)) != CONST_INT
+ 	     && ! s_register_operand (XEXP (operands[1], 1), VOIDmode))
+       operands[1] = gen_rtx (PLUS, GET_MODE (operands[1]),
+ 			     XEXP (operands[1], 1), XEXP (operands[1], 0));
    }
  ")
  
***************
*** 2464,2469 ****
--- 2505,2516 ----
  	XEXP (operands[2], 0) = plus_constant (operands[0], low);
  	operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
        }
+     /* Ensure the sum is in correct canonical form */
+     else if (GET_CODE (operands[1]) == PLUS
+ 	     && GET_CODE (XEXP (operands[1], 1)) != CONST_INT
+ 	     && ! s_register_operand (XEXP (operands[1], 1), VOIDmode))
+       operands[1] = gen_rtx (PLUS, GET_MODE (operands[1]),
+ 			     XEXP (operands[1], 1), XEXP (operands[1], 0));
    }
  ")
  

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