Patch for offsettable_address_p to handle LO_SUM

Michael Hayes m.hayes@elec.canterbury.ac.nz
Sat Jan 30 18:56:00 GMT 1999


This patch introduces a new function offsettable_lo_sum_address_p
which returns non-zero if a LO_SUM memory reference is valid
with an offset added to it.

I doubt that this function will get called for most targets.  The only
one that should is the PA.

Michael.

1999-01-31  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>

	* tm.texi (BITS_PER_LO_SUM, BITS_PER_HIGH): New macros.
	* recog.c (LO_SUM_OFFSET_MAX): New macro.
	(offsettable_lo_sum_address_p): New function.
	(offsettable_address_p): Call it.
	* recog.h (offsettable_lo_sum_address_p): Define prototype.
	* config/c4x/cx.h (BITS_PER_LO_SUM, BITS_PER_HIGH): Define.
	* config/i860/i860.h: Likewise.
	* config/m88k/m88k.h: Likewise.
	* config/mips/mips.h: Likewise.
	* config/pa/pa.h: Likewise.
	* config/rs6000/rs6000.h: Likewise.
	* config/sparc/sparc.h: Likewise.
	* config/v850/v850.h: Likewise.

Index: tm.texi
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tm.texi,v
retrieving revision 1.67
diff -c -3 -p -r1.67 tm.texi
*** tm.texi	1999/01/27 01:42:47	1.67
--- tm.texi	1999/01/31 02:38:25
*************** Minimum number of units in a word.  If t
*** 723,728 ****
--- 723,742 ----
  @code{UNITS_PER_WORD}.  Otherwise, it is the constant value that is the
  smallest value that @code{UNITS_PER_WORD} can have at run-time.
  
+ @findex BITS_PER_LO_SUM
+ @item BITS_PER_LO_SUM
+ Number of bits loaded by a @code{LO_SUM} operation.  This is used in
+ conjunction with @code{BITS_PER_HIGH} and @code{POINTER_SIZE} to
+ determine if a @code{LO_SUM} memory address is offsettable.  If this is
+ undefined then a @code{LO_SUM} memory address is considered to be not
+ offsettable.
+ 
+ @findex BITS_PER_HIGH
+ @item BITS_PER_HIGH
+ Number of bits loaded by a @code{HIGH} operation.  This is used to determine
+ if a @code{LO_SUM} memory address is offsettable.  If this is undefined
+ then a @code{LO_SUM} memory address is considered to be not offsettable.
+ 
  @findex POINTER_SIZE
  @item POINTER_SIZE
  Width of a pointer, in bits.  You must specify a value no wider than the
Index: recog.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/recog.c,v
retrieving revision 1.27
diff -c -3 -p -r1.27 recog.c
*** recog.c	1999/01/23 19:45:40	1.27
--- recog.c	1999/01/31 02:38:26
*************** find_constant_term_loc (p)
*** 1795,1805 ****
    return 0;
  }
  
