diff options
Diffstat (limited to 'contrib/gcc/config/rs6000/rs6000.h')
-rw-r--r-- | contrib/gcc/config/rs6000/rs6000.h | 685 |
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 }; |