summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/rs6000/rs6000.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/config/rs6000/rs6000.h')
-rw-r--r--contrib/gcc/config/rs6000/rs6000.h685
1 files changed, 513 insertions, 172 deletions
diff --git a/contrib/gcc/config/rs6000/rs6000.h b/contrib/gcc/config/rs6000/rs6000.h
index 8c77dd5..957fcec 100644
--- a/contrib/gcc/config/rs6000/rs6000.h
+++ b/contrib/gcc/config/rs6000/rs6000.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
@@ -46,46 +46,6 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_DEFAULT ((char *)0)
#endif
-/* Common CPP definitions used by CPP_SPEC among the various targets
- for handling -mcpu=xxx switches. */
-#define CPP_CPU_SPEC \
-"%{!mcpu*: \
- %{mpower: %{!mpower2: -D_ARCH_PWR}} \
- %{mpower2: -D_ARCH_PWR2} \
- %{mpowerpc*: -D_ARCH_PPC} \
- %{mno-power: %{!mpowerpc*: -D_ARCH_COM}} \
- %{!mno-power: %{!mpower2: %(cpp_default)}}} \
-%{mcpu=common: -D_ARCH_COM} \
-%{mcpu=power: -D_ARCH_PWR} \
-%{mcpu=power2: -D_ARCH_PWR2} \
-%{mcpu=powerpc: -D_ARCH_PPC} \
-%{mcpu=rios: -D_ARCH_PWR} \
-%{mcpu=rios1: -D_ARCH_PWR} \
-%{mcpu=rios2: -D_ARCH_PWR2} \
-%{mcpu=rsc: -D_ARCH_PWR} \
-%{mcpu=rsc1: -D_ARCH_PWR} \
-%{mcpu=401: -D_ARCH_PPC} \
-%{mcpu=403: -D_ARCH_PPC} \
-%{mcpu=405: -D_ARCH_PPC} \
-%{mcpu=505: -D_ARCH_PPC} \
-%{mcpu=601: -D_ARCH_PPC -D_ARCH_PWR} \
-%{mcpu=602: -D_ARCH_PPC} \
-%{mcpu=603: -D_ARCH_PPC} \
-%{mcpu=603e: -D_ARCH_PPC} \
-%{mcpu=ec603e: -D_ARCH_PPC} \
-%{mcpu=604: -D_ARCH_PPC} \
-%{mcpu=604e: -D_ARCH_PPC} \
-%{mcpu=620: -D_ARCH_PPC} \
-%{mcpu=740: -D_ARCH_PPC} \
-%{mcpu=7400: -D_ARCH_PPC} \
-%{mcpu=7450: -D_ARCH_PPC} \
-%{mcpu=750: -D_ARCH_PPC} \
-%{mcpu=801: -D_ARCH_PPC} \
-%{mcpu=821: -D_ARCH_PPC} \
-%{mcpu=823: -D_ARCH_PPC} \
-%{mcpu=860: -D_ARCH_PPC} \
-%{maltivec: -D__ALTIVEC__}"
-
/* Common ASM definitions used by ASM_SPEC among the various targets
for handling -mcpu=xxx switches. */
#define ASM_CPU_SPEC \
@@ -98,6 +58,8 @@ Boston, MA 02111-1307, USA. */
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwrx} \
+%{mcpu=power3: -m604} \
+%{mcpu=power4: -mpower4} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
@@ -116,6 +78,7 @@ Boston, MA 02111-1307, USA. */
%{mcpu=604: -mppc} \
%{mcpu=604e: -mppc} \
%{mcpu=620: -mppc} \
+%{mcpu=630: -m604} \
%{mcpu=740: -mppc} \
%{mcpu=7400: -mppc} \
%{mcpu=7450: -mppc} \
@@ -124,6 +87,7 @@ Boston, MA 02111-1307, USA. */
%{mcpu=821: -mppc} \
%{mcpu=823: -mppc} \
%{mcpu=860: -mppc} \
+%{mcpu=8540: -me500} \
%{maltivec: -maltivec}"
#define CPP_DEFAULT_SPEC ""
@@ -143,7 +107,6 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_EXTRA_SPECS
#define EXTRA_SPECS \
- { "cpp_cpu", CPP_CPU_SPEC }, \
{ "cpp_default", CPP_DEFAULT_SPEC }, \
{ "asm_cpu", ASM_CPU_SPEC }, \
{ "asm_default", ASM_DEFAULT_SPEC }, \
@@ -197,7 +160,7 @@ extern int target_flags;
/* Disable use of FPRs. */
#define MASK_SOFT_FLOAT 0x00000800
-/* Enable load/store multiple, even on powerpc */
+/* Enable load/store multiple, even on PowerPC */
#define MASK_MULTIPLE 0x00001000
#define MASK_MULTIPLE_SET 0x00002000
@@ -395,7 +358,9 @@ enum processor_type
PROCESSOR_PPC630,
PROCESSOR_PPC750,
PROCESSOR_PPC7400,
- PROCESSOR_PPC7450
+ PROCESSOR_PPC7450,
+ PROCESSOR_PPC8540,
+ PROCESSOR_POWER4
};
extern enum processor_type rs6000_cpu;
@@ -427,9 +392,18 @@ extern enum processor_type rs6000_cpu;
{"tune=", &rs6000_select[2].string, \
N_("Schedule code for given CPU") }, \
{"debug=", &rs6000_debug_name, N_("Enable debug output") }, \
+ {"traceback=", &rs6000_traceback_name, \
+ N_("Select full, part, or no traceback table") }, \
{"abi=", &rs6000_abi_string, N_("Specify ABI to use") }, \
{"long-double-", &rs6000_long_double_size_string, \
N_("Specify size of long double (64 or 128 bits)") }, \
+ {"isel=", &rs6000_isel_string, \
+ N_("Specify yes/no if isel instructions should be generated") }, \
+ {"vrsave=", &rs6000_altivec_vrsave_string, \
+ N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec") }, \
+ {"longcall", &rs6000_longcall_switch, \
+ N_("Avoid all range limits on call instructions") }, \
+ {"no-longcall", &rs6000_longcall_switch, "" }, \
SUBTARGET_OPTIONS \
}
@@ -453,14 +427,30 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define TARGET_DEBUG_STACK rs6000_debug_stack
#define TARGET_DEBUG_ARG rs6000_debug_arg
+extern const char *rs6000_traceback_name; /* Type of traceback table. */
+
/* These are separate from target_flags because we've run out of bits
there. */
extern const char *rs6000_long_double_size_string;
extern int rs6000_long_double_type_size;
extern int rs6000_altivec_abi;
+extern int rs6000_spe_abi;
+extern int rs6000_isel;
+extern int rs6000_fprs;
+extern const char *rs6000_isel_string;
+extern const char *rs6000_altivec_vrsave_string;
+extern int rs6000_altivec_vrsave;
+extern const char *rs6000_longcall_switch;
+extern int rs6000_default_long_calls;
#define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
#define TARGET_ALTIVEC_ABI rs6000_altivec_abi
+#define TARGET_ALTIVEC_VRSAVE rs6000_altivec_vrsave
+
+#define TARGET_SPE_ABI 0
+#define TARGET_SPE 0
+#define TARGET_ISEL 0
+#define TARGET_FPRS 1
/* Sometimes certain combinations of command options do not make sense
on a particular target machine. You can define a macro
@@ -480,11 +470,37 @@ extern int rs6000_altivec_abi;
/* Show we can debug even without a frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
-
-/* target machine storage layout */
-/* Define to support cross compilation to an RS6000 target. */
-#define REAL_ARITHMETIC
+/* Target pragma. */
+#define REGISTER_TARGET_PRAGMAS(PFILE) do { \
+ cpp_register_pragma (PFILE, 0, "longcall", rs6000_pragma_longcall); \
+} while (0)
+
+/* Target #defines. */
+#define TARGET_CPU_CPP_BUILTINS() \
+ rs6000_cpu_cpp_builtins (pfile)
+
+/* This is used by rs6000_cpu_cpp_builtins to indicate the byte order
+ we're compiling for. Some configurations may need to override it. */
+#define RS6000_CPU_CPP_ENDIAN_BUILTINS() \
+ do \
+ { \
+ if (BYTES_BIG_ENDIAN) \
+ { \
+ builtin_define ("__BIG_ENDIAN__"); \
+ builtin_define ("_BIG_ENDIAN"); \
+ builtin_assert ("machine=bigendian"); \
+ } \
+ else \
+ { \
+ builtin_define ("__LITTLE_ENDIAN__"); \
+ builtin_define ("_LITTLE_ENDIAN"); \
+ builtin_assert ("machine=littleendian"); \
+ } \
+ } \
+ while (0)
+
+/* Target machine storage layout. */
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
@@ -522,21 +538,18 @@ extern int rs6000_altivec_abi;
instructions for them. Might as well be consistent with bits and bytes. */
#define WORDS_BIG_ENDIAN 1
-/* number of bits in an addressable storage unit */
-#define BITS_PER_UNIT 8
-
-/* Width in bits of a "word", which is the contents of a machine register.
- Note that this is not necessarily the width of data type `int';
- if using 16-bit ints on a 68000, this would still be 32.
- But on a machine with 16-bit registers, this would be 16. */
-#define BITS_PER_WORD (! TARGET_POWERPC64 ? 32 : 64)
#define MAX_BITS_PER_WORD 64
/* Width of a word, in units (bytes). */
#define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
+#ifdef IN_LIBGCC2
+#define MIN_UNITS_PER_WORD UNITS_PER_WORD
+#else
#define MIN_UNITS_PER_WORD 4
+#endif
#define UNITS_PER_FP_WORD 8
#define UNITS_PER_ALTIVEC_WORD 16
+#define UNITS_PER_SPE_WORD 8
/* Type used for ptrdiff_t, as a string used in a declaration. */
#define PTRDIFF_TYPE "int"
@@ -572,12 +585,6 @@ extern int rs6000_altivec_abi;
words. */
#define LONG_LONG_TYPE_SIZE 64
-/* A C expression for the size in bits of the type `char' on the
- target machine. If you don't define this, the default is one
- quarter of a word. (If this would be less than one storage unit,
- it is rounded up to one unit.) */
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-
/* A C expression for the size in bits of the type `float' on the
target machine. If you don't define this, the default is one
word. */
@@ -627,7 +634,8 @@ extern int rs6000_altivec_abi;
local store. TYPE is the data type, and ALIGN is the alignment
that the object would ordinarily have. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
- ((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : ALIGN)
+ ((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \
+ (TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE) ? 64 : ALIGN)
/* Alignment of field after `int : 0' in a structure. */
#define EMPTY_FIELD_BOUNDARY 32
@@ -635,7 +643,19 @@ extern int rs6000_altivec_abi;
/* Every structure's size must be a multiple of this. */
#define STRUCTURE_SIZE_BOUNDARY 8
-/* A bitfield declared as `int' forces `int' alignment for the struct. */
+/* Return 1 if a structure or array containing FIELD should be
+ accessed using `BLKMODE'.
+
+ For the SPE, simd types are V2SI, and gcc can be tempted to put the
+ entire thing in a DI and use subregs to access the internals.
+ store_bit_field() will force (subreg:DI (reg:V2SI x))'s to the
+ back-end. Because a single GPR can hold a V2SI, but not a DI, the
+ best thing to do is set structs to BLKmode and avoid Severe Tire
+ Damage. */
+#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
+ (TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)
+
+/* A bit-field declared as `int' forces `int' alignment for the struct. */
#define PCC_BITFIELD_TYPE_MATTERS 1
/* Make strings word-aligned so strcpy from constants will be faster.
@@ -649,12 +669,12 @@ extern int rs6000_altivec_abi;
/* Make arrays of chars word-aligned for the same reasons.
Align vectors to 128 bits. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
- (TREE_CODE (TYPE) == VECTOR_TYPE ? 128 \
+ (TREE_CODE (TYPE) == VECTOR_TYPE ? (TARGET_SPE_ABI ? 64 : 128) \
: TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-/* Non-zero if move instructions will actually fail to work
+/* Nonzero if move instructions will actually fail to work
when given unaligned data. */
#define STRICT_ALIGNMENT 0
@@ -663,7 +683,8 @@ extern int rs6000_altivec_abi;
emulated in a trap handler. */
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
(STRICT_ALIGNMENT \
- || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \
+ || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
+ || (MODE) == DImode) \
&& (ALIGN) < 32))
/* Standard register usage. */
@@ -688,7 +709,7 @@ extern int rs6000_altivec_abi;
a register, in order to work around problems in allocating stack storage
in inline functions. */
-#define FIRST_PSEUDO_REGISTER 110
+#define FIRST_PSEUDO_REGISTER 113
/* This must be included for pre gcc 3.0 glibc compatibility. */
#define PRE_GCC3_DWARF_FRAME_REGISTERS 77
@@ -712,7 +733,8 @@ extern int rs6000_altivec_abi;
/* AltiVec registers. */ \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 1 \
+ 1, 1 \
+ , 1, 1 \
}
/* 1 for registers not available across function calls.
@@ -731,7 +753,8 @@ extern int rs6000_altivec_abi;
/* AltiVec registers. */ \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 1 \
+ 1, 1 \
+ , 1, 1 \
}
/* Like `CALL_USED_REGISTERS' except this macro doesn't require that
@@ -749,7 +772,8 @@ extern int rs6000_altivec_abi;
/* AltiVec registers. */ \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0 \
+ 0, 0 \
+ , 0, 0 \
}
#define MQ_REGNO 64
@@ -764,6 +788,9 @@ extern int rs6000_altivec_abi;
#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
/* List the order in which to allocate registers. Each register must be
listed once, even those in FIXED_REGISTERS.
@@ -786,7 +813,8 @@ extern int rs6000_altivec_abi;
mq (not saved; best to use it if we can)
ctr (not saved; when we have the choice ctr is better)
lr (saved)
- cr5, r1, r2, ap, xer, vrsave (fixed)
+ cr5, r1, r2, ap, xer, vrsave, vscr (fixed)
+ spe_acc, spefscr (fixed)
AltiVec registers:
v0 - v1 (not saved or used for anything)
@@ -817,7 +845,8 @@ extern int rs6000_altivec_abi;
79, \
96, 95, 94, 93, 92, 91, \
108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, \
- 97, 109 \
+ 97, 109, 110 \
+ , 111, 112 \
}
/* True if register is floating-point. */
@@ -832,6 +861,9 @@ extern int rs6000_altivec_abi;
/* True if register is an integer register. */
#define INT_REGNO_P(N) ((N) <= 31 || (N) == ARG_POINTER_REGNUM)
+/* SPE SIMD registers are just the GPRs. */
+#define SPE_SIMD_REGNO_P(N) ((N) <= 31)
+
/* True if register is the XER register. */
#define XER_REGNO_P(N) ((N) == XER_REGNO)
@@ -843,28 +875,41 @@ extern int rs6000_altivec_abi;
This is ordinarily the length in words of a value of mode MODE
but can be less for certain modes in special long registers.
+ For the SPE, GPRs are 64 bits but only 32 bits are visible in
+ scalar instructions. The upper 32 bits are only available to the
+ SIMD instructions.
+
POWER and PowerPC GPRs hold 32 bits worth;
PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
#define HARD_REGNO_NREGS(REGNO, MODE) \
(FP_REGNO_P (REGNO) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
+ : (SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE)) \
+ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD) \
: ALTIVEC_REGNO_P (REGNO) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
#define ALTIVEC_VECTOR_MODE(MODE) \
- ((MODE) == V16QImode \
- || (MODE) == V8HImode \
- || (MODE) == V4SFmode \
- || (MODE) == V4SImode)
+ ((MODE) == V16QImode \
+ || (MODE) == V8HImode \
+ || (MODE) == V4SFmode \
+ || (MODE) == V4SImode)
+
+#define SPE_VECTOR_MODE(MODE) \
+ ((MODE) == V4HImode \
+ || (MODE) == V2SFmode \
+ || (MODE) == V1DImode \
+ || (MODE) == V2SImode)
/* Define this macro to be nonzero if the port is prepared to handle
insns involving vector mode MODE. At the very least, it must have
move patterns for this mode. */
-#define VECTOR_MODE_SUPPORTED_P(MODE) \
- (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE))
+#define VECTOR_MODE_SUPPORTED_P(MODE) \
+ ((TARGET_SPE && SPE_VECTOR_MODE (MODE)) \
+ || (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
For POWER and PowerPC, the GPRs can hold any mode, but the float
@@ -878,10 +923,10 @@ extern int rs6000_altivec_abi;
|| (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \
: ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE) \
+ : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
: CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \
: XER_REGNO_P (REGNO) ? (MODE) == PSImode \
- : ! INT_REGNO_P (REGNO) ? (GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) \
+ : ! INT_REGNO_P (REGNO) ? GET_MODE_SIZE (MODE) <= UNITS_PER_WORD \
: 1)
/* Value is 1 if it is a good idea to tie two pseudo registers
@@ -904,35 +949,14 @@ extern int rs6000_altivec_abi;
: 1)
/* A C expression returning the cost of moving data from a register of class
- CLASS1 to one of CLASS2.
-
- On the RS/6000, copying between floating-point and fixed-point
- registers is expensive. */
-
-#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
- ((CLASS1) == FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 2 \
- : (CLASS1) == FLOAT_REGS && (CLASS2) != FLOAT_REGS ? 10 \
- : (CLASS1) != FLOAT_REGS && (CLASS2) == FLOAT_REGS ? 10 \
- : (CLASS1) == ALTIVEC_REGS && (CLASS2) != ALTIVEC_REGS ? 20 \
- : (CLASS1) != ALTIVEC_REGS && (CLASS2) == ALTIVEC_REGS ? 20 \
- : (((CLASS1) == SPECIAL_REGS || (CLASS1) == MQ_REGS \
- || (CLASS1) == LINK_REGS || (CLASS1) == CTR_REGS \
- || (CLASS1) == LINK_OR_CTR_REGS) \
- && ((CLASS2) == SPECIAL_REGS || (CLASS2) == MQ_REGS \
- || (CLASS2) == LINK_REGS || (CLASS2) == CTR_REGS \
- || (CLASS2) == LINK_OR_CTR_REGS)) ? 10 \
- : 2)
+ CLASS1 to one of CLASS2. */
-/* A C expressions returning the cost of moving data of MODE from a register to
- or from memory.
+#define REGISTER_MOVE_COST rs6000_register_move_cost
- On the RS/6000, bump this up a bit. */
+/* A C expressions returning the cost of moving data of MODE from a register to
+ or from memory. */
-#define MEMORY_MOVE_COST(MODE, CLASS, IN) \
- ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && (rs6000_cpu == PROCESSOR_RIOS1 || rs6000_cpu == PROCESSOR_PPC601) \
- ? 3 : 2) \
- + 4)
+#define MEMORY_MOVE_COST rs6000_memory_move_cost
/* Specify the cost of a branch insn; roughly the number of extra insns that
should be added to avoid a branch.
@@ -942,6 +966,20 @@ extern int rs6000_altivec_abi;
#define BRANCH_COST 3
+
+/* 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
+ compatability and reserve a register for it as well.. */
+
+#define FIXED_SCRATCH (TARGET_SPE ? 14 : 11)
+
/* Define this macro to change register usage conditional on target flags.
Set MQ register fixed (already call_used) if not POWER architecture
(RIOS1, RIOS2, RSC, and PPC601) so that it will not be allocated.
@@ -956,12 +994,16 @@ extern int rs6000_altivec_abi;
if (TARGET_64BIT) \
fixed_regs[13] = call_used_regs[13] \
= call_really_used_regs[13] = 1; \
- if (TARGET_SOFT_FLOAT) \
+ if (TARGET_SOFT_FLOAT || !TARGET_FPRS) \
for (i = 32; i < 64; i++) \
fixed_regs[i] = call_used_regs[i] \
= call_really_used_regs[i] = 1; \
if (DEFAULT_ABI == ABI_V4 \
&& PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM \
+ && flag_pic == 2) \
+ fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; \
+ if (DEFAULT_ABI == ABI_V4 \
+ && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM \
&& flag_pic == 1) \
fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
= call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
@@ -972,6 +1014,15 @@ extern int rs6000_altivec_abi;
= fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
= call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
= call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; \
+ if (TARGET_ALTIVEC) \
+ global_regs[VSCR_REGNO] = 1; \
+ if (TARGET_SPE) \
+ { \
+ global_regs[SPEFSCR_REGNO] = 1; \
+ fixed_regs[FIXED_SCRATCH] \
+ = call_used_regs[FIXED_SCRATCH] \
+ = call_really_used_regs[FIXED_SCRATCH] = 1; \
+ } \
if (! TARGET_ALTIVEC) \
{ \
for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) \
@@ -1056,6 +1107,9 @@ enum reg_class
FLOAT_REGS,
ALTIVEC_REGS,
VRSAVE_REGS,
+ VSCR_REGS,
+ SPE_ACC_REGS,
+ SPEFSCR_REGS,
NON_SPECIAL_REGS,
MQ_REGS,
LINK_REGS,
@@ -1083,6 +1137,9 @@ enum reg_class
"FLOAT_REGS", \
"ALTIVEC_REGS", \
"VRSAVE_REGS", \
+ "VSCR_REGS", \
+ "SPE_ACC_REGS", \
+ "SPEFSCR_REGS", \
"NON_SPECIAL_REGS", \
"MQ_REGS", \
"LINK_REGS", \
@@ -1109,6 +1166,9 @@ enum reg_class
{ 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /* ALTIVEC_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00010000 }, /* SPEFSCR_REGS */ \
{ 0xffffffff, 0xffffffff, 0x00000008, 0x00000000 }, /* NON_SPECIAL_REGS */ \
{ 0x00000000, 0x00000000, 0x00000001, 0x00000000 }, /* MQ_REGS */ \
{ 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */ \
@@ -1141,6 +1201,9 @@ enum reg_class
: (REGNO) == ARG_POINTER_REGNUM ? BASE_REGS \
: (REGNO) == XER_REGNO ? XER_REGS \
: (REGNO) == VRSAVE_REGNO ? VRSAVE_REGS \
+ : (REGNO) == VSCR_REGNO ? VRSAVE_REGS \
+ : (REGNO) == SPE_ACC_REGNO ? SPE_ACC_REGS \
+ : (REGNO) == SPEFSCR_REGNO ? SPEFSCR_REGS \
: NO_REGS)
/* The class value for index registers, and the one for base regs. */
@@ -1169,8 +1232,8 @@ enum reg_class
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 non-zero
- `K' is a constant with only the low-order 16 bits non-zero
+ `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
@@ -1209,7 +1272,8 @@ enum reg_class
'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. */
+ 'U' is for V.4 small data references.
+ 't' is for AND masks that can be performed by two rldic{l,r} insns. */
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
@@ -1218,6 +1282,10 @@ enum reg_class
: (C) == 'T' ? mask_operand (OP, SImode) \
: (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)) \
+ && !mask64_operand (OP, DImode)) \
: 0)
/* Given an rtx X being reloaded into a reg required to be
@@ -1273,16 +1341,16 @@ enum reg_class
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-/* If defined, gives a class of registers that cannot be used as the
- operand of a SUBREG that changes the mode of the object illegally. */
-#define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
+/* Return a class of registers that cannot change FROM mode to TO mode. */
-/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FLOAT_REGS, CLASS) \
+ : (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1 \
+ ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \
+ : 0)
-#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
-
/* Stack layout; function entry, exit and calling. */
/* Enumeration to give which calling sequence to use. */
@@ -1315,6 +1383,7 @@ typedef struct rs6000_stack {
int lr_save_offset; /* offset to save LR from initial SP */
int cr_save_offset; /* offset to save CR from initial SP */
int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
+ int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
int toc_save_offset; /* offset to save the TOC pointer */
int varargs_save_offset; /* offset to save the varargs registers */
int ehrd_offset; /* offset to EH return data */
@@ -1332,6 +1401,8 @@ typedef struct rs6000_stack {
int vrsave_size; /* size to hold VRSAVE if not in save_size */
int altivec_padding_size; /* size of altivec alignment padding if
not in save_size */
+ int spe_gp_size; /* size of 64-bit GPR save size for SPE */
+ int spe_padding_size;
int toc_size; /* size to hold TOC if not in save_size */
int total_size; /* total bytes allocated for stack */
} rs6000_stack_t;
@@ -1450,6 +1521,8 @@ typedef struct rs6000_stack {
If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0.
+ On the SPE, both FPs and vectors are returned in r3.
+
On RS/6000 an integer value is in r3 and a floating-point value is in
fp1, unless -msoft-float. */
@@ -1458,8 +1531,13 @@ typedef struct rs6000_stack {
&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
|| POINTER_TYPE_P (VALTYPE) \
? word_mode : TYPE_MODE (VALTYPE), \
- TREE_CODE (VALTYPE) == VECTOR_TYPE ? ALTIVEC_ARG_RETURN \
- : TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT \
+ TREE_CODE (VALTYPE) == VECTOR_TYPE \
+ && TARGET_ALTIVEC ? ALTIVEC_ARG_RETURN \
+ : TREE_CODE (VALTYPE) == REAL_TYPE \
+ && TARGET_SPE_ABI && !TARGET_FPRS \
+ ? GP_ARG_RETURN \
+ : TREE_CODE (VALTYPE) == REAL_TYPE \
+ && TARGET_HARD_FLOAT && TARGET_FPRS \
? FP_ARG_RETURN : GP_ARG_RETURN)
/* Define how to find the value returned by a library function
@@ -1468,7 +1546,7 @@ typedef struct rs6000_stack {
#define LIBCALL_VALUE(MODE) \
gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN \
: GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && TARGET_HARD_FLOAT \
+ && TARGET_HARD_FLOAT && TARGET_FPRS \
? FP_ARG_RETURN : GP_ARG_RETURN)
/* The AIX ABI for the RS/6000 specifies that all structures are
@@ -1481,13 +1559,17 @@ typedef struct rs6000_stack {
default, and -m switches get the final word. See
rs6000_override_options for more details.
+ The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
+ long double support is enabled. These values are returned in memory.
+
int_size_in_bytes returns -1 for variable size objects, which go in
memory always. The cast to unsigned makes -1 > 8. */
#define RETURN_IN_MEMORY(TYPE) \
- (AGGREGATE_TYPE_P (TYPE) && \
- (TARGET_AIX_STRUCT_RET || \
- (unsigned HOST_WIDEST_INT) int_size_in_bytes (TYPE) > 8))
+ ((AGGREGATE_TYPE_P (TYPE) \
+ && (TARGET_AIX_STRUCT_RET \
+ || (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 8)) \
+ || (DEFAULT_ABI == ABI_V4 && TYPE_MODE (TYPE) == TFmode))
/* DRAFT_V4_STRUCT_RET defaults off. */
#define DRAFT_V4_STRUCT_RET 0
@@ -1534,29 +1616,30 @@ typedef struct rs6000_stack {
#define CALL_V4_CLEAR_FP_ARGS 0x00000002 /* V.4, no FP args passed */
#define CALL_V4_SET_FP_ARGS 0x00000004 /* V.4, FP args were passed */
#define CALL_LONG 0x00000008 /* always call indirect */
+#define CALL_LIBCALL 0x00000010 /* libcall */
/* 1 if N is a possible register number for a function value
as seen by the caller.
On RS/6000, this is r3, fp1, and v2 (for AltiVec). */
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == GP_ARG_RETURN \
- || ((N) == FP_ARG_RETURN) \
- || (TARGET_ALTIVEC && \
- (N) == ALTIVEC_ARG_RETURN))
+#define FUNCTION_VALUE_REGNO_P(N) \
+ ((N) == GP_ARG_RETURN \
+ || ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT) \
+ || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC))
/* 1 if N is a possible register number for function argument passing.
On RS/6000, these are r3-r10 and fp1-fp13.
On AltiVec, v2 - v13 are used for passing vectors. */
#define FUNCTION_ARG_REGNO_P(N) \
- (((unsigned)((N) - GP_ARG_MIN_REG) < (unsigned)(GP_ARG_NUM_REG)) \
- || (TARGET_ALTIVEC && \
- (unsigned)((N) - ALTIVEC_ARG_MIN_REG) < (unsigned)(ALTIVEC_ARG_NUM_REG)) \
- || ((unsigned)((N) - FP_ARG_MIN_REG) < (unsigned)(FP_ARG_NUM_REG)))
-
+ ((unsigned) (N) - GP_ARG_MIN_REG < GP_ARG_NUM_REG \
+ || ((unsigned) (N) - ALTIVEC_ARG_MIN_REG < ALTIVEC_ARG_NUM_REG \
+ && TARGET_ALTIVEC) \
+ || ((unsigned) (N) - FP_ARG_MIN_REG < FP_ARG_NUM_REG \
+ && TARGET_HARD_FLOAT))
/* A C structure for machine-specific, per-function data.
This is added to the cfun structure. */
-typedef struct machine_function
+typedef struct machine_function GTY(())
{
/* Whether a System V.4 varargs area was created. */
int sysv_varargs_p;
@@ -1607,13 +1690,18 @@ typedef struct rs6000_args
For a library call, FNTYPE is 0. */
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
- init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE)
+ init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, FALSE)
/* Similar, but when scanning the definition of a procedure. We always
set NARGS_PROTOTYPE large so we never return an EXPR_LIST. */
#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,LIBNAME) \
- init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE)
+ init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE, FALSE)
+
+/* Like INIT_CUMULATIVE_ARGS' but only used for outgoing libcalls. */
+
+#define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
+ init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE)
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
@@ -1622,13 +1710,13 @@ typedef struct rs6000_args
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
function_arg_advance (&CUM, MODE, TYPE, NAMED)
-/* Non-zero if we can use a floating-point register to pass this arg. */
+/* Nonzero if we can use a floating-point register to pass this arg. */
#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
(GET_MODE_CLASS (MODE) == MODE_FLOAT \
&& (CUM).fregno <= FP_ARG_MAX_REG \
- && TARGET_HARD_FLOAT)
+ && TARGET_HARD_FLOAT && TARGET_FPRS)
-/* Non-zero if we can use an AltiVec register to pass this arg. */
+/* Nonzero if we can use an AltiVec register to pass this arg. */
#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE) \
(ALTIVEC_VECTOR_MODE (MODE) \
&& (CUM).vregno <= ALTIVEC_ARG_MAX_REG \
@@ -1712,8 +1800,8 @@ typedef struct rs6000_args
(VALIST) = rs6000_build_va_list ()
/* Implement `va_start' for varargs and stdarg. */
-#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
- rs6000_va_start (stdarg, valist, nextarg)
+#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
+ rs6000_va_start (valist, nextarg)
/* Implement `va_arg'. */
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
@@ -1731,6 +1819,10 @@ typedef struct rs6000_args
argument is passed depends on whether or not it is a named argument. */
#define STRICT_ARGUMENT_NAMING 1
+/* We do not allow indirect calls to be optimized into sibling calls, nor
+ do we allow calls with vector parameters. */
+#define FUNCTION_OK_FOR_SIBCALL(DECL) function_ok_for_sibcall ((DECL))
+
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
@@ -1741,7 +1833,7 @@ typedef struct rs6000_args
the stack pointer does not matter. No definition is equivalent to
always zero.
- On the RS/6000, this is non-zero because we can restore the stack from
+ On the RS/6000, this is nonzero because we can restore the stack from
its backpointer, which we maintain. */
#define EXIT_IGNORE_STACK 1
@@ -1755,7 +1847,7 @@ typedef struct rs6000_args
|| (TARGET_ALTIVEC && (REGNO) == VRSAVE_REGNO) \
|| (current_function_calls_eh_return \
&& TARGET_AIX \
- && (REGNO) == TOC_REGISTER))
+ && (REGNO) == 2))
/* TRAMPOLINE_TEMPLATE deleted */
@@ -1818,7 +1910,7 @@ typedef struct rs6000_args
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
- { 30, 30} }
+ { RS6000_PIC_OFFSET_TABLE_REGNUM, RS6000_PIC_OFFSET_TABLE_REGNUM } }
/* Given FROM and TO register numbers, say whether this elimination is allowed.
Frame pointer elimination is automatically handled.
@@ -1829,10 +1921,11 @@ typedef struct rs6000_args
We need r30 if -mminimal-toc was specified, and there are constant pool
references. */
-#define CAN_ELIMINATE(FROM, TO) \
- ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \
- ? ! frame_pointer_needed \
- : (FROM) == 30 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 \
+#define CAN_ELIMINATE(FROM, TO) \
+ ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \
+ ? ! frame_pointer_needed \
+ : (FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM \
+ ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 \
: 1)
/* Define the offset between two registers, one to be eliminated, and the other
@@ -1847,7 +1940,7 @@ typedef struct rs6000_args
(OFFSET) = info->total_size; \
else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
(OFFSET) = (info->push_p) ? info->total_size : 0; \
- else if ((FROM) == 30) \
+ else if ((FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM) \
(OFFSET) = 0; \
else \
abort (); \
@@ -1962,6 +2055,9 @@ typedef struct rs6000_args
#define TOC_RELATIVE_EXPR_P(X) (toc_relative_expr_p (X))
+/* SPE offset addressing is limited to 5-bits worth of double words. */
+#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
+
#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) \
(TARGET_TOC \
&& GET_CODE (X) == PLUS \
@@ -1986,11 +2082,14 @@ typedef struct rs6000_args
&& LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
&& (! ALTIVEC_VECTOR_MODE (MODE) \
|| (GET_CODE (XEXP (X,1)) == CONST_INT && INTVAL (XEXP (X,1)) == 0)) \
+ && (! SPE_VECTOR_MODE (MODE) \
+ || (GET_CODE (XEXP (X, 1)) == CONST_INT \
+ && SPE_CONST_OFFSET_OK (INTVAL (XEXP (X, 1))))) \
&& (((MODE) != DFmode && (MODE) != DImode) \
|| (TARGET_32BIT \
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
: ! (INTVAL (XEXP (X, 1)) & 3))) \
- && ((MODE) != TImode \
+ && (((MODE) != TFmode && (MODE) != TImode) \
|| (TARGET_32BIT \
? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
: (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
@@ -2013,7 +2112,7 @@ typedef struct rs6000_args
&& ! flag_pic && ! TARGET_TOC \
&& GET_MODE_NUNITS (MODE) == 1 \
&& (GET_MODE_BITSIZE (MODE) <= 32 \
- || (TARGET_HARD_FLOAT && (MODE) == DFmode)) \
+ || (TARGET_HARD_FLOAT && TARGET_FPRS && (MODE) == DFmode)) \
&& GET_CODE (X) == LO_SUM \
&& GET_CODE (XEXP (X, 0)) == REG \
&& INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
@@ -2106,7 +2205,7 @@ do { \
#define RS6000_PIC_OFFSET_TABLE_REGNUM 30
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? RS6000_PIC_OFFSET_TABLE_REGNUM : INVALID_REGNUM)
-#define TOC_REGISTER (TARGET_MINIMAL_TOC ? 30 : 2)
+#define TOC_REGISTER (TARGET_MINIMAL_TOC ? RS6000_PIC_OFFSET_TABLE_REGNUM : 2)
/* Define this macro if the register defined by
`PIC_OFFSET_TABLE_REGNUM' is clobbered by calls. Do not define
@@ -2178,7 +2277,7 @@ do { \
#define MAX_MOVE_MAX 8
/* Nonzero if access to memory by bytes is no faster than for words.
- Also non-zero if doing byte operations (specifically shifts) in registers
+ Also nonzero if doing byte operations (specifically shifts) in registers
is undesirable. */
#define SLOW_BYTE_ACCESS 1
@@ -2259,6 +2358,8 @@ do { \
? COSTS_N_INSNS (2) \
: COSTS_N_INSNS (1)); \
case MULT: \
+ if (optimize_size) \
+ return COSTS_N_INSNS (2); \
switch (rs6000_cpu) \
{ \
case PROCESSOR_RIOS1: \
@@ -2292,6 +2393,7 @@ do { \
: COSTS_N_INSNS (3)); \
case PROCESSOR_PPC403: \
case PROCESSOR_PPC604: \
+ case PROCESSOR_PPC8540: \
return COSTS_N_INSNS (4); \
case PROCESSOR_PPC620: \
case PROCESSOR_PPC630: \
@@ -2300,6 +2402,11 @@ do { \
? COSTS_N_INSNS (5) : COSTS_N_INSNS (7) \
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
+ case PROCESSOR_POWER4: \
+ return (GET_CODE (XEXP (X, 1)) != CONST_INT \
+ ? GET_MODE (XEXP (X, 1)) != DImode \
+ ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4) \
+ : COSTS_N_INSNS (2)); \
} \
case DIV: \
case MOD: \
@@ -2334,10 +2441,12 @@ do { \
return COSTS_N_INSNS (20); \
case PROCESSOR_PPC620: \
case PROCESSOR_PPC630: \
+ case PROCESSOR_POWER4: \
return (GET_MODE (XEXP (X, 1)) != DImode \
? COSTS_N_INSNS (21) \
: COSTS_N_INSNS (37)); \
case PROCESSOR_PPC750: \
+ case PROCESSOR_PPC8540: \
case PROCESSOR_PPC7400: \
return COSTS_N_INSNS (19); \
case PROCESSOR_PPC7450: \
@@ -2368,18 +2477,6 @@ do { \
/* #define ADJUST_INSN_LENGTH(X,LENGTH) */
-/* Add any extra modes needed to represent the condition code.
-
- For the RS/6000, we need separate modes when unsigned (logical) comparisons
- are being done and we need a separate mode for floating-point. We also
- use a mode for the case when we are comparing the results of two
- comparisons, as then only the EQ bit is valid in the register. */
-
-#define EXTRA_CC_MODES \
- CC(CCUNSmode, "CCUNS") \
- CC(CCFPmode, "CCFP") \
- CC(CCEQmode, "CCEQ")
-
/* Given a comparison code (EQ, NE, etc.) and the first operand of a
COMPARE, return the mode to be used for the comparison. For
floating-point, CCFPmode should be used. CCUNSmode should be used
@@ -2397,7 +2494,8 @@ do { \
stored from the compare operation. Note that we can't use "rtx" here
since it hasn't been defined! */
-extern struct rtx_def *rs6000_compare_op0, *rs6000_compare_op1;
+extern GTY(()) rtx rs6000_compare_op0;
+extern GTY(()) rtx rs6000_compare_op1;
extern int rs6000_compare_fp_p;
/* Control the assembler format that we output. */
@@ -2633,6 +2731,9 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
&rs6000_reg_names[107][0], /* v30 */ \
&rs6000_reg_names[108][0], /* v31 */ \
&rs6000_reg_names[109][0], /* vrsave */ \
+ &rs6000_reg_names[110][0], /* vscr */ \
+ &rs6000_reg_names[111][0], /* spe_acc */ \
+ &rs6000_reg_names[112][0], /* spefscr */ \
}
/* print-rtl can't handle the above REGISTER_NAMES, so define the
@@ -2641,8 +2742,8 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
#define DEBUG_REGISTER_NAMES \
{ \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
@@ -2651,12 +2752,13 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
"mq", "lr", "ctr", "ap", \
"cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
- "xer", \
+ "xer", \
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
"v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \
"v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", \
- "vrsave" \
+ "vrsave", "vscr", \
+ "spe_acc", "spefscr" \
}
/* Table of additional register names to use in user input. */
@@ -2686,7 +2788,8 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
{"v20", 97}, {"v21", 98}, {"v22", 99}, {"v23", 100}, \
{"v24", 101},{"v25", 102},{"v26", 103},{"v27", 104}, \
{"v28", 105},{"v29", 106},{"v30", 107},{"v31", 108}, \
- {"vrsave", 109}, \
+ {"vrsave", 109}, {"vscr", 110}, \
+ {"spe_acc", 111}, {"spefscr", 112}, \
/* no additional names for: mq, lr, ctr, ap */ \
{"cr0", 68}, {"cr1", 69}, {"cr2", 70}, {"cr3", 71}, \
{"cr4", 72}, {"cr5", 73}, {"cr6", 74}, {"cr7", 75}, \
@@ -2787,12 +2890,16 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
{"non_add_cint_operand", {CONST_INT}}, \
{"and_operand", {SUBREG, REG, CONST_INT}}, \
{"and64_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
+ {"and64_2_operand", {SUBREG, REG, CONST_INT}}, \
{"logical_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \
{"non_logical_cint_operand", {CONST_INT, CONST_DOUBLE}}, \
{"mask_operand", {CONST_INT}}, \
- {"mask64_operand", {CONST_INT, CONST_DOUBLE}}, \
+ {"mask_operand_wrap", {CONST_INT}}, \
+ {"mask64_operand", {CONST_INT}}, \
+ {"mask64_2_operand", {CONST_INT}}, \
{"count_register_operand", {REG}}, \
{"xer_operand", {REG}}, \
+ {"symbol_ref_operand", {SYMBOL_REF}}, \
{"call_operand", {SYMBOL_REF, REG}}, \
{"current_file_function_operand", {SYMBOL_REF}}, \
{"input_operand", {SUBREG, MEM, REG, CONST_INT, \
@@ -3032,4 +3139,238 @@ enum rs6000_builtins
ALTIVEC_BUILTIN_ABS_V4SF,
ALTIVEC_BUILTIN_ABS_V8HI,
ALTIVEC_BUILTIN_ABS_V16QI
+ /* SPE builtins. */
+ , SPE_BUILTIN_EVADDW,
+ SPE_BUILTIN_EVAND,
+ SPE_BUILTIN_EVANDC,
+ SPE_BUILTIN_EVDIVWS,
+ SPE_BUILTIN_EVDIVWU,
+ SPE_BUILTIN_EVEQV,
+ SPE_BUILTIN_EVFSADD,
+ SPE_BUILTIN_EVFSDIV,
+ SPE_BUILTIN_EVFSMUL,
+ SPE_BUILTIN_EVFSSUB,
+ SPE_BUILTIN_EVLDDX,
+ SPE_BUILTIN_EVLDHX,
+ SPE_BUILTIN_EVLDWX,
+ SPE_BUILTIN_EVLHHESPLATX,
+ SPE_BUILTIN_EVLHHOSSPLATX,
+ SPE_BUILTIN_EVLHHOUSPLATX,
+ SPE_BUILTIN_EVLWHEX,
+ SPE_BUILTIN_EVLWHOSX,
+ SPE_BUILTIN_EVLWHOUX,
+ SPE_BUILTIN_EVLWHSPLATX,
+ SPE_BUILTIN_EVLWWSPLATX,
+ SPE_BUILTIN_EVMERGEHI,
+ SPE_BUILTIN_EVMERGEHILO,
+ SPE_BUILTIN_EVMERGELO,
+ SPE_BUILTIN_EVMERGELOHI,
+ SPE_BUILTIN_EVMHEGSMFAA,
+ SPE_BUILTIN_EVMHEGSMFAN,
+ SPE_BUILTIN_EVMHEGSMIAA,
+ SPE_BUILTIN_EVMHEGSMIAN,
+ SPE_BUILTIN_EVMHEGUMIAA,
+ SPE_BUILTIN_EVMHEGUMIAN,
+ SPE_BUILTIN_EVMHESMF,
+ SPE_BUILTIN_EVMHESMFA,
+ SPE_BUILTIN_EVMHESMFAAW,
+ SPE_BUILTIN_EVMHESMFANW,
+ SPE_BUILTIN_EVMHESMI,
+ SPE_BUILTIN_EVMHESMIA,
+ SPE_BUILTIN_EVMHESMIAAW,
+ SPE_BUILTIN_EVMHESMIANW,
+ SPE_BUILTIN_EVMHESSF,
+ SPE_BUILTIN_EVMHESSFA,
+ SPE_BUILTIN_EVMHESSFAAW,
+ SPE_BUILTIN_EVMHESSFANW,
+ SPE_BUILTIN_EVMHESSIAAW,
+ SPE_BUILTIN_EVMHESSIANW,
+ SPE_BUILTIN_EVMHEUMI,
+ SPE_BUILTIN_EVMHEUMIA,
+ SPE_BUILTIN_EVMHEUMIAAW,
+ SPE_BUILTIN_EVMHEUMIANW,
+ SPE_BUILTIN_EVMHEUSIAAW,
+ SPE_BUILTIN_EVMHEUSIANW,
+ SPE_BUILTIN_EVMHOGSMFAA,
+ SPE_BUILTIN_EVMHOGSMFAN,
+ SPE_BUILTIN_EVMHOGSMIAA,
+ SPE_BUILTIN_EVMHOGSMIAN,
+ SPE_BUILTIN_EVMHOGUMIAA,
+ SPE_BUILTIN_EVMHOGUMIAN,
+ SPE_BUILTIN_EVMHOSMF,
+ SPE_BUILTIN_EVMHOSMFA,
+ SPE_BUILTIN_EVMHOSMFAAW,
+ SPE_BUILTIN_EVMHOSMFANW,
+ SPE_BUILTIN_EVMHOSMI,
+ SPE_BUILTIN_EVMHOSMIA,
+ SPE_BUILTIN_EVMHOSMIAAW,
+ SPE_BUILTIN_EVMHOSMIANW,
+ SPE_BUILTIN_EVMHOSSF,
+ SPE_BUILTIN_EVMHOSSFA,
+ SPE_BUILTIN_EVMHOSSFAAW,
+ SPE_BUILTIN_EVMHOSSFANW,
+ SPE_BUILTIN_EVMHOSSIAAW,
+ SPE_BUILTIN_EVMHOSSIANW,
+ SPE_BUILTIN_EVMHOUMI,
+ SPE_BUILTIN_EVMHOUMIA,
+ SPE_BUILTIN_EVMHOUMIAAW,
+ SPE_BUILTIN_EVMHOUMIANW,
+ SPE_BUILTIN_EVMHOUSIAAW,
+ SPE_BUILTIN_EVMHOUSIANW,
+ SPE_BUILTIN_EVMWHSMF,
+ SPE_BUILTIN_EVMWHSMFA,
+ SPE_BUILTIN_EVMWHSMI,
+ SPE_BUILTIN_EVMWHSMIA,
+ SPE_BUILTIN_EVMWHSSF,
+ SPE_BUILTIN_EVMWHSSFA,
+ SPE_BUILTIN_EVMWHUMI,
+ SPE_BUILTIN_EVMWHUMIA,
+ SPE_BUILTIN_EVMWLSMIAAW,
+ SPE_BUILTIN_EVMWLSMIANW,
+ SPE_BUILTIN_EVMWLSSIAAW,
+ SPE_BUILTIN_EVMWLSSIANW,
+ SPE_BUILTIN_EVMWLUMI,
+ SPE_BUILTIN_EVMWLUMIA,
+ SPE_BUILTIN_EVMWLUMIAAW,
+ SPE_BUILTIN_EVMWLUMIANW,
+ SPE_BUILTIN_EVMWLUSIAAW,
+ SPE_BUILTIN_EVMWLUSIANW,
+ SPE_BUILTIN_EVMWSMF,
+ SPE_BUILTIN_EVMWSMFA,
+ SPE_BUILTIN_EVMWSMFAA,
+ SPE_BUILTIN_EVMWSMFAN,
+ SPE_BUILTIN_EVMWSMI,
+ SPE_BUILTIN_EVMWSMIA,
+ SPE_BUILTIN_EVMWSMIAA,
+ SPE_BUILTIN_EVMWSMIAN,
+ SPE_BUILTIN_EVMWHSSFAA,
+ SPE_BUILTIN_EVMWSSF,
+ SPE_BUILTIN_EVMWSSFA,
+ SPE_BUILTIN_EVMWSSFAA,
+ SPE_BUILTIN_EVMWSSFAN,
+ SPE_BUILTIN_EVMWUMI,
+ SPE_BUILTIN_EVMWUMIA,
+ SPE_BUILTIN_EVMWUMIAA,
+ SPE_BUILTIN_EVMWUMIAN,
+ SPE_BUILTIN_EVNAND,
+ SPE_BUILTIN_EVNOR,
+ SPE_BUILTIN_EVOR,
+ SPE_BUILTIN_EVORC,
+ SPE_BUILTIN_EVRLW,
+ SPE_BUILTIN_EVSLW,
+ SPE_BUILTIN_EVSRWS,
+ SPE_BUILTIN_EVSRWU,
+ SPE_BUILTIN_EVSTDDX,
+ SPE_BUILTIN_EVSTDHX,
+ SPE_BUILTIN_EVSTDWX,
+ SPE_BUILTIN_EVSTWHEX,
+ SPE_BUILTIN_EVSTWHOX,
+ SPE_BUILTIN_EVSTWWEX,
+ SPE_BUILTIN_EVSTWWOX,
+ SPE_BUILTIN_EVSUBFW,
+ SPE_BUILTIN_EVXOR,
+ SPE_BUILTIN_EVABS,
+ SPE_BUILTIN_EVADDSMIAAW,
+ SPE_BUILTIN_EVADDSSIAAW,
+ SPE_BUILTIN_EVADDUMIAAW,
+ SPE_BUILTIN_EVADDUSIAAW,
+ SPE_BUILTIN_EVCNTLSW,
+ SPE_BUILTIN_EVCNTLZW,
+ SPE_BUILTIN_EVEXTSB,
+ SPE_BUILTIN_EVEXTSH,
+ SPE_BUILTIN_EVFSABS,
+ SPE_BUILTIN_EVFSCFSF,
+ SPE_BUILTIN_EVFSCFSI,
+ SPE_BUILTIN_EVFSCFUF,
+ SPE_BUILTIN_EVFSCFUI,
+ SPE_BUILTIN_EVFSCTSF,
+ SPE_BUILTIN_EVFSCTSI,
+ SPE_BUILTIN_EVFSCTSIZ,
+ SPE_BUILTIN_EVFSCTUF,
+ SPE_BUILTIN_EVFSCTUI,
+ SPE_BUILTIN_EVFSCTUIZ,
+ SPE_BUILTIN_EVFSNABS,
+ SPE_BUILTIN_EVFSNEG,
+ SPE_BUILTIN_EVMRA,
+ SPE_BUILTIN_EVNEG,
+ SPE_BUILTIN_EVRNDW,
+ SPE_BUILTIN_EVSUBFSMIAAW,
+ SPE_BUILTIN_EVSUBFSSIAAW,
+ SPE_BUILTIN_EVSUBFUMIAAW,
+ SPE_BUILTIN_EVSUBFUSIAAW,
+ SPE_BUILTIN_EVADDIW,
+ SPE_BUILTIN_EVLDD,
+ SPE_BUILTIN_EVLDH,
+ SPE_BUILTIN_EVLDW,
+ SPE_BUILTIN_EVLHHESPLAT,
+ SPE_BUILTIN_EVLHHOSSPLAT,
+ SPE_BUILTIN_EVLHHOUSPLAT,
+ SPE_BUILTIN_EVLWHE,
+ SPE_BUILTIN_EVLWHOS,
+ SPE_BUILTIN_EVLWHOU,
+ SPE_BUILTIN_EVLWHSPLAT,
+ SPE_BUILTIN_EVLWWSPLAT,
+ SPE_BUILTIN_EVRLWI,
+ SPE_BUILTIN_EVSLWI,
+ SPE_BUILTIN_EVSRWIS,
+ SPE_BUILTIN_EVSRWIU,
+ SPE_BUILTIN_EVSTDD,
+ SPE_BUILTIN_EVSTDH,
+ SPE_BUILTIN_EVSTDW,
+ SPE_BUILTIN_EVSTWHE,
+ SPE_BUILTIN_EVSTWHO,
+ SPE_BUILTIN_EVSTWWE,
+ SPE_BUILTIN_EVSTWWO,
+ SPE_BUILTIN_EVSUBIFW,
+
+ /* Compares. */
+ SPE_BUILTIN_EVCMPEQ,
+ SPE_BUILTIN_EVCMPGTS,
+ SPE_BUILTIN_EVCMPGTU,
+ SPE_BUILTIN_EVCMPLTS,
+ SPE_BUILTIN_EVCMPLTU,
+ SPE_BUILTIN_EVFSCMPEQ,
+ SPE_BUILTIN_EVFSCMPGT,
+ SPE_BUILTIN_EVFSCMPLT,
+ SPE_BUILTIN_EVFSTSTEQ,
+ SPE_BUILTIN_EVFSTSTGT,
+ SPE_BUILTIN_EVFSTSTLT,
+
+ /* EVSEL compares. */
+ SPE_BUILTIN_EVSEL_CMPEQ,
+ SPE_BUILTIN_EVSEL_CMPGTS,
+ SPE_BUILTIN_EVSEL_CMPGTU,
+ SPE_BUILTIN_EVSEL_CMPLTS,
+ SPE_BUILTIN_EVSEL_CMPLTU,
+ SPE_BUILTIN_EVSEL_FSCMPEQ,
+ SPE_BUILTIN_EVSEL_FSCMPGT,
+ SPE_BUILTIN_EVSEL_FSCMPLT,
+ SPE_BUILTIN_EVSEL_FSTSTEQ,
+ SPE_BUILTIN_EVSEL_FSTSTGT,
+ SPE_BUILTIN_EVSEL_FSTSTLT,
+
+ SPE_BUILTIN_EVSPLATFI,
+ SPE_BUILTIN_EVSPLATI,
+ SPE_BUILTIN_EVMWHSSMAA,
+ SPE_BUILTIN_EVMWHSMFAA,
+ SPE_BUILTIN_EVMWHSMIAA,
+ SPE_BUILTIN_EVMWHUSIAA,
+ SPE_BUILTIN_EVMWHUMIAA,
+ SPE_BUILTIN_EVMWHSSFAN,
+ SPE_BUILTIN_EVMWHSSIAN,
+ SPE_BUILTIN_EVMWHSMFAN,
+ SPE_BUILTIN_EVMWHSMIAN,
+ SPE_BUILTIN_EVMWHUSIAN,
+ SPE_BUILTIN_EVMWHUMIAN,
+ SPE_BUILTIN_EVMWHGSSFAA,
+ SPE_BUILTIN_EVMWHGSMFAA,
+ SPE_BUILTIN_EVMWHGSMIAA,
+ SPE_BUILTIN_EVMWHGUMIAA,
+ SPE_BUILTIN_EVMWHGSSFAN,
+ SPE_BUILTIN_EVMWHGSMFAN,
+ SPE_BUILTIN_EVMWHGSMIAN,
+ SPE_BUILTIN_EVMWHGUMIAN,
+ SPE_BUILTIN_MTSPEFSCR,
+ SPE_BUILTIN_MFSPEFSCR,
+ SPE_BUILTIN_BRINC
};
OpenPOWER on IntegriCloud