! /* Return 1 if OP is a memory reference
!    whose address contains no side effects
!    and remains valid after the addition
!    of a positive integer less than the
!    size of the object being referenced.
  
     We assume that the original address is valid and do not check it.
  
--- 1795,1803 ----
    return 0;
  }
  
! /* Return 1 if OP is a memory reference whose address contains no side
!    effects and remains valid after the addition of a positive integer
!    less than the size of the object being referenced.
  
     We assume that the original address is valid and do not check it.
  
*************** offsettable_nonstrict_memref_p (op)
*** 1825,1830 ****
--- 1823,1866 ----
  	  && offsettable_address_p (0, GET_MODE (op), XEXP (op, 0)));
  }
  
+ 
+ #if defined (BITS_PER_LO_SUM) && defined (BITS_PER_HIGH)
+ #if BITS_PER_LO_SUM + BITS_PER_HIGH > POINTER_SIZE
+ #define PAGE_SIZE (1 << BITS_PER_LO_SUM)
+ #define PAGE_SEPARATION (1 << (POINTER_SIZE - BITS_PER_HIGH))
+ /* Here we have overlapping pages of size PAGE_SIZE, separated
+   by PAGE_SEPARATION (with most targets there is no overlap).  When
+   dealing with memory addresses, we assume that the HIGH operation on
+   the address ADDR computes: 
+   (ADDR + PAGE_SIZE / 2) & ~ (PAGE_SEPARATION - 1).  Thus ADDR plus a
+   small offset is likely to fall within the same data page.  The
+   maximum offset is plus or minus PAGE_SIZE / 2.  However, due to
+   quantization of the high part, we have to be more conservative and
+   restrict the maximum offset to plus or minus (PAGE_SIZE -
+   PAGE_SEPARATION) / 2.  */
+ #define LO_SUM_OFFSET_MAX ((PAGE_SIZE - PAGE_SEPARATION) / 2)
+ #else
+ #define LO_SUM_OFFSET_MAX 0
+ #endif /* BITS_PER_LO_SUM + BITS_PER_HIGH > POINTER_SIZE  */
+ #else
+ /* By default, assume that a LO_SUM address is not offsettable.  */
+ #define LO_SUM_OFFSET_MAX 0
+ #endif /* defined (BITS_PER_LO_SUM) && defined (BITS_PER_HIGH)  */
+ 
+ 
+ /* Return 1 if OFFSET is valid for a LO_SUM memory address ADDR.  */
+ int
+ offsettable_lo_sum_address_p (addr, offset)
+      rtx addr;
+      int offset;
+ {
+   if (GET_CODE (addr) != LO_SUM)
+     abort();
+ 
+   return offset >= -LO_SUM_OFFSET_MAX && offset <= LO_SUM_OFFSET_MAX;
+ }
+ 
+ 
  /* Return 1 if Y is a memory address which contains no side effects
     and would remain valid after the addition of a positive integer
     less than the size of that mode.
*************** offsettable_address_p (strictp, mode, y)
*** 1846,1851 ****
--- 1882,1890 ----
    rtx y1 = y;
    rtx *y2;
    int (*addressp) () = (strictp ? strict_memory_address_p : memory_address_p);
+ 
+   if (GET_CODE (y) == LO_SUM)
+     return offsettable_lo_sum_address_p (y, GET_MODE_SIZE (mode) - 1);
  
    if (CONSTANT_ADDRESS_P (y))
      return 1;
Index: config/c4x/c4x.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/c4x/c4x.h,v
retrieving revision 1.13
diff -c -3 -p -r1.13 c4x.h
*** c4x.h	1999/01/30 18:36:35	1.13
--- c4x.h	1999/01/31 02:38:27
*************** extern void c4x_optimization_options ();
*** 340,345 ****
--- 340,350 ----
  #define TARGET_FLOAT_FORMAT	C4X_FLOAT_FORMAT
  #define MAX_FIXED_MODE_SIZE	64 /* HImode */
  
+ /* Number of bits in the high and low parts of a two stage
+    load of an immediate constant.  */
+ #define BITS_PER_HIGH 16
+ #define BITS_PER_LO_SUM 16
+ 
  /* Use the internal floating point stuff in the compiler and not the
     host floating point stuff. */
  
Index: config/i860/i860.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/i860/i860.h,v
retrieving revision 1.7
diff -c -3 -p -r1.7 i860.h
*** i860.h	1998/12/16 21:05:35	1.7
--- i860.h	1999/01/31 02:38:27
***************
*** 1,5 ****
  /* Definitions of target machine for GNU compiler, for Intel 860.
!    Copyright (C) 1989, 91, 93, 95, 96, 1997 Free Software Foundation, Inc.
     Hacked substantially by Ron Guilmette (rfg@monkeys.com) to cater to
     the whims of the System V Release 4 assembler.
  
--- 1,5 ----
  /* Definitions of target machine for GNU compiler, for Intel 860.
!    Copyright (C) 1989, 91, 93, 95, 96, 97, 1999 Free Software Foundation, Inc.
     Hacked substantially by Ron Guilmette (rfg@monkeys.com) to cater to
     the whims of the System V Release 4 assembler.
  
*************** extern int target_flags;
*** 96,101 ****
--- 96,106 ----
  /* Width in bits of a pointer.
     See also the macro `Pmode' defined below.  */
  #define POINTER_SIZE 32
