This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[mn10300, installed] improve PICness
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 28 Jun 2004 05:10:49 -0300
- Subject: [mn10300, installed] improve PICness
- Organization: Red Hat Global Engineering Services Compiler Team
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}