This is the mail archive of the gcc@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: reload displacement optimization


On Tue, Mar 10, 1998 at 01:50:26PM +0000, Joern Rennecke wrote:
> I made a new macro LEGITIMIZE_RELOAD_ADDRESS for the SH and i386 some time
> ago, but since Kenner doesn't care enough about embedded targets and the
> i386 didn't make a convincing case, it never got submitted.
> Could you fit your optimization into this framework?

Easily, thanks!  Jim, what do you think?

Oh, PPC folk will probably want to pretty much copy this verbatim,
since IIRC Alpha's ldah and PPC's addis do the same thing.


r~


Index: gcc/config/alpha/alpha.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/alpha/alpha.h,v
retrieving revision 1.23
diff -c -p -d -r1.23 alpha.h
*** alpha.h	1998/03/06 14:44:27	1.23
--- alpha.h	1998/03/10 17:08:21
*************** extern void alpha_init_expanders ();
*** 1467,1472 ****
--- 1467,1512 ----
      }								\
  }
  
+ /* Try a machine-dependent way of reloading an illegitimate address
+    operand.  If we find one, push the reload and jump to WIN.  This
+    macro is used in only one place: `find_reloads_address' in reload.c.
+ 
+    For the Alpha, we wish to handle large displacements off a base
+    register by splitting the addend across an ldah and the mem insn.
+    This cuts number of extra insns needed from 3 to 1.  */
+    
+ #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)	\
+ do {									\
+   if (GET_CODE (X) == PLUS						\
+       && GET_CODE (XEXP (X, 0)) == REG					\
+       && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER			\
+       && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE)			\
+       && GET_CODE (XEXP (X, 1)) == CONST_INT)				\
+     {									\
+       HOST_WIDE_INT val = INTVAL (XEXP (X, 1));				\
+       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;		\
+       HOST_WIDE_INT high						\
+ 	= (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;	\
+ 									\
+       /* Check for 32-bit overflow.  */					\
+       if (high + low != val)						\
+ 	break;								\
+ 									\
+       /* Reload the high part into a base reg; leave the low part	\
+ 	 in the mem directly.  */					\
+ 									\
+       X = gen_rtx_PLUS (GET_MODE (X),					\
+ 			gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0),	\
+ 				      GEN_INT (high)),			\
+ 			GEN_INT (low));					\
+ 	  								\
+       push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR,	\
+ 		   BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0,	\
+ 		   OPNUM, TYPE);					\
+       goto WIN;								\
+     }									\
+ } while (0)
+ 
  /* Go to LABEL if ADDR (a legitimate address expression)
     has an effect that depends on the machine mode it is used for.
     On the Alpha this is true only for the unaligned modes.   We can


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