diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1994-03-22 16:03:04 -0800 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1994-03-22 16:03:04 -0800 |
commit | 5de1e2cef4e8cd750d44a2ca52b550f212d7454e (patch) | |
tree | deb48b299d1dc5b5a113c9a1d4ee85ef92c739dc | |
parent | 508a48d1f460d14cbe808ec9932a747fcedfce5d (diff) | |
download | gcc-5de1e2cef4e8cd750d44a2ca52b550f212d7454e.zip gcc-5de1e2cef4e8cd750d44a2ca52b550f212d7454e.tar.gz gcc-5de1e2cef4e8cd750d44a2ca52b550f212d7454e.tar.bz2 |
(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
-rw-r--r-- | gcc/config/mips/mips.h | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index ba17866..d46ac65 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2236,8 +2236,9 @@ typedef struct mips_args { MIPS assembler does not have syntax to generate the \ appropriate relocation. */ \ \ - else if (!TARGET_DEBUG_A_MODE \ - && CONSTANT_ADDRESS_P (xplus1)) \ + /* Also accept CONST_INT addresses here, so no else. */ \ + if (!TARGET_DEBUG_A_MODE \ + && CONSTANT_ADDRESS_P (xplus1)) \ goto ADDR; \ } \ } \ @@ -2250,11 +2251,23 @@ typedef struct mips_args { /* 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)', 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) \ ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ - || GET_CODE (X) == HIGH) && (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X))) + || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \ + || (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. It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. @@ -2300,7 +2313,11 @@ typedef struct mips_args { Z = X + Y 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) \ { \ @@ -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) \ GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n"); \ } @@ -3333,13 +3360,12 @@ do { \ VALUE) /* This is how to output an element of a case-vector that is relative. - (We do not use such vectors, - but we must define this macro anyway.) */ + This is used for pc-relative code (e.g. when TARGET_ABICALLS). */ #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, VALUE, REL) \ - fprintf (STREAM, "\t%s\t$L%d-$L%d\n", \ - TARGET_LONG64 ? ".dword" : ".word", \ - VALUE, REL) + fprintf (STREAM, "\t%s\t$L%d\n", \ + TARGET_LONG64 ? ".gpdword" : ".gpword", \ + VALUE) /* This is how to output an assembler line that says to advance the location counter |