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]
Other format: [Raw text]

[mn10300, installed] improve PICness


This patch fixes a bug in the mn10300 back-end that permitted non-PIC
addressing modes such as (symbol+offset,register) to be emitted when
compiling with -fPIC.  I'm checking it in.  Tested on
i686-pc-linux-gnu-x-mn10300-elf.

This hadn't been noticed before because the linker fails to mark
non-PIC shared libraries with TEXTREL.  I'll fix this problem in
the linker as soon as I have a chance.

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* config/mn10300/mn10300-protos.h (legitimate_address_p): Declare.
	* config/mn10300/mn10300.c (legitimate_address_p): New.  Test that
	index is legitimate, compared with code moved from...
	* config/mn10300/mn10300.h (GO_IF_LEGITIMATE_ADDRESS): here.
	(REG_STRICT): Define, according to REG_OK_STRICT.
	(REGNO_IN_RANGE_P, REGNO_DATA_P, REGNO_ADDRESS_P, REGNO_SP_P,
	REGNO_EXTENDED_P, REGNO_AM33_P, REGNO_FP_P): Introduce strict
	argument.
	(REGNO_STRICT_OK_FOR_BASE_P, REGNO_STRICT_OK_FOR_BIT_BASE_P,
	REGNO_STRICT_OK_FOR_INDEX_P): New.
	(REGNO_OK_FOR_BASE_P, REG_OK_FOR_BASE_P, REGNO_OK_FOR_BIT_BASE_P,
	REG_OK_FOR_BIT_BASE_P, REGNO_OK_FOR_INDEX_P, REG_OK_FOR_INDEX_P,
	RTX_OK_FOR_BASE_P): Use them.

Index: gcc/config/mn10300/mn10300-protos.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/mn10300/mn10300-protos.h,v
retrieving revision 1.12
diff -u -p -r1.12 mn10300-protos.h
--- gcc/config/mn10300/mn10300-protos.h 25 Jan 2004 20:17:44 -0000 1.12
+++ gcc/config/mn10300/mn10300-protos.h 28 Jun 2004 04:46:02 -0000
@@ -28,6 +28,7 @@ extern void mn10300_va_start (tree, rtx)
 extern struct rtx_def *legitimize_address (rtx, rtx, enum machine_mode);
 extern rtx legitimize_pic_address (rtx, rtx);
 extern int legitimate_pic_operand_p (rtx);
+extern bool legitimate_address_p (enum machine_mode, rtx, int);
 extern void print_operand (FILE *, rtx, int);
 extern void print_operand_address (FILE *, rtx);
 extern void mn10300_print_reg_list (FILE *, int);
Index: gcc/config/mn10300/mn10300.c
===================================================================
RCS file: /cvs/uberbaum/gcc/config/mn10300/mn10300.c,v
retrieving revision 1.67
diff -u -p -r1.67 mn10300.c
--- gcc/config/mn10300/mn10300.c 17 Mar 2004 05:16:17 -0000 1.67
+++ gcc/config/mn10300/mn10300.c 28 Jun 2004 04:46:03 -0000
@@ -1864,6 +1864,56 @@ legitimate_pic_operand_p (rtx x)
   return 1;
 }
 
