/* Definitions of target machine for GNU compiler, for IBM RS/6000.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GCC.
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
+ by 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, but WITHOUT
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/>. */
/* Note that some other tm.h files include this one and then override
many of the definitions. */
#define PPC405_ERRATUM77 0
#endif
+#ifndef TARGET_PAIRED_FLOAT
+#define TARGET_PAIRED_FLOAT 0
+#endif
+
+#ifdef HAVE_AS_POPCNTB
+#define ASM_CPU_POWER5_SPEC "-mpower5"
+#else
+#define ASM_CPU_POWER5_SPEC "-mpower4"
+#endif
+
+#ifdef HAVE_AS_DFP
+#define ASM_CPU_POWER6_SPEC "-mpower6 -maltivec"
+#else
+#define ASM_CPU_POWER6_SPEC "-mpower4 -maltivec"
+#endif
+
/* Common ASM definitions used by ASM_SPEC among the various targets
for handling -mcpu=xxx switches. */
#define ASM_CPU_SPEC \
%{mno-power: %{!mpowerpc*: -mcom}} \
%{!mno-power: %{!mpower*: %(asm_default)}}} \
%{mcpu=common: -mcom} \
+%{mcpu=cell: -mcell} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwrx} \
%{mcpu=power3: -mppc64} \
%{mcpu=power4: -mpower4} \
-%{mcpu=power5: -mpower4} \
-%{mcpu=power5+: -mpower4} \
+%{mcpu=power5: %(asm_cpu_power5)} \
+%{mcpu=power5+: %(asm_cpu_power5)} \
+%{mcpu=power6: %(asm_cpu_power6) -maltivec} \
+%{mcpu=power6x: %(asm_cpu_power6) -maltivec} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
%{mcpu=970: -mpower4 -maltivec} \
%{mcpu=G5: -mpower4 -maltivec} \
%{mcpu=8540: -me500} \
+%{mcpu=8548: -me500} \
+%{mcpu=e300c2: -me300} \
+%{mcpu=e300c3: -me300} \
%{maltivec: -maltivec} \
-many"
{ "cpp_default", CPP_DEFAULT_SPEC }, \
{ "asm_cpu", ASM_CPU_SPEC }, \
{ "asm_default", ASM_DEFAULT_SPEC }, \
+ { "cc1_cpu", CC1_CPU_SPEC }, \
+ { "asm_cpu_power5", ASM_CPU_POWER5_SPEC }, \
+ { "asm_cpu_power6", ASM_CPU_POWER6_SPEC }, \
SUBTARGET_EXTRA_SPECS
+/* -mcpu=native handling only makes sense with compiler running on
+ an PowerPC chip. If changing this condition, also change
+ the condition in driver-rs6000.c. */
+#if defined(__powerpc__) || defined(__POWERPC__) || defined(_AIX)
+/* In driver-rs6000.c. */
+extern const char *host_detect_local_cpu (int argc, const char **argv);
+#define EXTRA_SPEC_FUNCTIONS \
+ { "local_cpu_detect", host_detect_local_cpu },
+#define HAVE_LOCAL_CPU_DETECT
+#endif
+
+#ifndef CC1_CPU_SPEC
+#ifdef HAVE_LOCAL_CPU_DETECT
+#define CC1_CPU_SPEC \
+"%{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)} \
+ %{mtune=native:%<mtune=native %:local_cpu_detect(tune)}"
+#else
+#define CC1_CPU_SPEC ""
+#endif
+#endif
+
/* Architecture type. */
/* Define TARGET_MFCRF if the target assembler does not support the
#define TARGET_FPRND 0
#endif
+/* Define TARGET_CMPB if the target assembler does not support the
+ cmpb instruction. */
+
+#ifndef HAVE_AS_CMPB
+#undef TARGET_CMPB
+#define TARGET_CMPB 0
+#endif
+
+/* Define TARGET_MFPGPR if the target assembler does not support the
+ mffpr and mftgpr instructions. */
+
+#ifndef HAVE_AS_MFPGPR
+#undef TARGET_MFPGPR
+#define TARGET_MFPGPR 0
+#endif
+
+/* Define TARGET_DFP if the target assembler does not support decimal
+ floating point instructions. */
+#ifndef HAVE_AS_DFP
+#undef TARGET_DFP
+#define TARGET_DFP 0
+#endif
+
#ifndef TARGET_SECURE_PLT
#define TARGET_SECURE_PLT 0
#endif
#ifdef IN_LIBGCC2
/* For libgcc2 we make sure this is a compile time constant */
-#if defined (__64BIT__) || defined (__powerpc64__)
+#if defined (__64BIT__) || defined (__powerpc64__) || defined (__ppc64__)
#undef TARGET_POWERPC64
#define TARGET_POWERPC64 1
#else
PROCESSOR_PPC7400,
PROCESSOR_PPC7450,
PROCESSOR_PPC8540,
+ PROCESSOR_PPCE300C2,
+ PROCESSOR_PPCE300C3,
PROCESSOR_POWER4,
- PROCESSOR_POWER5
+ PROCESSOR_POWER5,
+ PROCESSOR_POWER6,
+ PROCESSOR_CELL
};
extern enum processor_type rs6000_cpu;
/* These are separate from target_flags because we've run out of bits
there. */
extern int rs6000_long_double_type_size;
+extern int rs6000_ieeequad;
extern int rs6000_altivec_abi;
extern int rs6000_spe_abi;
+extern int rs6000_spe;
+extern int rs6000_isel;
extern int rs6000_float_gprs;
extern int rs6000_alignment_flags;
extern const char *rs6000_sched_insert_nops_str;
#endif
#define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
+#define TARGET_IEEEQUAD rs6000_ieeequad
#define TARGET_ALTIVEC_ABI rs6000_altivec_abi
#define TARGET_SPE_ABI 0
#define TARGET_FPRS 1
#define TARGET_E500_SINGLE 0
#define TARGET_E500_DOUBLE 0
+#define CHECK_E500_OPTIONS do { } while (0)
+
+/* E500 processors only support plain "sync", not lwsync. */
+#define TARGET_NO_LWSYNC TARGET_E500
/* Sometimes certain combinations of command options do not make sense
on a particular target machine. You can define a macro
#define UNITS_PER_FP_WORD 8
#define UNITS_PER_ALTIVEC_WORD 16
#define UNITS_PER_SPE_WORD 8
+#define UNITS_PER_PAIRED_WORD 8
/* Type used for ptrdiff_t, as a string used in a declaration. */
#define PTRDIFF_TYPE "int"
that the object would ordinarily have. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \
- (TARGET_E500_DOUBLE && TYPE_MODE (TYPE) == DFmode) ? 64 : \
- (TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE) ? 64 : ALIGN)
+ (TARGET_E500_DOUBLE \
+ && (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 : \
+ ((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE \
+ && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \
+ && TREE_CODE (TYPE) == VECTOR_TYPE \
+ && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) ? 64 : ALIGN)
/* Alignment of field after `int : 0' in a structure. */
#define EMPTY_FIELD_BOUNDARY 32
fit into 1, whereas DI still needs two. */
#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
((TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
- || (TARGET_E500_DOUBLE && (MODE) == DFmode))
+ || (TARGET_E500_DOUBLE && ((MODE) == DFmode || (MODE) == DDmode)))
/* A bit-field declared as `int' forces `int' alignment for the struct. */
#define PCC_BITFIELD_TYPE_MATTERS 1
Make vector constants quadword aligned. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
(TREE_CODE (EXP) == STRING_CST \
+ && (STRICT_ALIGNMENT || !optimize_size) \
&& (ALIGN) < BITS_PER_WORD \
? BITS_PER_WORD \
: (ALIGN))
Align vectors to 128 bits. Align SPE vectors and E500 v2 doubles to
64 bits. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
- (TREE_CODE (TYPE) == VECTOR_TYPE ? (TARGET_SPE_ABI ? 64 : 128) \
- : (TARGET_E500_DOUBLE && TYPE_MODE (TYPE) == DFmode) ? 64 \
+ (TREE_CODE (TYPE) == VECTOR_TYPE ? ((TARGET_SPE_ABI \
+ || TARGET_PAIRED_FLOAT) ? 64 : 128) \
+ : (TARGET_E500_DOUBLE \
+ && (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 \
: TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
(STRICT_ALIGNMENT \
|| (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
+ || (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode \
|| (MODE) == DImode) \
&& (ALIGN) < 32))
\f
#define DWARF_REG_TO_UNWIND_COLUMN(r) \
((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER - 1) : (r))
+/* Use standard DWARF numbering for DWARF debugging information. */
+#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
+
/* Use gcc hard register numbering for eh_frame. */
#define DWARF_FRAME_REGNUM(REGNO) (REGNO)
+/* Map register numbers held in the call frame info that gcc has
+ collected using DWARF_FRAME_REGNUM to those that should be output in
+ .debug_frame and .eh_frame. We continue to use gcc hard reg numbers
+ for .eh_frame, but use the numbers mandated by the various ABIs for
+ .debug_frame. rs6000_emit_prologue has translated any combination of
+ CR2, CR3, CR4 saves to a save of CR2. The actual code emitted saves
+ the whole of CR, so we map CR2_REGNO to the DWARF reg for CR. */
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) \
+ ((FOR_EH) ? (REGNO) \
+ : (REGNO) == CR2_REGNO ? 64 \
+ : DBX_REGISTER_NUMBER (REGNO))
+
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
, 0, 0, 0 \
}
-#define MQ_REGNO 64
-#define CR0_REGNO 68
-#define CR1_REGNO 69
-#define CR2_REGNO 70
-#define CR3_REGNO 71
-#define CR4_REGNO 72
-#define MAX_CR_REGNO 75
-#define XER_REGNO 76
-#define FIRST_ALTIVEC_REGNO 77
-#define LAST_ALTIVEC_REGNO 108
#define TOTAL_ALTIVEC_REGS (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO + 1)
-#define VRSAVE_REGNO 109
-#define VSCR_REGNO 110
-#define SPE_ACC_REGNO 111
-#define SPEFSCR_REGNO 112
#define FIRST_SAVED_ALTIVEC_REGNO (FIRST_ALTIVEC_REGNO+20)
#define FIRST_SAVED_FP_REGNO (14+32)
#define FP_REGNO_P(N) ((N) >= 32 && (N) <= 63)
/* True if register is a condition register. */
-#define CR_REGNO_P(N) ((N) >= 68 && (N) <= 75)
+#define CR_REGNO_P(N) ((N) >= CR0_REGNO && (N) <= CR7_REGNO)
/* True if register is a condition register, but not cr0. */
-#define CR_REGNO_NOT_CR0_P(N) ((N) >= 69 && (N) <= 75)
+#define CR_REGNO_NOT_CR0_P(N) ((N) >= CR1_REGNO && (N) <= CR7_REGNO)
/* True if register is an integer register. */
#define INT_REGNO_P(N) \
/* SPE SIMD registers are just the GPRs. */
#define SPE_SIMD_REGNO_P(N) ((N) <= 31)
+/* PAIRED SIMD registers are just the FPRs. */
+#define PAIRED_SIMD_REGNO_P(N) ((N) >= 32 && (N) <= 63)
+
/* True if register is the XER register. */
#define XER_REGNO_P(N) ((N) == XER_REGNO)
|| (MODE) == V1DImode \
|| (MODE) == V2SImode)
-#define UNITS_PER_SIMD_WORD \
- (TARGET_ALTIVEC ? UNITS_PER_ALTIVEC_WORD \
- : (TARGET_SPE ? UNITS_PER_SPE_WORD : UNITS_PER_WORD))
+#define PAIRED_VECTOR_MODE(MODE) \
+ ((MODE) == V2SFmode)
+
+#define UNITS_PER_SIMD_WORD \
+ (TARGET_ALTIVEC ? UNITS_PER_ALTIVEC_WORD \
+ : (TARGET_SPE ? UNITS_PER_SPE_WORD : (TARGET_PAIRED_FLOAT ? \
+ UNITS_PER_PAIRED_WORD : UNITS_PER_WORD)))
/* Value is TRUE if hard register REGNO can hold a value of
machine-mode MODE. */
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) == MODE_FLOAT \
- ? GET_MODE_CLASS (MODE2) == MODE_FLOAT \
- : GET_MODE_CLASS (MODE2) == MODE_FLOAT \
- ? GET_MODE_CLASS (MODE1) == MODE_FLOAT \
+ (SCALAR_FLOAT_MODE_P (MODE1) \
+ ? SCALAR_FLOAT_MODE_P (MODE2) \
+ : SCALAR_FLOAT_MODE_P (MODE2) \
+ ? SCALAR_FLOAT_MODE_P (MODE1) \
: GET_MODE_CLASS (MODE1) == MODE_CC \
? GET_MODE_CLASS (MODE2) == MODE_CC \
: GET_MODE_CLASS (MODE2) == MODE_CC \
emitted the vrsave mask. */
#define HARD_REGNO_RENAME_OK(SRC, DST) \
- (! ALTIVEC_REGNO_P (DST) || regs_ever_live[DST])
+ (! ALTIVEC_REGNO_P (DST) || df_regs_ever_live_p (DST))
/* A C expression returning the cost of moving data from a register of class
CLASS1 to one of CLASS2. */
#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
-/* A fixed register used at prologue and epilogue generation to fix
- addressing modes. The SPE needs heavy addressing fixes at the last
- minute, and it's best to save a register for it.
-
- AltiVec also needs fixes, but we've gotten around using r11, which
- is actually wrong because when use_backchain_to_restore_sp is true,
- we end up clobbering r11.
-
- The AltiVec case needs to be fixed. Dunno if we should break ABI
- compatibility and reserve a register for it as well.. */
+/* A fixed register used at epilogue generation to address SPE registers
+ with negative offsets. The 64-bit load/store instructions on the SPE
+ only take positive offsets (and small ones at that), so we need to
+ reserve a register for consing up negative offsets. */
-#define FIXED_SCRATCH (TARGET_SPE ? 14 : 11)
+#define FIXED_SCRATCH 0
/* Define this macro to change register usage conditional on target
flags. */
/* Place to put static chain when calling a function that requires it. */
#define STATIC_CHAIN_REGNUM 11
-/* Link register number. */
-#define LINK_REGISTER_REGNUM 65
-
-/* Count register number. */
-#define COUNT_REGISTER_REGNUM 66
\f
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
{ 0xffffffff, 0x00000000, 0x0000000f, 0x00022000 }, /* SPEC_OR_GEN_REGS */ \
{ 0x00000000, 0x00000000, 0x00000010, 0x00000000 }, /* CR0_REGS */ \
{ 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */ \
- { 0xffffffff, 0x00000000, 0x0000efff, 0x00000000 }, /* NON_FLOAT_REGS */ \
+ { 0xffffffff, 0x00000000, 0x0000efff, 0x00020000 }, /* NON_FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* XER_REGS */ \
{ 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff } /* ALL_REGS */ \
}
: (REGNO) == CR0_REGNO ? CR0_REGS \
: CR_REGNO_P (REGNO) ? CR_REGS \
: (REGNO) == MQ_REGNO ? MQ_REGS \
- : (REGNO) == LINK_REGISTER_REGNUM ? LINK_REGS \
- : (REGNO) == COUNT_REGISTER_REGNUM ? CTR_REGS \
+ : (REGNO) == LR_REGNO ? LINK_REGS \
+ : (REGNO) == CTR_REGNO ? CTR_REGS \
: (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS \
: (REGNO) == XER_REGNO ? XER_REGS \
: (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS \
#define INDEX_REG_CLASS GENERAL_REGS
#define BASE_REG_CLASS BASE_REGS
-/* Get reg_class from a letter such as appears in the machine description. */
-
-#define REG_CLASS_FROM_LETTER(C) \
- ((C) == 'f' ? ((TARGET_HARD_FLOAT && TARGET_FPRS) ? FLOAT_REGS : NO_REGS) \
- : (C) == 'b' ? BASE_REGS \
- : (C) == 'h' ? SPECIAL_REGS \
- : (C) == 'q' ? MQ_REGS \
- : (C) == 'c' ? CTR_REGS \
- : (C) == 'l' ? LINK_REGS \
- : (C) == 'v' ? ALTIVEC_REGS \
- : (C) == 'x' ? CR0_REGS \
- : (C) == 'y' ? CR_REGS \
- : (C) == 'z' ? XER_REGS \
- : NO_REGS)
-
-/* The letters I, J, K, L, M, N, and P 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 a signed 16-bit constant
- `J' is a constant with only the high-order 16 bits nonzero
- `K' is a constant with only the low-order 16 bits nonzero
- `L' is a signed 16-bit constant shifted left 16 bits
- `M' is a constant that is greater than 31
- `N' is a positive constant that is an exact power of two
- `O' is the constant zero
- `P' is a constant whose negation is a signed 16-bit constant */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000 \
- : (C) == 'J' ? ((VALUE) & (~ (unsigned HOST_WIDE_INT) 0xffff0000)) == 0 \
- : (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0 \
- : (C) == 'L' ? (((VALUE) & 0xffff) == 0 \
- && ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0)) \
- : (C) == 'M' ? (VALUE) > 31 \
- : (C) == 'N' ? (VALUE) > 0 && exact_log2 (VALUE) >= 0 \
- : (C) == 'O' ? (VALUE) == 0 \
- : (C) == 'P' ? (unsigned HOST_WIDE_INT) ((- (VALUE)) + 0x8000) < 0x10000 \
- : 0)
-
-/* Similar, but for floating constants, and defining letters G and H.
- Here VALUE is the CONST_DOUBLE rtx itself.
-
- We flag for special constants when we can copy the constant into
- a general register in two insns for DF/DI and one insn for SF.
-
- 'H' is used for DI/DF constants that take 3 insns. */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
- ( (C) == 'G' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) \
- == ((GET_MODE (VALUE) == SFmode) ? 1 : 2)) \
- : (C) == 'H' ? (num_insns_constant (VALUE, GET_MODE (VALUE)) == 3) \
- : 0)
-
-/* Optional extra constraints for this machine.
-
- 'Q' means that is a memory operand that is just an offset from a reg.
- 'R' is for AIX TOC entries.
- 'S' is a constant that can be placed into a 64-bit mask operand.
- 'T' is a constant that can be placed into a 32-bit mask operand.
- 'U' is for V.4 small data references.
- 'W' is a vector constant that can be easily generated (no mem refs).
- 'Y' is an indexed or word-aligned displacement memory operand.
- 'Z' is an indexed or indirect memory operand.
- 'a' is an indexed or indirect address operand.
- 't' is for AND masks that can be performed by two rldic{l,r} insns
- (but excluding those that could match other constraints of anddi3.) */
-
-#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
- : (C) == 'R' ? legitimate_constant_pool_address_p (OP) \
- : (C) == 'S' ? mask64_operand (OP, DImode) \
- : (C) == 'T' ? mask_operand (OP, GET_MODE (OP)) \
- : (C) == 'U' ? (DEFAULT_ABI == ABI_V4 \
- && small_data_operand (OP, GET_MODE (OP))) \
- : (C) == 't' ? (mask64_2_operand (OP, DImode) \
- && (fixed_regs[CR0_REGNO] \
- || !logical_operand (OP, DImode)) \
- && !mask_operand (OP, DImode) \
- && !mask64_operand (OP, DImode)) \
- : (C) == 'W' ? (easy_vector_constant (OP, GET_MODE (OP))) \
- : (C) == 'Y' ? (word_offset_memref_operand (OP, GET_MODE (OP))) \
- : (C) == 'Z' ? (indexed_or_indirect_operand (OP, GET_MODE (OP))) \
- : (C) == 'a' ? (indexed_or_indirect_address (OP, GET_MODE (OP))) \
- : 0)
-
-/* Define which constraints are memory constraints. Tell reload
- that any memory address can be reloaded by copying the
- memory address into a base register if required. */
-
-#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
- ((C) == 'Q' || (C) == 'Y' || (C) == 'Z')
-
-/* Define which constraints should be treated like address constraints
- by the reload pass. */
-
-#define EXTRA_ADDRESS_CONSTRAINT(C, STR) \
- ((C) == 'a')
-
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
In general this is just CLASS; but on some machines
NO_REGS is returned. */
#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
- secondary_reload_class (CLASS, MODE, IN)
+ rs6000_secondary_reload_class (CLASS, MODE, IN)
/* If we are copying between FP or AltiVec registers and anything
- else, we need a memory location. */
-
-#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
- ((CLASS1) != (CLASS2) && ((CLASS1) == FLOAT_REGS \
- || (CLASS2) == FLOAT_REGS \
- || (CLASS1) == ALTIVEC_REGS \
+ else, we need a memory location. The exception is when we are
+ targeting ppc64 and the move to/from fpr to gpr instructions
+ are available.*/
+
+#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
+ ((CLASS1) != (CLASS2) && (((CLASS1) == FLOAT_REGS \
+ && (!TARGET_MFPGPR || !TARGET_POWERPC64 \
+ || ((MODE != DFmode) \
+ && (MODE != DDmode) \
+ && (MODE != DImode)))) \
+ || ((CLASS2) == FLOAT_REGS \
+ && (!TARGET_MFPGPR || !TARGET_POWERPC64 \
+ || ((MODE != DFmode) \
+ && (MODE != DDmode) \
+ && (MODE != DImode)))) \
+ || (CLASS1) == ALTIVEC_REGS \
|| (CLASS2) == ALTIVEC_REGS))
+/* For cpus that cannot load/store SDmode values from the 64-bit
+ FP registers without using a full 64-bit load/store, we need
+ to allocate a full 64-bit stack slot for them. */
+
+#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
+ rs6000_secondary_memory_needed_rtx (MODE)
+
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
#define CLASS_MAX_NREGS(CLASS, MODE) \
(((CLASS) == FLOAT_REGS) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
- : (TARGET_E500_DOUBLE && (CLASS) == GENERAL_REGS && (MODE) == DFmode) \
+ : (TARGET_E500_DOUBLE && (CLASS) == GENERAL_REGS \
+ && ((MODE) == DFmode || (MODE) == DDmode)) \
? 1 \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
-/* Return a class of registers that cannot change FROM mode to TO mode. */
-
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
- (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) \
- && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8) \
- ? 0 \
- : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- ? reg_classes_intersect_p (FLOAT_REGS, CLASS) \
- : (TARGET_E500_DOUBLE && (((TO) == DFmode) + ((FROM) == DFmode)) == 1) \
- ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \
- : (TARGET_E500_DOUBLE && (((TO) == DImode) + ((FROM) == DImode)) == 1) \
- ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \
- : (TARGET_SPE && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1) \
- ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \
- : 0)
+/* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? ((GET_MODE_SIZE (FROM) < 8 || GET_MODE_SIZE (TO) < 8 \
+ || TARGET_IEEEQUAD) \
+ && reg_classes_intersect_p (FLOAT_REGS, CLASS)) \
+ : (((TARGET_E500_DOUBLE \
+ && ((((TO) == DFmode) + ((FROM) == DFmode)) == 1 \
+ || (((TO) == TFmode) + ((FROM) == TFmode)) == 1 \
+ || (((TO) == DDmode) + ((FROM) == DDmode)) == 1 \
+ || (((TO) == TDmode) + ((FROM) == TDmode)) == 1 \
+ || (((TO) == DImode) + ((FROM) == DImode)) == 1)) \
+ || (TARGET_SPE \
+ && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1)) \
+ && reg_classes_intersect_p (GENERAL_REGS, CLASS)))
/* Stack layout; function entry, exit and calling. */
#define STARTING_FRAME_OFFSET \
(FRAME_GROWS_DOWNWARD \
? 0 \
- : (RS6000_ALIGN (current_function_outgoing_args_size, \
+ : (RS6000_ALIGN (crtl->outgoing_args_size, \
TARGET_ALTIVEC ? 16 : 8) \
+ RS6000_SAVE_AREA))
length of the outgoing arguments. The default is correct for most
machines. See `function.c' for details. */
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
- (RS6000_ALIGN (current_function_outgoing_args_size, \
+ (RS6000_ALIGN (crtl->outgoing_args_size, \
TARGET_ALTIVEC ? 16 : 8) \
+ (STACK_POINTER_OFFSET))
/* Define this if the above stack space is to be considered part of the
space allocated by the caller. */
-#define OUTGOING_REG_PARM_STACK_SPACE
+#define OUTGOING_REG_PARM_STACK_SPACE 1
/* This is the difference between the logical top of stack and the actual sp.
/* Define this if the maximum size of all the outgoing args is to be
accumulated and pushed during the prologue. The amount can be
- found in the variable current_function_outgoing_args_size. */
+ found in the variable crtl->outgoing_args_size. */
#define ACCUMULATE_OUTGOING_ARGS 1
/* Value is the number of bytes of arguments automatically
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
function_arg_boundary (MODE, TYPE)
-/* Implement `va_start' for varargs and stdarg. */
-#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
- rs6000_va_start (valist, nextarg)
-
#define PAD_VARARGS_DOWN \
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
needed. */
#define EPILOGUE_USES(REGNO) \
- ((reload_completed && (REGNO) == LINK_REGISTER_REGNUM) \
+ ((reload_completed && (REGNO) == LR_REGNO) \
|| (TARGET_ALTIVEC && (REGNO) == VRSAVE_REGNO) \
|| (current_function_calls_eh_return \
&& TARGET_AIX \
#define HAVE_PRE_DECREMENT 1
#define HAVE_PRE_INCREMENT 1
+#define HAVE_PRE_MODIFY_DISP 1
+#define HAVE_PRE_MODIFY_REG 1
/* Macros to check register numbers against specific register classes. */
#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)
#define EASY_VECTOR_15_ADD_SELF(n) (!EASY_VECTOR_15((n)) \
- && EASY_VECTOR_15((n) >> 1))
+ && EASY_VECTOR_15((n) >> 1) \
+ && ((n) & 1) == 0)
/* 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 in the non-strict case. */
#define INT_REG_OK_FOR_INDEX_P(X, STRICT) \
- ((! (STRICT) \
- && (REGNO (X) <= 31 \
- || REGNO (X) == ARG_POINTER_REGNUM \
- || REGNO (X) == FRAME_POINTER_REGNUM \
- || REGNO (X) >= FIRST_PSEUDO_REGISTER)) \
- || ((STRICT) && REGNO_OK_FOR_INDEX_P (REGNO (X))))
+ ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
+ || REGNO_OK_FOR_INDEX_P (REGNO (X)))
/* Nonzero if X is a hard reg that can be used as a base reg
or if it is a pseudo reg in the non-strict case. */
#define INT_REG_OK_FOR_BASE_P(X, STRICT) \
- (REGNO (X) > 0 && INT_REG_OK_FOR_INDEX_P (X, (STRICT)))
+ ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
+ || REGNO_OK_FOR_BASE_P (REGNO (X)))
#define REG_OK_FOR_INDEX_P(X) INT_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
#define REG_OK_FOR_BASE_P(X) INT_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)
The MODE argument is the machine mode for the MEM expression
that wants to use this address.
- On the RS/6000, there are four valid address: a SYMBOL_REF that
+ On the RS/6000, there are four valid addresses: a SYMBOL_REF that
refers to a constant pool entry of an address (or the sum of it
plus a constant), a short (16-bit signed) constant plus a register,
the sum of two registers, or a register indirect, possibly with an
- auto-increment. For DFmode and DImode with a constant plus register,
- we must ensure that both words are addressable or PowerPC64 with offset
- word aligned.
+ auto-increment. For DFmode, DDmode and DImode with a constant plus
+ register, we must ensure that both words are addressable or PowerPC64
+ with offset word aligned.
- For modes spanning multiple registers (DFmode in 32-bit GPRs,
+ For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
32-bit DImode, TImode), indexed addressing cannot be used because
adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */
/* The cntlzw and cntlzd instructions return 32 and 64 for input of zero. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
- ((VALUE) = ((MODE) == SImode ? 32 : 64))
+ ((VALUE) = ((MODE) == SImode ? 32 : 64), 1)
/* The CTZ patterns return -1 for input of zero. */
-#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1)
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 1)
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
comparison. CCmode should be used in all other cases. */
#define SELECT_CC_MODE(OP,X,Y) \
- (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CCFPmode \
+ (SCALAR_FLOAT_MODE_P (GET_MODE (X)) ? CCFPmode \
: (OP) == GTU || (OP) == LTU || (OP) == GEU || (OP) == LEU ? CCUNSmode \
: (((OP) == EQ || (OP) == NE) && COMPARISON_P (X) \
? CCEQmode : CCmode))
dwarf2 unwind information. This also enables the table driven
mechanism. */
-#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
-#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGISTER_REGNUM)
+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNO)
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LR_REGNO)
/* Describe how we implement __builtin_eh_return. */
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 3 : INVALID_REGNUM)
SPE_BUILTIN_MFSPEFSCR,
SPE_BUILTIN_BRINC,
+ /* PAIRED builtins. */
+ PAIRED_BUILTIN_DIVV2SF3,
+ PAIRED_BUILTIN_ABSV2SF2,
+ PAIRED_BUILTIN_NEGV2SF2,
+ PAIRED_BUILTIN_SQRTV2SF2,
+ PAIRED_BUILTIN_ADDV2SF3,
+ PAIRED_BUILTIN_SUBV2SF3,
+ PAIRED_BUILTIN_RESV2SF2,
+ PAIRED_BUILTIN_MULV2SF3,
+ PAIRED_BUILTIN_MSUB,
+ PAIRED_BUILTIN_MADD,
+ PAIRED_BUILTIN_NMSUB,
+ PAIRED_BUILTIN_NMADD,
+ PAIRED_BUILTIN_NABSV2SF2,
+ PAIRED_BUILTIN_SUM0,
+ PAIRED_BUILTIN_SUM1,
+ PAIRED_BUILTIN_MULS0,
+ PAIRED_BUILTIN_MULS1,
+ PAIRED_BUILTIN_MERGE00,
+ PAIRED_BUILTIN_MERGE01,
+ PAIRED_BUILTIN_MERGE10,
+ PAIRED_BUILTIN_MERGE11,
+ PAIRED_BUILTIN_MADDS0,
+ PAIRED_BUILTIN_MADDS1,
+ PAIRED_BUILTIN_STX,
+ PAIRED_BUILTIN_LX,
+ PAIRED_BUILTIN_SELV2SF4,
+ PAIRED_BUILTIN_CMPU0,
+ PAIRED_BUILTIN_CMPU1,
+
+ RS6000_BUILTIN_RECIP,
+ RS6000_BUILTIN_RECIPF,
+ RS6000_BUILTIN_RSQRTF,
+
RS6000_BUILTIN_COUNT
};