This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: RFC: Add power7 support to the rs6000 (part 4 of 12)
- From: Michael Meissner <meissner at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 4 Jun 2009 17:46:40 -0400
- Subject: [PATCH]: RFC: Add power7 support to the rs6000 (part 4 of 12)
- References: <20090604214253.GA31633@hungry-tiger.westford.ibm.com>
2009-06-04 Michael Meissner <meissner@linux.vnet.ibm.com>
Pat Haugen <pthaugen@us.ibm.com>
Revital1 Eres <ERES@il.ibm.com>
* config/rs6000/rs6000.h (ASM_CPU_POWER7_SPEC): Key off of
HAVE_AS_POPCNTD, instead of HAVE_AS_VSX.
(ASM_CPU_SPEC): Add -mcpu=power7 support. If -mcpu=native, use
the assembler options to enable the appropriate instructions for
the machine we are running on for a native compiler.
(TARGET_POPCNTD): If the assembler doesn't support popcntd, don't
allow the -mpopcntd switch.
(enum processor_type): Add PROCESSOR_POWER7.
(rs6000_debug_*): New variables for -mdebug= options.
(TARGET_DEBUG_*): New target options for -mdebug= options.
(rs6000_isel): Delete, -misel moved to be a target bit.
(enum rs6000_vector): New enum to describe the vector mode.
(VECTOR_UNIT_*_P): New macros to say whether a given mode is
supported by the appropriate vector unit.
(VECTOR_MEM_*_P): New macros to say whether a given mode is loaded
or stored by the appropriate vector unit.
(VECTOR_ALIGN): New macro to give the alignment of a vector type,
based on the vector unit being used.
(TARGET_ISEL): Delete, provided by rs6000.opt now.
(TARGET_ISEL64): New macro for -misel on 64-bit targets.
(UNITS_PER_VSX_WORD): Define.
(STACK_BOUNDARY): Add VSX support.
(LOCAL_ALIGNMENT): Ditto.
(SLOW_UNALIGNED_ACCESS): Ditto.
(UNITS_PER_SIMD_WORD): Ditto.
(MODES_TIEABLE_P): Ditto.
(STARTING_FRAME_OFFSET): Ditto.
(STACK_DYNAMIC_OFFSET): Ditto.
(ADDITIONAL_REGISTER_NAMES): Ditto.
(VSX_REGNO_P): New macro for VSX support.
(VSX_VECTOR_MODE): Ditto.
(VSX_SCALAR_MODE): Ditto.
(VSX_MODE): Ditto.
(VSX_MOVE_MODE): Ditto.
(VSX_REG_CLASS_P): Ditto.
(VFLOAT_REGNO_P): New macro for vector abstraction support.
(VINT_REGNO_P): Ditto.
(VLOGICAL_REGNO_P): Ditto.
(HARD_REGNO_NREGS): Rewrite to be an array lookup instead of a
function call.
(REGNO_REG_CLASS): Ditto.
(CLASS_MAX_NREGS): Ditto.
(enum reg_class): Add VSX_REGS, which is a superset of the
traditional floating point registers and altivec registers.
(REG_CLASS_NAMES): Ditto.
(REG_CLASS_CONTENTS): Ditto.
(IRA_COVER_CLASSES_PRE_VSX): Rename from IRA_COVER_CLASSES, and
provide this via the target hook if not -mvsx.
(IRA_COVER_CLASSES_VSX): Ira cover classes for vsx that accounts
for traditional floating point registers and altivec registers
being subsets of VSX registers.
(rs6000_vector_reg_class): New array to map vector mode to
preferred register class.
(rs6000_vsx_reg_class): New scalar to give the current register
class for vsx.
(PREFERRED_RELOAD_CLASS): Convert to a function call through a
pointer instead of direct code.
(SECONDARY_MEMORY_NEEDED): Ditto.
(CANNOT_CHANGE_MODE_CLASS): Ditto.
(SECONDARY_RELOAD_CLASS): Call through a pointer to allow new
debugging to be inserted invisibly.
(LEGITIMZE_RELOAD_ADDRESS): Ditto.
(GO_IF_MODE_DEPENDENT_ADDRESS): Ditto.
(EPILOGUE_USES): Make spacing consistant.
(ALTIVEC_BUILTIN_*): Add new builtins for functions taking vector
unsigned arguments and for things like vperm that operate on VSX
types as well.
(VSX_BUILTIN_*): Add builtins for the new VSX instructions.
(VECTOR_BUILTIN_*): New builtins for combined Altivec/VSX support.
(POWER7_BUILTIN_BPERMD): New builtin for bpermd instruction.
(rs6000_builtin_type_index): Add types for VSX support.
(V2DI_type_node): Ditto.
(V2DF_type_node): Ditto.
(unsigned_V2DI_type_node): Ditto.
(bool_long_type_node): Ditto.
(bool_V2DI_type_node): Ditto.
(intDI_type_internal_node): Ditto.
(uintDI_type_internal_node): Ditto.
(double_type_internal_node): Ditto.
(struct rs6000_addrsize): New structure to hold things that
changed based on -m64/-m32.
(rs6000_address_size): Add declaration.
(POINTER_SIZE): Rather than expand the ?: at runtime, use an
external variable that is filled in at initialization time.
(Pmode): Ditto.
(rs6000_class_max_nregs): Add external declaration here.
(rs6000_hard_regno_nregs): Ditto.
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h (.../svn+ssh://meissner@gcc.gnu.org/svn/gcc/trunk/gcc/config/rs6000/rs6000.h) (revision 148152)
+++ gcc/config/rs6000/rs6000.h (.../gcc/config/rs6000/rs6000.h) (working copy)
@@ -77,14 +77,16 @@
#define ASM_CPU_POWER6_SPEC "-mpower4 -maltivec"
#endif
-#ifdef HAVE_AS_VSX
+#ifdef HAVE_AS_POPCNTD
#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. */
+/* Common ASM definitions used by ASM_SPEC among the various targets for
+ handling -mcpu=xxx switches. There is a parallel list in driver-rs6000.c to
+ provide the default assembler options if the user uses -mcpu=native, so if
+ you make changes here, make them also there. */
#define ASM_CPU_SPEC \
"%{!mcpu*: \
%{mpower: %{!mpower2: -mpwr}} \
@@ -93,6 +95,7 @@
%{!mpowerpc64*: %{mpowerpc*: -mppc}} \
%{mno-power: %{!mpowerpc*: -mcom}} \
%{!mno-power: %{!mpower*: %(asm_default)}}} \
+%{mcpu=native: %(asm_cpu_native)} \
%{mcpu=common: -mcom} \
%{mcpu=cell: -mcell} \
%{mcpu=power: -mpwr} \
@@ -168,6 +171,7 @@
#define EXTRA_SPECS \
{ "cpp_default", CPP_DEFAULT_SPEC }, \
{ "asm_cpu", ASM_CPU_SPEC }, \
+ { "asm_cpu_native", ASM_CPU_NATIVE_SPEC }, \
{ "asm_default", ASM_DEFAULT_SPEC }, \
{ "cc1_cpu", CC1_CPU_SPEC }, \
{ "asm_cpu_power5", ASM_CPU_POWER5_SPEC }, \
@@ -184,6 +188,10 @@ extern const char *host_detect_local_cpu
#define EXTRA_SPEC_FUNCTIONS \
{ "local_cpu_detect", host_detect_local_cpu },
#define HAVE_LOCAL_CPU_DETECT
+#define ASM_CPU_NATIVE_SPEC "%:local_cpu_detect(asm)"
+
+#else
+#define ASM_CPU_NATIVE_SPEC "%(asm_default)"
#endif
#ifndef CC1_CPU_SPEC
@@ -245,6 +253,14 @@ extern const char *host_detect_local_cpu
#define TARGET_DFP 0
#endif
+/* Define TARGET_POPCNTD if the target assembler does not support the
+ popcount word and double word instructions. */
+
+#ifndef HAVE_AS_POPCNTD
+#undef TARGET_POPCNTD
+#define TARGET_POPCNTD 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
@@ -309,6 +325,7 @@ enum processor_type
PROCESSOR_POWER4,
PROCESSOR_POWER5,
PROCESSOR_POWER6,
+ PROCESSOR_POWER7,
PROCESSOR_CELL
};
@@ -392,9 +409,15 @@ extern struct rs6000_cpu_select rs6000_s
extern const char *rs6000_debug_name; /* Name for -mdebug-xxxx option */
extern int rs6000_debug_stack; /* debug stack applications */
extern int rs6000_debug_arg; /* debug argument handling */
+extern int rs6000_debug_reg; /* debug register handling */
+extern int rs6000_debug_addr; /* debug memory addressing */
+extern int rs6000_debug_cost; /* debug rtx_costs */
#define TARGET_DEBUG_STACK rs6000_debug_stack
#define TARGET_DEBUG_ARG rs6000_debug_arg
+#define TARGET_DEBUG_REG rs6000_debug_reg
+#define TARGET_DEBUG_ADDR rs6000_debug_addr
+#define TARGET_DEBUG_COST rs6000_debug_cost
extern const char *rs6000_traceback_name; /* Type of traceback table. */
@@ -405,13 +428,65 @@ 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;
+/* Describe which vector unit to use for a given machine mode. */
+enum rs6000_vector {
+ VECTOR_NONE, /* Type is not a vector or not supported */
+ VECTOR_ALTIVEC, /* Use altivec for vector processing */
+ VECTOR_VSX, /* Use VSX for vector processing */
+ VECTOR_PAIRED, /* Use paired floating point for vectors */
+ VECTOR_SPE, /* Use SPE for vector processing */
+ VECTOR_OTHER /* Some other vector unit */
+};
+
+extern enum rs6000_vector rs6000_vector_unit[];
+
+#define VECTOR_UNIT_NONE_P(MODE) \
+ (rs6000_vector_unit[(MODE)] == VECTOR_NONE)
+
+#define VECTOR_UNIT_VSX_P(MODE) \
+ (rs6000_vector_unit[(MODE)] == VECTOR_VSX)
+
+#define VECTOR_UNIT_ALTIVEC_P(MODE) \
+ (rs6000_vector_unit[(MODE)] == VECTOR_ALTIVEC)
+
+#define VECTOR_UNIT_ALTIVEC_OR_VSX_P(MODE) \
+ (rs6000_vector_unit[(MODE)] == VECTOR_ALTIVEC \
+ || rs6000_vector_unit[(MODE)] == VECTOR_VSX)
+
+/* Describe whether to use VSX loads or Altivec loads. For now, just use the
+ same unit as the vector unit we are using, but we may want to migrate to
+ using VSX style loads even for types handled by altivec. */
+extern enum rs6000_vector rs6000_vector_mem[];
+
+#define VECTOR_MEM_NONE_P(MODE) \
+ (rs6000_vector_mem[(MODE)] == VECTOR_NONE)
+
+#define VECTOR_MEM_VSX_P(MODE) \
+ (rs6000_vector_mem[(MODE)] == VECTOR_VSX)
+
+#define VECTOR_MEM_ALTIVEC_P(MODE) \
+ (rs6000_vector_mem[(MODE)] == VECTOR_ALTIVEC)
+
+#define VECTOR_MEM_ALTIVEC_OR_VSX_P(MODE) \
+ (rs6000_vector_mem[(MODE)] == VECTOR_ALTIVEC \
+ || rs6000_vector_mem[(MODE)] == VECTOR_VSX)
+
+/* Return the alignment of a given vector type, which is set based on the
+ vector unit use. VSX for instance can load 32 or 64 bit aligned words
+ without problems, while Altivec requires 128-bit aligned vectors. */
+extern int rs6000_vector_align[];
+
+#define VECTOR_ALIGN(MODE) \
+ ((rs6000_vector_align[(MODE)] != 0) \
+ ? rs6000_vector_align[(MODE)] \
+ : (int)GET_MODE_BITSIZE ((MODE)))
+
/* Alignment options for fields in structures for sub-targets following
AIX-like ABI.
ALIGN_POWER word-aligns FP doubles (default AIX ABI).
@@ -436,7 +511,7 @@ extern int rs6000_xilinx_fpu;
#define TARGET_SPE_ABI 0
#define TARGET_SPE 0
#define TARGET_E500 0
-#define TARGET_ISEL rs6000_isel
+#define TARGET_ISEL64 (TARGET_ISEL && TARGET_POWERPC64)
#define TARGET_FPRS 1
#define TARGET_E500_SINGLE 0
#define TARGET_E500_DOUBLE 0
@@ -534,6 +609,7 @@ extern int rs6000_xilinx_fpu;
#endif
#define UNITS_PER_FP_WORD 8
#define UNITS_PER_ALTIVEC_WORD 16
+#define UNITS_PER_VSX_WORD 16
#define UNITS_PER_SPE_WORD 8
#define UNITS_PER_PAIRED_WORD 8
@@ -598,14 +674,16 @@ extern int rs6000_xilinx_fpu;
/* Width in bits of a pointer.
See also the macro `Pmode' defined below. */
-#define POINTER_SIZE (TARGET_32BIT ? 32 : 64)
+extern unsigned rs6000_pointer_size;
+#define POINTER_SIZE rs6000_pointer_size
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
/* Boundary (in *bits*) on which stack pointer should be aligned. */
-#define STACK_BOUNDARY \
- ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define STACK_BOUNDARY \
+ ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI && !TARGET_VSX) \
+ ? 64 : 128)
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
@@ -617,10 +695,11 @@ extern int rs6000_xilinx_fpu;
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 : \
+ (((TARGET_ALTIVEC || TARGET_VSX) \
+ && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \
(TARGET_E500_DOUBLE \
- && TYPE_MODE (TYPE) == DFmode) ? 64 : \
- ((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE \
+ && 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)
@@ -678,15 +757,17 @@ extern int rs6000_xilinx_fpu;
/* 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. */
+/* Altivec vector memory instructions simply ignore the low bits; SPE vector
+ memory instructions trap on unaligned accesses; VSX memory instructions are
+ aligned to 4 or 8 bytes. */
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
(STRICT_ALIGNMENT \
|| (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
|| (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode \
|| (MODE) == DImode) \
&& (ALIGN) < 32) \
- || (VECTOR_MODE_P ((MODE)) && (ALIGN) < GET_MODE_BITSIZE ((MODE))))
+ || (VECTOR_MODE_P ((MODE)) && (((int)(ALIGN)) < VECTOR_ALIGN (MODE))))
+
/* Standard register usage. */
@@ -913,16 +994,49 @@ extern int rs6000_xilinx_fpu;
/* True if register is an AltiVec register. */
#define ALTIVEC_REGNO_P(N) ((N) >= FIRST_ALTIVEC_REGNO && (N) <= LAST_ALTIVEC_REGNO)
+/* True if register is a VSX register. */
+#define VSX_REGNO_P(N) (FP_REGNO_P (N) || ALTIVEC_REGNO_P (N))
+
+/* Alternate name for any vector register supporting floating point, no matter
+ which instruction set(s) are available. */
+#define VFLOAT_REGNO_P(N) \
+ (ALTIVEC_REGNO_P (N) || (TARGET_VSX && FP_REGNO_P (N)))
+
+/* Alternate name for any vector register supporting integer, no matter which
+ instruction set(s) are available. */
+#define VINT_REGNO_P(N) ALTIVEC_REGNO_P (N)
+
+/* Alternate name for any vector register supporting logical operations, no
+ matter which instruction set(s) are available. */
+#define VLOGICAL_REGNO_P(N) VFLOAT_REGNO_P (N)
+
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE. */
-#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs ((REGNO), (MODE))
+#define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)]
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
((TARGET_32BIT && TARGET_POWERPC64 \
&& (GET_MODE_SIZE (MODE) > 4) \
&& INT_REGNO_P (REGNO)) ? 1 : 0)
+#define VSX_VECTOR_MODE(MODE) \
+ ((MODE) == V4SFmode \
+ || (MODE) == V2DFmode) \
+
+#define VSX_SCALAR_MODE(MODE) \
+ ((MODE) == DFmode)
+
+#define VSX_MODE(MODE) \
+ (VSX_VECTOR_MODE (MODE) \
+ || VSX_SCALAR_MODE (MODE))
+
+#define VSX_MOVE_MODE(MODE) \
+ (VSX_VECTOR_MODE (MODE) \
+ || VSX_SCALAR_MODE (MODE) \
+ || ALTIVEC_VECTOR_MODE (MODE) \
+ || (MODE) == TImode)
+
#define ALTIVEC_VECTOR_MODE(MODE) \
((MODE) == V16QImode \
|| (MODE) == V8HImode \
@@ -938,10 +1052,12 @@ extern int rs6000_xilinx_fpu;
#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)))
+#define UNITS_PER_SIMD_WORD(MODE) \
+ (TARGET_VSX ? UNITS_PER_VSX_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. */
@@ -969,6 +1085,10 @@ extern int rs6000_xilinx_fpu;
? ALTIVEC_VECTOR_MODE (MODE2) \
: ALTIVEC_VECTOR_MODE (MODE2) \
? ALTIVEC_VECTOR_MODE (MODE1) \
+ : VSX_VECTOR_MODE (MODE1) \
+ ? VSX_VECTOR_MODE (MODE2) \
+ : VSX_VECTOR_MODE (MODE2) \
+ ? VSX_VECTOR_MODE (MODE1) \
: 1)
/* Post-reload, we can't use any new AltiVec registers, as we already
@@ -1054,9 +1174,10 @@ extern int rs6000_xilinx_fpu;
For any two classes, it is very desirable that there be another
class that represents their union. */
-/* The RS/6000 has three types of registers, fixed-point, floating-point,
- and condition registers, plus three special registers, MQ, CTR, and the
- link register. AltiVec adds a vector register class.
+/* The RS/6000 has three types of registers, fixed-point, floating-point, and
+ condition registers, plus three special registers, MQ, CTR, and the link
+ register. AltiVec adds a vector register class. VSX registers overlap the
+ FPR registers and the Altivec registers.
However, r0 is special in that it cannot be used as a base register.
So make a class for registers valid as base registers.
@@ -1071,6 +1192,7 @@ enum reg_class
GENERAL_REGS,
FLOAT_REGS,
ALTIVEC_REGS,
+ VSX_REGS,
VRSAVE_REGS,
VSCR_REGS,
SPE_ACC_REGS,
@@ -1101,6 +1223,7 @@ enum reg_class
"GENERAL_REGS", \
"FLOAT_REGS", \
"ALTIVEC_REGS", \
+ "VSX_REGS", \
"VRSAVE_REGS", \
"VSCR_REGS", \
"SPE_ACC_REGS", \
@@ -1130,6 +1253,7 @@ enum reg_class
{ 0xffffffff, 0x00000000, 0x00000008, 0x00020000 }, /* GENERAL_REGS */ \
{ 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* FLOAT_REGS */ \
{ 0x00000000, 0x00000000, 0xffffe000, 0x00001fff }, /* ALTIVEC_REGS */ \
+ { 0x00000000, 0xffffffff, 0xffffe000, 0x00001fff }, /* VSX_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00002000 }, /* VRSAVE_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */ \
@@ -1154,12 +1278,24 @@ enum reg_class
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. */
+ marker.
+
+ We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
+ account for the Altivec and Floating registers being subsets of the VSX
+ register set. */
+
+#define IRA_COVER_CLASSES_PRE_VSX \
+{ \
+ GENERAL_REGS, SPECIAL_REGS, FLOAT_REGS, ALTIVEC_REGS, /* VSX_REGS, */ \
+ /* VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS, \
+ /* MQ_REGS, LINK_REGS, CTR_REGS, */ \
+ CR_REGS, XER_REGS, LIM_REG_CLASSES \
+}
-#define IRA_COVER_CLASSES \
+#define IRA_COVER_CLASSES_VSX \
{ \
- GENERAL_REGS, SPECIAL_REGS, FLOAT_REGS, ALTIVEC_REGS, \
- /*VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS, \
+ GENERAL_REGS, SPECIAL_REGS, /* FLOAT_REGS, ALTIVEC_REGS, */ VSX_REGS, \
+ /* VRSAVE_REGS,*/ VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS, \
/* MQ_REGS, LINK_REGS, CTR_REGS, */ \
CR_REGS, XER_REGS, LIM_REG_CLASSES \
}
@@ -1169,29 +1305,29 @@ enum reg_class
reg number REGNO. This could be a conditional expression
or could index an array. */
-#define REGNO_REG_CLASS(REGNO) \
- ((REGNO) == 0 ? GENERAL_REGS \
- : (REGNO) < 32 ? BASE_REGS \
- : FP_REGNO_P (REGNO) ? FLOAT_REGS \
- : ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_REGS \
- : (REGNO) == CR0_REGNO ? CR0_REGS \
- : CR_REGNO_P (REGNO) ? CR_REGS \
- : (REGNO) == MQ_REGNO ? MQ_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 \
- : (REGNO) == VSCR_REGNO ? VRSAVE_REGS \
- : (REGNO) == SPE_ACC_REGNO ? SPE_ACC_REGS \
- : (REGNO) == SPEFSCR_REGNO ? SPEFSCR_REGS \
- : (REGNO) == FRAME_POINTER_REGNUM ? BASE_REGS \
- : NO_REGS)
+extern enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
+
+#if ENABLE_CHECKING
+#define REGNO_REG_CLASS(REGNO) \
+ (gcc_assert (IN_RANGE ((REGNO), 0, FIRST_PSEUDO_REGISTER-1)), \
+ rs6000_regno_regclass[(REGNO)])
+
+#else
+#define REGNO_REG_CLASS(REGNO) rs6000_regno_regclass[(REGNO)]
+#endif
+
+/* VSX register classes. */
+extern enum reg_class rs6000_vector_reg_class[];
+extern enum reg_class rs6000_vsx_reg_class;
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS GENERAL_REGS
#define BASE_REG_CLASS BASE_REGS
+/* Return whether a given register class can hold VSX objects. */
+#define VSX_REG_CLASS_P(CLASS) \
+ ((CLASS) == VSX_REGS || (CLASS) == FLOAT_REGS || (CLASS) == ALTIVEC_REGS)
+
/* 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
@@ -1211,20 +1347,14 @@ enum reg_class
*/
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
- ((CONSTANT_P (X) \
- && reg_classes_intersect_p ((CLASS), FLOAT_REGS)) \
- ? NO_REGS \
- : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \
- && (CLASS) == NON_SPECIAL_REGS) \
- ? GENERAL_REGS \
- : (CLASS))
+ rs6000_preferred_reload_class_ptr (X, CLASS)
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
NO_REGS is returned. */
#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
- rs6000_secondary_reload_class (CLASS, MODE, IN)
+ rs6000_secondary_reload_class_ptr (CLASS, MODE, IN)
/* If we are copying between FP or AltiVec registers and anything
else, we need a memory location. The exception is when we are
@@ -1232,18 +1362,7 @@ enum reg_class
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))
+ rs6000_secondary_memory_needed_ptr (CLASS1, CLASS2, MODE)
/* For cpus that cannot load/store SDmode values from the 64-bit
FP registers without using a full 64-bit load/store, we need
@@ -1255,32 +1374,15 @@ enum reg_class
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
- On RS/6000, this is the size of MODE in words,
- except in the FP regs, where a single reg is enough for two words. */
-#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) \
- ? 1 \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+ On RS/6000, this is the size of MODE in words, except in the FP regs, where
+ a single reg is enough for two words, unless we have VSX, where the FP
+ registers can hold 128 bits. */
+#define CLASS_MAX_NREGS(CLASS, MODE) rs6000_class_max_nregs[(MODE)][(CLASS)]
/* 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)))
+ rs6000_cannot_change_mode_class_ptr (FROM, TO, CLASS)
/* Stack layout; function entry, exit and calling. */
@@ -1341,8 +1443,8 @@ extern enum rs6000_abi rs6000_current_ab
#define STARTING_FRAME_OFFSET \
(FRAME_GROWS_DOWNWARD \
? 0 \
- : (RS6000_ALIGN (crtl->outgoing_args_size, \
- TARGET_ALTIVEC ? 16 : 8) \
+ : (RS6000_ALIGN (crtl->outgoing_args_size, \
+ (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \
+ RS6000_SAVE_AREA))
/* Offset from the stack pointer register to an item dynamically
@@ -1352,8 +1454,8 @@ extern enum rs6000_abi rs6000_current_ab
length of the outgoing arguments. The default is correct for most
machines. See `function.c' for details. */
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
- (RS6000_ALIGN (crtl->outgoing_args_size, \
- TARGET_ALTIVEC ? 16 : 8) \
+ (RS6000_ALIGN (crtl->outgoing_args_size, \
+ (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \
+ (STACK_POINTER_OFFSET))
/* If we generate an insn to push BYTES bytes,
@@ -1603,7 +1705,7 @@ typedef struct rs6000_args
#define EPILOGUE_USES(REGNO) \
((reload_completed && (REGNO) == LR_REGNO) \
|| (TARGET_ALTIVEC && (REGNO) == VRSAVE_REGNO) \
- || (crtl->calls_eh_return \
+ || (crtl->calls_eh_return \
&& TARGET_AIX \
&& (REGNO) == 2))
@@ -1779,7 +1881,7 @@ typedef struct rs6000_args
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
do { \
int win; \
- (X) = rs6000_legitimize_reload_address ((X), (MODE), (OPNUM), \
+ (X) = rs6000_legitimize_reload_address_ptr ((X), (MODE), (OPNUM), \
(int)(TYPE), (IND_LEVELS), &win); \
if ( win ) \
goto WIN; \
@@ -1790,7 +1892,7 @@ do { \
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
do { \
- if (rs6000_mode_dependent_address (ADDR)) \
+ if (rs6000_mode_dependent_address_ptr (ADDR)) \
goto LABEL; \
} while (0)
@@ -1892,7 +1994,8 @@ do { \
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
-#define Pmode (TARGET_32BIT ? SImode : DImode)
+extern unsigned rs6000_pmode;
+#define Pmode ((enum machine_mode)rs6000_pmode)
/* Supply definition of STACK_SIZE_MODE for allocate_dynamic_stack_space. */
#define STACK_SIZE_MODE (TARGET_32BIT ? SImode : DImode)
@@ -2233,7 +2336,24 @@ extern char rs6000_reg_names[][8]; /* re
/* no additional names for: mq, lr, ctr, ap */ \
{"cr0", 68}, {"cr1", 69}, {"cr2", 70}, {"cr3", 71}, \
{"cr4", 72}, {"cr5", 73}, {"cr6", 74}, {"cr7", 75}, \
- {"cc", 68}, {"sp", 1}, {"toc", 2} }
+ {"cc", 68}, {"sp", 1}, {"toc", 2}, \
+ /* VSX registers overlaid on top of FR, Altivec registers */ \
+ {"vs0", 32}, {"vs1", 33}, {"vs2", 34}, {"vs3", 35}, \
+ {"vs4", 36}, {"vs5", 37}, {"vs6", 38}, {"vs7", 39}, \
+ {"vs8", 40}, {"vs9", 41}, {"vs10", 42}, {"vs11", 43}, \
+ {"vs12", 44}, {"vs13", 45}, {"vs14", 46}, {"vs15", 47}, \
+ {"vs16", 48}, {"vs17", 49}, {"vs18", 50}, {"vs19", 51}, \
+ {"vs20", 52}, {"vs21", 53}, {"vs22", 54}, {"vs23", 55}, \
+ {"vs24", 56}, {"vs25", 57}, {"vs26", 58}, {"vs27", 59}, \
+ {"vs28", 60}, {"vs29", 61}, {"vs30", 62}, {"vs31", 63}, \
+ {"vs32", 77}, {"vs33", 78}, {"vs34", 79}, {"vs35", 80}, \
+ {"vs36", 81}, {"vs37", 82}, {"vs38", 83}, {"vs39", 84}, \
+ {"vs40", 85}, {"vs41", 86}, {"vs42", 87}, {"vs43", 88}, \
+ {"vs44", 89}, {"vs45", 90}, {"vs46", 91}, {"vs47", 92}, \
+ {"vs48", 93}, {"vs49", 94}, {"vs50", 95}, {"vs51", 96}, \
+ {"vs52", 97}, {"vs53", 98}, {"vs54", 99}, {"vs55", 100}, \
+ {"vs56", 101},{"vs57", 102},{"vs58", 103},{"vs59", 104}, \
+ {"vs60", 105},{"vs61", 106},{"vs62", 107},{"vs63", 108} }
/* Text to write out after a CALL that may be replaced by glue code by
the loader. This depends on the AIX version. */
@@ -2383,24 +2503,40 @@ enum rs6000_builtins
ALTIVEC_BUILTIN_VMINSW,
ALTIVEC_BUILTIN_VMINFP,
ALTIVEC_BUILTIN_VMULEUB,
+ ALTIVEC_BUILTIN_VMULEUB_UNS,
ALTIVEC_BUILTIN_VMULESB,
ALTIVEC_BUILTIN_VMULEUH,
+ ALTIVEC_BUILTIN_VMULEUH_UNS,
ALTIVEC_BUILTIN_VMULESH,
ALTIVEC_BUILTIN_VMULOUB,
+ ALTIVEC_BUILTIN_VMULOUB_UNS,
ALTIVEC_BUILTIN_VMULOSB,
ALTIVEC_BUILTIN_VMULOUH,
+ ALTIVEC_BUILTIN_VMULOUH_UNS,
ALTIVEC_BUILTIN_VMULOSH,
ALTIVEC_BUILTIN_VNMSUBFP,
ALTIVEC_BUILTIN_VNOR,
ALTIVEC_BUILTIN_VOR,
+ ALTIVEC_BUILTIN_VSEL_2DF, /* needed for VSX */
+ ALTIVEC_BUILTIN_VSEL_2DI, /* needed for VSX */
ALTIVEC_BUILTIN_VSEL_4SI,
ALTIVEC_BUILTIN_VSEL_4SF,
ALTIVEC_BUILTIN_VSEL_8HI,
ALTIVEC_BUILTIN_VSEL_16QI,
+ ALTIVEC_BUILTIN_VSEL_2DI_UNS,
+ ALTIVEC_BUILTIN_VSEL_4SI_UNS,
+ ALTIVEC_BUILTIN_VSEL_8HI_UNS,
+ ALTIVEC_BUILTIN_VSEL_16QI_UNS,
+ ALTIVEC_BUILTIN_VPERM_2DF, /* needed for VSX */
+ ALTIVEC_BUILTIN_VPERM_2DI, /* needed for VSX */
ALTIVEC_BUILTIN_VPERM_4SI,
ALTIVEC_BUILTIN_VPERM_4SF,
ALTIVEC_BUILTIN_VPERM_8HI,
ALTIVEC_BUILTIN_VPERM_16QI,
+ ALTIVEC_BUILTIN_VPERM_2DI_UNS,
+ ALTIVEC_BUILTIN_VPERM_4SI_UNS,
+ ALTIVEC_BUILTIN_VPERM_8HI_UNS,
+ ALTIVEC_BUILTIN_VPERM_16QI_UNS,
ALTIVEC_BUILTIN_VPKUHUM,
ALTIVEC_BUILTIN_VPKUWUM,
ALTIVEC_BUILTIN_VPKPX,
@@ -2756,6 +2892,7 @@ enum rs6000_builtins
ALTIVEC_BUILTIN_VEC_PROMOTE,
ALTIVEC_BUILTIN_VEC_INSERT,
ALTIVEC_BUILTIN_VEC_SPLATS,
+
ALTIVEC_BUILTIN_OVERLOADED_LAST = ALTIVEC_BUILTIN_VEC_SPLATS,
/* SPE builtins. */
@@ -3027,6 +3164,213 @@ enum rs6000_builtins
RS6000_BUILTIN_RECIPF,
RS6000_BUILTIN_RSQRTF,
+ /* VSX builtins. */
+ VSX_BUILTIN_LXSDUX,
+ VSX_BUILTIN_LXSDX,
+ VSX_BUILTIN_LXVD2UX,
+ VSX_BUILTIN_LXVD2X,
+ VSX_BUILTIN_LXVDSX,
+ VSX_BUILTIN_LXVW4UX,
+ VSX_BUILTIN_LXVW4X,
+ VSX_BUILTIN_STXSDUX,
+ VSX_BUILTIN_STXSDX,
+ VSX_BUILTIN_STXVD2UX,
+ VSX_BUILTIN_STXVD2X,
+ VSX_BUILTIN_STXVW4UX,
+ VSX_BUILTIN_STXVW4X,
+ VSX_BUILTIN_XSABSDP,
+ VSX_BUILTIN_XSADDDP,
+ VSX_BUILTIN_XSCMPODP,
+ VSX_BUILTIN_XSCMPUDP,
+ VSX_BUILTIN_XSCPSGNDP,
+ VSX_BUILTIN_XSCVDPSP,
+ VSX_BUILTIN_XSCVDPSXDS,
+ VSX_BUILTIN_XSCVDPSXWS,
+ VSX_BUILTIN_XSCVDPUXDS,
+ VSX_BUILTIN_XSCVDPUXWS,
+ VSX_BUILTIN_XSCVSPDP,
+ VSX_BUILTIN_XSCVSXDDP,
+ VSX_BUILTIN_XSCVUXDDP,
+ VSX_BUILTIN_XSDIVDP,
+ VSX_BUILTIN_XSMADDADP,
+ VSX_BUILTIN_XSMADDMDP,
+ VSX_BUILTIN_XSMAXDP,
+ VSX_BUILTIN_XSMINDP,
+ VSX_BUILTIN_XSMOVDP,
+ VSX_BUILTIN_XSMSUBADP,
+ VSX_BUILTIN_XSMSUBMDP,
+ VSX_BUILTIN_XSMULDP,
+ VSX_BUILTIN_XSNABSDP,
+ VSX_BUILTIN_XSNEGDP,
+ VSX_BUILTIN_XSNMADDADP,
+ VSX_BUILTIN_XSNMADDMDP,
+ VSX_BUILTIN_XSNMSUBADP,
+ VSX_BUILTIN_XSNMSUBMDP,
+ VSX_BUILTIN_XSRDPI,
+ VSX_BUILTIN_XSRDPIC,
+ VSX_BUILTIN_XSRDPIM,
+ VSX_BUILTIN_XSRDPIP,
+ VSX_BUILTIN_XSRDPIZ,
+ VSX_BUILTIN_XSREDP,
+ VSX_BUILTIN_XSRSQRTEDP,
+ VSX_BUILTIN_XSSQRTDP,
+ VSX_BUILTIN_XSSUBDP,
+ VSX_BUILTIN_XSTDIVDP,
+ VSX_BUILTIN_XSTSQRTDP,
+ VSX_BUILTIN_XVABSDP,
+ VSX_BUILTIN_XVABSSP,
+ VSX_BUILTIN_XVADDDP,
+ VSX_BUILTIN_XVADDSP,
+ VSX_BUILTIN_XVCMPEQDP,
+ VSX_BUILTIN_XVCMPEQSP,
+ VSX_BUILTIN_XVCMPGEDP,
+ VSX_BUILTIN_XVCMPGESP,
+ VSX_BUILTIN_XVCMPGTDP,
+ VSX_BUILTIN_XVCMPGTSP,
+ VSX_BUILTIN_XVCMPEQDP_P,
+ VSX_BUILTIN_XVCMPEQSP_P,
+ VSX_BUILTIN_XVCMPGEDP_P,
+ VSX_BUILTIN_XVCMPGESP_P,
+ VSX_BUILTIN_XVCMPGTDP_P,
+ VSX_BUILTIN_XVCMPGTSP_P,
+ VSX_BUILTIN_XVCPSGNDP,
+ VSX_BUILTIN_XVCPSGNSP,
+ VSX_BUILTIN_XVCVDPSP,
+ VSX_BUILTIN_XVCVDPSXDS,
+ VSX_BUILTIN_XVCVDPSXWS,
+ VSX_BUILTIN_XVCVDPUXDS,
+ VSX_BUILTIN_XVCVDPUXDS_UNS,
+ VSX_BUILTIN_XVCVDPUXWS,
+ VSX_BUILTIN_XVCVSPDP,
+ VSX_BUILTIN_XVCVSPSXDS,
+ VSX_BUILTIN_XVCVSPSXWS,
+ VSX_BUILTIN_XVCVSPUXDS,
+ VSX_BUILTIN_XVCVSPUXWS,
+ VSX_BUILTIN_XVCVSXDDP,
+ VSX_BUILTIN_XVCVSXDSP,
+ VSX_BUILTIN_XVCVSXWDP,
+ VSX_BUILTIN_XVCVSXWSP,
+ VSX_BUILTIN_XVCVUXDDP,
+ VSX_BUILTIN_XVCVUXDDP_UNS,
+ VSX_BUILTIN_XVCVUXDSP,
+ VSX_BUILTIN_XVCVUXWDP,
+ VSX_BUILTIN_XVCVUXWSP,
+ VSX_BUILTIN_XVDIVDP,
+ VSX_BUILTIN_XVDIVSP,
+ VSX_BUILTIN_XVMADDDP,
+ VSX_BUILTIN_XVMADDSP,
+ VSX_BUILTIN_XVMAXDP,
+ VSX_BUILTIN_XVMAXSP,
+ VSX_BUILTIN_XVMINDP,
+ VSX_BUILTIN_XVMINSP,
+ VSX_BUILTIN_XVMSUBDP,
+ VSX_BUILTIN_XVMSUBSP,
+ VSX_BUILTIN_XVMULDP,
+ VSX_BUILTIN_XVMULSP,
+ VSX_BUILTIN_XVNABSDP,
+ VSX_BUILTIN_XVNABSSP,
+ VSX_BUILTIN_XVNEGDP,
+ VSX_BUILTIN_XVNEGSP,
+ VSX_BUILTIN_XVNMADDDP,
+ VSX_BUILTIN_XVNMADDSP,
+ VSX_BUILTIN_XVNMSUBDP,
+ VSX_BUILTIN_XVNMSUBSP,
+ VSX_BUILTIN_XVRDPI,
+ VSX_BUILTIN_XVRDPIC,
+ VSX_BUILTIN_XVRDPIM,
+ VSX_BUILTIN_XVRDPIP,
+ VSX_BUILTIN_XVRDPIZ,
+ VSX_BUILTIN_XVREDP,
+ VSX_BUILTIN_XVRESP,
+ VSX_BUILTIN_XVRSPI,
+ VSX_BUILTIN_XVRSPIC,
+ VSX_BUILTIN_XVRSPIM,
+ VSX_BUILTIN_XVRSPIP,
+ VSX_BUILTIN_XVRSPIZ,
+ VSX_BUILTIN_XVRSQRTEDP,
+ VSX_BUILTIN_XVRSQRTESP,
+ VSX_BUILTIN_XVSQRTDP,
+ VSX_BUILTIN_XVSQRTSP,
+ VSX_BUILTIN_XVSUBDP,
+ VSX_BUILTIN_XVSUBSP,
+ VSX_BUILTIN_XVTDIVDP,
+ VSX_BUILTIN_XVTDIVSP,
+ VSX_BUILTIN_XVTSQRTDP,
+ VSX_BUILTIN_XVTSQRTSP,
+ VSX_BUILTIN_XXSEL_2DI,
+ VSX_BUILTIN_XXSEL_2DF,
+ VSX_BUILTIN_XXSEL_4SI,
+ VSX_BUILTIN_XXSEL_4SF,
+ VSX_BUILTIN_XXSEL_8HI,
+ VSX_BUILTIN_XXSEL_16QI,
+ VSX_BUILTIN_XXSEL_2DI_UNS,
+ VSX_BUILTIN_XXSEL_4SI_UNS,
+ VSX_BUILTIN_XXSEL_8HI_UNS,
+ VSX_BUILTIN_XXSEL_16QI_UNS,
+ VSX_BUILTIN_VPERM_2DI,
+ VSX_BUILTIN_VPERM_2DF,
+ VSX_BUILTIN_VPERM_4SI,
+ VSX_BUILTIN_VPERM_4SF,
+ VSX_BUILTIN_VPERM_8HI,
+ VSX_BUILTIN_VPERM_16QI,
+ VSX_BUILTIN_VPERM_2DI_UNS,
+ VSX_BUILTIN_VPERM_4SI_UNS,
+ VSX_BUILTIN_VPERM_8HI_UNS,
+ VSX_BUILTIN_VPERM_16QI_UNS,
+ VSX_BUILTIN_XXPERMDI_2DF,
+ VSX_BUILTIN_XXPERMDI_2DI,
+ VSX_BUILTIN_XXPERMDI_4SF,
+ VSX_BUILTIN_XXPERMDI_4SI,
+ VSX_BUILTIN_XXPERMDI_8HI,
+ VSX_BUILTIN_XXPERMDI_16QI,
+ VSX_BUILTIN_CONCAT_2DF,
+ VSX_BUILTIN_CONCAT_2DI,
+ VSX_BUILTIN_SET_2DF,
+ VSX_BUILTIN_SET_2DI,
+ VSX_BUILTIN_SPLAT_2DF,
+ VSX_BUILTIN_SPLAT_2DI,
+ VSX_BUILTIN_XXMRGHW_4SF,
+ VSX_BUILTIN_XXMRGHW_4SI,
+ VSX_BUILTIN_XXMRGLW_4SF,
+ VSX_BUILTIN_XXMRGLW_4SI,
+ VSX_BUILTIN_XXSLDWI_16QI,
+ VSX_BUILTIN_XXSLDWI_8HI,
+ VSX_BUILTIN_XXSLDWI_4SI,
+ VSX_BUILTIN_XXSLDWI_4SF,
+ VSX_BUILTIN_XXSLDWI_2DI,
+ VSX_BUILTIN_XXSLDWI_2DF,
+ VSX_BUILTIN_VEC_INIT_V2DF,
+ VSX_BUILTIN_VEC_INIT_V2DI,
+ VSX_BUILTIN_VEC_SET_V2DF,
+ VSX_BUILTIN_VEC_SET_V2DI,
+ VSX_BUILTIN_VEC_EXT_V2DF,
+ VSX_BUILTIN_VEC_EXT_V2DI,
+
+ /* VSX overloaded builtins, add the overloaded functions not present in
+ Altivec. */
+ VSX_BUILTIN_VEC_MUL,
+ VSX_BUILTIN_OVERLOADED_FIRST = VSX_BUILTIN_VEC_MUL,
+ VSX_BUILTIN_VEC_MSUB,
+ VSX_BUILTIN_VEC_NMADD,
+ VSX_BUITLIN_VEC_NMSUB,
+ VSX_BUILTIN_VEC_DIV,
+ VSX_BUILTIN_VEC_XXMRGHW,
+ VSX_BUILTIN_VEC_XXMRGLW,
+ VSX_BUILTIN_VEC_XXPERMDI,
+ VSX_BUILTIN_VEC_XXSLDWI,
+ VSX_BUILTIN_VEC_XXSPLTD,
+ VSX_BUILTIN_VEC_XXSPLTW,
+ VSX_BUILTIN_OVERLOADED_LAST = VSX_BUILTIN_VEC_XXSPLTW,
+
+ /* Combined VSX/Altivec builtins. */
+ VECTOR_BUILTIN_FLOAT_V4SI_V4SF,
+ VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF,
+ VECTOR_BUILTIN_FIX_V4SF_V4SI,
+ VECTOR_BUILTIN_FIXUNS_V4SF_V4SI,
+
+ /* Power7 builtins, that aren't VSX instructions. */
+ POWER7_BUILTIN_BPERMD,
+
RS6000_BUILTIN_COUNT
};
@@ -3040,6 +3384,8 @@ enum rs6000_builtin_type_index
RS6000_BTI_V16QI,
RS6000_BTI_V2SI,
RS6000_BTI_V2SF,
+ RS6000_BTI_V2DI,
+ RS6000_BTI_V2DF,
RS6000_BTI_V4HI,
RS6000_BTI_V4SI,
RS6000_BTI_V4SF,
@@ -3047,13 +3393,16 @@ enum rs6000_builtin_type_index
RS6000_BTI_unsigned_V16QI,
RS6000_BTI_unsigned_V8HI,
RS6000_BTI_unsigned_V4SI,
+ RS6000_BTI_unsigned_V2DI,
RS6000_BTI_bool_char, /* __bool char */
RS6000_BTI_bool_short, /* __bool short */
RS6000_BTI_bool_int, /* __bool int */
+ RS6000_BTI_bool_long, /* __bool long */
RS6000_BTI_pixel, /* __pixel */
RS6000_BTI_bool_V16QI, /* __vector __bool char */
RS6000_BTI_bool_V8HI, /* __vector __bool short */
RS6000_BTI_bool_V4SI, /* __vector __bool int */
+ RS6000_BTI_bool_V2DI, /* __vector __bool long */
RS6000_BTI_pixel_V8HI, /* __vector __pixel */
RS6000_BTI_long, /* long_integer_type_node */
RS6000_BTI_unsigned_long, /* long_unsigned_type_node */
@@ -3063,7 +3412,10 @@ enum rs6000_builtin_type_index
RS6000_BTI_UINTHI, /* unsigned_intHI_type_node */
RS6000_BTI_INTSI, /* intSI_type_node */
RS6000_BTI_UINTSI, /* unsigned_intSI_type_node */
+ RS6000_BTI_INTDI, /* intDI_type_node */
+ RS6000_BTI_UINTDI, /* unsigned_intDI_type_node */
RS6000_BTI_float, /* float_type_node */
+ RS6000_BTI_double, /* double_type_node */
RS6000_BTI_void, /* void_type_node */
RS6000_BTI_MAX
};
@@ -3074,6 +3426,8 @@ enum rs6000_builtin_type_index
#define opaque_p_V2SI_type_node (rs6000_builtin_types[RS6000_BTI_opaque_p_V2SI])
#define opaque_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_opaque_V4SI])
#define V16QI_type_node (rs6000_builtin_types[RS6000_BTI_V16QI])
+#define V2DI_type_node (rs6000_builtin_types[RS6000_BTI_V2DI])
+#define V2DF_type_node (rs6000_builtin_types[RS6000_BTI_V2DF])
#define V2SI_type_node (rs6000_builtin_types[RS6000_BTI_V2SI])
#define V2SF_type_node (rs6000_builtin_types[RS6000_BTI_V2SF])
#define V4HI_type_node (rs6000_builtin_types[RS6000_BTI_V4HI])
@@ -3083,13 +3437,16 @@ enum rs6000_builtin_type_index
#define unsigned_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V16QI])
#define unsigned_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V8HI])
#define unsigned_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V4SI])
+#define unsigned_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V2DI])
#define bool_char_type_node (rs6000_builtin_types[RS6000_BTI_bool_char])
#define bool_short_type_node (rs6000_builtin_types[RS6000_BTI_bool_short])
#define bool_int_type_node (rs6000_builtin_types[RS6000_BTI_bool_int])
+#define bool_long_type_node (rs6000_builtin_types[RS6000_BTI_bool_long])
#define pixel_type_node (rs6000_builtin_types[RS6000_BTI_pixel])
#define bool_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V16QI])
#define bool_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V8HI])
#define bool_V4SI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V4SI])
+#define bool_V2DI_type_node (rs6000_builtin_types[RS6000_BTI_bool_V2DI])
#define pixel_V8HI_type_node (rs6000_builtin_types[RS6000_BTI_pixel_V8HI])
#define long_integer_type_internal_node (rs6000_builtin_types[RS6000_BTI_long])
@@ -3100,7 +3457,10 @@ enum rs6000_builtin_type_index
#define uintHI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTHI])
#define intSI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTSI])
#define uintSI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTSI])
+#define intDI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTDI])
+#define uintDI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTDI])
#define float_type_internal_node (rs6000_builtin_types[RS6000_BTI_float])
+#define double_type_internal_node (rs6000_builtin_types[RS6000_BTI_double])
#define void_type_internal_node (rs6000_builtin_types[RS6000_BTI_void])
extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
--
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meissner@linux.vnet.ibm.com