diff options
Diffstat (limited to 'gcc-4.8/gcc/config/rs6000/rs6000.h')
-rw-r--r-- | gcc-4.8/gcc/config/rs6000/rs6000.h | 304 |
1 files changed, 225 insertions, 79 deletions
diff --git a/gcc-4.8/gcc/config/rs6000/rs6000.h b/gcc-4.8/gcc/config/rs6000/rs6000.h index 8a3608410..1dc71f6db 100644 --- a/gcc-4.8/gcc/config/rs6000/rs6000.h +++ b/gcc-4.8/gcc/config/rs6000/rs6000.h @@ -92,7 +92,7 @@ #ifdef HAVE_AS_POWER8 #define ASM_CPU_POWER8_SPEC "-mpower8" #else -#define ASM_CPU_POWER8_SPEC "-mpower4 -maltivec" +#define ASM_CPU_POWER8_SPEC ASM_CPU_POWER7_SPEC #endif #ifdef HAVE_AS_DCI @@ -164,6 +164,7 @@ %{mcpu=e6500: -me6500} \ %{maltivec: -maltivec} \ %{mvsx: -mvsx %{!maltivec: -maltivec} %{!mcpu*: %(asm_cpu_power7)}} \ +%{mpower8-vector|mcrypto|mdirect-move|mhtm: %{!mcpu*: %(asm_cpu_power8)}} \ -many" #define CPP_DEFAULT_SPEC "" @@ -277,6 +278,21 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define TARGET_POPCNTD 0 #endif +/* Define the ISA 2.07 flags as 0 if the target assembler does not support the + waitasecond instruction. Allow -mpower8-fusion, since it does not add new + instructions. */ + +#ifndef HAVE_AS_POWER8 +#undef TARGET_DIRECT_MOVE +#undef TARGET_CRYPTO +#undef TARGET_HTM +#undef TARGET_P8_VECTOR +#define TARGET_DIRECT_MOVE 0 +#define TARGET_CRYPTO 0 +#define TARGET_HTM 0 +#define TARGET_P8_VECTOR 0 +#endif + /* Define TARGET_LWSYNC_INSTRUCTION if the assembler knows about lwsync. If not, generate the lwsync code as an integer constant. */ #ifdef HAVE_AS_LWSYNC @@ -386,6 +402,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); #define TARGET_DEBUG_TARGET (rs6000_debug & MASK_DEBUG_TARGET) #define TARGET_DEBUG_BUILTIN (rs6000_debug & MASK_DEBUG_BUILTIN) +/* Describe the vector unit used for arithmetic operations. */ extern enum rs6000_vector rs6000_vector_unit[]; #define VECTOR_UNIT_NONE_P(MODE) \ @@ -394,12 +411,25 @@ extern enum rs6000_vector rs6000_vector_unit[]; #define VECTOR_UNIT_VSX_P(MODE) \ (rs6000_vector_unit[(MODE)] == VECTOR_VSX) +#define VECTOR_UNIT_P8_VECTOR_P(MODE) \ + (rs6000_vector_unit[(MODE)] == VECTOR_P8_VECTOR) + #define VECTOR_UNIT_ALTIVEC_P(MODE) \ (rs6000_vector_unit[(MODE)] == VECTOR_ALTIVEC) +#define VECTOR_UNIT_VSX_OR_P8_VECTOR_P(MODE) \ + (IN_RANGE ((int)rs6000_vector_unit[(MODE)], \ + (int)VECTOR_VSX, \ + (int)VECTOR_P8_VECTOR)) + +/* VECTOR_UNIT_ALTIVEC_OR_VSX_P is used in places where we are using either + altivec (VMX) or VSX vector instructions. P8 vector support is upwards + compatible, so allow it as well, rather than changing all of the uses of the + macro. */ #define VECTOR_UNIT_ALTIVEC_OR_VSX_P(MODE) \ - (rs6000_vector_unit[(MODE)] == VECTOR_ALTIVEC \ - || rs6000_vector_unit[(MODE)] == VECTOR_VSX) + (IN_RANGE ((int)rs6000_vector_unit[(MODE)], \ + (int)VECTOR_ALTIVEC, \ + (int)VECTOR_P8_VECTOR)) /* 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 @@ -412,12 +442,21 @@ extern enum rs6000_vector rs6000_vector_mem[]; #define VECTOR_MEM_VSX_P(MODE) \ (rs6000_vector_mem[(MODE)] == VECTOR_VSX) +#define VECTOR_MEM_P8_VECTOR_P(MODE) \ + (rs6000_vector_mem[(MODE)] == VECTOR_VSX) + #define VECTOR_MEM_ALTIVEC_P(MODE) \ (rs6000_vector_mem[(MODE)] == VECTOR_ALTIVEC) +#define VECTOR_MEM_VSX_OR_P8_VECTOR_P(MODE) \ + (IN_RANGE ((int)rs6000_vector_mem[(MODE)], \ + (int)VECTOR_VSX, \ + (int)VECTOR_P8_VECTOR)) + #define VECTOR_MEM_ALTIVEC_OR_VSX_P(MODE) \ - (rs6000_vector_mem[(MODE)] == VECTOR_ALTIVEC \ - || rs6000_vector_mem[(MODE)] == VECTOR_VSX) + (IN_RANGE ((int)rs6000_vector_mem[(MODE)], \ + (int)VECTOR_ALTIVEC, \ + (int)VECTOR_P8_VECTOR)) /* 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 @@ -429,6 +468,15 @@ extern int rs6000_vector_align[]; ? rs6000_vector_align[(MODE)] \ : (int)GET_MODE_BITSIZE ((MODE))) +/* Determine the element order to use for vector instructions. By + default we use big-endian element order when targeting big-endian, + and little-endian element order when targeting little-endian. For + programs being ported from BE Power to LE Power, it can sometimes + be useful to use big-endian element order when targeting little-endian. + This is set via -maltivec=be, for example. */ +#define VECTOR_ELT_ORDER_BIG \ + (BYTES_BIG_ENDIAN || (rs6000_altivec_element_order == 2)) + /* Alignment options for fields in structures for sub-targets following AIX-like ABI. ALIGN_POWER word-aligns FP doubles (default AIX ABI). @@ -479,22 +527,45 @@ extern int rs6000_vector_align[]; #define TARGET_FCTIDUZ TARGET_POPCNTD #define TARGET_FCTIWUZ TARGET_POPCNTD +#define TARGET_XSCVDPSPN (TARGET_DIRECT_MOVE || TARGET_P8_VECTOR) +#define TARGET_XSCVSPDPN (TARGET_DIRECT_MOVE || TARGET_P8_VECTOR) +#define TARGET_VADDUQM (TARGET_P8_VECTOR && TARGET_POWERPC64) + +/* Byte/char syncs were added as phased in for ISA 2.06B, but are not present + in power7, so conditionalize them on p8 features. TImode syncs need quad + memory support. */ +#define TARGET_SYNC_HI_QI (TARGET_QUAD_MEMORY \ + || TARGET_QUAD_MEMORY_ATOMIC \ + || TARGET_DIRECT_MOVE) + +#define TARGET_SYNC_TI TARGET_QUAD_MEMORY_ATOMIC + +/* Power7 has both 32-bit load and store integer for the FPRs, so we don't need + to allocate the SDmode stack slot to get the value into the proper location + in the register. */ +#define TARGET_NO_SDMODE_STACK (TARGET_LFIWZX && TARGET_STFIWX && TARGET_DFP) + /* In switching from using target_flags to using rs6000_isa_flags, the options machinery creates OPTION_MASK_<xxx> instead of MASK_<xxx>. For now map OPTION_MASK_<xxx> back into MASK_<xxx>. */ #define MASK_ALTIVEC OPTION_MASK_ALTIVEC #define MASK_CMPB OPTION_MASK_CMPB +#define MASK_CRYPTO OPTION_MASK_CRYPTO #define MASK_DFP OPTION_MASK_DFP +#define MASK_DIRECT_MOVE OPTION_MASK_DIRECT_MOVE #define MASK_DLMZB OPTION_MASK_DLMZB #define MASK_EABI OPTION_MASK_EABI #define MASK_FPRND OPTION_MASK_FPRND +#define MASK_P8_FUSION OPTION_MASK_P8_FUSION #define MASK_HARD_FLOAT OPTION_MASK_HARD_FLOAT +#define MASK_HTM OPTION_MASK_HTM #define MASK_ISEL OPTION_MASK_ISEL #define MASK_MFCRF OPTION_MASK_MFCRF #define MASK_MFPGPR OPTION_MASK_MFPGPR #define MASK_MULHW OPTION_MASK_MULHW #define MASK_MULTIPLE OPTION_MASK_MULTIPLE #define MASK_NO_UPDATE OPTION_MASK_NO_UPDATE +#define MASK_P8_VECTOR OPTION_MASK_P8_VECTOR #define MASK_POPCNTB OPTION_MASK_POPCNTB #define MASK_POPCNTD OPTION_MASK_POPCNTD #define MASK_PPC_GFXOPT OPTION_MASK_PPC_GFXOPT @@ -505,6 +576,7 @@ extern int rs6000_vector_align[]; #define MASK_STRING OPTION_MASK_STRING #define MASK_UPDATE OPTION_MASK_UPDATE #define MASK_VSX OPTION_MASK_VSX +#define MASK_VSX_TIMODE OPTION_MASK_VSX_TIMODE #ifndef IN_LIBGCC2 #define MASK_POWERPC64 OPTION_MASK_POWERPC64 @@ -551,13 +623,33 @@ extern int rs6000_vector_align[]; || TARGET_CMPB /* ISA 2.05 */ \ || TARGET_POPCNTD /* ISA 2.06 */ \ || TARGET_ALTIVEC \ - || TARGET_VSX))) + || TARGET_VSX \ + || TARGET_HARD_FLOAT))) /* E500 cores only support plain "sync", not lwsync. */ #define TARGET_NO_LWSYNC (rs6000_cpu == PROCESSOR_PPC8540 \ || rs6000_cpu == PROCESSOR_PPC8548) +/* Whether SF/DF operations are supported on the E500. */ +#define TARGET_SF_SPE (TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT \ + && !TARGET_FPRS) + +#define TARGET_DF_SPE (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT \ + && !TARGET_FPRS && TARGET_E500_DOUBLE) + +/* Whether SF/DF operations are supported by by the normal floating point unit + (or the vector/scalar unit). */ +#define TARGET_SF_FPR (TARGET_HARD_FLOAT && TARGET_FPRS \ + && TARGET_SINGLE_FLOAT) + +#define TARGET_DF_FPR (TARGET_HARD_FLOAT && TARGET_FPRS \ + && TARGET_DOUBLE_FLOAT) + +/* Whether SF/DF operations are supported by any hardware. */ +#define TARGET_SF_INSN (TARGET_SF_FPR || TARGET_SF_SPE) +#define TARGET_DF_INSN (TARGET_DF_FPR || TARGET_DF_SPE) + /* Which machine supports the various reciprocal estimate instructions. */ #define TARGET_FRES (TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT \ && TARGET_FPRS && TARGET_SINGLE_FLOAT) @@ -595,9 +687,6 @@ extern unsigned char rs6000_recip_bits[]; #define RS6000_RECIP_AUTO_RSQRTE_P(MODE) \ (rs6000_recip_bits[(int)(MODE)] & RS6000_RECIP_MASK_AUTO_RSQRTE) -#define RS6000_RECIP_HIGH_PRECISION_P(MODE) \ - ((MODE) == SFmode || (MODE) == V4SFmode || TARGET_RECIP_PRECISION) - /* The default CPU for TARGET_OPTION_OVERRIDE. */ #define OPTION_TARGET_CPU_DEFAULT TARGET_CPU_DEFAULT @@ -760,12 +849,6 @@ extern unsigned rs6000_pointer_size; /* No data type wants to be aligned rounder than this. */ #define BIGGEST_ALIGNMENT 128 -/* A C expression to compute the alignment for a variables in the - local store. TYPE is the data type, and ALIGN is the alignment - that the object would ordinarily have. */ -#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ - DATA_ALIGNMENT (TYPE, ALIGN) - /* Alignment of field after `int : 0' in a structure. */ #define EMPTY_FIELD_BOUNDARY 32 @@ -775,8 +858,15 @@ extern unsigned rs6000_pointer_size; /* 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. - Make vector constants quadword aligned. */ +enum data_align { align_abi, align_opt, align_both }; + +/* A C expression to compute the alignment for a variables in the + local store. TYPE is the data type, and ALIGN is the alignment + that the object would ordinarily have. */ +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ + rs6000_data_alignment (TYPE, ALIGN, align_both) + +/* Make strings word-aligned so strcpy from constants will be faster. */ #define CONSTANT_ALIGNMENT(EXP, ALIGN) \ (TREE_CODE (EXP) == STRING_CST \ && (STRICT_ALIGNMENT || !optimize_size) \ @@ -784,21 +874,14 @@ extern unsigned rs6000_pointer_size; ? BITS_PER_WORD \ : (ALIGN)) -/* Make arrays of chars word-aligned for the same reasons. - Align vectors to 128 bits. Align SPE vectors and E500 v2 doubles to - 64 bits. */ +/* Make arrays of chars word-aligned for the same reasons. */ #define DATA_ALIGNMENT(TYPE, ALIGN) \ - (TREE_CODE (TYPE) == VECTOR_TYPE \ - ? (((TARGET_SPE && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) \ - || (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) \ - ? 64 : 128) \ - : ((TARGET_E500_DOUBLE \ - && TREE_CODE (TYPE) == REAL_TYPE \ - && TYPE_MODE (TYPE) == DFmode) \ - ? 64 \ - : (TREE_CODE (TYPE) == ARRAY_TYPE \ - && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ - && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN))) + rs6000_data_alignment (TYPE, ALIGN, align_opt) + +/* Align vectors to 128 bits. Align SPE vectors and E500 v2 doubles to + 64 bits. */ +#define DATA_ABI_ALIGNMENT(TYPE, ALIGN) \ + rs6000_data_alignment (TYPE, ALIGN, align_abi) /* Nonzero if move instructions will actually fail to work when given unaligned data. */ @@ -842,15 +925,17 @@ extern unsigned rs6000_pointer_size; in inline functions. Another pseudo (not included in DWARF_FRAME_REGISTERS) is soft frame - pointer, which is eventually eliminated in favor of SP or FP. */ + pointer, which is eventually eliminated in favor of SP or FP. -#define FIRST_PSEUDO_REGISTER 114 + The 3 HTM registers aren't also included in DWARF_FRAME_REGISTERS. */ + +#define FIRST_PSEUDO_REGISTER 117 /* This must be included for pre gcc 3.0 glibc compatibility. */ #define PRE_GCC3_DWARF_FRAME_REGISTERS 77 /* Add 32 dwarf columns for synthetic SPE registers. */ -#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 1) + 32) +#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 4) + 32) /* The SPE has an additional 32 synthetic registers, with DWARF debug info numbering for these registers starting at 1200. While eh_frame @@ -866,7 +951,7 @@ extern unsigned rs6000_pointer_size; We must map them here to avoid huge unwinder tables mostly consisting of unused space. */ #define DWARF_REG_TO_UNWIND_COLUMN(r) \ - ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER - 1) : (r)) + ((r) > 1200 ? ((r) - 1200 + (DWARF_FRAME_REGISTERS - 32)) : (r)) /* Use standard DWARF numbering for DWARF debugging information. */ #define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) @@ -906,7 +991,7 @@ extern unsigned rs6000_pointer_size; 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, 1, 1, 1, 1, 1 \ } /* 1 for registers not available across function calls. @@ -926,7 +1011,7 @@ extern unsigned rs6000_pointer_size; 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, 1, 1, 1, 1, 1 \ } /* Like `CALL_USED_REGISTERS' except this macro doesn't require that @@ -945,7 +1030,7 @@ extern unsigned rs6000_pointer_size; 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 \ + , 0, 0, 0, 0, 0, 0 \ } #define TOTAL_ALTIVEC_REGS (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO + 1) @@ -984,6 +1069,9 @@ extern unsigned rs6000_pointer_size; vrsave, vscr (fixed) spe_acc, spefscr (fixed) sfp (fixed) + tfhar (fixed) + tfiar (fixed) + texasr (fixed) */ #if FIXED_R2 == 1 @@ -1004,7 +1092,9 @@ extern unsigned rs6000_pointer_size; #define REG_ALLOC_ORDER \ {32, \ - 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, \ + /* move fr13 (ie 45) later, so if we need TFmode, it does */ \ + /* not use fr14 which is a saved register. */ \ + 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 45, \ 33, \ 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \ 50, 49, 48, 47, 46, \ @@ -1023,7 +1113,7 @@ extern unsigned rs6000_pointer_size; 96, 95, 94, 93, 92, 91, \ 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, \ 109, 110, \ - 111, 112, 113 \ + 111, 112, 113, 114, 115, 116 \ } /* True if register is floating-point. */ @@ -1064,8 +1154,11 @@ extern unsigned rs6000_pointer_size; #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) + matter which instruction set(s) are available. Allow GPRs as well as the + vector registers. */ +#define VLOGICAL_REGNO_P(N) \ + (INT_REGNO_P (N) || ALTIVEC_REGNO_P (N) \ + || (TARGET_VSX && FP_REGNO_P (N))) \ /* Return number of consecutive hard regs needed starting at reg REGNO to hold something of mode MODE. */ @@ -1106,7 +1199,7 @@ extern unsigned rs6000_pointer_size; #define ALTIVEC_OR_VSX_VECTOR_MODE(MODE) \ (ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE) \ - || (MODE) == V2DImode) + || (MODE) == V2DImode || (MODE) == V1TImode) #define SPE_VECTOR_MODE(MODE) \ ((MODE) == V4HImode \ @@ -1125,28 +1218,32 @@ extern unsigned rs6000_pointer_size; /* Value is 1 if it is a good idea to tie two pseudo registers when one has mode MODE1 and one has mode MODE2. If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ + for any hard reg, then this must be 0 for correct output. + + PTImode cannot tie with other modes because PTImode is restricted to even + GPR registers, and TImode can go in any GPR as well as VSX registers (PR + 57744). */ #define MODES_TIEABLE_P(MODE1, MODE2) \ - (SCALAR_FLOAT_MODE_P (MODE1) \ + ((MODE1) == PTImode \ + ? (MODE2) == PTImode \ + : (MODE2) == PTImode \ + ? 0 \ + : SCALAR_FLOAT_MODE_P (MODE1) \ ? SCALAR_FLOAT_MODE_P (MODE2) \ : SCALAR_FLOAT_MODE_P (MODE2) \ - ? SCALAR_FLOAT_MODE_P (MODE1) \ + ? 0 \ : GET_MODE_CLASS (MODE1) == MODE_CC \ ? GET_MODE_CLASS (MODE2) == MODE_CC \ : GET_MODE_CLASS (MODE2) == MODE_CC \ - ? GET_MODE_CLASS (MODE1) == MODE_CC \ + ? 0 \ : SPE_VECTOR_MODE (MODE1) \ ? SPE_VECTOR_MODE (MODE2) \ : SPE_VECTOR_MODE (MODE2) \ - ? SPE_VECTOR_MODE (MODE1) \ - : ALTIVEC_VECTOR_MODE (MODE1) \ - ? ALTIVEC_VECTOR_MODE (MODE2) \ - : ALTIVEC_VECTOR_MODE (MODE2) \ - ? ALTIVEC_VECTOR_MODE (MODE1) \ + ? 0 \ : ALTIVEC_OR_VSX_VECTOR_MODE (MODE1) \ ? ALTIVEC_OR_VSX_VECTOR_MODE (MODE2) \ : ALTIVEC_OR_VSX_VECTOR_MODE (MODE2) \ - ? ALTIVEC_OR_VSX_VECTOR_MODE (MODE1) \ + ? 0 \ : 1) /* Post-reload, we can't use any new AltiVec registers, as we already @@ -1240,6 +1337,7 @@ enum reg_class VSCR_REGS, SPE_ACC_REGS, SPEFSCR_REGS, + SPR_REGS, NON_SPECIAL_REGS, LINK_REGS, CTR_REGS, @@ -1270,6 +1368,7 @@ enum reg_class "VSCR_REGS", \ "SPE_ACC_REGS", \ "SPEFSCR_REGS", \ + "SPR_REGS", \ "NON_SPECIAL_REGS", \ "LINK_REGS", \ "CTR_REGS", \ @@ -1299,6 +1398,7 @@ enum reg_class { 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00010000 }, /* SPEFSCR_REGS */ \ + { 0x00000000, 0x00000000, 0x00000000, 0x00040000 }, /* SPR_REGS */ \ { 0xffffffff, 0xffffffff, 0x00000008, 0x00020000 }, /* NON_SPECIAL_REGS */ \ { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */ \ { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */ \ @@ -1309,7 +1409,7 @@ enum reg_class { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */ \ { 0xffffffff, 0x00000000, 0x00000ffe, 0x00020000 }, /* NON_FLOAT_REGS */ \ { 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* CA_REGS */ \ - { 0xffffffff, 0xffffffff, 0xfffffffe, 0x0003ffff } /* ALL_REGS */ \ + { 0xffffffff, 0xffffffff, 0xfffffffe, 0x0007ffff } /* ALL_REGS */ \ } /* The same information, inverted: @@ -1337,7 +1437,18 @@ enum r6000_reg_class_enum { RS6000_CONSTRAINT_wa, /* Any VSX register */ RS6000_CONSTRAINT_wd, /* VSX register for V2DF */ RS6000_CONSTRAINT_wf, /* VSX register for V4SF */ + RS6000_CONSTRAINT_wg, /* FPR register for -mmfpgpr */ + RS6000_CONSTRAINT_wl, /* FPR register for LFIWAX */ + RS6000_CONSTRAINT_wm, /* VSX register for direct move */ + RS6000_CONSTRAINT_wr, /* GPR register if 64-bit */ RS6000_CONSTRAINT_ws, /* VSX register for DF */ + RS6000_CONSTRAINT_wt, /* VSX register for TImode */ + RS6000_CONSTRAINT_wu, /* Altivec register for float load/stores. */ + RS6000_CONSTRAINT_wv, /* Altivec register for double load/stores. */ + RS6000_CONSTRAINT_ww, /* FP or VSX register for vsx float ops. */ + RS6000_CONSTRAINT_wx, /* FPR register for STFIWX */ + RS6000_CONSTRAINT_wy, /* VSX register for SF */ + RS6000_CONSTRAINT_wz, /* FPR register for LFIWZX */ RS6000_CONSTRAINT_MAX }; @@ -1425,21 +1536,14 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; arguments. */ #define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0 || flag_asan != 0) -/* Size of the outgoing register save area */ -#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \ - || DEFAULT_ABI == ABI_DARWIN) \ - ? (TARGET_64BIT ? 64 : 32) \ - : 0) - /* Size of the fixed area on the stack */ #define RS6000_SAVE_AREA \ - (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8) \ + ((DEFAULT_ABI == ABI_V4 ? 8 : DEFAULT_ABI == ABI_ELFv2 ? 16 : 24) \ << (TARGET_64BIT ? 1 : 0)) -/* MEM representing address to save the TOC register */ -#define RS6000_SAVE_TOC gen_rtx_MEM (Pmode, \ - plus_constant (Pmode, stack_pointer_rtx, \ - (TARGET_32BIT ? 20 : 40))) +/* Stack offset for toc save slot. */ +#define RS6000_TOC_SAVE_SLOT \ + ((DEFAULT_ABI == ABI_ELFv2 ? 12 : 20) << (TARGET_64BIT ? 1 : 0)) /* Align an address */ #define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1)) @@ -1489,7 +1593,7 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; /* Define this if stack space is still allocated for a parameter passed in a register. The value is the number of bytes allocated to this area. */ -#define REG_PARM_STACK_SPACE(FNDECL) RS6000_REG_SAVE +#define REG_PARM_STACK_SPACE(FNDECL) rs6000_reg_parm_stack_space((FNDECL)) /* Define this if the above stack space is to be considered part of the space allocated by the caller. */ @@ -1522,7 +1626,7 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; NONLOCAL needs twice Pmode to maintain both backchain and SP. */ #define STACK_SAVEAREA_MODE(LEVEL) \ (LEVEL == SAVE_FUNCTION ? VOIDmode \ - : LEVEL == SAVE_NONLOCAL ? (TARGET_32BIT ? DImode : TImode) : Pmode) + : LEVEL == SAVE_NONLOCAL ? (TARGET_32BIT ? DImode : PTImode) : Pmode) /* Minimum and maximum general purpose registers used to hold arguments. */ #define GP_ARG_MIN_REG 3 @@ -1533,9 +1637,8 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; #define FP_ARG_MIN_REG 33 #define FP_ARG_AIX_MAX_REG 45 #define FP_ARG_V4_MAX_REG 40 -#define FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX \ - || DEFAULT_ABI == ABI_DARWIN) \ - ? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG) +#define FP_ARG_MAX_REG (DEFAULT_ABI == ABI_V4 \ + ? FP_ARG_V4_MAX_REG : FP_ARG_AIX_MAX_REG) #define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1) /* Minimum and maximum AltiVec registers used to hold arguments. */ @@ -1543,10 +1646,17 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; #define ALTIVEC_ARG_MAX_REG (ALTIVEC_ARG_MIN_REG + 11) #define ALTIVEC_ARG_NUM_REG (ALTIVEC_ARG_MAX_REG - ALTIVEC_ARG_MIN_REG + 1) +/* Maximum number of registers per ELFv2 homogeneous aggregate argument. */ +#define AGGR_ARG_NUM_REG 8 + /* Return registers */ #define GP_ARG_RETURN GP_ARG_MIN_REG #define FP_ARG_RETURN FP_ARG_MIN_REG #define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2) +#define FP_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 ? FP_ARG_RETURN \ + : (FP_ARG_RETURN + AGGR_ARG_NUM_REG - 1)) +#define ALTIVEC_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 ? ALTIVEC_ARG_RETURN \ + : (ALTIVEC_ARG_RETURN + AGGR_ARG_NUM_REG - 1)) /* Flags for the call/call_value rtl operations set up by function_arg */ #define CALL_NORMAL 0x00000000 /* no special processing */ @@ -1566,8 +1676,10 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; 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_HARD_FLOAT && TARGET_FPRS) \ - || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)) + || ((N) >= FP_ARG_RETURN && (N) <= FP_ARG_MAX_RETURN \ + && TARGET_HARD_FLOAT && TARGET_FPRS) \ + || ((N) >= ALTIVEC_ARG_RETURN && (N) <= ALTIVEC_ARG_MAX_RETURN \ + && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)) /* 1 if N is a possible register number for function argument passing. On RS/6000, these are r3-r10 and fp1-fp13. @@ -1692,10 +1804,7 @@ typedef struct rs6000_args rs6000_stack_info in rs6000.c for more information on how the different abi's store the return address. */ #define RETURN_ADDRESS_OFFSET \ - ((DEFAULT_ABI == ABI_AIX \ - || DEFAULT_ABI == ABI_DARWIN) ? (TARGET_32BIT ? 8 : 16) : \ - (DEFAULT_ABI == ABI_V4) ? 4 : \ - (internal_error ("RETURN_ADDRESS_OFFSET not supported"), 0)) + ((DEFAULT_ABI == ABI_V4 ? 4 : 8) << (TARGET_64BIT ? 1 : 0)) /* The current return address is in link register (65). The return address of anything farther back is accessed normally at an offset of 8 from the @@ -2215,6 +2324,9 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ &rs6000_reg_names[111][0], /* spe_acc */ \ &rs6000_reg_names[112][0], /* spefscr */ \ &rs6000_reg_names[113][0], /* sfp */ \ + &rs6000_reg_names[114][0], /* tfhar */ \ + &rs6000_reg_names[115][0], /* tfiar */ \ + &rs6000_reg_names[116][0], /* texasr */ \ } /* Table of additional register names to use in user input. */ @@ -2268,7 +2380,9 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ {"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} } + {"vs60", 105},{"vs61", 106},{"vs62", 107},{"vs63", 108}, \ + /* Transactional Memory Facility (HTM) Registers. */ \ + {"tfhar", 114}, {"tfiar", 115}, {"texasr", 116} } /* This is how to output an element of a case-vector that is relative. */ @@ -2357,7 +2471,12 @@ extern int frame_pointer_needed; #define RS6000_BTC_ATTR_MASK 0x00000700 /* Mask of the attributes. */ /* Miscellaneous information. */ -#define RS6000_BTC_OVERLOADED 0x4000000 /* function is overloaded. */ +#define RS6000_BTC_SPR 0x01000000 /* function references SPRs. */ +#define RS6000_BTC_VOID 0x02000000 /* function has no return value. */ +#define RS6000_BTC_OVERLOADED 0x04000000 /* function is overloaded. */ +#define RS6000_BTC_32BIT 0x08000000 /* function references SPRs. */ +#define RS6000_BTC_64BIT 0x10000000 /* function references SPRs. */ +#define RS6000_BTC_MISC_MASK 0x1f000000 /* Mask of the misc info. */ /* Convenience macros to document the instruction type. */ #define RS6000_BTC_MEM RS6000_BTC_MISC /* load/store touches mem. */ @@ -2369,6 +2488,9 @@ extern int frame_pointer_needed; #define RS6000_BTM_ALWAYS 0 /* Always enabled. */ #define RS6000_BTM_ALTIVEC MASK_ALTIVEC /* VMX/altivec vectors. */ #define RS6000_BTM_VSX MASK_VSX /* VSX (vector/scalar). */ +#define RS6000_BTM_P8_VECTOR MASK_P8_VECTOR /* ISA 2.07 vector. */ +#define RS6000_BTM_CRYPTO MASK_CRYPTO /* crypto funcs. */ +#define RS6000_BTM_HTM MASK_HTM /* hardware TM funcs. */ #define RS6000_BTM_SPE MASK_STRING /* E500 */ #define RS6000_BTM_PAIRED MASK_MULHW /* 750CL paired insns. */ #define RS6000_BTM_FRE MASK_POPCNTB /* FRE instruction. */ @@ -2377,15 +2499,22 @@ extern int frame_pointer_needed; #define RS6000_BTM_FRSQRTES MASK_POPCNTB /* FRSQRTES instruction. */ #define RS6000_BTM_POPCNTD MASK_POPCNTD /* Target supports ISA 2.06. */ #define RS6000_BTM_CELL MASK_FPRND /* Target is cell powerpc. */ +#define RS6000_BTM_DFP MASK_DFP /* Decimal floating point. */ +#define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */ #define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \ | RS6000_BTM_VSX \ + | RS6000_BTM_P8_VECTOR \ + | RS6000_BTM_CRYPTO \ | RS6000_BTM_FRE \ | RS6000_BTM_FRES \ | RS6000_BTM_FRSQRTE \ | RS6000_BTM_FRSQRTES \ + | RS6000_BTM_HTM \ | RS6000_BTM_POPCNTD \ - | RS6000_BTM_CELL) + | RS6000_BTM_CELL \ + | RS6000_BTM_DFP \ + | RS6000_BTM_HARD_FLOAT) /* Define builtin enum index. */ @@ -2395,6 +2524,7 @@ extern int frame_pointer_needed; #undef RS6000_BUILTIN_A #undef RS6000_BUILTIN_D #undef RS6000_BUILTIN_E +#undef RS6000_BUILTIN_H #undef RS6000_BUILTIN_P #undef RS6000_BUILTIN_Q #undef RS6000_BUILTIN_S @@ -2406,6 +2536,7 @@ extern int frame_pointer_needed; #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) ENUM, #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) ENUM, #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) ENUM, +#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) ENUM, #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) ENUM, #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) ENUM, #define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) ENUM, @@ -2424,6 +2555,7 @@ enum rs6000_builtins #undef RS6000_BUILTIN_A #undef RS6000_BUILTIN_D #undef RS6000_BUILTIN_E +#undef RS6000_BUILTIN_H #undef RS6000_BUILTIN_P #undef RS6000_BUILTIN_Q #undef RS6000_BUILTIN_S @@ -2437,6 +2569,7 @@ enum rs6000_builtin_type_index RS6000_BTI_opaque_p_V2SI, RS6000_BTI_opaque_V4SI, RS6000_BTI_V16QI, + RS6000_BTI_V1TI, RS6000_BTI_V2SI, RS6000_BTI_V2SF, RS6000_BTI_V2DI, @@ -2446,6 +2579,7 @@ enum rs6000_builtin_type_index RS6000_BTI_V4SF, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V2DI, @@ -2471,8 +2605,13 @@ enum rs6000_builtin_type_index RS6000_BTI_UINTSI, /* unsigned_intSI_type_node */ RS6000_BTI_INTDI, /* intDI_type_node */ RS6000_BTI_UINTDI, /* unsigned_intDI_type_node */ + RS6000_BTI_INTTI, /* intTI_type_node */ + RS6000_BTI_UINTTI, /* unsigned_intTI_type_node */ RS6000_BTI_float, /* float_type_node */ RS6000_BTI_double, /* double_type_node */ + RS6000_BTI_long_double, /* long_double_type_node */ + RS6000_BTI_dfloat64, /* dfloat64_type_node */ + RS6000_BTI_dfloat128, /* dfloat128_type_node */ RS6000_BTI_void, /* void_type_node */ RS6000_BTI_MAX }; @@ -2483,6 +2622,7 @@ 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 V1TI_type_node (rs6000_builtin_types[RS6000_BTI_V1TI]) #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]) @@ -2492,6 +2632,7 @@ enum rs6000_builtin_type_index #define V4SF_type_node (rs6000_builtin_types[RS6000_BTI_V4SF]) #define V8HI_type_node (rs6000_builtin_types[RS6000_BTI_V8HI]) #define unsigned_V16QI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V16QI]) +#define unsigned_V1TI_type_node (rs6000_builtin_types[RS6000_BTI_unsigned_V1TI]) #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]) @@ -2518,8 +2659,13 @@ enum rs6000_builtin_type_index #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 intTI_type_internal_node (rs6000_builtin_types[RS6000_BTI_INTTI]) +#define uintTI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTTI]) #define float_type_internal_node (rs6000_builtin_types[RS6000_BTI_float]) #define double_type_internal_node (rs6000_builtin_types[RS6000_BTI_double]) +#define long_double_type_internal_node (rs6000_builtin_types[RS6000_BTI_long_double]) +#define dfloat64_type_internal_node (rs6000_builtin_types[RS6000_BTI_dfloat64]) +#define dfloat128_type_internal_node (rs6000_builtin_types[RS6000_BTI_dfloat128]) #define void_type_internal_node (rs6000_builtin_types[RS6000_BTI_void]) extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX]; |