-/* 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. */
-/* ??? SGI Irix 6 assembler fails for CONST address, so reject them
- when !TARGET_GAS. */
-/* We should be rejecting everything but const addresses. */
-#define CONSTANT_ADDRESS_P(X) \
- (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
- || (GET_CODE (X) == CONST \
- && ! (flag_pic && pic_address_needs_scratch (X)) \
- && (TARGET_GAS) \
- && (mips_abi != ABI_N32 \
- && mips_abi != ABI_64)))
-
-
-/* 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.
-
- At present, GAS doesn't understand li.[sd], so don't allow it
- to be generated at present. Also, the MIPS assembler does not
- grok li.d Infinity. */
-
-/* ??? SGI Irix 6 assembler fails for CONST address, so reject them.
- Note that the Irix 6 assembler problem may already be fixed.
- Note also that the GET_CODE (X) == CONST test catches the mips16
- gp pseudo reg (see mips16_gp_pseudo_reg) deciding it is not
- a LEGITIMATE_CONSTANT. If we ever want mips16 and ABI_N32 or
- ABI_64 to work together, we'll need to fix this. */
-#define LEGITIMATE_CONSTANT_P(X) \
- ((GET_CODE (X) != CONST_DOUBLE \
- || mips_const_double_ok (X, GET_MODE (X))) \
- && ! (GET_CODE (X) == CONST \
- && ! TARGET_GAS \
- && (mips_abi == ABI_N32 \
- || mips_abi == ABI_64)) \
- && (! TARGET_MIPS16 || mips16_constant (X, GET_MODE (X), 0, 0)))
-
-/* A C compound statement that attempts to replace X with a valid
- memory address for an operand of mode MODE. WIN will be a C
- statement label elsewhere in the code; the macro definition may
- use
-
- GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN);
-
- to avoid further processing if the address has become legitimate.
-
- X will always be the result of a call to `break_out_memory_refs',
- and OLDX will be the operand that was given to that function to
- produce X.
-
- The code generated by this macro should not alter the
- substructure of X. If it transforms X into a more legitimate
- form, it should assign X (which will always be a C variable) a
- new value.
-
- It is not necessary for this macro to come up with a legitimate
- address. The compiler has standard ways of doing so in all
- cases. In fact, it is safe for this macro to do nothing. But
- often a machine-dependent strategy can generate better code.
-
- For the MIPS, transform:
-
- memory(X + <large int>)
-
- into:
-
- Y = <large int> & ~0x7fff;
- Z = X + Y
- memory (Z + (<large int> & 0x7fff));
-
- 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) \
-{ \
- register rtx xinsn = (X); \
- \
- if (TARGET_DEBUG_B_MODE) \
- { \
- GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n"); \
- GO_DEBUG_RTX (xinsn); \
- } \
- \
- if (mips_split_addresses && mips_check_split (X, MODE)) \
- { \
- /* ??? Is this ever executed? */ \
- X = gen_rtx_LO_SUM (Pmode, \
- copy_to_mode_reg (Pmode, \
- gen_rtx (HIGH, Pmode, X)), \
- X); \
- goto WIN; \
- } \
- \
- if (GET_CODE (xinsn) == CONST \
- && ((flag_pic && pic_address_needs_scratch (xinsn)) \
- /* ??? SGI's Irix 6 assembler can't handle CONST. */ \
- || (!TARGET_GAS \
- && (mips_abi == ABI_N32 \
- || mips_abi == ABI_64)))) \
- { \
- rtx ptr_reg = gen_reg_rtx (Pmode); \
- rtx constant = XEXP (XEXP (xinsn, 0), 1); \
- \
- emit_move_insn (ptr_reg, XEXP (XEXP (xinsn, 0), 0)); \
- \
- X = gen_rtx_PLUS (Pmode, ptr_reg, constant); \
- if (SMALL_INT (constant)) \
- goto WIN; \
- /* Otherwise we fall through so the code below will fix the \
- constant. */ \
- xinsn = X; \
- } \
- \
- if (GET_CODE (xinsn) == PLUS) \
- { \
- register rtx xplus0 = XEXP (xinsn, 0); \
- register rtx xplus1 = XEXP (xinsn, 1); \
- register enum rtx_code code0 = GET_CODE (xplus0); \
- register enum rtx_code code1 = GET_CODE (xplus1); \
- \
- if (code0 != REG && code1 == REG) \
- { \
- xplus0 = XEXP (xinsn, 1); \
- xplus1 = XEXP (xinsn, 0); \
- code0 = GET_CODE (xplus0); \
- code1 = GET_CODE (xplus1); \
- } \
- \
- if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, MODE) \
- && code1 == CONST_INT && !SMALL_INT (xplus1)) \
- { \
- rtx int_reg = gen_reg_rtx (Pmode); \
- rtx ptr_reg = gen_reg_rtx (Pmode); \
- \
- emit_move_insn (int_reg, \
- GEN_INT (INTVAL (xplus1) & ~ 0x7fff)); \
- \
- emit_insn (gen_rtx_SET (VOIDmode, \
- ptr_reg, \
- gen_rtx_PLUS (Pmode, xplus0, int_reg))); \
- \
- X = plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff); \
- goto WIN; \
- } \
- } \
- \
- if (TARGET_DEBUG_B_MODE) \
- GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n"); \
-}