Commit 5de1e2ce by Jim Wilson

(GO_IF_LEGITIMATE_ADDRESS): Also pretend that we have REG plus CONST_INT…

(GO_IF_LEGITIMATE_ADDRESS): Also pretend that we have REG plus CONST_INT addresses by deleting an else.

(GO_IF_LEGITIMATE_ADDRESS): Also pretend that we have REG
plus CONST_INT addresses by deleting an else.
(CONSTANT_ADDRESS_P): When pic, don't accept addresses which are
symbol_ref plus a large integer.
(LEGITIMATE_PIC_OPERAND_P): Likewise.
(LEGITIMIZE_ADDRESS): When pic, convert addresses which are
symbol_reg plus a large integer, to reg plus a large integer.
(ASM_OUTPUT_ADDR_DIFF_ELT): Use .gpword instead of subtracting
labels.

From-SVN: r6849
parent 508a48d1
...@@ -2236,8 +2236,9 @@ typedef struct mips_args { ...@@ -2236,8 +2236,9 @@ typedef struct mips_args {
MIPS assembler does not have syntax to generate the \ MIPS assembler does not have syntax to generate the \
appropriate relocation. */ \ appropriate relocation. */ \
\ \
else if (!TARGET_DEBUG_A_MODE \ /* Also accept CONST_INT addresses here, so no else. */ \
&& CONSTANT_ADDRESS_P (xplus1)) \ if (!TARGET_DEBUG_A_MODE \
&& CONSTANT_ADDRESS_P (xplus1)) \
goto ADDR; \ goto ADDR; \
} \ } \
} \ } \
...@@ -2250,11 +2251,23 @@ typedef struct mips_args { ...@@ -2250,11 +2251,23 @@ typedef struct mips_args {
/* A C expression that is 1 if the RTX X is a constant which is a /* A C expression that is 1 if the RTX X is a constant which is a
valid address. This is defined to be the same as `CONSTANT_P (X)', valid address. This is defined to be the same as `CONSTANT_P (X)',
but rejecting CONST_DOUBLE. */ but rejecting CONST_DOUBLE. */
/* When pic, we must reject addresses of the form symbol+large int.
This is because an instruction `sw $4,s+70000' needs to be converted
by the assembler to `lw $at,s($gp);sw $4,70000($at)'. Normally the
assembler would use $at as a temp to load in the large offset. In this
case $at is already in use. We convert such problem addresses to
`la $5,s;sw $4,70000($5)' via LEGITIMIZE_ADDRESS. */
#define CONSTANT_ADDRESS_P(X) \ #define CONSTANT_ADDRESS_P(X) \
((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
|| GET_CODE (X) == HIGH) && (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X))) || (GET_CODE (X) == CONST \
&& ! (flag_pic && pic_address_needs_scratch (X)))) \
&& (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X)))
/* Define this, so that when PIC, reload won't try to reload invalid
addresses which require two reload registers. */
#define LEGITIMATE_PIC_OPERAND_P(X) (! pic_address_needs_scratch (X))
/* Nonzero if the constant value X is a legitimate general operand. /* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
...@@ -2300,7 +2313,11 @@ typedef struct mips_args { ...@@ -2300,7 +2313,11 @@ typedef struct mips_args {
Z = X + Y Z = X + Y
memory (Z + (<large int> & 0x7fff)); memory (Z + (<large int> & 0x7fff));
This is for CSE to find several similar references, and only use one Z. */ This is for CSE to find several similar references, and only use one Z.
When PIC, convert addresses of the form memory (symbol+large int) to
memory (reg+large int). */
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
{ \ { \
...@@ -2346,6 +2363,16 @@ typedef struct mips_args { ...@@ -2346,6 +2363,16 @@ typedef struct mips_args {
} \ } \
} \ } \
\ \
if (flag_pic && pic_address_needs_scratch (xinsn)) \
{ \
rtx ptr_reg = gen_reg_rtx (Pmode); \
\
emit_move_insn (ptr_reg, XEXP (XEXP (xinsn, 0), 0)); \
\
X = gen_rtx (PLUS, Pmode, ptr_reg, XEXP (XEXP (xinsn, 0), 1)); \
goto WIN; \
} \
\
if (TARGET_DEBUG_B_MODE) \ if (TARGET_DEBUG_B_MODE) \
GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n"); \ GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n"); \
} }
...@@ -3333,13 +3360,12 @@ do { \ ...@@ -3333,13 +3360,12 @@ do { \
VALUE) VALUE)
/* This is how to output an element of a case-vector that is relative. /* This is how to output an element of a case-vector that is relative.
(We do not use such vectors, This is used for pc-relative code (e.g. when TARGET_ABICALLS). */
but we must define this macro anyway.) */
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, VALUE, REL) \ #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, VALUE, REL) \
fprintf (STREAM, "\t%s\t$L%d-$L%d\n", \ fprintf (STREAM, "\t%s\t$L%d\n", \
TARGET_LONG64 ? ".dword" : ".word", \ TARGET_LONG64 ? ".gpdword" : ".gpword", \
VALUE, REL) VALUE)
/* This is how to output an assembler line /* This is how to output an assembler line
that says to advance the location counter that says to advance the location counter
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment