calls. They are used only in non-pic code. */
#define TARGET_LONG_ABS_CALL (TARGET_SOM && !TARGET_GAS)
-/* Define to a C expression evaluating to true to use long pic symbol
- difference calls. This is a call variant similar to the long pic
- pc-relative call. Long pic symbol difference calls are only used with
- the HP SOM linker. Currently, only the HP assembler supports these
- calls. GAS doesn't allow an arbitrary difference of two symbols. */
-#define TARGET_LONG_PIC_SDIFF_CALL (!TARGET_GAS)
-
-/* Define to a C expression evaluating to true to use long pic
- pc-relative calls. Long pic pc-relative calls are only used with
- GAS. Currently, they are usable for calls within a module but
- not for external calls. */
+/* Define to a C expression evaluating to true to use long PIC symbol
+ difference calls. Long PIC symbol difference calls are only used with
+ the HP assembler and linker. The HP assembler detects this instruction
+ sequence and treats it as long pc-relative call. Currently, GAS only
+ allows a difference of two symbols in the same subspace, and it doesn't
+ detect the sequence as a pc-relative call. */
+#define TARGET_LONG_PIC_SDIFF_CALL (!TARGET_GAS && TARGET_HPUX)
+
+/* Define to a C expression evaluating to true to use long PIC
+ pc-relative calls. Long PIC pc-relative calls are only used with
+ GAS. Currently, they are usable for calls which bind local to a
+ module but not for external calls. */
#define TARGET_LONG_PIC_PCREL_CALL 0
/* Define to a C expression evaluating to true to use SOM secondary
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
for any hard reg, then this must be 0 for correct output. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
- (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
+ pa_modes_tieable_p (MODE1, MODE2)
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
#define MAYBE_FP_REG_CLASS_P(CLASS) \
reg_classes_intersect_p ((CLASS), FP_REGS)
-/* On the PA it is not possible to directly move data between
- GENERAL_REGS and FP_REGS. On the 32-bit port, we use the
- location at SP-16. We don't expose this location in the RTL to
- avoid scheduling related problems. For example, the store and
- load could be separated by a call to a pure or const function
- which has no frame and uses SP-16. */
-#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
- (TARGET_64BIT \
- && (MAYBE_FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2) \
- || MAYBE_FP_REG_CLASS_P (CLASS2) != FP_REG_CLASS_P (CLASS1)))
-
\f
/* Stack layout; function entry, exit and calling. */
#define TRAMPOLINE_ADJUST_ADDRESS(ADDR) \
if (!TARGET_64BIT) (ADDR) = memory_address (Pmode, plus_constant ((ADDR), 46))
-
-/* Implement `va_start' for varargs and stdarg. */
-
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
- hppa_va_start (valist, nextarg)
\f
/* Addressing modes, and classification of registers for them.
&& REG_OK_FOR_BASE_P (XEXP (OP, 0)) \
&& GET_CODE (XEXP (OP, 1)) == UNSPEC)
+/* Nonzero if 14-bit offsets can be used for all loads and stores.
+ This is not possible when generating PA 1.x code as floating point
+ loads and stores only support 5-bit offsets. Note that we do not
+ forbid the use of 14-bit offsets in GO_IF_LEGITIMATE_ADDRESS.
+ Instead, we use pa_secondary_reload() to reload integer mode
+ REG+D memory addresses used in floating point loads and stores.
+
+ FIXME: the ELF32 linker clobbers the LSB of the FP register number
+ in PA 2.0 floating-point insns with long displacements. This is
+ because R_PARISC_DPREL14WR and other relocations like it are not
+ yet supported by GNU ld. For now, we reject long displacements
+ on this target. */
+
+#define INT14_OK_STRICT \
+ (TARGET_SOFT_FLOAT \
+ || TARGET_DISABLE_FPREGS \
+ || (TARGET_PA_20 && !TARGET_ELF32))
+
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
/* Nonzero if X is a hard reg that can be used as an index
or if it is a pseudo reg. */
#define REG_OK_FOR_INDEX_P(X) \
-(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+ (REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+
/* Nonzero if X is a hard reg that can be used as a base reg
or if it is a pseudo reg. */
#define REG_OK_FOR_BASE_P(X) \
-(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+ (REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
#else
/* Nonzero if X is a hard reg that can be used as an index. */
#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+
/* Nonzero if X is a hard reg that can be used as a base reg. */
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
We treat a SYMBOL_REF as legitimate if it is part of the current
function's constant-pool, because such addresses can actually be
- output as REG+SMALLINT.
-
- Note we only allow 5-bit immediates for access to a constant address;
- doing so avoids losing for loading/storing a FP register at an address
- which will not fit in 5 bits. */
+ output as REG+SMALLINT. */
#define VAL_5_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x10 < 0x20)
#define INT_5_BITS(X) VAL_5_BITS_P (INTVAL (X))
((TARGET_64BIT && (MODE) == DImode) \
|| (MODE) == SImode \
|| (MODE) == HImode \
- || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))
+ || (MODE) == SFmode \
+ || (MODE) == DFmode)
/* These are the modes that we allow for unscaled indexing. */
#define MODE_OK_FOR_UNSCALED_INDEXING_P(MODE) \
|| (MODE) == SImode \
|| (MODE) == HImode \
|| (MODE) == QImode \
- || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))
+ || (MODE) == SFmode \
+ || (MODE) == DFmode)
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ \
|| (INTVAL (index) % 8) == 0)) \
/* Similarly, the base register for SFmode/DFmode \
loads and stores with long displacements must \
- be aligned. \
- \
- FIXME: the ELF32 linker clobbers the LSB of \
- the FP register number in PA 2.0 floating-point \
- insns with long displacements. This is because \
- R_PARISC_DPREL14WR and other relocations like \
- it are not supported. For now, we reject long \
- displacements on this target. */ \
+ be aligned. */ \
|| (((MODE) == SFmode || (MODE) == DFmode) \
- && (TARGET_SOFT_FLOAT \
- || (TARGET_PA_20 \
- && !TARGET_ELF32 \
- && (INTVAL (index) \
- % GET_MODE_SIZE (MODE)) == 0))))) \
+ && INT14_OK_STRICT \
+ && (INTVAL (index) % GET_MODE_SIZE (MODE)) == 0))) \
|| INT_5_BITS (index))) \
goto ADDR; \
if (!TARGET_DISABLE_INDEXING \
rtx new, temp = NULL_RTX; \
\
mask = (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- ? (TARGET_PA_20 && !TARGET_ELF32 ? 0x3fff : 0x1f) : 0x3fff); \
+ ? (INT14_OK_STRICT ? 0x3fff : 0x1f) : 0x3fff); \
\
if (optimize && GET_CODE (AD) == PLUS) \
temp = simplify_binary_operation (PLUS, Pmode, \
newoffset = offset & ~mask; \
\
/* Ensure that long displacements are aligned. */ \
- if (!VAL_5_BITS_P (newoffset) \
- && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
- newoffset &= ~(GET_MODE_SIZE (MODE) -1); \
+ if (mask == 0x3fff \
+ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ || (TARGET_64BIT && (MODE) == DImode))) \
+ newoffset &= ~(GET_MODE_SIZE (MODE) - 1); \
\
if (newoffset != 0 && VAL_14_BITS_P (newoffset)) \
{ \