+/* Return TRUE if the address X, taken from a (MEM:MODE X) rtx, is
+   legitimate, and FALSE otherwise.  */
+bool
+legitimate_address_p (enum machine_mode mode, rtx x, int strict)
+{
+  if (CONSTANT_ADDRESS_P (x)
+      && (! flag_pic || legitimate_pic_operand_p (x)))
+    return TRUE;
+
+  if (RTX_OK_FOR_BASE_P (x, strict))
+    return TRUE;
+
+  if (TARGET_AM33
+      && GET_CODE (x) == POST_INC
+      && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict)
+      && (mode == SImode || mode == SFmode || mode == HImode))
+    return TRUE;
+
+  if (GET_CODE (x) == PLUS)
+    {
+      rtx base = 0, index = 0;
+
+      if (REG_P (XEXP (x, 0))
+	  && REGNO_STRICT_OK_FOR_BASE_P (REGNO (XEXP (x, 0)), strict))
+	{
+	  base = XEXP (x, 0);
+	  index = XEXP (x, 1);
+	}
+
+      if (REG_P (XEXP (x, 1))
+	  && REGNO_STRICT_OK_FOR_BASE_P (REGNO (XEXP (x, 1)), strict))
+	{
+	  base = XEXP (x, 1);
+	  index = XEXP (x, 0);
+	}
+
+      if (base != 0 && index != 0)
+	{
+	  if (GET_CODE (index) == CONST_INT)
+	    return TRUE;
+	  if (GET_CODE (index) == CONST
+	      && (! flag_pic
+ 		  || legitimate_pic_operand_p (index)))
+	    return TRUE;
+	}
+    }
+
+  return FALSE;
+}
+
 static int
 mn10300_address_cost_1 (rtx x, int *unsig)
 {
Index: gcc/config/mn10300/mn10300.h
===================================================================
RCS file: /cvs/uberbaum/gcc/config/mn10300/mn10300.h,v
retrieving revision 1.79
diff -u -p -r1.79 mn10300.h
--- gcc/config/mn10300/mn10300.h 6 Feb 2004 06:18:32 -0000 1.79
+++ gcc/config/mn10300/mn10300.h 28 Jun 2004 04:46:04 -0000
@@ -366,41 +366,59 @@ enum reg_class {
    has been allocated, which happens in local-alloc.c.  */
 
 #ifndef REG_OK_STRICT
-# define REGNO_IN_RANGE_P(regno,min,max) \
-  (IN_RANGE ((regno), (min), (max)) || (regno) >= FIRST_PSEUDO_REGISTER)
+# define REG_STRICT 0
 #else
-# define REGNO_IN_RANGE_P(regno,min,max) \
-  (IN_RANGE ((regno), (min), (max)) \
-   || (reg_renumber \
-       && reg_renumber[(regno)] >= (min) && reg_renumber[(regno)] <= (max)))
+# define REG_STRICT 1
 #endif
 
-#define REGNO_DATA_P(regno) \
-  REGNO_IN_RANGE_P ((regno), FIRST_DATA_REGNUM, LAST_DATA_REGNUM)
-#define REGNO_ADDRESS_P(regno) \
-  REGNO_IN_RANGE_P ((regno), FIRST_ADDRESS_REGNUM, LAST_ADDRESS_REGNUM)
-#define REGNO_SP_P(regno) \
-  REGNO_IN_RANGE_P ((regno), STACK_POINTER_REGNUM, STACK_POINTER_REGNUM)
-#define REGNO_EXTENDED_P(regno) \
-  REGNO_IN_RANGE_P ((regno), FIRST_EXTENDED_REGNUM, LAST_EXTENDED_REGNUM)
-#define REGNO_AM33_P(regno) \
-  (REGNO_DATA_P ((regno)) || REGNO_ADDRESS_P ((regno)) \
-   || REGNO_EXTENDED_P ((regno)))
-#define REGNO_FP_P(regno) \
-  REGNO_IN_RANGE_P ((regno), FIRST_FP_REGNUM, LAST_FP_REGNUM)
-
+# define REGNO_IN_RANGE_P(regno,min,max,strict) \
+  (IN_RANGE ((regno), (min), (max)) 		\
+   || ((strict)					\
+       ? (reg_renumber				\
+	  && reg_renumber[(regno)] >= (min)	\
+	  && reg_renumber[(regno)] <= (max))	\
+       : (regno) >= FIRST_PSEUDO_REGISTER))
+
+#define REGNO_DATA_P(regno, strict) \
+  (REGNO_IN_RANGE_P ((regno), FIRST_DATA_REGNUM, LAST_DATA_REGNUM, \
+		     (strict)))
+#define REGNO_ADDRESS_P(regno, strict) \
+  (REGNO_IN_RANGE_P ((regno), FIRST_ADDRESS_REGNUM, LAST_ADDRESS_REGNUM, \
+		     (strict)))
+#define REGNO_SP_P(regno, strict) \
+  (REGNO_IN_RANGE_P ((regno), STACK_POINTER_REGNUM, STACK_POINTER_REGNUM, \
+		     (strict)))
+#define REGNO_EXTENDED_P(regno, strict) \
+  (REGNO_IN_RANGE_P ((regno), FIRST_EXTENDED_REGNUM, LAST_EXTENDED_REGNUM, \
+		     (strict)))
+#define REGNO_AM33_P(regno, strict) \
+  (REGNO_DATA_P ((regno), (strict)) || REGNO_ADDRESS_P ((regno), (strict)) \
+   || REGNO_EXTENDED_P ((regno), (strict)))
+#define REGNO_FP_P(regno, strict) \
+  (REGNO_IN_RANGE_P ((regno), FIRST_FP_REGNUM, LAST_FP_REGNUM, (strict)))
+
+#define REGNO_STRICT_OK_FOR_BASE_P(regno, strict) \
+  (REGNO_SP_P ((regno), (strict)) \
+   || REGNO_ADDRESS_P ((regno), (strict)) \
+   || REGNO_EXTENDED_P ((regno), (strict)))
 #define REGNO_OK_FOR_BASE_P(regno) \
-  (REGNO_SP_P ((regno)) \
-   || REGNO_ADDRESS_P ((regno)) || REGNO_EXTENDED_P ((regno)))
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+  (REGNO_STRICT_OK_FOR_BASE_P ((regno), REG_STRICT))
+#define REG_OK_FOR_BASE_P(X) \
+  (REGNO_OK_FOR_BASE_P (REGNO (X)))
 
+#define REGNO_STRICT_OK_FOR_BIT_BASE_P(regno, strict) \
+  (REGNO_SP_P ((regno), (strict)) || REGNO_ADDRESS_P ((regno), (strict)))
 #define REGNO_OK_FOR_BIT_BASE_P(regno) \
-  (REGNO_SP_P ((regno)) || REGNO_ADDRESS_P ((regno)))
-#define REG_OK_FOR_BIT_BASE_P(X) REGNO_OK_FOR_BIT_BASE_P (REGNO (X))
+  (REGNO_STRICT_OK_FOR_BIT_BASE_P ((regno), REG_STRICT))
+#define REG_OK_FOR_BIT_BASE_P(X) \
+  (REGNO_OK_FOR_BIT_BASE_P (REGNO (X)))
 
+#define REGNO_STRICT_OK_FOR_INDEX_P(regno, strict) \
+  (REGNO_DATA_P ((regno), (strict)) || REGNO_EXTENDED_P ((regno), (strict)))
 #define REGNO_OK_FOR_INDEX_P(regno) \
-  (REGNO_DATA_P ((regno)) || REGNO_EXTENDED_P ((regno)))
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+  (REGNO_STRICT_OK_FOR_INDEX_P ((regno), REG_STRICT))
+#define REG_OK_FOR_INDEX_P(X) \
+  (REGNO_OK_FOR_INDEX_P (REGNO (X)))
 
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
@@ -756,41 +774,20 @@ struct cum_arg {int nbytes; };
 
 /* Accept either REG or SUBREG where a register is valid.  */
   
-#define RTX_OK_FOR_BASE_P(X)					\
-  ((REG_P (X) && REG_OK_FOR_BASE_P (X))				\
+#define RTX_OK_FOR_BASE_P(X, strict)				\
+  ((REG_P (X) && REGNO_STRICT_OK_FOR_BASE_P (REGNO (X),		\
+ 					     (strict))) 	\
    || (GET_CODE (X) == SUBREG && REG_P (SUBREG_REG (X))		\
-       && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
+       && REGNO_STRICT_OK_FOR_BASE_P (REGNO (SUBREG_REG (X)),	\
+ 				      (strict))))
 
 #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)    	\
-{							\
-  if (CONSTANT_ADDRESS_P (X)				\
-      && (! flag_pic || legitimate_pic_operand_p (X)))	\
-    goto ADDR;						\
-  if (RTX_OK_FOR_BASE_P (X))				\
-    goto ADDR;						\
-  if (TARGET_AM33					\
-      && GET_CODE (X) == POST_INC			\
-      && RTX_OK_FOR_BASE_P (XEXP (X, 0))		\
-      && (MODE == SImode || MODE == SFmode || MODE == HImode))\
-    goto ADDR;						\
-  if (GET_CODE (X) == PLUS)				\
-    {							\
-      rtx base = 0, index = 0;				\
-      if (REG_P (XEXP (X, 0))				\
-	  && REG_OK_FOR_BASE_P (XEXP (X, 0)))		\
-	base = XEXP (X, 0), index = XEXP (X, 1);	\
-      if (REG_P (XEXP (X, 1))				\
-	  && REG_OK_FOR_BASE_P (XEXP (X, 1)))		\
-	base = XEXP (X, 1), index = XEXP (X, 0);	\
-      if (base != 0 && index != 0)			\
-	{						\
-	  if (GET_CODE (index) == CONST_INT)		\
-	    goto ADDR;					\
-	  if (GET_CODE (index) == CONST)		\
-	    goto ADDR;					\
-	}						\
-    }							\
-}
+do							\
+  {							\
+    if (legitimate_address_p ((MODE), (X), REG_STRICT))	\
+      goto ADDR;					\
+  }							\
+while (0) 
 
 
 /* Try machine-dependent ways of modifying an illegitimate address
-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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