+ 
+ /* Number of bits in the high and low parts of a two stage
+    load of an immediate constant.  */
+ #define BITS_PER_HIGH 16
+ #define BITS_PER_LO_SUM 16
  
  /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
  #define PARM_BOUNDARY 32
Index: config/m88k/m88k.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/m88k/m88k.h,v
retrieving revision 1.12
diff -c -3 -p -r1.12 m88k.h
*** m88k.h	1998/12/16 21:08:23	1.12
--- m88k.h	1999/01/31 02:38:28
***************
*** 1,6 ****
  /* Definitions of target machine for GNU compiler for
     Motorola m88100 in an 88open OCS/BCS environment.
!    Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
     Contributed by Michael Tiemann (tiemann@cygnus.com).
     Currently maintained by (gcc@dg-rtp.dg.com)
  
--- 1,6 ----
  /* Definitions of target machine for GNU compiler for
     Motorola m88100 in an 88open OCS/BCS environment.
!    Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc.
     Contributed by Michael Tiemann (tiemann@cygnus.com).
     Currently maintained by (gcc@dg-rtp.dg.com)
  
*************** extern char * reg_names[];
*** 407,412 ****
--- 407,417 ----
  /* Width in bits of a pointer.
     See also the macro `Pmode' defined below.  */
  #define POINTER_SIZE 32
+ 
+ /* Number of bits in the high and low parts of a two stage
+    load of an immediate constant.  */
+ #define BITS_PER_HIGH 16
+ #define BITS_PER_LO_SUM 16
  
  /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
  #define PARM_BOUNDARY 32
Index: config/mips/mips.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/mips/mips.c,v
retrieving revision 1.47
diff -c -3 -p -r1.47 mips.c
*** mips.c	1998/12/23 07:09:00	1.47
--- mips.c	1999/01/31 02:38:30
*************** output_block_move (insn, operands, num_r
*** 3291,3301 ****
  	}
      }
  
!   /* ??? We really shouldn't get any LO_SUM addresses here, because they
!      are not offsettable, however, offsettable_address_p says they are
!      offsettable. I think this is a bug in offsettable_address_p.
!      For expediency, we fix this by just loading the address into a register
!      if we happen to get one.  */
  
    if (GET_CODE (src_reg) == LO_SUM)
      {
--- 3291,3299 ----
  	}
      }
  
!   /* ??? We really shouldn't get any LO_SUM addresses here, because
!      they are not offsettable.  For expediency, we fix this by just
!      loading the address into a register if we happen to get one.  */
  
    if (GET_CODE (src_reg) == LO_SUM)
      {
Index: config/mips/mips.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/mips/mips.h,v
retrieving revision 1.44
diff -c -3 -p -r1.44 mips.h
*** mips.h	1999/01/13 00:02:31	1.44
--- mips.h	1999/01/31 02:38:31
*************** do {							\
*** 1347,1352 ****
--- 1347,1357 ----
  #define POINTER_SIZE (TARGET_LONG64 ? 64 : 32)
  #endif
  
+ /* Number of bits in the high and low parts of a two stage
+    load of an immediate constant.  */
+ #define BITS_PER_HIGH 16
+ #define BITS_PER_LO_SUM 16
+ 
  /* Allocation boundary (in *bits*) for storing pointers in memory.  */
  #define POINTER_BOUNDARY (Pmode == DImode ? 64 : 32)
  
Index: config/pa/pa.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/pa/pa.h,v
retrieving revision 1.32
diff -c -3 -p -r1.32 pa.h
*** pa.h	1999/01/06 23:06:29	1.32
--- pa.h	1999/01/31 02:38:31
*************** do {								\
*** 382,387 ****
--- 382,392 ----
     See also the macro `Pmode' defined below.  */
  #define POINTER_SIZE 32
  
+ /* Number of bits in the high and low parts of a two stage
+    load of an immediate constant.  */
+ #define BITS_PER_HIGH 14
+ #define BITS_PER_LO_SUM 21
+ 
  /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
  #define PARM_BOUNDARY 32
  
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.41
diff -c -3 -p -r1.41 rs6000.h
*** rs6000.h	1999/01/22 09:30:03	1.41
--- rs6000.h	1999/01/31 02:38:32
*************** extern int rs6000_debug_arg;		/* debug a
*** 609,614 ****
--- 609,619 ----
     See also the macro `Pmode' defined below.  */
  #define POINTER_SIZE (TARGET_32BIT ? 32 : 64)
  
+ /* Number of bits in the high and low parts of a two stage
+    load of an immediate constant.  */
+ #define BITS_PER_HIGH 16
+ #define BITS_PER_LO_SUM 16
+ 
  /* Allocation boundary (in *bits*) for storing arguments in argument list.  */
  #define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
  
Index: config/sparc/sparc.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/sparc/sparc.h,v
retrieving revision 1.56
diff -c -3 -p -r1.56 sparc.h
*** sparc.h	1999/01/15 17:52:15	1.56
--- sparc.h	1999/01/31 02:38:33
*************** extern int sparc_align_funcs;
*** 758,763 ****
--- 758,769 ----
     See also the macro `Pmode' defined below.  */
  #define POINTER_SIZE (TARGET_PTR64 ? 64 : 32)
  
+ /* Number of bits in the high and low parts of a two stage
+    load of an immediate constant.  Note that while the processor
+    supports 13 bits for the LO_SUM, not all the binutils do.  */
+ #define BITS_PER_HIGH 22
+ #define BITS_PER_LO_SUM 10
+ 
  /* A macro to update MODE and UNSIGNEDP when an object whose type
     is TYPE and which has the specified mode and signedness is to be
     stored in a register.  This macro is only called when TYPE is a
Index: config/v850/v850.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/v850/v850.h,v
retrieving revision 1.18
diff -c -3 -p -r1.18 v850.h
*** v850.h	1998/12/16 21:14:18	1.18
--- v850.h	1999/01/31 02:38:34
***************
*** 1,5 ****
  /* Definitions of target machine for GNU compiler. NEC V850 series
!    Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
     Contributed by Jeff Law (law@cygnus.com).
  
  This file is part of GNU CC.
--- 1,5 ----
  /* Definitions of target machine for GNU compiler. NEC V850 series
!    Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
     Contributed by Jeff Law (law@cygnus.com).
  
  This file is part of GNU CC.
*************** extern struct small_memory_info small_me
*** 265,270 ****
--- 265,275 ----
  /* Width in bits of a pointer.
     See also the macro `Pmode' defined below.  */
  #define POINTER_SIZE 		32
+ 
+ /* Number of bits in the high and low parts of a two stage
+    load of an immediate constant.  */
+ #define BITS_PER_HIGH 16
+ #define BITS_PER_LO_SUM 16
  
  /* Define this macro if it is advisable to hold scalars in registers
     in a wider mode than that declared by the program.  In such cases,
Index: recog.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/recog.h,v
retrieving revision 1.17
diff -c -3 -p -r1.17 recog.h
*** recog.h	1999/01/23 19:45:41	1.17
--- recog.h	1999/01/31 02:46:23
*************** extern int comparison_operator		PROTO((r
*** 106,111 ****
--- 106,112 ----
  
  extern int offsettable_memref_p		PROTO((rtx));
  extern int offsettable_nonstrict_memref_p	PROTO((rtx));
+ extern int offsettable_lo_sum_address_p	PROTO((rtx, int));
  extern int offsettable_address_p	PROTO((int, enum machine_mode, rtx));
  extern int mode_dependent_address_p	PROTO((rtx));
  



More information about the Gcc-patches mailing list