/* 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, 2006
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
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
or FITNESS FOR A PARTICULAR PURPOSE. See the 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. */
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. 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
+
+#ifdef HAVE_AS_VSX
+#define ASM_CPU_POWER7_SPEC "-mpower7"
+#else
+#define ASM_CPU_POWER7_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=power7: %(asm_cpu_power7)} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
%{mcpu=405fp: -m405} \
%{mcpu=440: -m440} \
%{mcpu=440fp: -m440} \
+%{mcpu=464: -m440} \
+%{mcpu=464fp: -m440} \
%{mcpu=505: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=602: -mppc} \
%{mcpu=970: -mpower4 -maltivec} \
%{mcpu=G5: -mpower4 -maltivec} \
%{mcpu=8540: -me500} \
+%{mcpu=8548: -me500} \
+%{mcpu=e300c2: -me300} \
+%{mcpu=e300c3: -me300} \
+%{mcpu=e500mc: -me500mc} \
%{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 }, \
+ { "asm_cpu_power7", ASM_CPU_POWER7_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
+
+/* Define TARGET_TLS_MARKERS if the target assembler does not support
+ arg markers for __tls_get_addr calls. */
+#ifndef HAVE_AS_TLS_MARKERS
+#undef TARGET_TLS_MARKERS
+#define TARGET_TLS_MARKERS 0
+#else
+#define TARGET_TLS_MARKERS tls_markers
+#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_PPCE500MC,
PROCESSOR_POWER4,
- PROCESSOR_POWER5
+ PROCESSOR_POWER5,
+ PROCESSOR_POWER6,
+ PROCESSOR_CELL
};
+/* FPU operations supported.
+ Each use of TARGET_SINGLE_FLOAT or TARGET_DOUBLE_FLOAT must
+ also test TARGET_HARD_FLOAT. */
+#define TARGET_SINGLE_FLOAT 1
+#define TARGET_DOUBLE_FLOAT 1
+#define TARGET_SINGLE_FPU 0
+#define TARGET_SIMPLE_FPU 0
+#define TARGET_XILINX_FPU 0
+
extern enum processor_type rs6000_cpu;
/* Recast the processor type to the cpu attribute. */
#define PROCESSOR_DEFAULT PROCESSOR_RIOS1
#define PROCESSOR_DEFAULT64 PROCESSOR_RS64A
+/* FP processor type. */
+enum fpu_type_t
+{
+ FPU_NONE, /* No FPU */
+ FPU_SF_LITE, /* Limited Single Precision FPU */
+ FPU_DF_LITE, /* Limited Double Precision FPU */
+ FPU_SF_FULL, /* Full Single Precision FPU */
+ FPU_DF_FULL /* Full Double Single Precision FPU */
+};
+
+extern enum fpu_type_t fpu_type;
+
/* Specify the dialect of assembler to use. New mnemonics is dialect one
and the old mnemonics are dialect zero. */
#define ASSEMBLER_DIALECT (TARGET_NEW_MNEMONICS ? 1 : 0)
previous_group
};
-/* Support for a compile-time default CPU, et cetera. The rules are:
- --with-cpu is ignored if -mcpu is specified.
- --with-tune is ignored if -mtune is specified.
- --with-float is ignored if -mhard-float or -msoft-float are
- specified. */
-#define OPTION_DEFAULT_SPECS \
- {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
- {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
- {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
-
/* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */
struct rs6000_cpu_select
{
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;
extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
+extern int rs6000_xilinx_fpu;
/* Alignment options for fields in structures for sub-targets following
AIX-like ABI.
#define TARGET_SPE_ABI 0
#define TARGET_SPE 0
#define TARGET_E500 0
-#define TARGET_ISEL 0
+#define TARGET_ISEL rs6000_isel
#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) ? 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
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) ? 64 \
: TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
/* Define this macro to be the value 1 if unaligned accesses have a cost
many times greater than aligned accesses, for example if they are
emulated in a trap handler. */
+/* Altivec vector memory instructions simply ignore the low bits; SPE
+ vector memory instructions trap on unaligned accesses. */
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
(STRICT_ALIGNMENT \
|| (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
+ || (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode \
|| (MODE) == DImode) \
- && (ALIGN) < 32))
+ && (ALIGN) < 32) \
+ || (VECTOR_MODE_P ((MODE)) && (ALIGN) < GET_MODE_BITSIZE ((MODE))))
\f
/* Standard register usage. */
#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(MODE) \
+ (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. */
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. */
Set this to 3 on the RS/6000 since that is roughly the average cost of an
unscheduled conditional branch. */
-#define BRANCH_COST 3
+#define BRANCH_COST(speed_p, predictable_p) 3
/* Override BRANCH_COST heuristic which empirically produces worse
performance for removing short circuiting from the logical ops. */
#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.
+/* 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. */
- The AltiVec case needs to be fixed. Dunno if we should break ABI
- compatibility and reserve a register for it as well.. */
-
-#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 */ \
}
+/* The following macro defines cover classes for Integrated Register
+ Allocator. Cover classes is a set of non-intersected register
+ classes covering all hard registers used for register allocation
+ purpose. Any move between two registers of a cover class should be
+ cheaper than load or store of the registers. The macro value is
+ array of register classes with LIM_REG_CLASSES used as the end
+ marker. */
+
+#define IRA_COVER_CLASSES \
+{ \
+ GENERAL_REGS, SPECIAL_REGS, FLOAT_REGS, ALTIVEC_REGS, \
+ /*VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS, \
+ /* MQ_REGS, LINK_REGS, CTR_REGS, */ \
+ CR_REGS, XER_REGS, LIM_REG_CLASSES \
+}
+
/* The same information, inverted:
Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
: (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
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) \
? 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) \
- (!TARGET_IEEEQUAD \
- && 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(FNTYPE) 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 \
+ || (crtl->calls_eh_return \
&& TARGET_AIX \
&& (REGNO) == 2))
#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.
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. */
if (rs6000_mode_dependent_address (ADDR)) \
goto LABEL; \
} while (0)
+
+#define FIND_BASE_TERM rs6000_find_base_term
\f
/* The register number of the register used to address a table of
static data addresses in memory. In some cases this register is
/* Define this if some processing needs to be done immediately before
emitting code for an insn. */
-/* #define FINAL_PRESCAN_INSN(INSN,OPERANDS,NOPERANDS) */
+#define FINAL_PRESCAN_INSN(INSN,OPERANDS,NOPERANDS) \
+ rs6000_final_prescan_insn (INSN, OPERANDS, NOPERANDS)
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
/* 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
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)
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
+#define OUTPUT_ADDR_CONST_EXTRA(STREAM, X, FAIL) \
+ do \
+ if (!rs6000_output_addr_const_extra (STREAM, X)) \
+ goto FAIL; \
+ while (0)
+
/* uncomment for disabling the corresponding default options */
/* #define MACHINE_no_sched_interblock */
/* #define MACHINE_no_sched_speculative */
ALTIVEC_BUILTIN_LVXL,
ALTIVEC_BUILTIN_LVX,
ALTIVEC_BUILTIN_STVX,
+ ALTIVEC_BUILTIN_LVLX,
+ ALTIVEC_BUILTIN_LVLXL,
+ ALTIVEC_BUILTIN_LVRX,
+ ALTIVEC_BUILTIN_LVRXL,
ALTIVEC_BUILTIN_STVEBX,
ALTIVEC_BUILTIN_STVEHX,
ALTIVEC_BUILTIN_STVEWX,
ALTIVEC_BUILTIN_STVXL,
+ ALTIVEC_BUILTIN_STVLX,
+ ALTIVEC_BUILTIN_STVLXL,
+ ALTIVEC_BUILTIN_STVRX,
+ ALTIVEC_BUILTIN_STVRXL,
ALTIVEC_BUILTIN_VCMPBFP_P,
ALTIVEC_BUILTIN_VCMPEQFP_P,
ALTIVEC_BUILTIN_VCMPEQUB_P,
ALTIVEC_BUILTIN_VEC_AND,
ALTIVEC_BUILTIN_VEC_ANDC,
ALTIVEC_BUILTIN_VEC_AVG,
+ ALTIVEC_BUILTIN_VEC_EXTRACT,
ALTIVEC_BUILTIN_VEC_CEIL,
ALTIVEC_BUILTIN_VEC_CMPB,
ALTIVEC_BUILTIN_VEC_CMPEQ,
ALTIVEC_BUILTIN_VEC_LVEBX,
ALTIVEC_BUILTIN_VEC_LVEHX,
ALTIVEC_BUILTIN_VEC_LVEWX,
+ ALTIVEC_BUILTIN_VEC_LVLX,
+ ALTIVEC_BUILTIN_VEC_LVLXL,
+ ALTIVEC_BUILTIN_VEC_LVRX,
+ ALTIVEC_BUILTIN_VEC_LVRXL,
ALTIVEC_BUILTIN_VEC_LVSL,
ALTIVEC_BUILTIN_VEC_LVSR,
ALTIVEC_BUILTIN_VEC_MADD,
ALTIVEC_BUILTIN_VEC_STVEBX,
ALTIVEC_BUILTIN_VEC_STVEHX,
ALTIVEC_BUILTIN_VEC_STVEWX,
+ ALTIVEC_BUILTIN_VEC_STVLX,
+ ALTIVEC_BUILTIN_VEC_STVLXL,
+ ALTIVEC_BUILTIN_VEC_STVRX,
+ ALTIVEC_BUILTIN_VEC_STVRXL,
ALTIVEC_BUILTIN_VEC_SUB,
ALTIVEC_BUILTIN_VEC_SUBC,
ALTIVEC_BUILTIN_VEC_SUBS,
ALTIVEC_BUILTIN_VEC_VUPKLSH,
ALTIVEC_BUILTIN_VEC_XOR,
ALTIVEC_BUILTIN_VEC_STEP,
- ALTIVEC_BUILTIN_OVERLOADED_LAST = ALTIVEC_BUILTIN_VEC_STEP,
+ ALTIVEC_BUILTIN_VEC_PROMOTE,
+ ALTIVEC_BUILTIN_VEC_INSERT,
+ ALTIVEC_BUILTIN_VEC_SPLATS,
+ ALTIVEC_BUILTIN_OVERLOADED_LAST = ALTIVEC_BUILTIN_VEC_SPLATS,
/* SPE builtins. */
SPE_BUILTIN_EVADDW,
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
};