aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2003-02-26 11:24:17 +0000
committerRichard Sandiford <rsandifo@redhat.com>2003-02-26 11:24:17 +0000
commit1e59c82dbc5f2609e3bddd3c233ab5b619569a61 (patch)
tree67d25a373a7f8ecbc4278ad56ea93e08f124f1b4
parentd1b8996b44432b85ba8d48dae4c523f1409a9f6c (diff)
* config/mips/mips-protos.h (mips_global_pic_constant_p): Declare.
* config/mips/mips.h (LEA_REGS): New register class. (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add entries for it. (GR_REG_CLASS_P): Include LEA_REGS. (DANGEROUS_FOR_LA25_P): New macro. (EXTRA_CONSTRAINT): Add !DANGEROUS_FOR_LA25_P to R's condition. Add a T constraint for the DANGEROUS_FOR_LA25_P case. * config/mips/mips.c (mips_regno_to_class): Change GR_REGS entries to LEA_REGS. (mips_global_pic_constant_p): New function. (override_options): Add 'e' register constraint. (mips_secondary_reload_class): Return LEA_REGS when reloading a dangerous constant into a class containing $25. * config/mips/mips.md (movdi_internal2): Add an e <- T alternative. (movsi_internal): Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/mips-3_4-rewrite-branch@63465 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.rewrite18
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c33
-rw-r--r--gcc/config/mips/mips.h26
-rw-r--r--gcc/config/mips/mips.md16
5 files changed, 75 insertions, 19 deletions
diff --git a/gcc/ChangeLog.rewrite b/gcc/ChangeLog.rewrite
index 94523939255..0a11c9b8acd 100644
--- a/gcc/ChangeLog.rewrite
+++ b/gcc/ChangeLog.rewrite
@@ -1,3 +1,21 @@
+2003-02-26 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_global_pic_constant_p): Declare.
+ * config/mips/mips.h (LEA_REGS): New register class.
+ (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add entries for it.
+ (GR_REG_CLASS_P): Include LEA_REGS.
+ (DANGEROUS_FOR_LA25_P): New macro.
+ (EXTRA_CONSTRAINT): Add !DANGEROUS_FOR_LA25_P to R's condition.
+ Add a T constraint for the DANGEROUS_FOR_LA25_P case.
+ * config/mips/mips.c (mips_regno_to_class): Change GR_REGS
+ entries to LEA_REGS.
+ (mips_global_pic_constant_p): New function.
+ (override_options): Add 'e' register constraint.
+ (mips_secondary_reload_class): Return LEA_REGS when reloading
+ a dangerous constant into a class containing $25.
+ * config/mips/mips.md (movdi_internal2): Add an e <- T alternative.
+ (movsi_internal): Likewise.
+
2003-02-23 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips.h (TARGET_SPLIT_CALLS): New macro.
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index b3cf2b61c71..2311c9bf480 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -127,6 +127,7 @@ extern int coprocessor2_operand PARAMS ((rtx, enum machine_mode));
extern int mips_address_insns PARAMS ((rtx, enum machine_mode));
extern int mips_fetch_insns PARAMS ((rtx));
extern int mips_const_insns PARAMS ((rtx));
+extern bool mips_global_pic_constant_p PARAMS ((rtx));
extern bool mips_legitimate_address_p PARAMS ((enum machine_mode,
rtx, int));
extern bool mips_legitimize_address PARAMS ((rtx *,
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 6331b428ec1..b9e1d99a0d7 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -624,14 +624,14 @@ char mips_sw_reg_names[][8] =
/* Map hard register number to register class */
const enum reg_class mips_regno_to_class[] =
{
- GR_REGS, GR_REGS, M16_NA_REGS, M16_NA_REGS,
+ LEA_REGS, LEA_REGS, M16_NA_REGS, M16_NA_REGS,
M16_REGS, M16_REGS, M16_REGS, M16_REGS,
- GR_REGS, GR_REGS, GR_REGS, GR_REGS,
- GR_REGS, GR_REGS, GR_REGS, GR_REGS,
- M16_NA_REGS, M16_NA_REGS, GR_REGS, GR_REGS,
- GR_REGS, GR_REGS, GR_REGS, GR_REGS,
- T_REG, PIC_FN_ADDR_REG, GR_REGS, GR_REGS,
- GR_REGS, GR_REGS, GR_REGS, GR_REGS,
+ LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
+ LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
+ M16_NA_REGS, M16_NA_REGS, LEA_REGS, LEA_REGS,
+ LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
+ T_REG, PIC_FN_ADDR_REG, LEA_REGS, LEA_REGS,
+ LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
@@ -1303,6 +1303,20 @@ mips_fetch_insns (x)
}
+/* Return true if OP is a symbolic constant that refers to a
+ global PIC symbol. */
+
+int
+mips_global_pic_constant_p (op)
+ rtx op;
+{
+ struct mips_constant_info c;
+
+ return (mips_classify_constant (&c, op) == CONSTANT_SYMBOLIC
+ && mips_classify_symbol (c.symbol) == SYMBOL_GOT_GLOBAL);
+}
+
+
/* Return truth value of whether OP can be used as an operands
where a register or 16 bit unsigned integer is needed. */
@@ -5686,6 +5700,7 @@ override_options ()
mips_char_to_class['c'] = (TARGET_ABICALLS ? PIC_FN_ADDR_REG :
TARGET_MIPS16 ? M16_NA_REGS :
GR_REGS);
+ mips_char_to_class['e'] = LEA_REGS;
mips_char_to_class['y'] = GR_REGS;
mips_char_to_class['z'] = ST_REGS;
mips_char_to_class['B'] = COP0_REGS;
@@ -8784,6 +8799,10 @@ mips_secondary_reload_class (class, mode, x, in_p)
gp_reg_p = TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
+ if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], 25)
+ && DANGEROUS_FOR_LA25_P (x))
+ return LEA_REGS;
+
/* We always require a general register when copying anything to
HILO_REGNUM, except when copying an SImode value from HILO_REGNUM
to a general register, or when copying from register 0. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index c53420cdcec..56131a5b9e5 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1997,6 +1997,7 @@ enum reg_class
T_REG, /* mips16 T register ($24) */
M16_T_REGS, /* mips16 registers plus T register */
PIC_FN_ADDR_REG, /* SVR4 PIC function address register */
+ LEA_REGS, /* Every GPR except $25 */
GR_REGS, /* integer registers */
FP_REGS, /* floating point registers */
HI_REG, /* hi register */
@@ -2036,6 +2037,7 @@ enum reg_class
"T_REG", \
"M16_T_REGS", \
"PIC_FN_ADDR_REG", \
+ "LEA_REGS", \
"GR_REGS", \
"FP_REGS", \
"HI_REG", \
@@ -2078,6 +2080,7 @@ enum reg_class
{ 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* mips16 T register */ \
{ 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* mips16 and T regs */ \
{ 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* SVR4 PIC function address register */ \
+ { 0xfdffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* Every other GPR */ \
{ 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* integer registers */ \
{ 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* floating registers*/ \
{ 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000 }, /* hi register */ \
@@ -2135,7 +2138,7 @@ extern const enum reg_class mips_regno_to_class[];
#define GR_REG_CLASS_P(CLASS) \
((CLASS) == GR_REGS || (CLASS) == M16_REGS || (CLASS) == T_REG \
|| (CLASS) == M16_T_REGS || (CLASS) == M16_NA_REGS \
- || (CLASS) == PIC_FN_ADDR_REG)
+ || (CLASS) == PIC_FN_ADDR_REG || (CLASS) == LEA_REGS)
/* This macro is also used later on in the file. */
#define COP_REG_CLASS_P(CLASS) \
@@ -2275,6 +2278,15 @@ extern enum reg_class mips_char_to_class[256];
((C) == 'G' \
&& (VALUE) == CONST0_RTX (GET_MODE (VALUE)))
+/* True if OP is a constant that should not be moved into $25.
+ We need this because many versions of gas treat 'la $25,foo' as
+ part of a call sequence and allow a global 'foo' to be lazily bound. */
+
+#define DANGEROUS_FOR_LA25_P(OP) \
+ (TARGET_ABICALLS \
+ && !TARGET_EXPLICIT_RELOCS \
+ && mips_global_pic_constant_p (OP))
+
/* Letters in the range `Q' through `U' may be defined in a
machine-dependent fashion to stand for arbitrary operand types.
The machine description macro `EXTRA_CONSTRAINT' is passed the
@@ -2282,14 +2294,20 @@ extern enum reg_class mips_char_to_class[256];
second operand.
`Q' is for signed 16-bit constants.
- `R' is for constant move_operands.
- `S' is for legitimate constant call addresses. */
+ `R' is for constant move_operands that can be safely loaded into $25.
+ `S' is for legitimate constant call addresses.
+ `T' is for constant move_operands that cannot be safely loaded into $25. */
#define EXTRA_CONSTRAINT(OP,CODE) \
(((CODE) == 'Q') ? const_arith_operand (OP, VOIDmode) \
- : ((CODE) == 'R') ? (CONSTANT_P (OP) && move_operand (OP, VOIDmode)) \
+ : ((CODE) == 'R') ? (CONSTANT_P (OP) \
+ && move_operand (OP, VOIDmode) \
+ && !DANGEROUS_FOR_LA25_P (OP)) \
: ((CODE) == 'S') ? (CONSTANT_P (OP) \
&& call_insn_operand (OP, VOIDmode)) \
+ : ((CODE) == 'T') ? (CONSTANT_P (OP) \
+ && move_operand (OP, VOIDmode) \
+ && DANGEROUS_FOR_LA25_P (OP)) \
: FALSE)
/* Given an rtx X being reloaded into a reg required to be
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index e8d18dcd8f4..b92fb5a4489 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -5268,17 +5268,17 @@ move\\t%0,%z4\\n\\
"")
(define_insn "movdi_internal2"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*d,*m")
- (match_operand:DI 1 "move_operand" "d,R,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*J,*d,*m,*B*C*D,*B*C*D"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*d,*m")
+ (match_operand:DI 1 "move_operand" "d,R,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*J,*d,*m,*B*C*D,*B*C*D"))]
"TARGET_64BIT && !TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
|| operands[1] == CONST0_RTX (DImode))"
"* return mips_move_2words (operands, insn); "
- [(set_attr "type" "move,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
+ [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
(set_attr "mode" "DI")
- (set_attr "length" "4,*,*,*,4,4,*,4,*,4,4,4,8,8,*,8,*")])
+ (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,8,8,*,8,*")])
;; Sign-extended operands are reloaded using this instruction, so the
;; constraints must handle every SImode source operand X and destination
@@ -5581,16 +5581,16 @@ move\\t%0,%z4\\n\\
;; in FP registers (off by default, use -mdebugh to enable).
(define_insn "movsi_internal"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*d,*m")
- (match_operand:SI 1 "move_operand" "d,R,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*B*C*D,*B*C*D"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*d,*m")
+ (match_operand:SI 1 "move_operand" "d,R,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*B*C*D,*B*C*D"))]
"!TARGET_MIPS16
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
"* return mips_move_1word (operands, insn, FALSE);"
- [(set_attr "type" "move,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
+ [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
(set_attr "mode" "SI")
- (set_attr "length" "4,*,*,*,4,4,*,4,*,4,4,4,4,4,4,4,*,4,*")])
+ (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,4,*,4,*")])
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d,*d")