/* Definitions of target machine for GNU compiler, for the HP Spectrum.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) of Cygnus Support
and Tim Moore (moore@defmacro.cs.utah.edu) of the Center for
Software Science at the University of Utah.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
enum cmp_type /* comparison type */
{
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. */
is already live or already being saved (due to eh). */
#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
- ((NEW_REG) != 2 || regs_ever_live[2] || current_function_calls_eh_return)
+ ((NEW_REG) != 2 || df_regs_ever_live_p (2) || current_function_calls_eh_return)
/* C statement to store the difference between the frame pointer
and the stack pointer values immediately after the function prologue.
#define EH_RETURN_DATA_REGNO(N) \
((N) < 3 ? (N) + 20 : (N) == 3 ? 31 : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 29)
-#define EH_RETURN_HANDLER_RTX \
- gen_rtx_MEM (word_mode, \
- gen_rtx_PLUS (word_mode, frame_pointer_rtx, \
- TARGET_64BIT ? GEN_INT (-16) : GEN_INT (-20)))
+#define EH_RETURN_HANDLER_RTX pa_eh_return_handler_rtx ()
/* Offset from the frame pointer register value to the top of stack. */
#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0
} \
} while (0)
\f
-/* The letters I, J, K, L and M in a register constraint string
- can be used to stand for particular ranges of immediate operands.
- This macro defines what the ranges are.
- C is the letter, and VALUE is a constant value.
- Return 1 if VALUE is in the range specified by C.
-
- `I' is used for the 11-bit constants.
- `J' is used for the 14-bit constants.
- `K' is used for values that can be moved with a zdepi insn.
- `L' is used for the 5-bit constants.
- `M' is used for 0.
- `N' is used for values with the least significant 11 bits equal to zero
- and when sign extended from 32 to 64 bits the
- value does not change.
- `O' is used for numbers n such that n+1 is a power of 2.
- */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'I' ? VAL_11_BITS_P (VALUE) \
- : (C) == 'J' ? VAL_14_BITS_P (VALUE) \
- : (C) == 'K' ? zdepi_cint_p (VALUE) \
- : (C) == 'L' ? VAL_5_BITS_P (VALUE) \
- : (C) == 'M' ? (VALUE) == 0 \
- : (C) == 'N' ? (((VALUE) & (((HOST_WIDE_INT) -1 << 31) | 0x7ff)) == 0 \
- || (((VALUE) & (((HOST_WIDE_INT) -1 << 31) | 0x7ff)) \
- == (HOST_WIDE_INT) -1 << 31)) \
- : (C) == 'O' ? (((VALUE) & ((VALUE) + 1)) == 0) \
- : (C) == 'P' ? and_mask_p (VALUE) \
- : 0)
-
-/* Similar, but for floating or large integer constants, and defining letters
- G and H. Here VALUE is the CONST_DOUBLE rtx itself.
-
- For PA, `G' is the floating-point constant zero. `H' is undefined. */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
- && (VALUE) == CONST0_RTX (GET_MODE (VALUE))) \
- : 0)
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS GENERAL_REGS
#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.
#define SYMBOL_REF_REFERENCED_P(RTX) \
((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_REFERENCED) != 0)
-/* Subroutines for EXTRA_CONSTRAINT.
-
- Return 1 iff OP is a pseudo which did not get a hard register and
- we are running the reload pass. */
-#define IS_RELOADING_PSEUDO_P(OP) \
- ((reload_in_progress \
- && GET_CODE (OP) == REG \
- && REGNO (OP) >= FIRST_PSEUDO_REGISTER \
- && reg_renumber [REGNO (OP)] < 0))
+/* Defines for constraints.md. */
/* Return 1 iff OP is a scaled or unscaled index address. */
#define IS_INDEX_ADDR_P(OP) \
&& REG_OK_FOR_BASE_P (XEXP (OP, 0)) \
&& GET_CODE (XEXP (OP, 1)) == UNSPEC)
-/* Optional extra constraints for this machine. Borrowed from sparc.h.
-
- `A' is a LO_SUM DLT memory operand.
-
- `Q' is any memory operand that isn't a symbolic, indexed or lo_sum
- memory operand. Note that an unassigned pseudo register is such a
- memory operand. Needed because reload will generate these things
- and then not re-recognize the insn, causing constrain_operands to
- fail.
-
- `R' is a scaled/unscaled indexed memory operand.
-
- `S' is the constant 31.
-
- `T' is for floating-point loads and stores.
-
- `U' is the constant 63.
-
- `W' is a register indirect memory operand. We could allow short
- displacements but GO_IF_LEGITIMATE_ADDRESS can't tell when a
- long displacement is valid. This is only used for prefetch
- instructions with the `sl' completer. */
-
-#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? \
- (IS_RELOADING_PSEUDO_P (OP) \
- || (GET_CODE (OP) == MEM \
- && (reload_in_progress \
- || memory_address_p (GET_MODE (OP), XEXP (OP, 0))) \
- && !symbolic_memory_operand (OP, VOIDmode) \
- && !IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0)) \
- && !IS_INDEX_ADDR_P (XEXP (OP, 0)))) \
- : ((C) == 'W' ? \
- (GET_CODE (OP) == MEM \
- && REG_P (XEXP (OP, 0)) \
- && REG_OK_FOR_BASE_P (XEXP (OP, 0))) \
- : ((C) == 'A' ? \
- (GET_CODE (OP) == MEM \
- && IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0))) \
- : ((C) == 'R' ? \
- (GET_CODE (OP) == MEM \
- && IS_INDEX_ADDR_P (XEXP (OP, 0))) \
- : ((C) == 'T' ? \
- (GET_CODE (OP) == MEM \
- && !IS_LO_SUM_DLT_ADDR_P (XEXP (OP, 0)) \
- && !IS_INDEX_ADDR_P (XEXP (OP, 0)) \
- /* Floating-point loads and stores are used to load \
- integer values as well as floating-point values. \
- They don't have the same set of REG+D address modes \
- as integer loads and stores. PA 1.x supports only \
- short displacements. PA 2.0 supports long displacements \
- but the base register needs to be aligned. \
- \
- The checks in GO_IF_LEGITIMATE_ADDRESS for SFmode and \
- DFmode test the validity of an address for use in a \
- floating point load or store. So, we use SFmode/DFmode \
- to see if the address is valid for a floating-point \
- load/store operation. */ \
- && memory_address_p ((GET_MODE_SIZE (GET_MODE (OP)) == 4 \
- ? SFmode \
- : DFmode), \
- XEXP (OP, 0))) \
- : ((C) == 'S' ? \
- (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 31) \
- : ((C) == 'U' ? \
- (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 63) : 0)))))))
-
+/* 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.
/* 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)) \
{ \
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
pa_asm_output_aligned_local (FILE, NAME, SIZE, ALIGN)
-
-#define ASM_PN_FORMAT "%s___%lu"
-
/* All HP assemblers use "!" to separate logical lines. */
-#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '!')
+#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == '!')
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
((CHAR) == '@' || (CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^')