From: Segher Boessenkool Date: Wed, 24 May 2017 19:35:49 +0000 (+0200) Subject: Split off powerpcspe from rs6000 port X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=83349046151acb6be52e01c6566c71a905ebf40e;p=gcc.git Split off powerpcspe from rs6000 port * config/powerpcspe: New port. Files are copied from the rs6000 port, with "rs6000" in filenames replaced by "powerpcspe". * config.gcc (powerpc*-*-*spe*): New. (powerpc-*-eabispe*): Use ${cpu_type} instead of hardcoded pathnames. (powerpc-*-rtems*spe*): New. (powerpc*-*-linux*spe*): New. (powerpc-wrs-vxworksspe): New. (powerpc*-*-*, rs6000-*-*): Use ${cpu_type}. (misc flags) [powerpc*-*-*, rs6000-*-*): Use ${cpu_type}. * config.host (powerpc*-*-*spe*): New. From-SVN: r248429 --- diff --git a/ChangeLog b/ChangeLog index b75693b1ed4..e1ab7c8e667 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2017-05-24 Segher Boessenkool + + * config.gcc (powerpc*-*-*spe*): New. + (powerpc-*-eabispe*): Use ${cpu_type} instead of hardcoded pathnames. + (powerpc-*-rtems*spe*): New. + (powerpc*-*-linux*spe*): New. + (powerpc-wrs-vxworksspe): New. + (powerpc*-*-*, rs6000-*-*): Use ${cpu_type}. + (misc flags) [powerpc*-*-*, rs6000-*-*): Use ${cpu_type}. + * config.host (powerpc*-*-*spe*): New. + 2017-05-19 Martin Liska * configure.ac: Add --enable-werror-always just for diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1b70fa034b2..0de25314406 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2017-05-24 Segher Boessenkool + + * config/powerpcspe: New port. Files are copied from the rs6000 + port, with "rs6000" in filenames replaced by "powerpcspe". + 2017-05-24 Wilco Dijkstra PR rtl-optimization/80754 diff --git a/gcc/common/config/powerpcspe/powerpcspe-common.c b/gcc/common/config/powerpcspe/powerpcspe-common.c new file mode 100644 index 00000000000..3c0106ae555 --- /dev/null +++ b/gcc/common/config/powerpcspe/powerpcspe-common.c @@ -0,0 +1,333 @@ +/* Common hooks for IBM RS/6000. + Copyright (C) 1991-2017 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "tm.h" +#include "common/common-target.h" +#include "common/common-target-def.h" +#include "opts.h" +#include "flags.h" +#include "params.h" + +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */ +static const struct default_options rs6000_option_optimization_table[] = + { + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + /* Enable -fsched-pressure for first pass instruction scheduling. */ + { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +/* Implement TARGET_OPTION_INIT_STRUCT. */ + +static void +rs6000_option_init_struct (struct gcc_options *opts) +{ + if (DEFAULT_ABI == ABI_DARWIN) + /* The Darwin libraries never set errno, so we might as well + avoid calling them when that's the only reason we would. */ + opts->x_flag_errno_math = 0; + + /* Enable section anchors by default. */ + if (!TARGET_MACHO) + opts->x_flag_section_anchors = 1; +} + +/* Implement TARGET_OPTION_DEFAULT_PARAMS. */ + +static void +rs6000_option_default_params (void) +{ + /* Double growth factor to counter reduced min jump length. */ + set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16); +} + +/* If not otherwise specified by a target, make 'long double' equivalent to + 'double'. */ + +#ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE +#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64 +#endif + +/* Implement TARGET_HANDLE_OPTION. */ + +static bool +rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, + const struct cl_decoded_option *decoded, + location_t loc) +{ + enum fpu_type_t fpu_type = FPU_NONE; + char *p, *q; + size_t code = decoded->opt_index; + const char *arg = decoded->arg; + int value = decoded->value; + + switch (code) + { + case OPT_mfull_toc: + opts->x_rs6000_isa_flags &= ~OPTION_MASK_MINIMAL_TOC; + opts->x_TARGET_NO_FP_IN_TOC = 0; + opts->x_TARGET_NO_SUM_IN_TOC = 0; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; +#ifdef TARGET_USES_SYSV4_OPT + /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be + just the same as -mminimal-toc. */ + opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; +#endif + break; + +#ifdef TARGET_USES_SYSV4_OPT + case OPT_mtoc: + /* Make -mtoc behave like -mminimal-toc. */ + opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; + break; +#endif + +#ifdef TARGET_USES_AIX64_OPT + case OPT_maix64: +#else + case OPT_m64: +#endif + opts->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64; + opts->x_rs6000_isa_flags |= (~opts_set->x_rs6000_isa_flags + & OPTION_MASK_PPC_GFXOPT); + opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64; + break; + +#ifdef TARGET_USES_AIX64_OPT + case OPT_maix32: +#else + case OPT_m32: +#endif + opts->x_rs6000_isa_flags &= ~OPTION_MASK_POWERPC64; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_POWERPC64; + break; + + case OPT_mminimal_toc: + if (value == 1) + { + opts->x_TARGET_NO_FP_IN_TOC = 0; + opts->x_TARGET_NO_SUM_IN_TOC = 0; + } + break; + + case OPT_mpowerpc_gpopt: + case OPT_mpowerpc_gfxopt: + break; + + case OPT_mdebug_: + p = ASTRDUP (arg); + opts->x_rs6000_debug = 0; + + while ((q = strtok (p, ",")) != NULL) + { + unsigned mask = 0; + bool invert; + + p = NULL; + if (*q == '!') + { + invert = true; + q++; + } + else + invert = false; + + if (! strcmp (q, "all")) + mask = MASK_DEBUG_ALL; + else if (! strcmp (q, "stack")) + mask = MASK_DEBUG_STACK; + else if (! strcmp (q, "arg")) + mask = MASK_DEBUG_ARG; + else if (! strcmp (q, "reg")) + mask = MASK_DEBUG_REG; + else if (! strcmp (q, "addr")) + mask = MASK_DEBUG_ADDR; + else if (! strcmp (q, "cost")) + mask = MASK_DEBUG_COST; + else if (! strcmp (q, "target")) + mask = MASK_DEBUG_TARGET; + else if (! strcmp (q, "builtin")) + mask = MASK_DEBUG_BUILTIN; + else + error_at (loc, "unknown -mdebug-%s switch", q); + + if (invert) + opts->x_rs6000_debug &= ~mask; + else + opts->x_rs6000_debug |= mask; + } + break; + +#ifdef TARGET_USES_SYSV4_OPT + case OPT_mrelocatable: + if (value == 1) + { + opts->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; + opts->x_TARGET_NO_FP_IN_TOC = 1; + } + break; + + case OPT_mrelocatable_lib: + if (value == 1) + { + opts->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE + | OPTION_MASK_MINIMAL_TOC); + opts_set->x_rs6000_isa_flags |= (OPTION_MASK_RELOCATABLE + | OPTION_MASK_MINIMAL_TOC); + opts->x_TARGET_NO_FP_IN_TOC = 1; + } + else + { + opts->x_rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_RELOCATABLE; + } + break; +#endif + + case OPT_mabi_altivec: + /* Enabling the AltiVec ABI turns off the SPE ABI. */ + opts->x_rs6000_spe_abi = 0; + break; + + case OPT_mabi_spe: + opts->x_rs6000_altivec_abi = 0; + break; + + case OPT_mlong_double_: + if (value != 64 && value != 128) + { + error_at (loc, "unknown switch -mlong-double-%s", arg); + opts->x_rs6000_long_double_type_size + = RS6000_DEFAULT_LONG_DOUBLE_SIZE; + return false; + } + break; + + case OPT_msingle_float: + if (!TARGET_SINGLE_FPU) + warning_at (loc, 0, + "-msingle-float option equivalent to -mhard-float"); + /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */ + opts->x_rs6000_double_float = 0; + opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; + break; + + case OPT_mdouble_float: + /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */ + opts->x_rs6000_single_float = 1; + opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; + break; + + case OPT_msimple_fpu: + if (!TARGET_SINGLE_FPU) + warning_at (loc, 0, "-msimple-fpu option ignored"); + break; + + case OPT_mhard_float: + /* -mhard_float implies -msingle-float and -mdouble-float. */ + opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; + break; + + case OPT_msoft_float: + /* -msoft_float implies -mnosingle-float and -mnodouble-float. */ + opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; + break; + + case OPT_mfpu_: + fpu_type = (enum fpu_type_t) value; + if (fpu_type != FPU_NONE) + { + /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on + HARD_FLOAT. */ + opts->x_rs6000_isa_flags &= ~OPTION_MASK_SOFT_FLOAT; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; + opts->x_rs6000_xilinx_fpu = 1; + if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL) + opts->x_rs6000_single_float = 1; + if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL) + opts->x_rs6000_single_float = opts->x_rs6000_double_float = 1; + if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE) + opts->x_rs6000_simple_fpu = 1; + } + else + { + /* -mfpu=none is equivalent to -msoft-float. */ + opts->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; + opts_set->x_rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; + opts->x_rs6000_single_float = opts->x_rs6000_double_float = 0; + } + break; + + case OPT_mrecip: + opts->x_rs6000_recip_name = (value) ? "default" : "none"; + break; + } + return true; +} + +/* -fsplit-stack uses a field in the TCB, available with glibc-2.19. + We also allow 2.18 because alignment padding guarantees that the + space is available there too. */ + +static bool +rs6000_supports_split_stack (bool report, + struct gcc_options *opts ATTRIBUTE_UNUSED) +{ +#ifndef TARGET_GLIBC_MAJOR +#define TARGET_GLIBC_MAJOR 0 +#endif +#ifndef TARGET_GLIBC_MINOR +#define TARGET_GLIBC_MINOR 0 +#endif + /* Note: Can't test DEFAULT_ABI here, it isn't set until later. */ + if (TARGET_GLIBC_MAJOR * 1000 + TARGET_GLIBC_MINOR >= 2018 + && TARGET_64BIT + && TARGET_ELF) + return true; + + if (report) + error ("%<-fsplit-stack%> currently only supported on PowerPC64 GNU/Linux with glibc-2.18 or later"); + return false; +} + +#undef TARGET_HANDLE_OPTION +#define TARGET_HANDLE_OPTION rs6000_handle_option + +#undef TARGET_OPTION_INIT_STRUCT +#define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct + +#undef TARGET_OPTION_DEFAULT_PARAMS +#define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params + +#undef TARGET_OPTION_OPTIMIZATION_TABLE +#define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table + +#undef TARGET_SUPPORTS_SPLIT_STACK +#define TARGET_SUPPORTS_SPLIT_STACK rs6000_supports_split_stack + +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER; diff --git a/gcc/config.gcc b/gcc/config.gcc index 8ce94d01ee0..f55dcaa335b 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -442,6 +442,16 @@ nios2-*-*) nvptx-*-*) cpu_type=nvptx ;; +powerpc*-*-*spe*) + cpu_type=powerpcspe + extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h htmintrin.h htmxlintrin.h" + case x$with_cpu in + xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[3456789]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|xe6500) + cpu_is_64bit=yes + ;; + esac + extra_options="${extra_options} g.opt fused-madd.opt powerpcspe/powerpcspe-tables.opt" + ;; powerpc*-*-*) cpu_type=rs6000 extra_headers="ppc-asm.h altivec.h htmintrin.h htmxlintrin.h" @@ -2372,9 +2382,9 @@ powerpc-*-netbsd*) extra_options="${extra_options} rs6000/sysv4.opt" ;; powerpc-*-eabispe*) - tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabispe.h" - extra_options="${extra_options} rs6000/sysv4.opt" - tmake_file="rs6000/t-spe rs6000/t-ppccomm" + tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h ${cpu_type}/sysv4.h ${cpu_type}/eabi.h ${cpu_type}/e500.h ${cpu_type}/eabispe.h" + extra_options="${extra_options} ${cpu_type}/sysv4.opt" + tmake_file="${cpu_type}/t-spe ${cpu_type}/t-ppccomm" use_gcc_stdint=wrap ;; powerpc-*-eabisimaltivec*) @@ -2412,11 +2422,27 @@ powerpc-*-eabi*) tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm" use_gcc_stdint=wrap ;; +powerpc-*-rtems*spe*) + tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h powerpcspe/sysv4.h powerpcspe/eabi.h powerpcspe/e500.h powerpcspe/rtems.h rtems.h" + extra_options="${extra_options} powerpcspe/sysv4.opt" + tmake_file="${tmake_file} powerpcspe/t-fprules powerpcspe/t-rtems powerpcspe/t-ppccomm" + ;; powerpc-*-rtems*) tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/rtems.h rtems.h" extra_options="${extra_options} rs6000/sysv4.opt" tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-rtems rs6000/t-ppccomm" ;; +powerpc*-*-linux*spe*) + tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h freebsd-spec.h powerpcspe/sysv4.h" + extra_options="${extra_options} powerpcspe/sysv4.opt" + tmake_file="${tmake_file} powerpcspe/t-fprules powerpcspe/t-ppccomm" + extra_objs="$extra_objs powerpcspe-linux.o" + maybe_biarch= + tm_file="${tm_file} powerpcspe/linux.h glibc-stdint.h" + tmake_file="${tmake_file} powerpcspe/t-ppcos powerpcspe/t-linux" + tm_file="${tm_file} powerpcspe/linuxspe.h powerpcspe/e500.h" + default_gnu_indirect_function=yes + ;; powerpc*-*-linux*) tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h freebsd-spec.h rs6000/sysv4.h" extra_options="${extra_options} rs6000/sysv4.opt" @@ -2504,6 +2530,13 @@ powerpc*-*-linux*) ;; esac ;; +powerpc-wrs-vxworksspe) + tm_file="${tm_file} elfos.h freebsd-spec.h powerpcspe/sysv4.h" + tmake_file="${tmake_file} powerpcspe/t-fprules powerpcspe/t-ppccomm powerpcspe/t-vxworks" + extra_options="${extra_options} powerpcspe/sysv4.opt" + extra_headers=ppc-asm.h + tm_file="${tm_file} vx-common.h vxworks.h powerpcspe/vxworks.h powerpcspe/e500.h" + ;; powerpc-wrs-vxworks|powerpc-wrs-vxworksae|powerpc-wrs-vxworksmils) tm_file="${tm_file} elfos.h freebsd-spec.h rs6000/sysv4.h" tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-ppccomm rs6000/t-vxworks" @@ -3060,7 +3093,7 @@ i[34567]86-*-* | x86_64-*-*) tmake_file="${tmake_file} i386/t-gmm_malloc i386/t-i386" ;; powerpc*-*-* | rs6000-*-*) - tm_file="${tm_file} rs6000/option-defaults.h" + tm_file="${tm_file} ${cpu_type}/option-defaults.h" esac # Build mkoffload tool @@ -4554,10 +4587,10 @@ case ${target} in then target_cpu_default2="\\\"$with_cpu\\\"" fi - out_file=rs6000/rs6000.c - c_target_objs="${c_target_objs} rs6000-c.o" - cxx_target_objs="${cxx_target_objs} rs6000-c.o" - tmake_file="rs6000/t-rs6000 ${tmake_file}" + out_file="${cpu_type}/${cpu_type}.c" + c_target_objs="${c_target_objs} ${cpu_type}-c.o" + cxx_target_objs="${cxx_target_objs} ${cpu_type}-c.o" + tmake_file="${cpu_type}/t-${cpu_type} ${tmake_file}" ;; sh[123456ble]*-*-* | sh-*-*) diff --git a/gcc/config.host b/gcc/config.host index 5e2db5327e3..48120ae1c89 100644 --- a/gcc/config.host +++ b/gcc/config.host @@ -144,6 +144,10 @@ case ${host} in rs6000-*-* \ | powerpc*-*-* ) case ${target} in + powerpc*-*-*spe*) + host_extra_gcc_objs="driver-powerpcspe.o" + host_xmake_file="${host_xmake_file} powerpcspe/x-powerpcspe" + ;; rs6000-*-* \ | powerpc*-*-* ) host_extra_gcc_objs="driver-rs6000.o" diff --git a/gcc/config/powerpcspe/40x.md b/gcc/config/powerpcspe/40x.md new file mode 100644 index 00000000000..d832a90c409 --- /dev/null +++ b/gcc/config/powerpcspe/40x.md @@ -0,0 +1,124 @@ +;; Scheduling description for IBM PowerPC 403 and PowerPC 405 processors. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "ppc40x,ppc40xiu") +(define_cpu_unit "bpu_40x,fpu_405" "ppc40x") +(define_cpu_unit "iu_40x" "ppc40xiu") + +;; PPC401 / PPC403 / PPC405 32-bit integer only IU BPU +;; Embedded PowerPC controller +;; In-order execution +;; Max issue two insns/cycle (includes one branch) +(define_insn_reservation "ppc403-load" 2 + (and (eq_attr "type" "load,load_l,store_c,sync") + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x") + +(define_insn_reservation "ppc403-store" 2 + (and (eq_attr "type" "store") + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x") + +(define_insn_reservation "ppc403-integer" 1 + (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x") + +(define_insn_reservation "ppc403-two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x,iu_40x") + +(define_insn_reservation "ppc403-three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x,iu_40x,iu_40x") + +(define_insn_reservation "ppc403-compare" 3 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x,nothing,bpu_40x") + +(define_insn_reservation "ppc403-imul" 4 + (and (eq_attr "type" "mul") + (eq_attr "cpu" "ppc403")) + "iu_40x*4") + +(define_insn_reservation "ppc405-imul" 5 + (and (eq_attr "type" "mul") + (eq_attr "size" "32") + (eq_attr "cpu" "ppc405")) + "iu_40x*4") + +(define_insn_reservation "ppc405-imul2" 3 + (and (eq_attr "type" "mul") + (eq_attr "size" "16") + (eq_attr "cpu" "ppc405")) + "iu_40x*2") + +(define_insn_reservation "ppc405-imul3" 2 + (and (ior (eq_attr "type" "halfmul") + (and (eq_attr "type" "mul") + (eq_attr "size" "8"))) + (eq_attr "cpu" "ppc405")) + "iu_40x") + +(define_insn_reservation "ppc403-idiv" 33 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x*33") + +(define_insn_reservation "ppc403-mfcr" 2 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x") + +(define_insn_reservation "ppc403-mtcr" 3 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x") + +(define_insn_reservation "ppc403-mtjmpr" 4 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x") + +(define_insn_reservation "ppc403-mfjmpr" 2 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "ppc403,ppc405")) + "iu_40x") + +(define_insn_reservation "ppc403-jmpreg" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppc403,ppc405")) + "bpu_40x") + +(define_insn_reservation "ppc403-cr" 2 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppc403,ppc405")) + "bpu_40x") + +(define_insn_reservation "ppc405-float" 11 + (and (eq_attr "type" "fpload,fpstore,fpcompare,fp,fpsimple,dmul,sdiv,ddiv") + (eq_attr "cpu" "ppc405")) + "fpu_405*10") diff --git a/gcc/config/powerpcspe/440.md b/gcc/config/powerpcspe/440.md new file mode 100644 index 00000000000..80964e8bbac --- /dev/null +++ b/gcc/config/powerpcspe/440.md @@ -0,0 +1,138 @@ +;; Scheduling description for IBM PowerPC 440 processor. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; PPC440 Embedded PowerPC controller +;; dual issue +;; i_pipe - complex integer / compare / branch +;; j_pipe - simple integer arithmetic +;; l_pipe - load-store +;; f_pipe - floating point arithmetic + +(define_automaton "ppc440_core,ppc440_apu") +(define_cpu_unit "ppc440_i_pipe,ppc440_j_pipe,ppc440_l_pipe" "ppc440_core") +(define_cpu_unit "ppc440_f_pipe" "ppc440_apu") +(define_cpu_unit "ppc440_issue_0,ppc440_issue_1" "ppc440_core") + +(define_reservation "ppc440_issue" "ppc440_issue_0|ppc440_issue_1") + + +(define_insn_reservation "ppc440-load" 3 + (and (eq_attr "type" "load,load_l,store_c,sync") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_l_pipe") + +(define_insn_reservation "ppc440-store" 3 + (and (eq_attr "type" "store") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_l_pipe") + +(define_insn_reservation "ppc440-fpload" 4 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_l_pipe") + +(define_insn_reservation "ppc440-fpstore" 3 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_l_pipe") + +(define_insn_reservation "ppc440-integer" 1 + (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_i_pipe|ppc440_j_pipe") + +(define_insn_reservation "ppc440-two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppc440")) + "ppc440_issue_0+ppc440_issue_1,\ + ppc440_i_pipe|ppc440_j_pipe,ppc440_i_pipe|ppc440_j_pipe") + +(define_insn_reservation "ppc440-three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppc440")) + "ppc440_issue_0+ppc440_issue_1,ppc440_i_pipe|ppc440_j_pipe,\ + ppc440_i_pipe|ppc440_j_pipe,ppc440_i_pipe|ppc440_j_pipe") + +(define_insn_reservation "ppc440-imul" 3 + (and (eq_attr "type" "mul") + (eq_attr "size" "32") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_i_pipe") + +(define_insn_reservation "ppc440-imul2" 2 + (and (ior (eq_attr "type" "halfmul") + (and (eq_attr "type" "mul") + (eq_attr "size" "8,16"))) + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_i_pipe") + +(define_insn_reservation "ppc440-idiv" 34 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_i_pipe*33") + +(define_insn_reservation "ppc440-branch" 1 + (and (eq_attr "type" "branch,jmpreg,isync") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_i_pipe") + +(define_insn_reservation "ppc440-compare" 2 + (and (ior (eq_attr "type" "cmp,cr_logical,delayed_cr,mfcr") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_i_pipe") + +(define_insn_reservation "ppc440-fpcompare" 3 ; 2 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_f_pipe+ppc440_i_pipe") + +(define_insn_reservation "ppc440-fp" 5 + (and (eq_attr "type" "fp,fpsimple,dmul") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_f_pipe") + +(define_insn_reservation "ppc440-sdiv" 19 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_f_pipe*15") + +(define_insn_reservation "ppc440-ddiv" 33 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_f_pipe*29") + +(define_insn_reservation "ppc440-mtcr" 3 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_i_pipe") + +(define_insn_reservation "ppc440-mtjmpr" 4 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_i_pipe") + +(define_insn_reservation "ppc440-mfjmpr" 2 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "ppc440")) + "ppc440_issue,ppc440_i_pipe") + diff --git a/gcc/config/powerpcspe/476.h b/gcc/config/powerpcspe/476.h new file mode 100644 index 00000000000..f22e399b6c5 --- /dev/null +++ b/gcc/config/powerpcspe/476.h @@ -0,0 +1,32 @@ +/* Enable IBM PowerPC 476 support. + Copyright (C) 2011-2017 Free Software Foundation, Inc. + Contributed by Peter Bergner (bergner@vnet.ibm.com) + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#undef TARGET_LINK_STACK +#define TARGET_LINK_STACK (rs6000_link_stack) + +#undef SET_TARGET_LINK_STACK +#define SET_TARGET_LINK_STACK(X) do { TARGET_LINK_STACK = (X); } while (0) + +#undef TARGET_ASM_CODE_END +#define TARGET_ASM_CODE_END rs6000_code_end diff --git a/gcc/config/powerpcspe/476.md b/gcc/config/powerpcspe/476.md new file mode 100644 index 00000000000..aefead25ada --- /dev/null +++ b/gcc/config/powerpcspe/476.md @@ -0,0 +1,143 @@ +;; Scheduling description for IBM PowerPC 476 processor. +;; Copyright (C) 2009-2017 Free Software Foundation, Inc. +;; Contributed by Peter Bergner (bergner@vnet.ibm.com). +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; PPC476 Embedded PowerPC controller +;; 3 issue (476) / 4 issue (476fp) +;; +;; i_pipe - complex integer / compare +;; lj_pipe - load-store / simple integer arithmetic +;; b_pipe - branch pipe +;; f_pipe - floating point arithmetic + +(define_automaton "ppc476_core,ppc476_apu") + +(define_cpu_unit "ppc476_i_pipe,ppc476_lj_pipe,ppc476_b_pipe" "ppc476_core") +(define_cpu_unit "ppc476_issue_fp,ppc476_f_pipe" "ppc476_apu") +(define_cpu_unit "ppc476_issue_0,ppc476_issue_1,ppc476_issue_2" "ppc476_core") + +(define_reservation "ppc476_issue" "ppc476_issue_0|ppc476_issue_1|ppc476_issue_2") +(define_reservation "ppc476_issue2" "ppc476_issue_0+ppc476_issue_1\ + |ppc476_issue_0+ppc476_issue_2\ + |ppc476_issue_1+ppc476_issue_2") +(define_reservation "ppc476_issue3" "ppc476_issue_0+ppc476_issue_1+ppc476_issue_2") + +(define_insn_reservation "ppc476-load" 4 + (and (eq_attr "type" "load,load_l,store_c,sync") + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_lj_pipe") + +(define_insn_reservation "ppc476-store" 4 + (and (eq_attr "type" "store") + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_lj_pipe") + +(define_insn_reservation "ppc476-fpload" 4 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_lj_pipe") + +(define_insn_reservation "ppc476-fpstore" 4 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_lj_pipe") + +(define_insn_reservation "ppc476-simple-integer" 1 + (and (ior (eq_attr "type" "integer,insert") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_i_pipe|ppc476_lj_pipe") + +(define_insn_reservation "ppc476-complex-integer" 1 + (and (eq_attr "type" "cmp,cr_logical,delayed_cr,cntlz,isel,isync,sync,trap,popcnt") + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_i_pipe") + +(define_insn_reservation "ppc476-compare" 4 + (and (ior (eq_attr "type" "mfcr,mfcrf,mtcr,mfjmpr,mtjmpr") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_i_pipe") + +(define_insn_reservation "ppc476-imul" 4 + (and (eq_attr "type" "mul,halfmul") + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_i_pipe") + +(define_insn_reservation "ppc476-idiv" 11 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_i_pipe*11") + +(define_insn_reservation "ppc476-branch" 1 + (and (eq_attr "type" "branch,jmpreg") + (eq_attr "cpu" "ppc476")) + "ppc476_issue,\ + ppc476_b_pipe") + +(define_insn_reservation "ppc476-two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppc476")) + "ppc476_issue2,\ + ppc476_i_pipe|ppc476_lj_pipe,\ + ppc476_i_pipe|ppc476_lj_pipe") + +(define_insn_reservation "ppc476-three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppc476")) + "ppc476_issue3,\ + ppc476_i_pipe|ppc476_lj_pipe,\ + ppc476_i_pipe|ppc476_lj_pipe,\ + ppc476_i_pipe|ppc476_lj_pipe") + +(define_insn_reservation "ppc476-fpcompare" 6 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppc476")) + "ppc476_issue+ppc476_issue_fp,\ + ppc476_f_pipe+ppc476_i_pipe") + +(define_insn_reservation "ppc476-fp" 6 + (and (eq_attr "type" "fp,fpsimple,dmul") + (eq_attr "cpu" "ppc476")) + "ppc476_issue_fp,\ + ppc476_f_pipe") + +(define_insn_reservation "ppc476-sdiv" 19 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppc476")) + "ppc476_issue_fp, + ppc476_f_pipe*19") + +(define_insn_reservation "ppc476-ddiv" 33 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppc476")) + "ppc476_issue_fp,\ + ppc476_f_pipe*33") + diff --git a/gcc/config/powerpcspe/476.opt b/gcc/config/powerpcspe/476.opt new file mode 100644 index 00000000000..c681d2c03a5 --- /dev/null +++ b/gcc/config/powerpcspe/476.opt @@ -0,0 +1,24 @@ +; IBM PowerPC 476 options. +; +; Copyright (C) 2011-2017 Free Software Foundation, Inc. +; Contributed by Peter Bergner (bergner@vnet.ibm.com) +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 3, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY +; WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +; for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING3. If not see +; . + +mpreserve-link-stack +Target Var(rs6000_link_stack) Init(-1) Save +Preserve the PowerPC 476's link stack by matching up a blr with the bcl/bl insns used for GOT accesses. diff --git a/gcc/config/powerpcspe/601.md b/gcc/config/powerpcspe/601.md new file mode 100644 index 00000000000..79221260229 --- /dev/null +++ b/gcc/config/powerpcspe/601.md @@ -0,0 +1,137 @@ +;; Scheduling description for PowerPC 601 processor. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "ppc601,ppc601fp") +(define_cpu_unit "iu_ppc601" "ppc601") +(define_cpu_unit "fpu_ppc601" "ppc601fp") +(define_cpu_unit "bpu_ppc601" "ppc601") + +;; PPC601 32-bit IU, FPU, BPU + +(define_insn_reservation "ppc601-load" 2 + (and (eq_attr "type" "load,load_l,store_c,sync") + (eq_attr "cpu" "ppc601")) + "iu_ppc601") + +(define_insn_reservation "ppc601-store" 2 + (and (eq_attr "type" "store") + (eq_attr "cpu" "ppc601")) + "iu_ppc601") + +(define_insn_reservation "ppc601-fpload" 3 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppc601")) + "iu_ppc601") + +(define_insn_reservation "ppc601-fpstore" 3 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppc601")) + "iu_ppc601+fpu_ppc601") + +(define_insn_reservation "ppc601-integer" 1 + (and (ior (eq_attr "type" "integer,add,insert,trap,cntlz,isel") + (and (eq_attr "type" "shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "ppc601")) + "iu_ppc601") + +(define_insn_reservation "ppc601-two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppc601")) + "iu_ppc601,iu_ppc601") + +(define_insn_reservation "ppc601-three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppc601")) + "iu_ppc601,iu_ppc601,iu_ppc601") + +(define_insn_reservation "ppc601-imul" 5 + (and (eq_attr "type" "mul") + (eq_attr "cpu" "ppc601")) + "iu_ppc601*5") + +(define_insn_reservation "ppc601-idiv" 36 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppc601")) + "iu_ppc601*36") + +; compare executes on integer unit, but feeds insns which +; execute on the branch unit. +(define_insn_reservation "ppc601-compare" 3 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "shift,exts") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "ppc601")) + "iu_ppc601,nothing,bpu_ppc601") + +(define_insn_reservation "ppc601-fpcompare" 5 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppc601")) + "(fpu_ppc601+iu_ppc601*2),nothing*2,bpu_ppc601") + +(define_insn_reservation "ppc601-fp" 4 + (and (eq_attr "type" "fp,fpsimple") + (eq_attr "cpu" "ppc601")) + "fpu_ppc601") + +(define_insn_reservation "ppc601-dmul" 5 + (and (eq_attr "type" "dmul") + (eq_attr "cpu" "ppc601")) + "fpu_ppc601*2") + +(define_insn_reservation "ppc601-sdiv" 17 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppc601")) + "fpu_ppc601*17") + +(define_insn_reservation "ppc601-ddiv" 31 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppc601")) + "fpu_ppc601*31") + +(define_insn_reservation "ppc601-mfcr" 2 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppc601")) + "iu_ppc601,bpu_ppc601") + +(define_insn_reservation "ppc601-mtcr" 4 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppc601")) + "iu_ppc601,bpu_ppc601") + +(define_insn_reservation "ppc601-crlogical" 4 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppc601")) + "bpu_ppc601") + +(define_insn_reservation "ppc601-mtjmpr" 4 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "ppc601")) + "iu_ppc601,bpu_ppc601") + +(define_insn_reservation "ppc601-mfjmpr" 2 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "ppc601")) + "iu_ppc601,bpu_ppc601") + +(define_insn_reservation "ppc601-branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppc601")) + "bpu_ppc601") + diff --git a/gcc/config/powerpcspe/603.md b/gcc/config/powerpcspe/603.md new file mode 100644 index 00000000000..853746eb912 --- /dev/null +++ b/gcc/config/powerpcspe/603.md @@ -0,0 +1,147 @@ +;; Scheduling description for PowerPC 603 processor. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "ppc603,ppc603fp") +(define_cpu_unit "iu_603" "ppc603") +(define_cpu_unit "fpu_603" "ppc603fp") +(define_cpu_unit "lsu_603,bpu_603,sru_603" "ppc603") + +;; PPC603/PPC603e 32-bit IU, LSU, FPU, BPU, SRU +;; Max issue 3 insns/clock cycle (includes 1 branch) + +;; Branches go straight to the BPU. All other insns are handled +;; by a dispatch unit which can issue a max of 2 insns per cycle. + +;; The PPC603e user's manual recommends that to reduce branch mispredictions, +;; the insn that sets CR bits should be separated from the branch insn +;; that evaluates them; separation by more than 9 insns ensures that the CR +;; bits will be immediately available for execution. +;; This could be artificially achieved by exaggerating the latency of +;; compare insns but at the expense of a poorer schedule. + +;; CR insns get executed in the SRU. Not modelled. + +(define_insn_reservation "ppc603-load" 2 + (and (eq_attr "type" "load,load_l") + (eq_attr "cpu" "ppc603")) + "lsu_603") + +(define_insn_reservation "ppc603-store" 2 + (and (eq_attr "type" "store,fpstore") + (eq_attr "cpu" "ppc603")) + "lsu_603*2") + +(define_insn_reservation "ppc603-fpload" 2 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppc603")) + "lsu_603") + +(define_insn_reservation "ppc603-storec" 8 + (and (eq_attr "type" "store_c") + (eq_attr "cpu" "ppc603")) + "lsu_603") + +(define_insn_reservation "ppc603-integer" 1 + (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "ppc603")) + "iu_603") + +(define_insn_reservation "ppc603-two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppc603")) + "iu_603,iu_603") + +(define_insn_reservation "ppc603-three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppc603")) + "iu_603,iu_603,iu_603") + +; This takes 2 or 3 cycles +(define_insn_reservation "ppc603-imul" 3 + (and (eq_attr "type" "mul") + (eq_attr "size" "32") + (eq_attr "cpu" "ppc603")) + "iu_603*2") + +(define_insn_reservation "ppc603-imul2" 2 + (and (eq_attr "type" "mul") + (eq_attr "size" "8,16") + (eq_attr "cpu" "ppc603")) + "iu_603*2") + +(define_insn_reservation "ppc603-idiv" 37 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppc603")) + "iu_603*37") + +(define_insn_reservation "ppc603-compare" 3 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "ppc603")) + "iu_603,nothing,bpu_603") + +(define_insn_reservation "ppc603-fpcompare" 3 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppc603")) + "(fpu_603+iu_603*2),bpu_603") + +(define_insn_reservation "ppc603-fp" 3 + (and (eq_attr "type" "fp,fpsimple") + (eq_attr "cpu" "ppc603")) + "fpu_603") + +(define_insn_reservation "ppc603-dmul" 4 + (and (eq_attr "type" "dmul") + (eq_attr "cpu" "ppc603")) + "fpu_603*2") + +; Divides are not pipelined +(define_insn_reservation "ppc603-sdiv" 18 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppc603")) + "fpu_603*18") + +(define_insn_reservation "ppc603-ddiv" 33 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppc603")) + "fpu_603*33") + +(define_insn_reservation "ppc603-crlogical" 2 + (and (eq_attr "type" "cr_logical,delayed_cr,mfcr,mtcr") + (eq_attr "cpu" "ppc603")) + "sru_603") + +(define_insn_reservation "ppc603-mtjmpr" 4 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "ppc603")) + "sru_603") + +(define_insn_reservation "ppc603-mfjmpr" 2 + (and (eq_attr "type" "mfjmpr,isync,sync") + (eq_attr "cpu" "ppc603")) + "sru_603") + +(define_insn_reservation "ppc603-jmpreg" 1 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "ppc603")) + "bpu_603") + diff --git a/gcc/config/powerpcspe/6xx.md b/gcc/config/powerpcspe/6xx.md new file mode 100644 index 00000000000..64e5ebb7d6f --- /dev/null +++ b/gcc/config/powerpcspe/6xx.md @@ -0,0 +1,284 @@ +;; Scheduling description for PowerPC 604, PowerPC 604e, PowerPC 620, +;; and PowerPC 630 processors. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "ppc6xx,ppc6xxfp,ppc6xxfp2") +(define_cpu_unit "iu1_6xx,iu2_6xx,mciu_6xx" "ppc6xx") +(define_cpu_unit "fpu_6xx" "ppc6xxfp") +(define_cpu_unit "fpu1_6xx,fpu2_6xx" "ppc6xxfp2") +(define_cpu_unit "lsu_6xx,bpu_6xx,cru_6xx" "ppc6xx") + +;; PPC604 32-bit 2xSCIU, MCIU, LSU, FPU, BPU +;; PPC604e 32-bit 2xSCIU, MCIU, LSU, FPU, BPU, CRU +;; MCIU used for imul/idiv and moves from/to spr +;; LSU 2 stage pipelined +;; FPU 3 stage pipelined +;; Max issue 4 insns/clock cycle + +;; PPC604e is PPC604 with larger caches and a CRU. In the 604 +;; the CR logical operations are handled in the BPU. +;; In the 604e, the CRU shares bus with BPU so only one condition +;; register or branch insn can be issued per clock. Not modelled. + +;; PPC620 64-bit 2xSCIU, MCIU, LSU, FPU, BPU, CRU +;; PPC630 64-bit 2xSCIU, MCIU, LSU, 2xFPU, BPU, CRU +;; Max issue 4 insns/clock cycle +;; Out-of-order execution, in-order completion + +;; No following instruction can dispatch in the same cycle as a branch +;; instruction. Not modelled. This is no problem if RCSP is not +;; enabled since the scheduler stops a schedule when it gets to a branch. + +;; Four insns can be dispatched per cycle. + +(define_insn_reservation "ppc604-load" 2 + (and (eq_attr "type" "load") + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "lsu_6xx") + +(define_insn_reservation "ppc604-fpload" 3 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "lsu_6xx") + +(define_insn_reservation "ppc604-store" 3 + (and (eq_attr "type" "store,fpstore") + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "lsu_6xx") + +(define_insn_reservation "ppc604-llsc" 3 + (and (eq_attr "type" "load_l,store_c") + (eq_attr "cpu" "ppc604,ppc604e")) + "lsu_6xx") + +(define_insn_reservation "ppc630-llsc" 4 + (and (eq_attr "type" "load_l,store_c") + (eq_attr "cpu" "ppc620,ppc630")) + "lsu_6xx") + +(define_insn_reservation "ppc604-integer" 1 + (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "iu1_6xx|iu2_6xx") + +(define_insn_reservation "ppc604-two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "iu1_6xx|iu2_6xx,iu1_6xx|iu2_6xx") + +(define_insn_reservation "ppc604-three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "iu1_6xx|iu2_6xx,iu1_6xx|iu2_6xx,iu1_6xx|iu2_6xx") + +(define_insn_reservation "ppc604-imul" 4 + (and (eq_attr "type" "mul") + (eq_attr "cpu" "ppc604")) + "mciu_6xx*2") + +(define_insn_reservation "ppc604e-imul" 2 + (and (eq_attr "type" "mul") + (eq_attr "cpu" "ppc604e")) + "mciu_6xx") + +(define_insn_reservation "ppc620-imul" 5 + (and (eq_attr "type" "mul") + (eq_attr "size" "32") + (eq_attr "cpu" "ppc620,ppc630")) + "mciu_6xx*3") + +(define_insn_reservation "ppc620-imul2" 4 + (and (eq_attr "type" "mul") + (eq_attr "size" "16") + (eq_attr "cpu" "ppc620,ppc630")) + "mciu_6xx*3") + +(define_insn_reservation "ppc620-imul3" 3 + (and (eq_attr "type" "mul") + (eq_attr "size" "8") + (eq_attr "cpu" "ppc620,ppc630")) + "mciu_6xx*3") + +(define_insn_reservation "ppc620-lmul" 7 + (and (eq_attr "type" "mul") + (eq_attr "size" "64") + (eq_attr "cpu" "ppc620,ppc630")) + "mciu_6xx*5") + +(define_insn_reservation "ppc604-idiv" 20 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppc604,ppc604e")) + "mciu_6xx*19") + +(define_insn_reservation "ppc620-idiv" 37 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "ppc620")) + "mciu_6xx*36") + +(define_insn_reservation "ppc630-idiv" 21 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "ppc630")) + "mciu_6xx*20") + +(define_insn_reservation "ppc620-ldiv" 37 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "ppc620,ppc630")) + "mciu_6xx*36") + +(define_insn_reservation "ppc604-compare" 3 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "(iu1_6xx|iu2_6xx)") + +; FPU PPC604{,e},PPC620 +(define_insn_reservation "ppc604-fpcompare" 5 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppc604,ppc604e,ppc620")) + "fpu_6xx") + +(define_insn_reservation "ppc604-fp" 3 + (and (eq_attr "type" "fp,fpsimple") + (eq_attr "cpu" "ppc604,ppc604e,ppc620")) + "fpu_6xx") + +(define_insn_reservation "ppc604-dmul" 3 + (and (eq_attr "type" "dmul") + (eq_attr "cpu" "ppc604,ppc604e,ppc620")) + "fpu_6xx") + +; Divides are not pipelined +(define_insn_reservation "ppc604-sdiv" 18 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppc604,ppc604e,ppc620")) + "fpu_6xx*18") + +(define_insn_reservation "ppc604-ddiv" 32 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppc604,ppc604e,ppc620")) + "fpu_6xx*32") + +(define_insn_reservation "ppc620-ssqrt" 31 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "ppc620")) + "fpu_6xx*31") + +(define_insn_reservation "ppc620-dsqrt" 31 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "ppc620")) + "fpu_6xx*31") + + +; 2xFPU PPC630 +(define_insn_reservation "ppc630-fpcompare" 5 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppc630")) + "fpu1_6xx|fpu2_6xx") + +(define_insn_reservation "ppc630-fp" 3 + (and (eq_attr "type" "fp,dmul") + (eq_attr "cpu" "ppc630")) + "fpu1_6xx|fpu2_6xx") + +(define_insn_reservation "ppc630-sdiv" 17 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppc630")) + "fpu1_6xx*17|fpu2_6xx*17") + +(define_insn_reservation "ppc630-ddiv" 21 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppc630")) + "fpu1_6xx*21|fpu2_6xx*21") + +(define_insn_reservation "ppc630-ssqrt" 18 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "ppc630")) + "fpu1_6xx*18|fpu2_6xx*18") + +(define_insn_reservation "ppc630-dsqrt" 25 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "ppc630")) + "fpu1_6xx*25|fpu2_6xx*25") + +(define_insn_reservation "ppc604-mfcr" 3 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "mciu_6xx") + +(define_insn_reservation "ppc604-mtcr" 2 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "iu1_6xx|iu2_6xx") + +(define_insn_reservation "ppc604-crlogical" 2 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppc604")) + "bpu_6xx") + +(define_insn_reservation "ppc604e-crlogical" 2 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppc604e,ppc620,ppc630")) + "cru_6xx") + +(define_insn_reservation "ppc604-mtjmpr" 2 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "mciu_6xx") + +(define_insn_reservation "ppc604-mfjmpr" 3 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "ppc604,ppc604e,ppc620")) + "mciu_6xx") + +(define_insn_reservation "ppc630-mfjmpr" 2 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "ppc630")) + "mciu_6xx") + +(define_insn_reservation "ppc604-jmpreg" 1 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630")) + "bpu_6xx") + +(define_insn_reservation "ppc604-isync" 0 + (and (eq_attr "type" "isync") + (eq_attr "cpu" "ppc604,ppc604e")) + "bpu_6xx") + +(define_insn_reservation "ppc630-isync" 6 + (and (eq_attr "type" "isync") + (eq_attr "cpu" "ppc620,ppc630")) + "bpu_6xx") + +(define_insn_reservation "ppc604-sync" 35 + (and (eq_attr "type" "sync") + (eq_attr "cpu" "ppc604,ppc604e")) + "lsu_6xx") + +(define_insn_reservation "ppc630-sync" 26 + (and (eq_attr "type" "sync") + (eq_attr "cpu" "ppc620,ppc630")) + "lsu_6xx") + diff --git a/gcc/config/powerpcspe/7450.md b/gcc/config/powerpcspe/7450.md new file mode 100644 index 00000000000..8617708fd8b --- /dev/null +++ b/gcc/config/powerpcspe/7450.md @@ -0,0 +1,188 @@ +;; Scheduling description for Motorola PowerPC 7450 processor. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "ppc7450,ppc7450mciu,ppc7450fp,ppc7450vec") +(define_cpu_unit "iu1_7450,iu2_7450,iu3_7450" "ppc7450") +(define_cpu_unit "mciu_7450" "ppc7450mciu") +(define_cpu_unit "fpu_7450" "ppc7450fp") +(define_cpu_unit "lsu_7450,bpu_7450" "ppc7450") +(define_cpu_unit "du1_7450,du2_7450,du3_7450" "ppc7450") +(define_cpu_unit "vecsmpl_7450,veccmplx_7450,vecflt_7450,vecperm_7450" "ppc7450vec") +(define_cpu_unit "vdu1_7450,vdu2_7450" "ppc7450vec") + + +;; PPC7450 32-bit 3xIU, MCIU, LSU, SRU, FPU, BPU, 4xVEC +;; IU1,IU2,IU3 can perform all integer operations +;; MCIU performs imul and idiv, cr logical, SPR moves +;; LSU 2 stage pipelined +;; FPU 3 stage pipelined +;; It also has 4 vector units, one for each type of vector instruction. +;; However, we can only dispatch 2 instructions per cycle. +;; Max issue 3 insns/clock cycle (includes 1 branch) +;; In-order execution + +;; Branches go straight to the BPU. All other insns are handled +;; by a dispatch unit which can issue a max of 3 insns per cycle. +(define_reservation "ppc7450_du" "du1_7450|du2_7450|du3_7450") +(define_reservation "ppc7450_vec_du" "vdu1_7450|vdu2_7450") + +(define_insn_reservation "ppc7450-load" 3 + (and (eq_attr "type" "load,vecload") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,lsu_7450") + +(define_insn_reservation "ppc7450-store" 3 + (and (eq_attr "type" "store,vecstore") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,lsu_7450") + +(define_insn_reservation "ppc7450-fpload" 4 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,lsu_7450") + +(define_insn_reservation "ppc7450-fpstore" 3 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,lsu_7450*3") + +(define_insn_reservation "ppc7450-llsc" 3 + (and (eq_attr "type" "load_l,store_c") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,lsu_7450") + +(define_insn_reservation "ppc7450-sync" 35 + (and (eq_attr "type" "sync") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,lsu_7450") + +(define_insn_reservation "ppc7450-integer" 1 + (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,iu1_7450|iu2_7450|iu3_7450") + +(define_insn_reservation "ppc7450-two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,iu1_7450|iu2_7450|iu3_7450,iu1_7450|iu2_7450|iu3_7450") + +(define_insn_reservation "ppc7450-three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,iu1_7450|iu2_7450|iu3_7450,\ + iu1_7450|iu2_7450|iu3_7450,iu1_7450|iu2_7450|iu3_7450") + +(define_insn_reservation "ppc7450-imul" 4 + (and (eq_attr "type" "mul") + (eq_attr "size" "32") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,mciu_7450*2") + +(define_insn_reservation "ppc7450-imul2" 3 + (and (eq_attr "type" "mul") + (eq_attr "size" "8,16") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,mciu_7450") + +(define_insn_reservation "ppc7450-idiv" 23 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,mciu_7450*23") + +(define_insn_reservation "ppc7450-compare" 2 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,(iu1_7450|iu2_7450|iu3_7450)") + +(define_insn_reservation "ppc7450-fpcompare" 5 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,fpu_7450") + +(define_insn_reservation "ppc7450-fp" 5 + (and (eq_attr "type" "fp,fpsimple,dmul") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,fpu_7450") + +; Divides are not pipelined +(define_insn_reservation "ppc7450-sdiv" 21 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,fpu_7450*21") + +(define_insn_reservation "ppc7450-ddiv" 35 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,fpu_7450*35") + +(define_insn_reservation "ppc7450-mfcr" 2 + (and (eq_attr "type" "mfcr,mtcr") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,mciu_7450") + +(define_insn_reservation "ppc7450-crlogical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,mciu_7450") + +(define_insn_reservation "ppc7450-mtjmpr" 2 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "ppc7450")) + "nothing,mciu_7450*2") + +(define_insn_reservation "ppc7450-mfjmpr" 3 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "ppc7450")) + "nothing,mciu_7450*2") + +(define_insn_reservation "ppc7450-jmpreg" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppc7450")) + "nothing,bpu_7450") + +;; Altivec +(define_insn_reservation "ppc7450-vecsimple" 1 + (and (eq_attr "type" "vecsimple,veclogical,vecmove") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,ppc7450_vec_du,vecsmpl_7450") + +(define_insn_reservation "ppc7450-veccomplex" 4 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,ppc7450_vec_du,veccmplx_7450") + +(define_insn_reservation "ppc7450-veccmp" 2 + (and (eq_attr "type" "veccmp,veccmpfx") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,ppc7450_vec_du,veccmplx_7450") + +(define_insn_reservation "ppc7450-vecfloat" 4 + (and (eq_attr "type" "vecfloat") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,ppc7450_vec_du,vecflt_7450") + +(define_insn_reservation "ppc7450-vecperm" 2 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "ppc7450")) + "ppc7450_du,ppc7450_vec_du,vecperm_7450") + diff --git a/gcc/config/powerpcspe/750cl.h b/gcc/config/powerpcspe/750cl.h new file mode 100644 index 00000000000..b31f05fafd1 --- /dev/null +++ b/gcc/config/powerpcspe/750cl.h @@ -0,0 +1,30 @@ +/* Enable 750cl paired single support. + Copyright (C) 2007-2017 Free Software Foundation, Inc. + Contributed by Revital Eres (eres@il.ibm.com) + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#undef TARGET_PAIRED_FLOAT +#define TARGET_PAIRED_FLOAT rs6000_paired_float + +#undef ASM_CPU_SPEC +#define ASM_CPU_SPEC "-m750cl" + diff --git a/gcc/config/powerpcspe/7xx.md b/gcc/config/powerpcspe/7xx.md new file mode 100644 index 00000000000..4001bf9405d --- /dev/null +++ b/gcc/config/powerpcspe/7xx.md @@ -0,0 +1,186 @@ +;; Scheduling description for Motorola PowerPC 750 and PowerPC 7400 processors. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "ppc7xx,ppc7xxfp") +(define_cpu_unit "iu1_7xx,iu2_7xx" "ppc7xx") +(define_cpu_unit "fpu_7xx" "ppc7xxfp") +(define_cpu_unit "lsu_7xx,bpu_7xx,sru_7xx" "ppc7xx") +(define_cpu_unit "du1_7xx,du2_7xx" "ppc7xx") +(define_cpu_unit "veccmplx_7xx,vecperm_7xx,vdu_7xx" "ppc7xx") + +;; PPC740/PPC750/PPC7400 32-bit 2xIU, LSU, SRU, FPU, BPU +;; IU1 can perform all integer operations +;; IU2 can perform all integer operations except imul and idiv +;; LSU 2 stage pipelined +;; FPU 3 stage pipelined +;; Max issue 3 insns/clock cycle (includes 1 branch) +;; In-order execution + + +;; The PPC750 user's manual recommends that to reduce branch mispredictions, +;; the insn that sets CR bits should be separated from the branch insn +;; that evaluates them. There is no advantage have more than 10 cycles +;; of separation. +;; This could be artificially achieved by exaggerating the latency of +;; compare insns but at the expense of a poorer schedule. + +;; Branches go straight to the BPU. All other insns are handled +;; by a dispatch unit which can issue a max of 2 insns per cycle. +(define_reservation "ppc750_du" "du1_7xx|du2_7xx") +(define_reservation "ppc7400_vec_du" "vdu_7xx") + +(define_insn_reservation "ppc750-load" 2 + (and (eq_attr "type" "load,fpload,vecload,load_l") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,lsu_7xx") + +(define_insn_reservation "ppc750-store" 2 + (and (eq_attr "type" "store,fpstore,vecstore") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,lsu_7xx") + +(define_insn_reservation "ppc750-storec" 8 + (and (eq_attr "type" "store_c") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,lsu_7xx") + +(define_insn_reservation "ppc750-integer" 1 + (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,iu1_7xx|iu2_7xx") + +(define_insn_reservation "ppc750-two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,iu1_7xx|iu2_7xx,iu1_7xx|iu2_7xx") + +(define_insn_reservation "ppc750-three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,iu1_7xx|iu2_7xx,iu1_7xx|iu2_7xx,iu1_7xx|iu2_7xx") + +(define_insn_reservation "ppc750-imul" 4 + (and (eq_attr "type" "mul") + (eq_attr "size" "32") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,iu1_7xx*4") + +(define_insn_reservation "ppc750-imul2" 3 + (and (eq_attr "type" "mul") + (eq_attr "size" "16") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,iu1_7xx*2") + +(define_insn_reservation "ppc750-imul3" 2 + (and (eq_attr "type" "mul") + (eq_attr "size" "8") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,iu1_7xx") + +(define_insn_reservation "ppc750-idiv" 19 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,iu1_7xx*19") + +(define_insn_reservation "ppc750-compare" 2 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,(iu1_7xx|iu2_7xx)") + +(define_insn_reservation "ppc750-fpcompare" 2 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,fpu_7xx") + +(define_insn_reservation "ppc750-fp" 3 + (and (eq_attr "type" "fp,fpsimple") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,fpu_7xx") + +(define_insn_reservation "ppc750-dmul" 4 + (and (eq_attr "type" "dmul") + (eq_attr "cpu" "ppc750")) + "ppc750_du,fpu_7xx*2") + +(define_insn_reservation "ppc7400-dmul" 3 + (and (eq_attr "type" "dmul") + (eq_attr "cpu" "ppc7400")) + "ppc750_du,fpu_7xx") + +; Divides are not pipelined +(define_insn_reservation "ppc750-sdiv" 17 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,fpu_7xx*17") + +(define_insn_reservation "ppc750-ddiv" 31 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,fpu_7xx*31") + +(define_insn_reservation "ppc750-mfcr" 2 + (and (eq_attr "type" "mfcr,mtcr") + (eq_attr "cpu" "ppc750,ppc7400")) + "ppc750_du,iu1_7xx") + +(define_insn_reservation "ppc750-crlogical" 3 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppc750,ppc7400")) + "nothing,sru_7xx*2") + +(define_insn_reservation "ppc750-mtjmpr" 2 + (and (eq_attr "type" "mtjmpr,isync,sync") + (eq_attr "cpu" "ppc750,ppc7400")) + "nothing,sru_7xx*2") + +(define_insn_reservation "ppc750-mfjmpr" 3 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "ppc750,ppc7400")) + "nothing,sru_7xx*2") + +(define_insn_reservation "ppc750-jmpreg" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppc750,ppc7400")) + "nothing,bpu_7xx") + +;; Altivec +(define_insn_reservation "ppc7400-vecsimple" 1 + (and (eq_attr "type" "vecsimple,veclogical,vecmove,veccmp,veccmpfx") + (eq_attr "cpu" "ppc7400")) + "ppc750_du,ppc7400_vec_du,veccmplx_7xx") + +(define_insn_reservation "ppc7400-veccomplex" 4 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "ppc7400")) + "ppc750_du,ppc7400_vec_du,veccmplx_7xx") + +(define_insn_reservation "ppc7400-vecfloat" 4 + (and (eq_attr "type" "vecfloat") + (eq_attr "cpu" "ppc7400")) + "ppc750_du,ppc7400_vec_du,veccmplx_7xx") + +(define_insn_reservation "ppc7400-vecperm" 2 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "ppc7400")) + "ppc750_du,ppc7400_vec_du,vecperm_7xx") + diff --git a/gcc/config/powerpcspe/8540.md b/gcc/config/powerpcspe/8540.md new file mode 100644 index 00000000000..fae369de0c3 --- /dev/null +++ b/gcc/config/powerpcspe/8540.md @@ -0,0 +1,248 @@ +;; Pipeline description for Motorola PowerPC 8540 processor. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "ppc8540_most,ppc8540_long,ppc8540_retire") +(define_cpu_unit "ppc8540_decode_0,ppc8540_decode_1" "ppc8540_most") + +;; We don't simulate general issue queue (GIC). If we have SU insn +;; and then SU1 insn, they cannot be issued on the same cycle +;; (although SU1 insn and then SU insn can be issued) because the SU +;; insn will go to SU1 from GIC0 entry. Fortunately, the first cycle +;; multipass insn scheduling will find the situation and issue the SU1 +;; insn and then the SU insn. +(define_cpu_unit "ppc8540_issue_0,ppc8540_issue_1" "ppc8540_most") + +;; We could describe completion buffers slots in combination with the +;; retirement units and the order of completion but the result +;; automaton would behave in the same way because we cannot describe +;; real latency time with taking in order completion into account. +;; Actually we could define the real latency time by querying reserved +;; automaton units but the current scheduler uses latency time before +;; issuing insns and making any reservations. +;; +;; So our description is aimed to achieve a insn schedule in which the +;; insns would not wait in the completion buffer. +(define_cpu_unit "ppc8540_retire_0,ppc8540_retire_1" "ppc8540_retire") + +;; Branch unit: +(define_cpu_unit "ppc8540_bu" "ppc8540_most") + +;; SU: +(define_cpu_unit "ppc8540_su0_stage0,ppc8540_su1_stage0" "ppc8540_most") + +;; We could describe here MU subunits for float multiply, float add +;; etc. But the result automaton would behave the same way as the +;; described one pipeline below because MU can start only one insn +;; per cycle. Actually we could simplify the automaton more not +;; describing stages 1-3, the result automata would be the same. +(define_cpu_unit "ppc8540_mu_stage0,ppc8540_mu_stage1" "ppc8540_most") +(define_cpu_unit "ppc8540_mu_stage2,ppc8540_mu_stage3" "ppc8540_most") + +;; The following unit is used to describe non-pipelined division. +(define_cpu_unit "ppc8540_mu_div" "ppc8540_long") + +;; Here we simplified LSU unit description not describing the stages. +(define_cpu_unit "ppc8540_lsu" "ppc8540_most") + +;; The following units are used to make automata deterministic +(define_cpu_unit "present_ppc8540_decode_0" "ppc8540_most") +(define_cpu_unit "present_ppc8540_issue_0" "ppc8540_most") +(define_cpu_unit "present_ppc8540_retire_0" "ppc8540_retire") +(define_cpu_unit "present_ppc8540_su0_stage0" "ppc8540_most") + +;; The following sets to make automata deterministic when option ndfa is used. +(presence_set "present_ppc8540_decode_0" "ppc8540_decode_0") +(presence_set "present_ppc8540_issue_0" "ppc8540_issue_0") +(presence_set "present_ppc8540_retire_0" "ppc8540_retire_0") +(presence_set "present_ppc8540_su0_stage0" "ppc8540_su0_stage0") + +;; Some useful abbreviations. +(define_reservation "ppc8540_decode" + "ppc8540_decode_0|ppc8540_decode_1+present_ppc8540_decode_0") +(define_reservation "ppc8540_issue" + "ppc8540_issue_0|ppc8540_issue_1+present_ppc8540_issue_0") +(define_reservation "ppc8540_retire" + "ppc8540_retire_0|ppc8540_retire_1+present_ppc8540_retire_0") +(define_reservation "ppc8540_su_stage0" + "ppc8540_su0_stage0|ppc8540_su1_stage0+present_ppc8540_su0_stage0") + +;; Simple SU insns +(define_insn_reservation "ppc8540_su" 1 + (and (eq_attr "type" "integer,add,logical,insert,cmp,\ + shift,trap,cntlz,exts,isel") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire") + +(define_insn_reservation "ppc8540_two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire,\ + ppc8540_issue+ppc8540_su_stage0+ppc8540_retire") + +(define_insn_reservation "ppc8540_three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire,\ + ppc8540_issue+ppc8540_su_stage0+ppc8540_retire,\ + ppc8540_issue+ppc8540_su_stage0+ppc8540_retire") + +;; Branch. Actually this latency time is not used by the scheduler. +(define_insn_reservation "ppc8540_branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_bu,ppc8540_retire") + +;; Multiply +(define_insn_reservation "ppc8540_multiply" 4 + (and (eq_attr "type" "mul") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\ + ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire") + +;; Divide. We use the average latency time here. We omit reserving a +;; retire unit because of the result automata will be huge. We ignore +;; reservation of miu_stage3 here because we use the average latency +;; time. +(define_insn_reservation "ppc8540_divide" 14 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\ + ppc8540_mu_div*13") + +;; CR logical +(define_insn_reservation "ppc8540_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_bu,ppc8540_retire") + +;; Mfcr +(define_insn_reservation "ppc8540_mfcr" 1 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire") + +;; Mtcrf +(define_insn_reservation "ppc8540_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire") + +;; Mtjmpr +(define_insn_reservation "ppc8540_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire") + +;; Loads +(define_insn_reservation "ppc8540_load" 3 + (and (eq_attr "type" "load,load_l,sync") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire") + +;; Stores. +(define_insn_reservation "ppc8540_store" 3 + (and (eq_attr "type" "store,store_c") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire") + +;; Simple FP +(define_insn_reservation "ppc8540_simple_float" 1 + (and (eq_attr "type" "fpsimple") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire") + +;; FP +(define_insn_reservation "ppc8540_float" 4 + (and (eq_attr "type" "fp") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\ + ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire") + +;; float divides. We omit reserving a retire unit and miu_stage3 +;; because of the result automata will be huge. +(define_insn_reservation "ppc8540_float_vector_divide" 29 + (and (eq_attr "type" "vecfdiv") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\ + ppc8540_mu_div*28") + +;; Brinc +(define_insn_reservation "ppc8540_brinc" 1 + (and (eq_attr "type" "brinc") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire") + +;; Simple vector +(define_insn_reservation "ppc8540_simple_vector" 1 + (and (eq_attr "type" "vecsimple,veclogical,vecmove") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire") + +;; Simple vector compare +(define_insn_reservation "ppc8540_simple_vector_compare" 1 + (and (eq_attr "type" "veccmpsimple") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire") + +;; Vector compare +(define_insn_reservation "ppc8540_vector_compare" 1 + (and (eq_attr "type" "veccmp,veccmpfx") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire") + +;; evsplatfi evsplati +(define_insn_reservation "ppc8540_vector_perm" 1 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire") + +;; Vector float +(define_insn_reservation "ppc8540_float_vector" 4 + (and (eq_attr "type" "vecfloat") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\ + ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire") + +;; Vector divides: Use the average. We omit reserving a retire unit +;; because of the result automata will be huge. We ignore reservation +;; of miu_stage3 here because we use the average latency time. +(define_insn_reservation "ppc8540_vector_divide" 14 + (and (eq_attr "type" "vecdiv") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\ + ppc8540_mu_div*13") + +;; Complex vector. +(define_insn_reservation "ppc8540_complex_vector" 4 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\ + ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire") + +;; Vector load +(define_insn_reservation "ppc8540_vector_load" 3 + (and (eq_attr "type" "vecload") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire") + +;; Vector store +(define_insn_reservation "ppc8540_vector_store" 3 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "ppc8540,ppc8548")) + "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire") diff --git a/gcc/config/powerpcspe/a2.md b/gcc/config/powerpcspe/a2.md new file mode 100644 index 00000000000..d8dd3268f71 --- /dev/null +++ b/gcc/config/powerpcspe/a2.md @@ -0,0 +1,138 @@ +;; Scheduling description for PowerPC A2 processors. +;; Copyright (C) 2009-2017 Free Software Foundation, Inc. +;; Contributed by Ben Elliston (bje@au.ibm.com) + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "ppca2") + +;; CPU units + +;; The multiplier pipeline. +(define_cpu_unit "mult" "ppca2") + +;; The auxiliary processor unit (FP/vector unit). +(define_cpu_unit "axu" "ppca2") + +;; D.4.6 +;; Some peculiarities for certain SPRs + +(define_insn_reservation "ppca2-mfcr" 1 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppca2")) + "nothing") + +(define_insn_reservation "ppca2-mfjmpr" 5 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "ppca2")) + "nothing") + +(define_insn_reservation "ppca2-mtjmpr" 5 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "ppca2")) + "nothing") + +;; D.4.8 +(define_insn_reservation "ppca2-imul" 1 + (and (eq_attr "type" "mul") + (eq_attr "size" "8,16,32") + (eq_attr "cpu" "ppca2")) + "nothing") + +;; FIXME: latency and multiplier reservation for 64-bit multiply? +(define_insn_reservation "ppca2-lmul" 6 + (and (eq_attr "type" "mul") + (eq_attr "size" "64") + (eq_attr "cpu" "ppca2")) + "mult*3") + +;; D.4.9 +(define_insn_reservation "ppca2-idiv" 32 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "ppca2")) + "mult*32") + +(define_insn_reservation "ppca2-ldiv" 65 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "ppca2")) + "mult*65") + +;; D.4.13 +(define_insn_reservation "ppca2-load" 5 + (and (eq_attr "type" "load") + (eq_attr "cpu" "ppca2")) + "nothing") + +;; D.8.1 +(define_insn_reservation "ppca2-fp" 6 + (and (eq_attr "type" "fp,fpsimple") + (eq_attr "cpu" "ppca2")) + "axu") + +;; D.8.4 +(define_insn_reservation "ppca2-fp-load" 6 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppca2")) + "axu") + +;; D.8.5 +(define_insn_reservation "ppca2-fp-store" 2 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppca2")) + "axu") + +;; D.8.6 +(define_insn_reservation "ppca2-fpcompare" 5 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppca2")) + "axu") + +;; D.8.7 +;; +;; Instructions from the same thread succeeding the floating-point +;; divide cannot be executed until the floating-point divide has +;; completed. Since there is nothing else we can do, this thread will +;; just have to stall. + +(define_insn_reservation "ppca2-ddiv" 72 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppca2")) + "axu") + +(define_insn_reservation "ppca2-sdiv" 59 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppca2")) + "axu") + +;; D.8.8 +;; +;; Instructions from the same thread succeeding the floating-point +;; divide cannot be executed until the floating-point divide has +;; completed. Since there is nothing else we can do, this thread will +;; just have to stall. + +(define_insn_reservation "ppca2-dsqrt" 69 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "ppca2")) + "axu") + +(define_insn_reservation "ppca2-ssqrt" 65 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "ppca2")) + "axu") diff --git a/gcc/config/powerpcspe/aix-stdint.h b/gcc/config/powerpcspe/aix-stdint.h new file mode 100644 index 00000000000..77cc699daaf --- /dev/null +++ b/gcc/config/powerpcspe/aix-stdint.h @@ -0,0 +1,51 @@ +/* Definitions for types on systems using AIX. + Copyright (C) 2009-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#define SIG_ATOMIC_TYPE "int" + +#define INT8_TYPE "signed char" +#define INT16_TYPE "short int" +#define INT32_TYPE "int" +#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int") +#define UINT8_TYPE "unsigned char" +#define UINT16_TYPE "short unsigned int" +#define UINT32_TYPE "unsigned int" +#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int") + +#define INT_LEAST8_TYPE "signed char" +#define INT_LEAST16_TYPE "short int" +#define INT_LEAST32_TYPE "int" +#define INT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int") +#define UINT_LEAST8_TYPE "unsigned char" +#define UINT_LEAST16_TYPE "short unsigned int" +#define UINT_LEAST32_TYPE "unsigned int" +#define UINT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int") + +#define INT_FAST8_TYPE "signed char" +#define INT_FAST16_TYPE "short int" +#define INT_FAST32_TYPE "int" +#define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int") +#define UINT_FAST8_TYPE "unsigned char" +#define UINT_FAST16_TYPE "short unsigned int" +#define UINT_FAST32_TYPE "unsigned int" +#define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int") + +#define INTPTR_TYPE "long int" +#define UINTPTR_TYPE "long unsigned int" + diff --git a/gcc/config/powerpcspe/aix.h b/gcc/config/powerpcspe/aix.h new file mode 100644 index 00000000000..b90e2b06519 --- /dev/null +++ b/gcc/config/powerpcspe/aix.h @@ -0,0 +1,278 @@ +/* Definitions of target machine for GNU compiler, + for IBM RS/6000 POWER running AIX. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* Yes! We are AIX! */ +#define DEFAULT_ABI ABI_AIX +#undef TARGET_AIX +#define TARGET_AIX 1 + +/* Linux64.h wants to redefine TARGET_AIX based on -m64, but it can't be used + in the #if conditional in options-default.h, so provide another macro. */ +#undef TARGET_AIX_OS +#define TARGET_AIX_OS 1 + +/* AIX always has a TOC. */ +#define TARGET_NO_TOC 0 +#define TARGET_TOC 1 +#define FIXED_R2 1 + +/* AIX allows r13 to be used in 32-bit mode. */ +#define FIXED_R13 0 + +/* 32-bit and 64-bit AIX stack boundary is 128. */ +#undef STACK_BOUNDARY +#define STACK_BOUNDARY 128 + +/* Offset within stack frame to start allocating local variables at. + If FRAME_GROWS_DOWNWARD, this is the offset to the END of the + first local allocated. Otherwise, it is the offset to the BEGINNING + of the first local allocated. + + On the RS/6000, the frame pointer is the same as the stack pointer, + except for dynamic allocations. So we start after the fixed area and + outgoing parameter area. + + If the function uses dynamic stack space (CALLS_ALLOCA is set), that + space needs to be aligned to STACK_BOUNDARY, i.e. the sum of the + sizes of the fixed area and the parameter area must be a multiple of + STACK_BOUNDARY. */ + +#undef STARTING_FRAME_OFFSET +#define STARTING_FRAME_OFFSET \ + (FRAME_GROWS_DOWNWARD \ + ? 0 \ + : (cfun->calls_alloca \ + ? RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, 16) \ + : (RS6000_ALIGN (crtl->outgoing_args_size, 16) + RS6000_SAVE_AREA))) + +/* Offset from the stack pointer register to an item dynamically + allocated on the stack, e.g., by `alloca'. + + The default value for this macro is `STACK_POINTER_OFFSET' plus the + length of the outgoing arguments. The default is correct for most + machines. See `function.c' for details. + + This value must be a multiple of STACK_BOUNDARY (hard coded in + `emit-rtl.c'). */ +#undef STACK_DYNAMIC_OFFSET +#define STACK_DYNAMIC_OFFSET(FUNDECL) \ + RS6000_ALIGN (crtl->outgoing_args_size + STACK_POINTER_OFFSET, 16) + +#undef TARGET_IEEEQUAD +#define TARGET_IEEEQUAD 0 + +/* The AIX linker will discard static constructors in object files before + collect has a chance to see them, so scan the object files directly. */ +#define COLLECT_EXPORT_LIST + +/* On AIX, initialisers specified with -binitfini are called in breadth-first + order. + e.g. if a.out depends on lib1.so, the init function for a.out is called before + the init function for lib1.so. + + To ensure global C++ constructors in linked libraries are run before global + C++ constructors from the current module, there is additional symbol scanning + logic in collect2. + + The global initialiser/finaliser functions are named __GLOBAL_AIXI_{libname} + and __GLOBAL_AIXD_{libname} and are exported from each shared library. + + collect2 will detect these symbols when they exist in shared libraries that + the current program is being linked against. All such initiliser functions + will be called prior to the constructors of the current program, and + finaliser functions called after destructors. + + Reference counting generated by collect2 will ensure that constructors are + only invoked once in the case of multiple dependencies on a library. + + -binitfini is still used in parallel to this solution. + This handles the case where a library is loaded through dlopen(), and also + handles the option -blazy. +*/ +#define COLLECT_SHARED_INIT_FUNC(STREAM, FUNC) \ + fprintf ((STREAM), "void %s() {\n\t%s();\n}\n", aix_shared_initname, (FUNC)) +#define COLLECT_SHARED_FINI_FUNC(STREAM, FUNC) \ + fprintf ((STREAM), "void %s() {\n\t%s();\n}\n", aix_shared_fininame, (FUNC)) + +#if HAVE_AS_REF +/* Issue assembly directives that create a reference to the given DWARF table + identifier label from the current function section. This is defined to + ensure we drag frame tables associated with needed function bodies in + a link with garbage collection activated. */ +#define ASM_OUTPUT_DWARF_TABLE_REF rs6000_aix_asm_output_dwarf_table_ref +#endif + +/* This is the only version of nm that collect2 can work with. */ +#define REAL_NM_FILE_NAME "/usr/ucb/nm" + +#define USER_LABEL_PREFIX "" + +/* Don't turn -B into -L if the argument specifies a relative file name. */ +#define RELATIVE_PREFIX_NOT_LINKDIR + +/* Because of the above, we must have gcc search itself to find libgcc.a. */ +#define LINK_LIBGCC_SPECIAL_1 + +/* Names to predefine in the preprocessor for this target machine. */ +#define TARGET_OS_AIX_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("_IBMR2"); \ + builtin_define ("_POWER"); \ + builtin_define ("__unix__"); \ + builtin_define ("_AIX"); \ + builtin_define ("_AIX32"); \ + builtin_define ("_AIX41"); \ + builtin_define ("_LONG_LONG"); \ + if (TARGET_LONG_DOUBLE_128) \ + builtin_define ("__LONGDOUBLE128"); \ + builtin_assert ("system=unix"); \ + builtin_assert ("system=aix"); \ + if (TARGET_64BIT) \ + { \ + builtin_define ("__PPC__"); \ + builtin_define ("__PPC64__"); \ + builtin_define ("__powerpc__"); \ + builtin_define ("__powerpc64__"); \ + builtin_assert ("cpu=powerpc64"); \ + builtin_assert ("machine=powerpc64"); \ + } \ + else \ + { \ + builtin_define ("__PPC__"); \ + builtin_define ("__powerpc__"); \ + builtin_assert ("cpu=powerpc"); \ + builtin_assert ("machine=powerpc"); \ + } \ + } \ + while (0) + +/* Define appropriate architecture macros for preprocessor depending on + target switches. */ + +#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\ + %{ansi: -D_ANSI_C_SOURCE}" + +#define CC1_SPEC "%(cc1_cpu)" + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "" + +/* Tell the assembler to assume that all undefined names are external. + + Don't do this until the fixed IBM assembler is more generally available. + When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL, + ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no + longer be needed. Also, the extern declaration of mcount in + rs6000_xcoff_file_start will no longer be needed. */ + +/* #define ASM_SPEC "-u %(asm_cpu)" */ + +/* Default location of syscalls.exp under AIX */ +#define LINK_SYSCALLS_SPEC "-bI:%R/lib/syscalls.exp" + +/* Default location of libg.exp under AIX */ +#define LINK_LIBG_SPEC "-bexport:%R/usr/lib/libg.exp" + +/* Define the options for the binder: Start text at 512, align all segments + to 512 bytes, and warn if there is text relocation. + + The -bhalt:4 option supposedly changes the level at which ld will abort, + but it also suppresses warnings about multiply defined symbols and is + used by the AIX cc command. So we use it here. + + -bnodelcsect undoes a poor choice of default relating to multiply-defined + csects. See AIX documentation for more information about this. + + -bM:SRE tells the linker that the output file is Shared REusable. Note + that to actually build a shared library you will also need to specify an + export list with the -Wl,-bE option. */ + +#define LINK_SPEC "-T512 -H512 %{!r:-btextro} -bhalt:4 -bnodelcsect\ +%{static:-bnso %(link_syscalls) } \ +%{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}" + +/* Profiled library versions are used by linking with special directories. */ +#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ +%{p:-L%R/lib/profiled -L%R/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc" + +/* Static linking with shared libstdc++ requires libsupc++ as well. */ +#define LIBSTDCXX_STATIC "supc++" + +/* This now supports a natural alignment mode. */ +/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */ +#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \ + ((TARGET_ALIGN_NATURAL == 0 \ + && TYPE_MODE (strip_array_types (TYPE)) == DFmode) \ + ? MIN ((COMPUTED), 32) \ + : (COMPUTED)) + +/* AIX increases natural record alignment to doubleword if the first + field is an FP double while the FP fields remain word aligned. */ +#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \ + ((TREE_CODE (STRUCT) == RECORD_TYPE \ + || TREE_CODE (STRUCT) == UNION_TYPE \ + || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \ + && TARGET_ALIGN_NATURAL == 0 \ + ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \ + : MAX ((COMPUTED), (SPECIFIED))) + +/* The AIX ABI isn't explicit on whether aggregates smaller than a + word/doubleword should be padded upward or downward. One could + reasonably assume that they follow the normal rules for structure + layout treating the parameter area as any other block of memory, + then map the reg param area to registers, i.e., pad upward, which + is the way IBM Compilers for AIX behave. + Setting both of the following defines results in this behavior. */ +#define AGGREGATE_PADDING_FIXED 1 +#define AGGREGATES_PAD_UPWARD_ALWAYS 1 + +/* Specify padding for the last element of a block move between + registers and memory. FIRST is nonzero if this is the only + element. */ +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \ + (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE)) + +/* Indicate that jump tables go in the text section. */ + +#define JUMP_TABLES_IN_TEXT_SECTION 1 + +/* Define any extra SPECS that the compiler needs to generate. */ +#undef SUBTARGET_EXTRA_SPECS +#define SUBTARGET_EXTRA_SPECS \ + { "link_syscalls", LINK_SYSCALLS_SPEC }, \ + { "link_libg", LINK_LIBG_SPEC } + +#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL) + +/* No version of AIX fully supports AltiVec or 64-bit instructions in + 32-bit mode. */ +#define OS_MISSING_POWERPC64 1 +#define OS_MISSING_ALTIVEC 1 + +/* WINT_TYPE */ +#define WINT_TYPE "int" + +/* Static stack checking is supported by means of probes. */ +#define STACK_CHECK_STATIC_BUILTIN 1 + +/* Use standard DWARF numbering for DWARF debugging information. */ +#define RS6000_USE_DWARF_NUMBERING + diff --git a/gcc/config/powerpcspe/aix43.h b/gcc/config/powerpcspe/aix43.h new file mode 100644 index 00000000000..d61956d3b28 --- /dev/null +++ b/gcc/config/powerpcspe/aix43.h @@ -0,0 +1,167 @@ +/* Definitions of target machine for GNU compiler, + for IBM RS/6000 POWER running AIX version 4.3. + Copyright (C) 1998-2017 Free Software Foundation, Inc. + Contributed by David Edelsohn (edelsohn@gnu.org). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to + get control in TARGET_OPTION_OVERRIDE. */ + +#define SUBTARGET_OVERRIDE_OPTIONS \ +do { \ + if (TARGET_64BIT && ! TARGET_POWERPC64) \ + { \ + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ + warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ + } \ + if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ + { \ + rs6000_long_double_type_size = 64; \ + if (global_options_set.x_rs6000_long_double_type_size) \ + warning (0, "soft-float and long-double-128 are incompatible"); \ + } \ + if (TARGET_POWERPC64 && ! TARGET_64BIT) \ + { \ + error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ + } \ +} while (0); + +#undef ASM_SPEC +#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" + +/* Common ASM definitions used by ASM_SPEC amongst the various targets + for handling -mcpu=xxx switches. */ +#undef ASM_CPU_SPEC +#define ASM_CPU_SPEC \ +"%{!mcpu*: %{!maix64: \ + %{!mpowerpc64: %(asm_default)} \ + %{mpowerpc64: -mppc64}}} \ +%{mcpu=power3: -m620} \ +%{mcpu=power4: -m620} \ +%{mcpu=powerpc: -mppc} \ +%{mcpu=rs64a: -mppc} \ +%{mcpu=601: -m601} \ +%{mcpu=602: -mppc} \ +%{mcpu=603: -m603} \ +%{mcpu=603e: -m603} \ +%{mcpu=604: -m604} \ +%{mcpu=604e: -m604} \ +%{mcpu=620: -m620} \ +%{mcpu=630: -m620}" + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mppc" + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("_AIX43"); \ + TARGET_OS_AIX_CPP_BUILTINS (); \ + } \ + while (0) + +#undef CPP_SPEC +#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\ + %{ansi: -D_ANSI_C_SOURCE}\ + %{maix64: -D__64BIT__}\ + %{mpe: -I%R/usr/lpp/ppe.poe/include}\ + %{pthread: -D_THREAD_SAFE}" + +/* The GNU C++ standard library requires that these macros be + defined. */ +#undef CPLUSPLUS_CPP_SPEC +#define CPLUSPLUS_CPP_SPEC \ + "-D_ALL_SOURCE \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT 0 + +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_PPC604e + +/* AIX does not support Altivec. */ +#undef TARGET_ALTIVEC +#define TARGET_ALTIVEC 0 +#undef TARGET_ALTIVEC_ABI +#define TARGET_ALTIVEC_ABI 0 +#undef TARGET_EXTRA_BUILTINS +#define TARGET_EXTRA_BUILTINS 0 + + +/* Define this macro as a C expression for the initializer of an + array of string to tell the driver program which options are + defaults for this target and thus do not need to be handled + specially when using `MULTILIB_OPTIONS'. + + Do not define this macro if `MULTILIB_OPTIONS' is not defined in + the target makefile fragment or if none of the options listed in + `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ + +#undef MULTILIB_DEFAULTS +#define MULTILIB_DEFAULTS { "mcpu=common" } + +#undef LIB_SPEC +#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{!maix64:%{!shared:%{g*:-lg}}}\ + %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ + %{pthread:-L%R/usr/lib/threads -lpthreads -lc_r %R/usr/lib/libc.a}\ + %{!pthread:-lc}" + +#undef LINK_SPEC +#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\ + %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ + %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ + %{mpe:-binitfini:poe_remote_main}" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{!shared:\ + %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ + %{!maix64:\ + %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ + %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" + +/* AIX 4.3 typedefs ptrdiff_t as "long" while earlier releases used "int". */ + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" + +/* AIX 4.2 and above provides initialization and finalization function + support from linker command line. */ +#undef HAS_INIT_SECTION +#define HAS_INIT_SECTION + +#undef LD_INIT_SWITCH +#define LD_INIT_SWITCH "-binitfini" + +/* The IBM AIX 4.x assembler doesn't support forward references in + .set directives. We handle this by deferring the output of .set + directives to the end of the compilation unit. */ +#define TARGET_DEFERRED_OUTPUT_DEFS(DECL,TARGET) true + +/* This target uses the aix64.opt file. */ +#define TARGET_USES_AIX64_OPT 1 + +#define TARGET_AIX_VERSION 43 + +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function diff --git a/gcc/config/powerpcspe/aix51.h b/gcc/config/powerpcspe/aix51.h new file mode 100644 index 00000000000..af7e38e1775 --- /dev/null +++ b/gcc/config/powerpcspe/aix51.h @@ -0,0 +1,169 @@ +/* Definitions of target machine for GNU compiler, + for IBM RS/6000 POWER running AIX V5. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by David Edelsohn (edelsohn@gnu.org). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to + get control in TARGET_OPTION_OVERRIDE. */ + +#define SUBTARGET_OVERRIDE_OPTIONS \ +do { \ + if (TARGET_64BIT && ! TARGET_POWERPC64) \ + { \ + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ + warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ + } \ + if (TARGET_POWERPC64 && ! TARGET_64BIT) \ + { \ + error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ + } \ +} while (0); + +#undef ASM_SPEC +#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" + +/* Common ASM definitions used by ASM_SPEC amongst the various targets + for handling -mcpu=xxx switches. */ +#undef ASM_CPU_SPEC +#define ASM_CPU_SPEC \ +"%{!mcpu*: %{!maix64: \ + %{!mpowerpc64: %(asm_default)} \ + %{mpowerpc64: -mppc64}}} \ +%{mcpu=power3: -m620} \ +%{mcpu=power4: -m620} \ +%{mcpu=powerpc: -mppc} \ +%{mcpu=rs64a: -mppc} \ +%{mcpu=601: -m601} \ +%{mcpu=602: -mppc} \ +%{mcpu=603: -m603} \ +%{mcpu=603e: -m603} \ +%{mcpu=604: -m604} \ +%{mcpu=604e: -m604} \ +%{mcpu=620: -m620} \ +%{mcpu=630: -m620} \ +%{mcpu=970: -m620} \ +%{mcpu=G5: -m620}" + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mppc" + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("_AIX43"); \ + builtin_define ("_AIX51"); \ + TARGET_OS_AIX_CPP_BUILTINS (); \ + } \ + while (0) + +#undef CPP_SPEC +#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ + %{ansi: -D_ANSI_C_SOURCE} \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +/* The GNU C++ standard library requires that these macros be + defined. */ +#undef CPLUSPLUS_CPP_SPEC +#define CPLUSPLUS_CPP_SPEC \ + "-D_ALL_SOURCE \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT 0 + +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_PPC604e + +/* AIX does not support Altivec. */ +#undef TARGET_ALTIVEC +#define TARGET_ALTIVEC 0 +#undef TARGET_ALTIVEC_ABI +#define TARGET_ALTIVEC_ABI 0 +#undef TARGET_EXTRA_BUILTINS +#define TARGET_EXTRA_BUILTINS 0 + + +/* Define this macro as a C expression for the initializer of an + array of string to tell the driver program which options are + defaults for this target and thus do not need to be handled + specially when using `MULTILIB_OPTIONS'. + + Do not define this macro if `MULTILIB_OPTIONS' is not defined in + the target makefile fragment or if none of the options listed in + `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ + +#undef MULTILIB_DEFAULTS +#define MULTILIB_DEFAULTS { "mcpu=common" } + +#undef LIB_SPEC +#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{!maix64:%{!shared:%{g*:-lg}}}\ + %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ + %{pthread:-lpthreads} -lc" + +#undef LINK_SPEC +#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro}\ + %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ + %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ + %{mpe:-binitfini:poe_remote_main}" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{!shared:\ + %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ + %{!maix64:\ + %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ + %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" + +/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" + +/* Type used for wchar_t, as a string used in a declaration. */ +#undef WCHAR_TYPE +#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") + +/* Width of wchar_t in bits. */ +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) + +/* AIX 4.2 and above provides initialization and finalization function + support from linker command line. */ +#undef HAS_INIT_SECTION +#define HAS_INIT_SECTION + +#undef LD_INIT_SWITCH +#define LD_INIT_SWITCH "-binitfini" + +/* This target uses the aix64.opt file. */ +#define TARGET_USES_AIX64_OPT 1 + +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_AIX_VERSION 51 + +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function diff --git a/gcc/config/powerpcspe/aix52.h b/gcc/config/powerpcspe/aix52.h new file mode 100644 index 00000000000..35d2286e5b3 --- /dev/null +++ b/gcc/config/powerpcspe/aix52.h @@ -0,0 +1,179 @@ +/* Definitions of target machine for GNU compiler, + for IBM RS/6000 POWER running AIX V5.2. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + Contributed by David Edelsohn (edelsohn@gnu.org). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to + get control in TARGET_OPTION_OVERRIDE. */ + +#define SUBTARGET_OVERRIDE_OPTIONS \ +do { \ + if (TARGET_64BIT && ! TARGET_POWERPC64) \ + { \ + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ + warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ + } \ + if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ + { \ + rs6000_long_double_type_size = 64; \ + if (global_options_set.x_rs6000_long_double_type_size) \ + warning (0, "soft-float and long-double-128 are incompatible"); \ + } \ + if (TARGET_POWERPC64 && ! TARGET_64BIT) \ + { \ + error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ + } \ +} while (0); + +#undef ASM_SPEC +#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" + +/* Common ASM definitions used by ASM_SPEC amongst the various targets + for handling -mcpu=xxx switches. */ +#undef ASM_CPU_SPEC +#define ASM_CPU_SPEC \ +"%{!mcpu*: %{!maix64: \ + %{mpowerpc64: -mppc64} \ + %{!mpowerpc64: %(asm_default)}}} \ +%{mcpu=power3: -m620} \ +%{mcpu=power4: -m620} \ +%{mcpu=power5: -m620} \ +%{mcpu=power5+: -m620} \ +%{mcpu=power6: -m620} \ +%{mcpu=power6x: -m620} \ +%{mcpu=powerpc: -mppc} \ +%{mcpu=rs64a: -mppc} \ +%{mcpu=603: -m603} \ +%{mcpu=603e: -m603} \ +%{mcpu=604: -m604} \ +%{mcpu=604e: -m604} \ +%{mcpu=620: -m620} \ +%{mcpu=630: -m620} \ +%{mcpu=970: -m620} \ +%{mcpu=G5: -m620}" + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mppc" + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("_AIX43"); \ + builtin_define ("_AIX51"); \ + builtin_define ("_AIX52"); \ + TARGET_OS_AIX_CPP_BUILTINS (); \ + } \ + while (0) + +#undef CPP_SPEC +#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ + %{ansi: -D_ANSI_C_SOURCE} \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +/* The GNU C++ standard library requires that these macros be + defined. Synchronize with libstdc++ os_defines.h. */ +#undef CPLUSPLUS_CPP_SPEC +#define CPLUSPLUS_CPP_SPEC \ + "-D_ALL_SOURCE \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT 0 + +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_POWER4 +#undef PROCESSOR_DEFAULT64 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER4 + +/* AIX does not support Altivec. */ +#undef TARGET_ALTIVEC +#define TARGET_ALTIVEC 0 +#undef TARGET_ALTIVEC_ABI +#define TARGET_ALTIVEC_ABI 0 +#undef TARGET_EXTRA_BUILTINS +#define TARGET_EXTRA_BUILTINS 0 + +/* Define this macro as a C expression for the initializer of an + array of string to tell the driver program which options are + defaults for this target and thus do not need to be handled + specially when using `MULTILIB_OPTIONS'. + + Do not define this macro if `MULTILIB_OPTIONS' is not defined in + the target makefile fragment or if none of the options listed in + `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ + +#undef MULTILIB_DEFAULTS + +#undef LIB_SPEC +#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{!maix64:%{!shared:%{g*:-lg}}}\ + %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ + %{pthread:-lpthreads} -lc" + +#undef LINK_SPEC +#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro}\ + %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ + %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ + %{mpe:-binitfini:poe_remote_main}" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{!shared:\ + %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ + %{!maix64:\ + %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ + %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" + +/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" + +/* Type used for wchar_t, as a string used in a declaration. */ +#undef WCHAR_TYPE +#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") + +/* Width of wchar_t in bits. */ +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) + +/* AIX 4.2 and above provides initialization and finalization function + support from linker command line. */ +#undef HAS_INIT_SECTION +#define HAS_INIT_SECTION + +#undef LD_INIT_SWITCH +#define LD_INIT_SWITCH "-binitfini" + +#ifndef _AIX52 +extern long long int atoll(const char *); +#endif + +/* This target uses the aix64.opt file. */ +#define TARGET_USES_AIX64_OPT 1 + +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_AIX_VERSION 52 diff --git a/gcc/config/powerpcspe/aix53.h b/gcc/config/powerpcspe/aix53.h new file mode 100644 index 00000000000..a1fbd834d47 --- /dev/null +++ b/gcc/config/powerpcspe/aix53.h @@ -0,0 +1,180 @@ +/* Definitions of target machine for GNU compiler, + for IBM RS/6000 POWER running AIX V5.3. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + Contributed by David Edelsohn (edelsohn@gnu.org). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to + get control in TARGET_OPTION_OVERRIDE. */ + +#define SUBTARGET_OVERRIDE_OPTIONS \ +do { \ + if (TARGET_64BIT && ! TARGET_POWERPC64) \ + { \ + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ + warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ + } \ + if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ + { \ + rs6000_long_double_type_size = 64; \ + if (global_options_set.x_rs6000_long_double_type_size) \ + warning (0, "soft-float and long-double-128 are incompatible"); \ + } \ + if (TARGET_POWERPC64 && ! TARGET_64BIT) \ + { \ + error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ + } \ +} while (0); + +#undef ASM_SPEC +#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" + +/* Common ASM definitions used by ASM_SPEC amongst 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 there also. */ +#undef ASM_CPU_SPEC +#define ASM_CPU_SPEC \ +"%{!mcpu*: %{!maix64: \ + %{mpowerpc64: -mppc64} \ + %{maltivec: -m970} \ + %{!maltivec: %{!mpowerpc64: %(asm_default)}}}} \ +%{mcpu=native: %(asm_cpu_native)} \ +%{mcpu=power3: -m620} \ +%{mcpu=power4: -mpwr4} \ +%{mcpu=power5: -mpwr5} \ +%{mcpu=power5+: -mpwr5x} \ +%{mcpu=power6: -mpwr6} \ +%{mcpu=power6x: -mpwr6} \ +%{mcpu=power7: -mpwr7} \ +%{mcpu=power8: -mpwr8} \ +%{mcpu=power9: -mpwr9} \ +%{mcpu=powerpc: -mppc} \ +%{mcpu=rs64a: -mppc} \ +%{mcpu=603: -m603} \ +%{mcpu=603e: -m603} \ +%{mcpu=604: -m604} \ +%{mcpu=604e: -m604} \ +%{mcpu=620: -m620} \ +%{mcpu=630: -m620} \ +%{mcpu=970: -m970} \ +%{mcpu=G5: -m970}" + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mppc" + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("_AIX43"); \ + builtin_define ("_AIX51"); \ + builtin_define ("_AIX52"); \ + builtin_define ("_AIX53"); \ + TARGET_OS_AIX_CPP_BUILTINS (); \ + } \ + while (0) + +#undef CPP_SPEC +#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ + %{ansi: -D_ANSI_C_SOURCE} \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +/* The GNU C++ standard library requires that these macros be + defined. Synchronize with libstdc++ os_defines.h. */ +#undef CPLUSPLUS_CPP_SPEC +#define CPLUSPLUS_CPP_SPEC \ + "-D_ALL_SOURCE \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT 0 + +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_POWER5 +#undef PROCESSOR_DEFAULT64 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER5 + +/* Define this macro as a C expression for the initializer of an + array of string to tell the driver program which options are + defaults for this target and thus do not need to be handled + specially when using `MULTILIB_OPTIONS'. + + Do not define this macro if `MULTILIB_OPTIONS' is not defined in + the target makefile fragment or if none of the options listed in + `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ + +#undef MULTILIB_DEFAULTS + +#undef LIB_SPEC +#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{!maix64:%{!shared:%{g*:-lg}}}\ + %{fprofile-arcs|fprofile-generate*|coverage:-lpthreads}\ + %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ + %{pthread:-lpthreads} -lc" + +#undef LINK_SPEC +#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro}\ + %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ + %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ + %{mpe:-binitfini:poe_remote_main}" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{!shared:\ + %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ + %{!maix64:\ + %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ + %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}" + +/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" + +/* Type used for wchar_t, as a string used in a declaration. */ +#undef WCHAR_TYPE +#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") + +/* Width of wchar_t in bits. */ +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) + +/* AIX 4.2 and above provides initialization and finalization function + support from linker command line. */ +#undef HAS_INIT_SECTION +#define HAS_INIT_SECTION + +#undef LD_INIT_SWITCH +#define LD_INIT_SWITCH "-binitfini" + +#ifndef _AIX52 +extern long long int atoll(const char *); +#endif + +/* This target uses the aix64.opt file. */ +#define TARGET_USES_AIX64_OPT 1 + +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_AIX_VERSION 53 diff --git a/gcc/config/powerpcspe/aix61.h b/gcc/config/powerpcspe/aix61.h new file mode 100644 index 00000000000..0b615057087 --- /dev/null +++ b/gcc/config/powerpcspe/aix61.h @@ -0,0 +1,213 @@ +/* Definitions of target machine for GNU compiler, + for IBM RS/6000 POWER running AIX V6.1. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + Contributed by David Edelsohn (edelsohn@gnu.org). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to + get control in TARGET_OPTION_OVERRIDE. */ + +#define SUBTARGET_OVERRIDE_OPTIONS \ +do { \ + if (TARGET_64BIT && ! TARGET_POWERPC64) \ + { \ + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ + warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ + } \ + if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ + { \ + rs6000_long_double_type_size = 64; \ + if (global_options_set.x_rs6000_long_double_type_size) \ + warning (0, "soft-float and long-double-128 are incompatible"); \ + } \ + if (TARGET_POWERPC64 && ! TARGET_64BIT) \ + { \ + error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ + } \ + if ((rs6000_isa_flags_explicit \ + & OPTION_MASK_MINIMAL_TOC) != 0) \ + { \ + if (global_options_set.x_rs6000_current_cmodel \ + && rs6000_current_cmodel != CMODEL_SMALL) \ + error ("-mcmodel incompatible with other toc options"); \ + SET_CMODEL (CMODEL_SMALL); \ + } \ + if (rs6000_current_cmodel != CMODEL_SMALL) \ + { \ + TARGET_NO_FP_IN_TOC = 0; \ + TARGET_NO_SUM_IN_TOC = 0; \ + } \ + if (rs6000_current_cmodel == CMODEL_MEDIUM) \ + { \ + rs6000_current_cmodel = CMODEL_LARGE; \ + } \ +} while (0); + +#undef ASM_SPEC +#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" + +/* Common ASM definitions used by ASM_SPEC amongst 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 there also. */ +#undef ASM_CPU_SPEC +#define ASM_CPU_SPEC \ +"%{!mcpu*: %{!maix64: \ + %{mpowerpc64: -mppc64} \ + %{maltivec: -m970} \ + %{!maltivec: %{!mpowerpc64: %(asm_default)}}}} \ +%{mcpu=native: %(asm_cpu_native)} \ +%{mcpu=power3: -m620} \ +%{mcpu=power4: -mpwr4} \ +%{mcpu=power5: -mpwr5} \ +%{mcpu=power5+: -mpwr5x} \ +%{mcpu=power6: -mpwr6} \ +%{mcpu=power6x: -mpwr6} \ +%{mcpu=power7: -mpwr7} \ +%{mcpu=power8: -mpwr8} \ +%{mcpu=power9: -mpwr9} \ +%{mcpu=powerpc: -mppc} \ +%{mcpu=rs64a: -mppc} \ +%{mcpu=603: -m603} \ +%{mcpu=603e: -m603} \ +%{mcpu=604: -m604} \ +%{mcpu=604e: -m604} \ +%{mcpu=620: -m620} \ +%{mcpu=630: -m620} \ +%{mcpu=970: -m970} \ +%{mcpu=G5: -m970} \ +%{mvsx: %{!mcpu*: -mpwr6}} \ +-many" + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mpwr4" + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("_AIX43"); \ + builtin_define ("_AIX51"); \ + builtin_define ("_AIX52"); \ + builtin_define ("_AIX53"); \ + builtin_define ("_AIX61"); \ + TARGET_OS_AIX_CPP_BUILTINS (); \ + } \ + while (0) + +#undef CPP_SPEC +#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ + %{ansi: -D_ANSI_C_SOURCE} \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +/* The GNU C++ standard library requires that these macros be + defined. Synchronize with libstdc++ os_defines.h. */ +#undef CPLUSPLUS_CPP_SPEC +#define CPLUSPLUS_CPP_SPEC \ + "-D_ALL_SOURCE -D__COMPATMATH__ \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_PPC_GPOPT | MASK_PPC_GFXOPT | MASK_MFCRF) + +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_POWER7 +#undef PROCESSOR_DEFAULT64 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER7 + +/* AIX 6.1 kernel and assembler have necessary support for Altivec and VSX. */ +#undef OS_MISSING_ALTIVEC + +/* Define this macro as a C expression for the initializer of an + array of string to tell the driver program which options are + defaults for this target and thus do not need to be handled + specially when using `MULTILIB_OPTIONS'. + + Do not define this macro if `MULTILIB_OPTIONS' is not defined in + the target makefile fragment or if none of the options listed in + `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ + +#undef MULTILIB_DEFAULTS + +#undef LIB_SPEC +#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{!maix64:%{!shared:%{g*:-lg}}}\ + %{fprofile-arcs|fprofile-generate*|coverage:-lpthreads}\ + %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ + %{pthread:-lpthreads} -lc" + +#undef LINK_SPEC +#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro}\ + %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ + %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ + %{mpe:-binitfini:poe_remote_main}" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{!shared:\ + %{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\ + %{!maix64:\ + %{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\ + %{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}\ + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s" + +/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" + +/* Type used for wchar_t, as a string used in a declaration. */ +#undef WCHAR_TYPE +#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") + +/* Width of wchar_t in bits. */ +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) + +/* AIX 4.2 and above provides initialization and finalization function + support from linker command line. */ +#undef HAS_INIT_SECTION +#define HAS_INIT_SECTION + +#undef LD_INIT_SWITCH +#define LD_INIT_SWITCH "-binitfini" + +#ifndef _AIX52 +extern long long int atoll(const char *); +#endif + +/* This target uses the aix64.opt file. */ +#define TARGET_USES_AIX64_OPT 1 + +/* Large TOC Support */ +#ifdef HAVE_LD_LARGE_TOC +#undef TARGET_CMODEL +#define TARGET_CMODEL rs6000_current_cmodel +#define SET_CMODEL(opt) rs6000_current_cmodel = opt +#else +#define SET_CMODEL(opt) do {} while (0) +#endif + +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_AIX_VERSION 61 diff --git a/gcc/config/powerpcspe/aix64.opt b/gcc/config/powerpcspe/aix64.opt new file mode 100644 index 00000000000..ca8d1da6b0e --- /dev/null +++ b/gcc/config/powerpcspe/aix64.opt @@ -0,0 +1,55 @@ +; Options for the 64-bit flavor of AIX. +; +; Copyright (C) 2005-2017 Free Software Foundation, Inc. +; Contributed by Aldy Hernandez . +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 3, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +; License for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING3. If not see +; . + +maix64 +Target Report RejectNegative Negative(maix32) Mask(64BIT) Var(rs6000_isa_flags) +Compile for 64-bit pointers. + +maix32 +Target Report RejectNegative Negative(maix64) InverseMask(64BIT) Var(rs6000_isa_flags) +Compile for 32-bit pointers. + +mcmodel= +Target RejectNegative Joined Enum(rs6000_cmodel) Var(rs6000_current_cmodel) +Select code model. + +Enum +Name(rs6000_cmodel) Type(enum rs6000_cmodel) +Known code models (for use with the -mcmodel= option): + +EnumValue +Enum(rs6000_cmodel) String(small) Value(CMODEL_SMALL) + +EnumValue +Enum(rs6000_cmodel) String(medium) Value(CMODEL_MEDIUM) + +EnumValue +Enum(rs6000_cmodel) String(large) Value(CMODEL_LARGE) + +mpe +Target Report RejectNegative Var(internal_nothing_1) Save +Support message passing with the Parallel Environment. + +posix +Driver + +pthread +Driver diff --git a/gcc/config/powerpcspe/aix71.h b/gcc/config/powerpcspe/aix71.h new file mode 100644 index 00000000000..4b986d6a818 --- /dev/null +++ b/gcc/config/powerpcspe/aix71.h @@ -0,0 +1,230 @@ +/* Definitions of target machine for GNU compiler, + for IBM RS/6000 POWER running AIX V7.1. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + Contributed by David Edelsohn (edelsohn@gnu.org). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* The macro SUBTARGET_OVERRIDE_OPTIONS is provided for subtargets, to + get control in TARGET_OPTION_OVERRIDE. */ + +#define SUBTARGET_OVERRIDE_OPTIONS \ +do { \ + if (TARGET_64BIT && ! TARGET_POWERPC64) \ + { \ + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ + warning (0, "-maix64 requires PowerPC64 architecture remain enabled"); \ + } \ + if (TARGET_SOFT_FLOAT && TARGET_LONG_DOUBLE_128) \ + { \ + rs6000_long_double_type_size = 64; \ + if (global_options_set.x_rs6000_long_double_type_size) \ + warning (0, "soft-float and long-double-128 are incompatible"); \ + } \ + if (TARGET_POWERPC64 && ! TARGET_64BIT) \ + { \ + error ("-maix64 required: 64-bit computation with 32-bit addressing not yet supported"); \ + } \ + if ((rs6000_isa_flags_explicit \ + & OPTION_MASK_MINIMAL_TOC) != 0) \ + { \ + if (global_options_set.x_rs6000_current_cmodel \ + && rs6000_current_cmodel != CMODEL_SMALL) \ + error ("-mcmodel incompatible with other toc options"); \ + SET_CMODEL (CMODEL_SMALL); \ + } \ + if (rs6000_current_cmodel != CMODEL_SMALL) \ + { \ + TARGET_NO_FP_IN_TOC = 0; \ + TARGET_NO_SUM_IN_TOC = 0; \ + } \ + if (rs6000_current_cmodel == CMODEL_MEDIUM) \ + { \ + rs6000_current_cmodel = CMODEL_LARGE; \ + } \ +} while (0); + +#undef ASM_SPEC +#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)" + +/* Common ASM definitions used by ASM_SPEC amongst 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 there also. */ +#undef ASM_CPU_SPEC +#define ASM_CPU_SPEC \ +"%{!mcpu*: %{!maix64: \ + %{mpowerpc64: -mppc64} \ + %{maltivec: -m970} \ + %{!maltivec: %{!mpowerpc64: %(asm_default)}}}} \ +%{mcpu=native: %(asm_cpu_native)} \ +%{mcpu=power3: -m620} \ +%{mcpu=power4: -mpwr4} \ +%{mcpu=power5: -mpwr5} \ +%{mcpu=power5+: -mpwr5x} \ +%{mcpu=power6: -mpwr6} \ +%{mcpu=power6x: -mpwr6} \ +%{mcpu=power7: -mpwr7} \ +%{mcpu=power8: -mpwr8} \ +%{mcpu=power9: -mpwr9} \ +%{mcpu=powerpc: -mppc} \ +%{mcpu=rs64a: -mppc} \ +%{mcpu=603: -m603} \ +%{mcpu=603e: -m603} \ +%{mcpu=604: -m604} \ +%{mcpu=604e: -m604} \ +%{mcpu=620: -m620} \ +%{mcpu=630: -m620} \ +%{mcpu=970: -m970} \ +%{mcpu=G5: -m970} \ +%{mvsx: %{!mcpu*: -mpwr6}} \ +-many" + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mpwr4" + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("_AIX43"); \ + builtin_define ("_AIX51"); \ + builtin_define ("_AIX52"); \ + builtin_define ("_AIX53"); \ + builtin_define ("_AIX61"); \ + builtin_define ("_AIX71"); \ + TARGET_OS_AIX_CPP_BUILTINS (); \ + } \ + while (0) + +#undef CPP_SPEC +#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \ + %{ansi: -D_ANSI_C_SOURCE} \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +/* The GNU C++ standard library requires that these macros be + defined. Synchronize with libstdc++ os_defines.h. */ +#undef CPLUSPLUS_CPP_SPEC +#define CPLUSPLUS_CPP_SPEC \ + "-D_ALL_SOURCE -D__COMPATMATH__ \ + %{maix64: -D__64BIT__} \ + %{mpe: -I%R/usr/lpp/ppe.poe/include} \ + %{pthread: -D_THREAD_SAFE}" + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_PPC_GPOPT | MASK_PPC_GFXOPT | MASK_MFCRF) + +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_POWER7 +#undef PROCESSOR_DEFAULT64 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER7 + +/* AIX 7.1 kernel and assembler have necessary support for Altivec and VSX. */ +#undef OS_MISSING_ALTIVEC + +/* Define this macro as a C expression for the initializer of an + array of string to tell the driver program which options are + defaults for this target and thus do not need to be handled + specially when using `MULTILIB_OPTIONS'. + + Do not define this macro if `MULTILIB_OPTIONS' is not defined in + the target makefile fragment or if none of the options listed in + `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */ + +#undef MULTILIB_DEFAULTS + +#undef LIB_SPEC +#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\ + %{!maix64:%{!shared:%{g*:-lg}}}\ + %{fprofile-arcs|fprofile-generate*|coverage:-lpthreads}\ + %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\ + %{pthread:-lpthreads} -lc" + +#undef LINK_SPEC +#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro}\ + %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ + %{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\ + %{mpe:-binitfini:poe_remote_main}" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{!shared:\ + %{maix64:%{pg:gcrt0_64%O%s;:%{p:mcrt0_64%O%s;:crt0_64%O%s}};:\ + %{pthread:%{pg:gcrt0_r%O%s;:%{p:mcrt0_r%O%s;:crt0_r%O%s}};:\ + %{pg:gcrt0%O%s;:%{p:mcrt0%O%s;:crt0%O%s}}}}}\ + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s" + +/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */ + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" + +/* Type used for wchar_t, as a string used in a declaration. */ +#undef WCHAR_TYPE +#define WCHAR_TYPE (!TARGET_64BIT ? "short unsigned int" : "unsigned int") + +/* Width of wchar_t in bits. */ +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE (!TARGET_64BIT ? 16 : 32) + +/* AIX 4.2 and above provides initialization and finalization function + support from linker command line. */ +#undef HAS_INIT_SECTION +#define HAS_INIT_SECTION + +#undef LD_INIT_SWITCH +#define LD_INIT_SWITCH "-binitfini" + +#ifndef _AIX52 +extern long long int atoll(const char *); +#endif + +/* This target uses the aix64.opt file. */ +#define TARGET_USES_AIX64_OPT 1 + +/* Large TOC Support */ +#ifdef HAVE_LD_LARGE_TOC +#undef TARGET_CMODEL +#define TARGET_CMODEL rs6000_current_cmodel +#define SET_CMODEL(opt) rs6000_current_cmodel = opt +#else +#define SET_CMODEL(opt) do {} while (0) +#endif + +/* This target defines SUPPORTS_WEAK and TARGET_ASM_NAMED_SECTION, + but does not have crtbegin/end. */ + +#define TARGET_AIX_VERSION 71 + +/* AIX 7.1 supports DWARF3 debugging, but XCOFF remains the default. */ +#define DWARF2_DEBUGGING_INFO 1 +#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG +#define DEBUG_INFO_SECTION "0x10000" +#define DEBUG_LINE_SECTION "0x20000" +#define DEBUG_PUBNAMES_SECTION "0x30000" +#define DEBUG_PUBTYPES_SECTION "0x40000" +#define DEBUG_ARANGES_SECTION "0x50000" +#define DEBUG_ABBREV_SECTION "0x60000" +#define DEBUG_STR_SECTION "0x70000" +#define DEBUG_RANGES_SECTION "0x80000" +#define DEBUG_LOC_SECTION "0x90000" +#define DEBUG_FRAME_SECTION "0xA0000" +#define DEBUG_MACINFO_SECTION "0xB0000" +#define DEBUG_MACRO_SECTION "0xB0000" + diff --git a/gcc/config/powerpcspe/altivec.h b/gcc/config/powerpcspe/altivec.h new file mode 100644 index 00000000000..c92bccef150 --- /dev/null +++ b/gcc/config/powerpcspe/altivec.h @@ -0,0 +1,648 @@ +/* PowerPC AltiVec include file. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + Contributed by Aldy Hernandez (aldyh@redhat.com). + Rewritten by Paolo Bonzini (bonzini@gnu.org). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* Implemented to conform to the specification included in the AltiVec + Technology Programming Interface Manual (ALTIVECPIM/D 6/1999 Rev 0). */ + +#ifndef _ALTIVEC_H +#define _ALTIVEC_H 1 + +#if !defined(__VEC__) || !defined(__ALTIVEC__) +#error Use the "-maltivec" flag to enable PowerPC AltiVec support +#endif + +/* If __APPLE_ALTIVEC__ is defined, the compiler supports 'vector', + 'pixel' and 'bool' as context-sensitive AltiVec keywords (in + non-AltiVec contexts, they revert to their original meanings, + if any), so we do not need to define them as macros. */ + +#if !defined(__APPLE_ALTIVEC__) +/* You are allowed to undef these for C++ compatibility. */ +#define vector __vector +#define pixel __pixel +#define bool __bool +#endif + +/* Condition register codes for AltiVec predicates. */ + +#define __CR6_EQ 0 +#define __CR6_EQ_REV 1 +#define __CR6_LT 2 +#define __CR6_LT_REV 3 + +/* Synonyms. */ +#define vec_vaddcuw vec_addc +#define vec_vand vec_and +#define vec_vandc vec_andc +#define vec_vrfip vec_ceil +#define vec_vcmpbfp vec_cmpb +#define vec_vcmpgefp vec_cmpge +#define vec_vctsxs vec_cts +#define vec_vctuxs vec_ctu +#define vec_vexptefp vec_expte +#define vec_vrfim vec_floor +#define vec_lvx vec_ld +#define vec_lvxl vec_ldl +#define vec_vlogefp vec_loge +#define vec_vmaddfp vec_madd +#define vec_vmhaddshs vec_madds +#define vec_vmladduhm vec_mladd +#define vec_vmhraddshs vec_mradds +#define vec_vnmsubfp vec_nmsub +#define vec_vnor vec_nor +#define vec_vor vec_or +#define vec_vpkpx vec_packpx +#define vec_vperm vec_perm +#define vec_vrefp vec_re +#define vec_vrfin vec_round +#define vec_vrsqrtefp vec_rsqrte +#define vec_vsel vec_sel +#define vec_vsldoi vec_sld +#define vec_vsl vec_sll +#define vec_vslo vec_slo +#define vec_vspltisb vec_splat_s8 +#define vec_vspltish vec_splat_s16 +#define vec_vspltisw vec_splat_s32 +#define vec_vsr vec_srl +#define vec_vsro vec_sro +#define vec_stvx vec_st +#define vec_stvxl vec_stl +#define vec_vsubcuw vec_subc +#define vec_vsum2sws vec_sum2s +#define vec_vsumsws vec_sums +#define vec_vrfiz vec_trunc +#define vec_vxor vec_xor + +/* Functions that are resolved by the backend to one of the + typed builtins. */ +#define vec_vaddfp __builtin_vec_vaddfp +#define vec_addc __builtin_vec_addc +#define vec_adde __builtin_vec_adde +#define vec_addec __builtin_vec_addec +#define vec_vaddsws __builtin_vec_vaddsws +#define vec_vaddshs __builtin_vec_vaddshs +#define vec_vaddsbs __builtin_vec_vaddsbs +#define vec_vavgsw __builtin_vec_vavgsw +#define vec_vavguw __builtin_vec_vavguw +#define vec_vavgsh __builtin_vec_vavgsh +#define vec_vavguh __builtin_vec_vavguh +#define vec_vavgsb __builtin_vec_vavgsb +#define vec_vavgub __builtin_vec_vavgub +#define vec_ceil __builtin_vec_ceil +#define vec_cmpb __builtin_vec_cmpb +#define vec_vcmpeqfp __builtin_vec_vcmpeqfp +#define vec_cmpge __builtin_vec_cmpge +#define vec_vcmpgtfp __builtin_vec_vcmpgtfp +#define vec_vcmpgtsw __builtin_vec_vcmpgtsw +#define vec_vcmpgtuw __builtin_vec_vcmpgtuw +#define vec_vcmpgtsh __builtin_vec_vcmpgtsh +#define vec_vcmpgtuh __builtin_vec_vcmpgtuh +#define vec_vcmpgtsb __builtin_vec_vcmpgtsb +#define vec_vcmpgtub __builtin_vec_vcmpgtub +#define vec_vcfsx __builtin_vec_vcfsx +#define vec_vcfux __builtin_vec_vcfux +#define vec_cts __builtin_vec_cts +#define vec_ctu __builtin_vec_ctu +#define vec_cpsgn __builtin_vec_copysign +#define vec_double __builtin_vec_double +#define vec_expte __builtin_vec_expte +#define vec_floor __builtin_vec_floor +#define vec_loge __builtin_vec_loge +#define vec_madd __builtin_vec_madd +#define vec_madds __builtin_vec_madds +#define vec_mtvscr __builtin_vec_mtvscr +#define vec_vmaxfp __builtin_vec_vmaxfp +#define vec_vmaxsw __builtin_vec_vmaxsw +#define vec_vmaxsh __builtin_vec_vmaxsh +#define vec_vmaxsb __builtin_vec_vmaxsb +#define vec_vminfp __builtin_vec_vminfp +#define vec_vminsw __builtin_vec_vminsw +#define vec_vminsh __builtin_vec_vminsh +#define vec_vminsb __builtin_vec_vminsb +#define vec_mradds __builtin_vec_mradds +#define vec_vmsumshm __builtin_vec_vmsumshm +#define vec_vmsumuhm __builtin_vec_vmsumuhm +#define vec_vmsummbm __builtin_vec_vmsummbm +#define vec_vmsumubm __builtin_vec_vmsumubm +#define vec_vmsumshs __builtin_vec_vmsumshs +#define vec_vmsumuhs __builtin_vec_vmsumuhs +#define vec_vmulesb __builtin_vec_vmulesb +#define vec_vmulesh __builtin_vec_vmulesh +#define vec_vmuleuh __builtin_vec_vmuleuh +#define vec_vmuleub __builtin_vec_vmuleub +#define vec_vmulosh __builtin_vec_vmulosh +#define vec_vmulouh __builtin_vec_vmulouh +#define vec_vmulosb __builtin_vec_vmulosb +#define vec_vmuloub __builtin_vec_vmuloub +#define vec_nmsub __builtin_vec_nmsub +#define vec_packpx __builtin_vec_packpx +#define vec_vpkswss __builtin_vec_vpkswss +#define vec_vpkuwus __builtin_vec_vpkuwus +#define vec_vpkshss __builtin_vec_vpkshss +#define vec_vpkuhus __builtin_vec_vpkuhus +#define vec_vpkswus __builtin_vec_vpkswus +#define vec_vpkshus __builtin_vec_vpkshus +#define vec_re __builtin_vec_re +#define vec_round __builtin_vec_round +#define vec_recipdiv __builtin_vec_recipdiv +#define vec_rlmi __builtin_vec_rlmi +#define vec_vrlnm __builtin_vec_rlnm +#define vec_rlnm(a,b,c) (__builtin_vec_rlnm((a),((b)<<8)|(c))) +#define vec_rsqrt __builtin_vec_rsqrt +#define vec_rsqrte __builtin_vec_rsqrte +#define vec_vsubfp __builtin_vec_vsubfp +#define vec_subc __builtin_vec_subc +#define vec_vsubsws __builtin_vec_vsubsws +#define vec_vsubshs __builtin_vec_vsubshs +#define vec_vsubsbs __builtin_vec_vsubsbs +#define vec_sum4s __builtin_vec_sum4s +#define vec_vsum4shs __builtin_vec_vsum4shs +#define vec_vsum4sbs __builtin_vec_vsum4sbs +#define vec_vsum4ubs __builtin_vec_vsum4ubs +#define vec_sum2s __builtin_vec_sum2s +#define vec_sums __builtin_vec_sums +#define vec_trunc __builtin_vec_trunc +#define vec_vupkhpx __builtin_vec_vupkhpx +#define vec_vupkhsh __builtin_vec_vupkhsh +#define vec_vupkhsb __builtin_vec_vupkhsb +#define vec_vupklpx __builtin_vec_vupklpx +#define vec_vupklsh __builtin_vec_vupklsh +#define vec_vupklsb __builtin_vec_vupklsb +#define vec_abs __builtin_vec_abs +#define vec_nabs __builtin_vec_nabs +#define vec_abss __builtin_vec_abss +#define vec_add __builtin_vec_add +#define vec_adds __builtin_vec_adds +#define vec_and __builtin_vec_and +#define vec_andc __builtin_vec_andc +#define vec_avg __builtin_vec_avg +#define vec_cmpeq __builtin_vec_cmpeq +#define vec_cmpne __builtin_vec_cmpne +#define vec_cmpgt __builtin_vec_cmpgt +#define vec_ctf __builtin_vec_ctf +#define vec_dst __builtin_vec_dst +#define vec_dstst __builtin_vec_dstst +#define vec_dststt __builtin_vec_dststt +#define vec_dstt __builtin_vec_dstt +#define vec_ld __builtin_vec_ld +#define vec_lde __builtin_vec_lde +#define vec_ldl __builtin_vec_ldl +#define vec_lvebx __builtin_vec_lvebx +#define vec_lvehx __builtin_vec_lvehx +#define vec_lvewx __builtin_vec_lvewx +#define vec_neg __builtin_vec_neg +#define vec_pmsum_be __builtin_vec_vpmsum +#define vec_shasigma_be __builtin_crypto_vshasigma +/* Cell only intrinsics. */ +#ifdef __PPU__ +#define vec_lvlx __builtin_vec_lvlx +#define vec_lvlxl __builtin_vec_lvlxl +#define vec_lvrx __builtin_vec_lvrx +#define vec_lvrxl __builtin_vec_lvrxl +#endif +#define vec_lvsl __builtin_vec_lvsl +#define vec_lvsr __builtin_vec_lvsr +#define vec_max __builtin_vec_max +#define vec_mergee __builtin_vec_vmrgew +#define vec_mergeh __builtin_vec_mergeh +#define vec_mergel __builtin_vec_mergel +#define vec_mergeo __builtin_vec_vmrgow +#define vec_min __builtin_vec_min +#define vec_mladd __builtin_vec_mladd +#define vec_msum __builtin_vec_msum +#define vec_msums __builtin_vec_msums +#define vec_mul __builtin_vec_mul +#define vec_mule __builtin_vec_mule +#define vec_mulo __builtin_vec_mulo +#define vec_nor __builtin_vec_nor +#define vec_or __builtin_vec_or +#define vec_pack __builtin_vec_pack +#define vec_packs __builtin_vec_packs +#define vec_packsu __builtin_vec_packsu +#define vec_perm __builtin_vec_perm +#define vec_rl __builtin_vec_rl +#define vec_sel __builtin_vec_sel +#define vec_sl __builtin_vec_sl +#define vec_sld __builtin_vec_sld +#define vec_sldw __builtin_vsx_xxsldwi +#define vec_sll __builtin_vec_sll +#define vec_slo __builtin_vec_slo +#define vec_splat __builtin_vec_splat +#define vec_sr __builtin_vec_sr +#define vec_sra __builtin_vec_sra +#define vec_srl __builtin_vec_srl +#define vec_sro __builtin_vec_sro +#define vec_st __builtin_vec_st +#define vec_ste __builtin_vec_ste +#define vec_stl __builtin_vec_stl +#define vec_stvebx __builtin_vec_stvebx +#define vec_stvehx __builtin_vec_stvehx +#define vec_stvewx __builtin_vec_stvewx +/* Cell only intrinsics. */ +#ifdef __PPU__ +#define vec_stvlx __builtin_vec_stvlx +#define vec_stvlxl __builtin_vec_stvlxl +#define vec_stvrx __builtin_vec_stvrx +#define vec_stvrxl __builtin_vec_stvrxl +#endif +#define vec_sub __builtin_vec_sub +#define vec_subs __builtin_vec_subs +#define vec_sum __builtin_vec_sum +#define vec_unpackh __builtin_vec_unpackh +#define vec_unpackl __builtin_vec_unpackl +#define vec_vaddubm __builtin_vec_vaddubm +#define vec_vaddubs __builtin_vec_vaddubs +#define vec_vadduhm __builtin_vec_vadduhm +#define vec_vadduhs __builtin_vec_vadduhs +#define vec_vadduwm __builtin_vec_vadduwm +#define vec_vadduws __builtin_vec_vadduws +#define vec_vcmpequb __builtin_vec_vcmpequb +#define vec_vcmpequh __builtin_vec_vcmpequh +#define vec_vcmpequw __builtin_vec_vcmpequw +#define vec_vmaxub __builtin_vec_vmaxub +#define vec_vmaxuh __builtin_vec_vmaxuh +#define vec_vmaxuw __builtin_vec_vmaxuw +#define vec_vminub __builtin_vec_vminub +#define vec_vminuh __builtin_vec_vminuh +#define vec_vminuw __builtin_vec_vminuw +#define vec_vmrghb __builtin_vec_vmrghb +#define vec_vmrghh __builtin_vec_vmrghh +#define vec_vmrghw __builtin_vec_vmrghw +#define vec_vmrglb __builtin_vec_vmrglb +#define vec_vmrglh __builtin_vec_vmrglh +#define vec_vmrglw __builtin_vec_vmrglw +#define vec_vpkuhum __builtin_vec_vpkuhum +#define vec_vpkuwum __builtin_vec_vpkuwum +#define vec_vrlb __builtin_vec_vrlb +#define vec_vrlh __builtin_vec_vrlh +#define vec_vrlw __builtin_vec_vrlw +#define vec_vslb __builtin_vec_vslb +#define vec_vslh __builtin_vec_vslh +#define vec_vslw __builtin_vec_vslw +#define vec_vspltb __builtin_vec_vspltb +#define vec_vsplth __builtin_vec_vsplth +#define vec_vspltw __builtin_vec_vspltw +#define vec_vsrab __builtin_vec_vsrab +#define vec_vsrah __builtin_vec_vsrah +#define vec_vsraw __builtin_vec_vsraw +#define vec_vsrb __builtin_vec_vsrb +#define vec_vsrh __builtin_vec_vsrh +#define vec_vsrw __builtin_vec_vsrw +#define vec_vsububs __builtin_vec_vsububs +#define vec_vsububm __builtin_vec_vsububm +#define vec_vsubuhm __builtin_vec_vsubuhm +#define vec_vsubuhs __builtin_vec_vsubuhs +#define vec_vsubuwm __builtin_vec_vsubuwm +#define vec_vsubuws __builtin_vec_vsubuws +#define vec_xor __builtin_vec_xor + +#define vec_extract __builtin_vec_extract +#define vec_insert __builtin_vec_insert +#define vec_splats __builtin_vec_splats +#define vec_promote __builtin_vec_promote + +#ifdef __VSX__ +/* VSX additions */ +#define vec_div __builtin_vec_div +#define vec_mul __builtin_vec_mul +#define vec_msub __builtin_vec_msub +#define vec_nmadd __builtin_vec_nmadd +#define vec_nearbyint __builtin_vec_nearbyint +#define vec_rint __builtin_vec_rint +#define vec_sqrt __builtin_vec_sqrt +#define vec_vsx_ld __builtin_vec_vsx_ld +#define vec_vsx_st __builtin_vec_vsx_st +#define vec_xl __builtin_vec_vsx_ld +#define vec_xst __builtin_vec_vsx_st + +/* Note, xxsldi and xxpermdi were added as __builtin_vsx_ functions + instead of __builtin_vec_ */ +#define vec_xxsldwi __builtin_vsx_xxsldwi +#define vec_xxpermdi __builtin_vsx_xxpermdi +#endif + +#ifdef _ARCH_PWR8 +/* Vector additions added in ISA 2.07. */ +#define vec_eqv __builtin_vec_eqv +#define vec_nand __builtin_vec_nand +#define vec_orc __builtin_vec_orc +#define vec_vaddcuq __builtin_vec_vaddcuq +#define vec_vaddudm __builtin_vec_vaddudm +#define vec_vadduqm __builtin_vec_vadduqm +#define vec_vbpermq __builtin_vec_vbpermq +#define vec_bperm __builtin_vec_vbperm_api +#define vec_vclz __builtin_vec_vclz +#define vec_cntlz __builtin_vec_vclz +#define vec_vclzb __builtin_vec_vclzb +#define vec_vclzd __builtin_vec_vclzd +#define vec_vclzh __builtin_vec_vclzh +#define vec_vclzw __builtin_vec_vclzw +#define vec_vaddecuq __builtin_vec_vaddecuq +#define vec_vaddeuqm __builtin_vec_vaddeuqm +#define vec_vsubecuq __builtin_vec_vsubecuq +#define vec_vsubeuqm __builtin_vec_vsubeuqm +#define vec_vgbbd __builtin_vec_vgbbd +#define vec_gb __builtin_vec_vgbbd +#define vec_vmaxsd __builtin_vec_vmaxsd +#define vec_vmaxud __builtin_vec_vmaxud +#define vec_vminsd __builtin_vec_vminsd +#define vec_vminud __builtin_vec_vminud +#define vec_vmrgew __builtin_vec_vmrgew +#define vec_vmrgow __builtin_vec_vmrgow +#define vec_vpksdss __builtin_vec_vpksdss +#define vec_vpksdus __builtin_vec_vpksdus +#define vec_vpkudum __builtin_vec_vpkudum +#define vec_vpkudus __builtin_vec_vpkudus +#define vec_vpopcnt __builtin_vec_vpopcnt +#define vec_vpopcntb __builtin_vec_vpopcntb +#define vec_vpopcntd __builtin_vec_vpopcntd +#define vec_vpopcnth __builtin_vec_vpopcnth +#define vec_vpopcntw __builtin_vec_vpopcntw +#define vec_popcnt __builtin_vec_vpopcntu +#define vec_popcntb __builtin_vec_vpopcntub +#define vec_popcnth __builtin_vec_vpopcntuh +#define vec_popcntw __builtin_vec_vpopcntuw +#define vec_popcntd __builtin_vec_vpopcntud +#define vec_vrld __builtin_vec_vrld +#define vec_vsld __builtin_vec_vsld +#define vec_vsrad __builtin_vec_vsrad +#define vec_vsrd __builtin_vec_vsrd +#define vec_vsubcuq __builtin_vec_vsubcuq +#define vec_vsubudm __builtin_vec_vsubudm +#define vec_vsubuqm __builtin_vec_vsubuqm +#define vec_vupkhsw __builtin_vec_vupkhsw +#define vec_vupklsw __builtin_vec_vupklsw +#endif + +#ifdef __POWER9_VECTOR__ +/* Vector additions added in ISA 3.0. */ +#define vec_vctz __builtin_vec_vctz +#define vec_cnttz __builtin_vec_vctz +#define vec_vctzb __builtin_vec_vctzb +#define vec_vctzd __builtin_vec_vctzd +#define vec_vctzh __builtin_vec_vctzh +#define vec_vctzw __builtin_vec_vctzw +#define vec_vextract4b __builtin_vec_vextract4b +#define vec_vinsert4b __builtin_vec_vinsert4b +#define vec_vprtyb __builtin_vec_vprtyb +#define vec_vprtybd __builtin_vec_vprtybd +#define vec_vprtybw __builtin_vec_vprtybw + +#ifdef _ARCH_PPC64 +#define vec_vprtybq __builtin_vec_vprtybq +#endif + +#define vec_absd __builtin_vec_vadu +#define vec_absdb __builtin_vec_vadub +#define vec_absdh __builtin_vec_vaduh +#define vec_absdw __builtin_vec_vaduw + +#define vec_slv __builtin_vec_vslv +#define vec_srv __builtin_vec_vsrv + +#define vec_extract_exp __builtin_vec_extract_exp +#define vec_extract_sig __builtin_vec_extract_sig +#define vec_insert_exp __builtin_vec_insert_exp +#define vec_test_data_class __builtin_vec_test_data_class + +#define scalar_extract_exp __builtin_vec_scalar_extract_exp +#define scalar_extract_sig __builtin_vec_scalar_extract_sig +#define scalar_insert_exp __builtin_vec_scalar_insert_exp +#define scalar_test_data_class __builtin_vec_scalar_test_data_class +#define scalar_test_neg __builtin_vec_scalar_test_neg + +#define scalar_cmp_exp_gt __builtin_vec_scalar_cmp_exp_gt +#define scalar_cmp_exp_lt __builtin_vec_scalar_cmp_exp_lt +#define scalar_cmp_exp_eq __builtin_vec_scalar_cmp_exp_eq +#define scalar_cmp_exp_unordered __builtin_vec_scalar_cmp_exp_unordered + +#ifdef _ARCH_PPC64 +#define vec_xl_len __builtin_vec_lxvl +#define vec_xst_len __builtin_vec_stxvl +#endif + +#define vec_cmpnez __builtin_vec_vcmpnez + +#define vec_cntlz_lsbb __builtin_vec_vclzlsbb +#define vec_cnttz_lsbb __builtin_vec_vctzlsbb + +#define vec_xlx __builtin_vec_vextulx +#define vec_xrx __builtin_vec_vexturx + +#define vec_revb __builtin_vec_revb +#endif + +/* Predicates. + For C++, we use templates in order to allow non-parenthesized arguments. + For C, instead, we use macros since non-parenthesized arguments were + not allowed even in older GCC implementation of AltiVec. + + In the future, we may add more magic to the back-end, so that no + one- or two-argument macros are used. */ + +#ifdef __cplusplus__ +#define __altivec_unary_pred(NAME, CALL) \ +template int NAME (T a1) { return CALL; } + +#define __altivec_scalar_pred(NAME, CALL) \ +template int NAME (T a1, U a2) { return CALL; } + +/* Given the vec_step of a type, return the corresponding bool type. */ +template class __altivec_bool_ret { }; +template <> class __altivec_bool_ret <4> { + typedef __vector __bool int __ret; +}; +template <> class __altivec_bool_ret <8> { + typedef __vector __bool short __ret; +}; +template <> class __altivec_bool_ret <16> { + typedef __vector __bool char __ret; +}; + +/* Be very liberal in the pairs we accept. Mistakes such as passing + a `vector char' and `vector short' will be caught by the middle-end, + while any attempt to detect them here would produce hard to understand + error messages involving the implementation details of AltiVec. */ +#define __altivec_binary_pred(NAME, CALL) \ +template \ +typename __altivec_bool_ret ::__ret \ +NAME (T a1, U a2) \ +{ \ + return CALL; \ +} + +__altivec_binary_pred(vec_cmplt, + __builtin_vec_cmpgt (a2, a1)) +__altivec_binary_pred(vec_cmple, + __builtin_vec_cmpge (a2, a1)) + +__altivec_scalar_pred(vec_all_in, + __builtin_altivec_vcmpbfp_p (__CR6_EQ, a1, a2)) +__altivec_scalar_pred(vec_any_out, + __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, a1, a2)) + +__altivec_unary_pred(vec_all_nan, + __builtin_altivec_vcmpeq_p (__CR6_EQ, a1, a1)) +__altivec_unary_pred(vec_any_nan, + __builtin_altivec_vcmpeq_p (__CR6_LT_REV, a1, a1)) + +__altivec_unary_pred(vec_all_numeric, + __builtin_altivec_vcmpeq_p (__CR6_LT, a1, a1)) +__altivec_unary_pred(vec_any_numeric, + __builtin_altivec_vcmpeq_p (__CR6_EQ_REV, a1, a1)) + +__altivec_scalar_pred(vec_all_eq, + __builtin_vec_vcmpeq_p (__CR6_LT, a1, a2)) + +#ifndef __POWER9_VECTOR__ +__altivec_scalar_pred(vec_all_ne, + __builtin_vec_vcmpeq_p (__CR6_EQ, a1, a2)) +__altivec_scalar_pred(vec_any_eq, + __builtin_vec_vcmpeq_p (__CR6_EQ_REV, a1, a2)) +#else +__altivec_scalar_pred(vec_all_nez, + __builtin_vec_vcmpnez_p (__CR6_LT, a1, a2)) +__altivec_scalar_pred(vec_any_eqz, + __builtin_vec_vcmpnez_p (__CR6_LT_REV, a1, a2)) +__altivec_scalar_pred(vec_all_ne, + __builtin_vec_vcmpne_p (a1, a2)) +__altivec_scalar_pred(vec_any_eq, + __builtin_vec_vcmpae_p (a1, a2)) +#endif + +__altivec_scalar_pred(vec_any_ne, + __builtin_vec_vcmpeq_p (__CR6_LT_REV, a1, a2)) + +__altivec_scalar_pred(vec_all_gt, + __builtin_vec_vcmpgt_p (__CR6_LT, a1, a2)) +__altivec_scalar_pred(vec_all_lt, + __builtin_vec_vcmpgt_p (__CR6_LT, a2, a1)) +__altivec_scalar_pred(vec_any_gt, + __builtin_vec_vcmpgt_p (__CR6_EQ_REV, a1, a2)) +__altivec_scalar_pred(vec_any_lt, + __builtin_vec_vcmpgt_p (__CR6_EQ_REV, a2, a1)) + +__altivec_scalar_pred(vec_all_ngt, + __builtin_altivec_vcmpgt_p (__CR6_EQ, a1, a2)) +__altivec_scalar_pred(vec_all_nlt, + __builtin_altivec_vcmpgt_p (__CR6_EQ, a2, a1)) +__altivec_scalar_pred(vec_any_ngt, + __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a1, a2)) +__altivec_scalar_pred(vec_any_nlt, + __builtin_altivec_vcmpgt_p (__CR6_LT_REV, a2, a1)) + +/* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, + while for integer types it is converted to __builtin_vec_vcmpgt_p, + with inverted args and condition code. */ +__altivec_scalar_pred(vec_all_le, + __builtin_vec_vcmpge_p (__CR6_LT, a2, a1)) +__altivec_scalar_pred(vec_all_ge, + __builtin_vec_vcmpge_p (__CR6_LT, a1, a2)) +__altivec_scalar_pred(vec_any_le, + __builtin_vec_vcmpge_p (__CR6_EQ_REV, a2, a1)) +__altivec_scalar_pred(vec_any_ge, + __builtin_vec_vcmpge_p (__CR6_EQ_REV, a1, a2)) + +__altivec_scalar_pred(vec_all_nge, + __builtin_altivec_vcmpge_p (__CR6_EQ, a1, a2)) +__altivec_scalar_pred(vec_all_nle, + __builtin_altivec_vcmpge_p (__CR6_EQ, a2, a1)) +__altivec_scalar_pred(vec_any_nge, + __builtin_altivec_vcmpge_p (__CR6_LT_REV, a1, a2)) +__altivec_scalar_pred(vec_any_nle, + __builtin_altivec_vcmpge_p (__CR6_LT_REV, a2, a1)) + +#undef __altivec_scalar_pred +#undef __altivec_unary_pred +#undef __altivec_binary_pred +#else +#define vec_cmplt(a1, a2) __builtin_vec_cmpgt ((a2), (a1)) +#define vec_cmple(a1, a2) __builtin_vec_cmpge ((a2), (a1)) + +#define vec_all_in(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ, (a1), (a2)) +#define vec_any_out(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, (a1), (a2)) + +#define vec_all_nan(a1) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a1)) +#define vec_any_nan(a1) __builtin_vec_vcmpeq_p (__CR6_LT_REV, (a1), (a1)) + +#define vec_all_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a1)) +#define vec_any_numeric(a1) __builtin_vec_vcmpeq_p (__CR6_EQ_REV, (a1), (a1)) + +#define vec_all_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT, (a1), (a2)) + +#ifdef __POWER9_VECTOR__ +#define vec_all_nez(a1, a2) __builtin_vec_vcmpnez_p (__CR6_LT, (a1), (a2)) +#define vec_any_eqz(a1, a2) __builtin_vec_vcmpnez_p (__CR6_LT_REV, (a1), (a2)) +#define vec_all_ne(a1, a2) __builtin_vec_vcmpne_p ((a1), (a2)) +#define vec_any_eq(a1, a2) __builtin_vec_vcmpae_p ((a1), (a2)) +#else +#define vec_all_ne(a1, a2) __builtin_vec_vcmpeq_p (__CR6_EQ, (a1), (a2)) +#define vec_any_eq(a1, a2) __builtin_vec_vcmpeq_p (__CR6_EQ_REV, (a1), (a2)) +#endif + +#define vec_any_ne(a1, a2) __builtin_vec_vcmpeq_p (__CR6_LT_REV, (a1), (a2)) + +#define vec_all_gt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT, (a1), (a2)) +#define vec_all_lt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT, (a2), (a1)) +#define vec_any_gt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a1), (a2)) +#define vec_any_lt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ_REV, (a2), (a1)) + +#define vec_all_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a1), (a2)) +#define vec_all_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_EQ, (a2), (a1)) +#define vec_any_ngt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a1), (a2)) +#define vec_any_nlt(a1, a2) __builtin_vec_vcmpgt_p (__CR6_LT_REV, (a2), (a1)) + +/* __builtin_vec_vcmpge_p is vcmpgefp for floating-point vector types, + while for integer types it is converted to __builtin_vec_vcmpgt_p, + with inverted args and condition code. */ +#define vec_all_le(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT, (a2), (a1)) +#define vec_all_ge(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT, (a1), (a2)) +#define vec_any_le(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a2), (a1)) +#define vec_any_ge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ_REV, (a1), (a2)) + +#define vec_all_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a1), (a2)) +#define vec_all_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_EQ, (a2), (a1)) +#define vec_any_nge(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a1), (a2)) +#define vec_any_nle(a1, a2) __builtin_vec_vcmpge_p (__CR6_LT_REV, (a2), (a1)) +#endif + +/* These do not accept vectors, so they do not have a __builtin_vec_* + counterpart. */ +#define vec_dss(x) __builtin_altivec_dss((x)) +#define vec_dssall() __builtin_altivec_dssall () +#define vec_mfvscr() ((__vector unsigned short) __builtin_altivec_mfvscr ()) +#define vec_splat_s8(x) __builtin_altivec_vspltisb ((x)) +#define vec_splat_s16(x) __builtin_altivec_vspltish ((x)) +#define vec_splat_s32(x) __builtin_altivec_vspltisw ((x)) +#define vec_splat_u8(x) ((__vector unsigned char) vec_splat_s8 ((x))) +#define vec_splat_u16(x) ((__vector unsigned short) vec_splat_s16 ((x))) +#define vec_splat_u32(x) ((__vector unsigned int) vec_splat_s32 ((x))) + +/* This also accepts a type for its parameter, so it is not enough + to #define vec_step to __builtin_vec_step. */ +#define vec_step(x) __builtin_vec_step (* (__typeof__ (x) *) 0) + +#endif /* _ALTIVEC_H */ diff --git a/gcc/config/powerpcspe/altivec.md b/gcc/config/powerpcspe/altivec.md new file mode 100644 index 00000000000..649f1810d16 --- /dev/null +++ b/gcc/config/powerpcspe/altivec.md @@ -0,0 +1,4028 @@ +;; AltiVec patterns. +;; Copyright (C) 2002-2017 Free Software Foundation, Inc. +;; Contributed by Aldy Hernandez (aldy@quesejoda.com) + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_c_enum "unspec" + [UNSPEC_VCMPBFP + UNSPEC_VMSUMU + UNSPEC_VMSUMM + UNSPEC_VMSUMSHM + UNSPEC_VMSUMUHS + UNSPEC_VMSUMSHS + UNSPEC_VMHADDSHS + UNSPEC_VMHRADDSHS + UNSPEC_VADDCUW + UNSPEC_VADDU + UNSPEC_VADDS + UNSPEC_VAVGU + UNSPEC_VAVGS + UNSPEC_VMULEUB + UNSPEC_VMULESB + UNSPEC_VMULEUH + UNSPEC_VMULESH + UNSPEC_VMULOUB + UNSPEC_VMULOSB + UNSPEC_VMULOUH + UNSPEC_VMULOSH + UNSPEC_VPKPX + UNSPEC_VPACK_SIGN_SIGN_SAT + UNSPEC_VPACK_SIGN_UNS_SAT + UNSPEC_VPACK_UNS_UNS_SAT + UNSPEC_VPACK_UNS_UNS_MOD + UNSPEC_VPACK_UNS_UNS_MOD_DIRECT + UNSPEC_VSLV4SI + UNSPEC_VSLO + UNSPEC_VSR + UNSPEC_VSRO + UNSPEC_VSUBCUW + UNSPEC_VSUBU + UNSPEC_VSUBS + UNSPEC_VSUM4UBS + UNSPEC_VSUM4S + UNSPEC_VSUM2SWS + UNSPEC_VSUMSWS + UNSPEC_VPERM + UNSPEC_VPERMR + UNSPEC_VPERM_UNS + UNSPEC_VRFIN + UNSPEC_VCFUX + UNSPEC_VCFSX + UNSPEC_VCTUXS + UNSPEC_VCTSXS + UNSPEC_VLOGEFP + UNSPEC_VEXPTEFP + UNSPEC_VSLDOI + UNSPEC_VUNPACK_HI_SIGN + UNSPEC_VUNPACK_LO_SIGN + UNSPEC_VUNPACK_HI_SIGN_DIRECT + UNSPEC_VUNPACK_LO_SIGN_DIRECT + UNSPEC_VUPKHPX + UNSPEC_VUPKLPX + UNSPEC_DARN + UNSPEC_DARN_32 + UNSPEC_DARN_RAW + UNSPEC_DST + UNSPEC_DSTT + UNSPEC_DSTST + UNSPEC_DSTSTT + UNSPEC_LVSL + UNSPEC_LVSR + UNSPEC_LVE + UNSPEC_STVX + UNSPEC_STVXL + UNSPEC_STVE + UNSPEC_SET_VSCR + UNSPEC_GET_VRSAVE + UNSPEC_LVX + UNSPEC_REDUC_PLUS + UNSPEC_VECSH + UNSPEC_EXTEVEN_V4SI + UNSPEC_EXTEVEN_V8HI + UNSPEC_EXTEVEN_V16QI + UNSPEC_EXTEVEN_V4SF + UNSPEC_EXTODD_V4SI + UNSPEC_EXTODD_V8HI + UNSPEC_EXTODD_V16QI + UNSPEC_EXTODD_V4SF + UNSPEC_INTERHI_V4SI + UNSPEC_INTERHI_V8HI + UNSPEC_INTERHI_V16QI + UNSPEC_INTERLO_V4SI + UNSPEC_INTERLO_V8HI + UNSPEC_INTERLO_V16QI + UNSPEC_LVLX + UNSPEC_LVLXL + UNSPEC_LVRX + UNSPEC_LVRXL + UNSPEC_STVLX + UNSPEC_STVLXL + UNSPEC_STVRX + UNSPEC_STVRXL + UNSPEC_VADU + UNSPEC_VSLV + UNSPEC_VSRV + UNSPEC_VMULWHUB + UNSPEC_VMULWLUB + UNSPEC_VMULWHSB + UNSPEC_VMULWLSB + UNSPEC_VMULWHUH + UNSPEC_VMULWLUH + UNSPEC_VMULWHSH + UNSPEC_VMULWLSH + UNSPEC_VUPKHUB + UNSPEC_VUPKHUH + UNSPEC_VUPKLUB + UNSPEC_VUPKLUH + UNSPEC_VPERMSI + UNSPEC_VPERMHI + UNSPEC_INTERHI + UNSPEC_INTERLO + UNSPEC_VUPKHS_V4SF + UNSPEC_VUPKLS_V4SF + UNSPEC_VUPKHU_V4SF + UNSPEC_VUPKLU_V4SF + UNSPEC_VGBBD + UNSPEC_VMRGH_DIRECT + UNSPEC_VMRGL_DIRECT + UNSPEC_VSPLT_DIRECT + UNSPEC_VMRGEW_DIRECT + UNSPEC_VSUMSWS_DIRECT + UNSPEC_VADDCUQ + UNSPEC_VADDEUQM + UNSPEC_VADDECUQ + UNSPEC_VSUBCUQ + UNSPEC_VSUBEUQM + UNSPEC_VSUBECUQ + UNSPEC_VBPERMQ + UNSPEC_VBPERMD + UNSPEC_BCDADD + UNSPEC_BCDSUB + UNSPEC_BCD_OVERFLOW + UNSPEC_CMPRB + UNSPEC_CMPRB2 + UNSPEC_CMPEQB + UNSPEC_VRLMI + UNSPEC_VRLNM +]) + +(define_c_enum "unspecv" + [UNSPECV_SET_VRSAVE + UNSPECV_MTVSCR + UNSPECV_MFVSCR + UNSPECV_DSSALL + UNSPECV_DSS + ]) + +;; Like VI, defined in vector.md, but add ISA 2.07 integer vector ops +(define_mode_iterator VI2 [V4SI V8HI V16QI V2DI]) +;; Short vec int modes +(define_mode_iterator VIshort [V8HI V16QI]) +;; Longer vec int modes for rotate/mask ops +(define_mode_iterator VIlong [V2DI V4SI]) +;; Vec float modes +(define_mode_iterator VF [V4SF]) +;; Vec modes, pity mode iterators are not composable +(define_mode_iterator V [V4SI V8HI V16QI V4SF]) +;; Vec modes for move/logical/permute ops, include vector types for move not +;; otherwise handled by altivec (v2df, v2di, ti) +(define_mode_iterator VM [V4SI + V8HI + V16QI + V4SF + V2DF + V2DI + V1TI + TI + (KF "FLOAT128_VECTOR_P (KFmode)") + (TF "FLOAT128_VECTOR_P (TFmode)")]) + +;; Like VM, except don't do TImode +(define_mode_iterator VM2 [V4SI + V8HI + V16QI + V4SF + V2DF + V2DI + V1TI + (KF "FLOAT128_VECTOR_P (KFmode)") + (TF "FLOAT128_VECTOR_P (TFmode)")]) + +;; Specific iterator for parity which does not have a byte/half-word form, but +;; does have a quad word form +(define_mode_iterator VParity [V4SI + V2DI + V1TI + (TI "TARGET_VSX_TIMODE")]) + +(define_mode_attr VI_char [(V2DI "d") (V4SI "w") (V8HI "h") (V16QI "b")]) +(define_mode_attr VI_scalar [(V2DI "DI") (V4SI "SI") (V8HI "HI") (V16QI "QI")]) +(define_mode_attr VI_unit [(V16QI "VECTOR_UNIT_ALTIVEC_P (V16QImode)") + (V8HI "VECTOR_UNIT_ALTIVEC_P (V8HImode)") + (V4SI "VECTOR_UNIT_ALTIVEC_P (V4SImode)") + (V2DI "VECTOR_UNIT_P8_VECTOR_P (V2DImode)") + (V1TI "VECTOR_UNIT_ALTIVEC_P (V1TImode)")]) + +;; Vector pack/unpack +(define_mode_iterator VP [V2DI V4SI V8HI]) +(define_mode_attr VP_small [(V2DI "V4SI") (V4SI "V8HI") (V8HI "V16QI")]) +(define_mode_attr VP_small_lc [(V2DI "v4si") (V4SI "v8hi") (V8HI "v16qi")]) +(define_mode_attr VU_char [(V2DI "w") (V4SI "h") (V8HI "b")]) + +;; Vector negate +(define_mode_iterator VNEG [V4SI V2DI]) + +;; Vector move instructions. +(define_insn "*altivec_mov" + [(set (match_operand:VM2 0 "nonimmediate_operand" "=Z,v,v,?Y,?*r,?*r,v,v,?*r") + (match_operand:VM2 1 "input_operand" "v,Z,v,*r,Y,*r,j,W,W"))] + "VECTOR_MEM_ALTIVEC_P (mode) + && (register_operand (operands[0], mode) + || register_operand (operands[1], mode))" +{ + switch (which_alternative) + { + case 0: return "stvx %1,%y0"; + case 1: return "lvx %0,%y1"; + case 2: return "vor %0,%1,%1"; + case 3: return "#"; + case 4: return "#"; + case 5: return "#"; + case 6: return "vxor %0,%0,%0"; + case 7: return output_vec_const_move (operands); + case 8: return "#"; + default: gcc_unreachable (); + } +} + [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*,*") + (set_attr "length" "4,4,4,20,20,20,4,8,32")]) + +;; Unlike other altivec moves, allow the GPRs, since a normal use of TImode +;; is for unions. However for plain data movement, slightly favor the vector +;; loads +(define_insn "*altivec_movti" + [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,v,v,?Y,?r,?r,v,v") + (match_operand:TI 1 "input_operand" "v,Z,v,r,Y,r,j,W"))] + "VECTOR_MEM_ALTIVEC_P (TImode) + && (register_operand (operands[0], TImode) + || register_operand (operands[1], TImode))" +{ + switch (which_alternative) + { + case 0: return "stvx %1,%y0"; + case 1: return "lvx %0,%y1"; + case 2: return "vor %0,%1,%1"; + case 3: return "#"; + case 4: return "#"; + case 5: return "#"; + case 6: return "vxor %0,%0,%0"; + case 7: return output_vec_const_move (operands); + default: gcc_unreachable (); + } +} + [(set_attr "type" "vecstore,vecload,veclogical,store,load,*,veclogical,*")]) + +;; Load up a vector with the most significant bit set by loading up -1 and +;; doing a shift left +(define_split + [(set (match_operand:VM 0 "altivec_register_operand" "") + (match_operand:VM 1 "easy_vector_constant_msb" ""))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode) && reload_completed" + [(const_int 0)] +{ + rtx dest = operands[0]; + machine_mode mode = GET_MODE (operands[0]); + rtvec v; + int i, num_elements; + + if (mode == V4SFmode) + { + mode = V4SImode; + dest = gen_lowpart (V4SImode, dest); + } + + num_elements = GET_MODE_NUNITS (mode); + v = rtvec_alloc (num_elements); + for (i = 0; i < num_elements; i++) + RTVEC_ELT (v, i) = constm1_rtx; + + emit_insn (gen_vec_initv4si (dest, gen_rtx_PARALLEL (mode, v))); + emit_insn (gen_rtx_SET (dest, gen_rtx_ASHIFT (mode, dest, dest))); + DONE; +}) + +(define_split + [(set (match_operand:VM 0 "altivec_register_operand" "") + (match_operand:VM 1 "easy_vector_constant_add_self" ""))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode) && reload_completed" + [(set (match_dup 0) (match_dup 3)) + (set (match_dup 0) (match_dup 4))] +{ + rtx dup = gen_easy_altivec_constant (operands[1]); + rtx const_vec; + machine_mode op_mode = mode; + + /* Divide the operand of the resulting VEC_DUPLICATE, and use + simplify_rtx to make a CONST_VECTOR. */ + XEXP (dup, 0) = simplify_const_binary_operation (ASHIFTRT, QImode, + XEXP (dup, 0), const1_rtx); + const_vec = simplify_rtx (dup); + + if (op_mode == V4SFmode) + { + op_mode = V4SImode; + operands[0] = gen_lowpart (op_mode, operands[0]); + } + if (GET_MODE (const_vec) == op_mode) + operands[3] = const_vec; + else + operands[3] = gen_lowpart (op_mode, const_vec); + operands[4] = gen_rtx_PLUS (op_mode, operands[0], operands[0]); +}) + +(define_split + [(set (match_operand:VM 0 "altivec_register_operand" "") + (match_operand:VM 1 "easy_vector_constant_vsldoi" ""))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode) && can_create_pseudo_p ()" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 4) (match_dup 5)) + (set (match_dup 0) + (unspec:VM [(match_dup 2) + (match_dup 4) + (match_dup 6)] + UNSPEC_VSLDOI))] +{ + rtx op1 = operands[1]; + int elt = (BYTES_BIG_ENDIAN) ? 0 : GET_MODE_NUNITS (mode) - 1; + HOST_WIDE_INT val = const_vector_elt_as_int (op1, elt); + rtx rtx_val = GEN_INT (val); + int shift = vspltis_shifted (op1); + int nunits = GET_MODE_NUNITS (mode); + int i; + + gcc_assert (shift != 0); + operands[2] = gen_reg_rtx (mode); + operands[3] = gen_rtx_CONST_VECTOR (mode, rtvec_alloc (nunits)); + operands[4] = gen_reg_rtx (mode); + + if (shift < 0) + { + operands[5] = CONSTM1_RTX (mode); + operands[6] = GEN_INT (-shift); + } + else + { + operands[5] = CONST0_RTX (mode); + operands[6] = GEN_INT (shift); + } + + /* Populate the constant vectors. */ + for (i = 0; i < nunits; i++) + XVECEXP (operands[3], 0, i) = rtx_val; +}) + +(define_insn "get_vrsave_internal" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(reg:SI VRSAVE_REGNO)] UNSPEC_GET_VRSAVE))] + "TARGET_ALTIVEC" +{ + if (TARGET_MACHO) + return "mfspr %0,256"; + else + return "mfvrsave %0"; +} + [(set_attr "type" "*")]) + +(define_insn "*set_vrsave_internal" + [(match_parallel 0 "vrsave_operation" + [(set (reg:SI VRSAVE_REGNO) + (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r") + (reg:SI VRSAVE_REGNO)] UNSPECV_SET_VRSAVE))])] + "TARGET_ALTIVEC" +{ + if (TARGET_MACHO) + return "mtspr 256,%1"; + else + return "mtvrsave %1"; +} + [(set_attr "type" "*")]) + +(define_insn "*save_world" + [(match_parallel 0 "save_world_operation" + [(clobber (reg:SI LR_REGNO)) + (use (match_operand:SI 1 "call_operand" "s"))])] + "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT" + "bl %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*restore_world" + [(match_parallel 0 "restore_world_operation" + [(return) + (use (reg:SI LR_REGNO)) + (use (match_operand:SI 1 "call_operand" "s")) + (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])] + "TARGET_MACHO && (DEFAULT_ABI == ABI_DARWIN) && TARGET_32BIT" + "b %z1") + +;; The save_vregs and restore_vregs patterns don't use memory_operand +;; because (plus (reg) (const_int)) is not a valid vector address. +;; This way is more compact than describing exactly what happens in +;; the out-of-line functions, ie. loading the constant into r11/r12 +;; then using indexed addressing, and requires less editing of rtl +;; to describe the operation to dwarf2out_frame_debug_expr. +(define_insn "*save_vregs__r11" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P LR_REGNO)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (clobber (reg:P 11)) + (use (reg:P 0)) + (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b") + (match_operand:P 3 "short_cint_operand" "I"))) + (match_operand:V4SI 4 "altivec_register_operand" "v"))])] + "TARGET_ALTIVEC" + "bl %1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*save_vregs__r12" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P LR_REGNO)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (clobber (reg:P 12)) + (use (reg:P 0)) + (set (mem:V4SI (plus:P (match_operand:P 2 "gpc_reg_operand" "b") + (match_operand:P 3 "short_cint_operand" "I"))) + (match_operand:V4SI 4 "altivec_register_operand" "v"))])] + "TARGET_ALTIVEC" + "bl %1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*restore_vregs__r11" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P LR_REGNO)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (clobber (reg:P 11)) + (use (reg:P 0)) + (set (match_operand:V4SI 2 "altivec_register_operand" "=v") + (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b") + (match_operand:P 4 "short_cint_operand" "I"))))])] + "TARGET_ALTIVEC" + "bl %1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*restore_vregs__r12" + [(match_parallel 0 "any_parallel_operand" + [(clobber (reg:P LR_REGNO)) + (use (match_operand:P 1 "symbol_ref_operand" "s")) + (clobber (reg:P 12)) + (use (reg:P 0)) + (set (match_operand:V4SI 2 "altivec_register_operand" "=v") + (mem:V4SI (plus:P (match_operand:P 3 "gpc_reg_operand" "b") + (match_operand:P 4 "short_cint_operand" "I"))))])] + "TARGET_ALTIVEC" + "bl %1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +;; Simple binary operations. + +;; add +(define_insn "add3" + [(set (match_operand:VI2 0 "register_operand" "=v") + (plus:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vaddum %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*altivec_addv4sf3" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (plus:V4SF (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v")))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vaddfp %0,%1,%2" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vaddcuw" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VADDCUW))] + "VECTOR_UNIT_ALTIVEC_P (V4SImode)" + "vaddcuw %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_vaddus" + [(set (match_operand:VI 0 "register_operand" "=v") + (unspec:VI [(match_operand:VI 1 "register_operand" "v") + (match_operand:VI 2 "register_operand" "v")] + UNSPEC_VADDU)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "" + "vaddus %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_vaddss" + [(set (match_operand:VI 0 "register_operand" "=v") + (unspec:VI [(match_operand:VI 1 "register_operand" "v") + (match_operand:VI 2 "register_operand" "v")] + UNSPEC_VADDS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "VECTOR_UNIT_ALTIVEC_P (mode)" + "vaddss %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +;; sub +(define_insn "sub3" + [(set (match_operand:VI2 0 "register_operand" "=v") + (minus:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vsubum %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*altivec_subv4sf3" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (minus:V4SF (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v")))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vsubfp %0,%1,%2" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vsubcuw" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSUBCUW))] + "VECTOR_UNIT_ALTIVEC_P (V4SImode)" + "vsubcuw %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_vsubus" + [(set (match_operand:VI 0 "register_operand" "=v") + (unspec:VI [(match_operand:VI 1 "register_operand" "v") + (match_operand:VI 2 "register_operand" "v")] + UNSPEC_VSUBU)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "VECTOR_UNIT_ALTIVEC_P (mode)" + "vsubus %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_vsubss" + [(set (match_operand:VI 0 "register_operand" "=v") + (unspec:VI [(match_operand:VI 1 "register_operand" "v") + (match_operand:VI 2 "register_operand" "v")] + UNSPEC_VSUBS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "VECTOR_UNIT_ALTIVEC_P (mode)" + "vsubss %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +;; +(define_insn "altivec_vavgu" + [(set (match_operand:VI 0 "register_operand" "=v") + (unspec:VI [(match_operand:VI 1 "register_operand" "v") + (match_operand:VI 2 "register_operand" "v")] + UNSPEC_VAVGU))] + "TARGET_ALTIVEC" + "vavgu %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_vavgs" + [(set (match_operand:VI 0 "register_operand" "=v") + (unspec:VI [(match_operand:VI 1 "register_operand" "v") + (match_operand:VI 2 "register_operand" "v")] + UNSPEC_VAVGS))] + "VECTOR_UNIT_ALTIVEC_P (mode)" + "vavgs %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_vcmpbfp" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v")] + UNSPEC_VCMPBFP))] + "VECTOR_UNIT_ALTIVEC_P (V4SImode)" + "vcmpbfp %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "*altivec_eq" + [(set (match_operand:VI2 0 "altivec_register_operand" "=v") + (eq:VI2 (match_operand:VI2 1 "altivec_register_operand" "v") + (match_operand:VI2 2 "altivec_register_operand" "v")))] + "" + "vcmpequ %0,%1,%2" + [(set_attr "type" "veccmpfx")]) + +(define_insn "*altivec_gt" + [(set (match_operand:VI2 0 "altivec_register_operand" "=v") + (gt:VI2 (match_operand:VI2 1 "altivec_register_operand" "v") + (match_operand:VI2 2 "altivec_register_operand" "v")))] + "" + "vcmpgts %0,%1,%2" + [(set_attr "type" "veccmpfx")]) + +(define_insn "*altivec_gtu" + [(set (match_operand:VI2 0 "altivec_register_operand" "=v") + (gtu:VI2 (match_operand:VI2 1 "altivec_register_operand" "v") + (match_operand:VI2 2 "altivec_register_operand" "v")))] + "" + "vcmpgtu %0,%1,%2" + [(set_attr "type" "veccmpfx")]) + +(define_insn "*altivec_eqv4sf" + [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") + (eq:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") + (match_operand:V4SF 2 "altivec_register_operand" "v")))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vcmpeqfp %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "*altivec_gtv4sf" + [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") + (gt:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") + (match_operand:V4SF 2 "altivec_register_operand" "v")))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vcmpgtfp %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "*altivec_gev4sf" + [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") + (ge:V4SF (match_operand:V4SF 1 "altivec_register_operand" "v") + (match_operand:V4SF 2 "altivec_register_operand" "v")))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vcmpgefp %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "*altivec_vsel" + [(set (match_operand:VM 0 "altivec_register_operand" "=v") + (if_then_else:VM + (ne:CC (match_operand:VM 1 "altivec_register_operand" "v") + (match_operand:VM 4 "zero_constant" "")) + (match_operand:VM 2 "altivec_register_operand" "v") + (match_operand:VM 3 "altivec_register_operand" "v")))] + "VECTOR_MEM_ALTIVEC_P (mode)" + "vsel %0,%3,%2,%1" + [(set_attr "type" "vecmove")]) + +(define_insn "*altivec_vsel_uns" + [(set (match_operand:VM 0 "altivec_register_operand" "=v") + (if_then_else:VM + (ne:CCUNS (match_operand:VM 1 "altivec_register_operand" "v") + (match_operand:VM 4 "zero_constant" "")) + (match_operand:VM 2 "altivec_register_operand" "v") + (match_operand:VM 3 "altivec_register_operand" "v")))] + "VECTOR_MEM_ALTIVEC_P (mode)" + "vsel %0,%3,%2,%1" + [(set_attr "type" "vecmove")]) + +;; Fused multiply add. + +(define_insn "*altivec_fmav4sf4" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (fma:V4SF (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v") + (match_operand:V4SF 3 "register_operand" "v")))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vmaddfp %0,%1,%2,%3" + [(set_attr "type" "vecfloat")]) + +;; We do multiply as a fused multiply-add with an add of a -0.0 vector. + +(define_expand "altivec_mulv4sf3" + [(set (match_operand:V4SF 0 "register_operand" "") + (fma:V4SF (match_operand:V4SF 1 "register_operand" "") + (match_operand:V4SF 2 "register_operand" "") + (match_dup 3)))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" +{ + rtx neg0; + + /* Generate [-0.0, -0.0, -0.0, -0.0]. */ + neg0 = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); + emit_insn (gen_vashlv4si3 (neg0, neg0, neg0)); + + operands[3] = gen_lowpart (V4SFmode, neg0); +}) + +;; 32-bit integer multiplication +;; A_high = Operand_0 & 0xFFFF0000 >> 16 +;; A_low = Operand_0 & 0xFFFF +;; B_high = Operand_1 & 0xFFFF0000 >> 16 +;; B_low = Operand_1 & 0xFFFF +;; result = A_low * B_low + (A_high * B_low + B_high * A_low) << 16 + +;; (define_insn "mulv4si3" +;; [(set (match_operand:V4SI 0 "register_operand" "=v") +;; (mult:V4SI (match_operand:V4SI 1 "register_operand" "v") +;; (match_operand:V4SI 2 "register_operand" "v")))] +(define_insn "mulv4si3_p8" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (mult:V4SI (match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")))] + "TARGET_P8_VECTOR" + "vmuluwm %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_expand "mulv4si3" + [(use (match_operand:V4SI 0 "register_operand" "")) + (use (match_operand:V4SI 1 "register_operand" "")) + (use (match_operand:V4SI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + rtx zero; + rtx swap; + rtx small_swap; + rtx sixteen; + rtx one; + rtx two; + rtx low_product; + rtx high_product; + + if (TARGET_P8_VECTOR) + { + emit_insn (gen_mulv4si3_p8 (operands[0], operands[1], operands[2])); + DONE; + } + + zero = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vspltisw (zero, const0_rtx)); + + sixteen = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vspltisw (sixteen, gen_rtx_CONST_INT (V4SImode, -16))); + + swap = gen_reg_rtx (V4SImode); + emit_insn (gen_vrotlv4si3 (swap, operands[2], sixteen)); + + one = gen_reg_rtx (V8HImode); + convert_move (one, operands[1], 0); + + two = gen_reg_rtx (V8HImode); + convert_move (two, operands[2], 0); + + small_swap = gen_reg_rtx (V8HImode); + convert_move (small_swap, swap, 0); + + low_product = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vmulouh (low_product, one, two)); + + high_product = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vmsumuhm (high_product, one, small_swap, zero)); + + emit_insn (gen_vashlv4si3 (high_product, high_product, sixteen)); + + emit_insn (gen_addv4si3 (operands[0], high_product, low_product)); + + DONE; +}) + +(define_expand "mulv8hi3" + [(use (match_operand:V8HI 0 "register_operand" "")) + (use (match_operand:V8HI 1 "register_operand" "")) + (use (match_operand:V8HI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + rtx zero = gen_reg_rtx (V8HImode); + + emit_insn (gen_altivec_vspltish (zero, const0_rtx)); + emit_insn (gen_altivec_vmladduhm(operands[0], operands[1], operands[2], zero)); + + DONE; +}) + +;; Fused multiply subtract +(define_insn "*altivec_vnmsubfp" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (neg:V4SF + (fma:V4SF (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v") + (neg:V4SF + (match_operand:V4SF 3 "register_operand" "v")))))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vnmsubfp %0,%1,%2,%3" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vmsumum" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") + (match_operand:VIshort 2 "register_operand" "v") + (match_operand:V4SI 3 "register_operand" "v")] + UNSPEC_VMSUMU))] + "TARGET_ALTIVEC" + "vmsumum %0,%1,%2,%3" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmsummm" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") + (match_operand:VIshort 2 "register_operand" "v") + (match_operand:V4SI 3 "register_operand" "v")] + UNSPEC_VMSUMM))] + "TARGET_ALTIVEC" + "vmsummm %0,%1,%2,%3" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmsumshm" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v") + (match_operand:V4SI 3 "register_operand" "v")] + UNSPEC_VMSUMSHM))] + "TARGET_ALTIVEC" + "vmsumshm %0,%1,%2,%3" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmsumuhs" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v") + (match_operand:V4SI 3 "register_operand" "v")] + UNSPEC_VMSUMUHS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "TARGET_ALTIVEC" + "vmsumuhs %0,%1,%2,%3" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmsumshs" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v") + (match_operand:V4SI 3 "register_operand" "v")] + UNSPEC_VMSUMSHS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "TARGET_ALTIVEC" + "vmsumshs %0,%1,%2,%3" + [(set_attr "type" "veccomplex")]) + +;; max + +(define_insn "umax3" + [(set (match_operand:VI2 0 "register_operand" "=v") + (umax:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vmaxu %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "smax3" + [(set (match_operand:VI2 0 "register_operand" "=v") + (smax:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vmaxs %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*altivec_smaxv4sf3" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (smax:V4SF (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v")))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vmaxfp %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "umin3" + [(set (match_operand:VI2 0 "register_operand" "=v") + (umin:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vminu %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "smin3" + [(set (match_operand:VI2 0 "register_operand" "=v") + (smin:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vmins %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*altivec_sminv4sf3" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (smin:V4SF (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v")))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vminfp %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "altivec_vmhaddshs" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v") + (match_operand:V8HI 3 "register_operand" "v")] + UNSPEC_VMHADDSHS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "TARGET_ALTIVEC" + "vmhaddshs %0,%1,%2,%3" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmhraddshs" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v") + (match_operand:V8HI 3 "register_operand" "v")] + UNSPEC_VMHRADDSHS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "TARGET_ALTIVEC" + "vmhraddshs %0,%1,%2,%3" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmladduhm" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (plus:V8HI (mult:V8HI (match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")) + (match_operand:V8HI 3 "register_operand" "v")))] + "TARGET_ALTIVEC" + "vmladduhm %0,%1,%2,%3" + [(set_attr "type" "veccomplex")]) + +(define_expand "altivec_vmrghb" + [(use (match_operand:V16QI 0 "register_operand" "")) + (use (match_operand:V16QI 1 "register_operand" "")) + (use (match_operand:V16QI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25), + GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27), + GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29), + GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31)); + x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]); + } + else + { + v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17), + GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19), + GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21), + GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23)); + x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]); + } + + x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v)); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vmrghb_internal" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")) + (parallel [(const_int 0) (const_int 16) + (const_int 1) (const_int 17) + (const_int 2) (const_int 18) + (const_int 3) (const_int 19) + (const_int 4) (const_int 20) + (const_int 5) (const_int 21) + (const_int 6) (const_int 22) + (const_int 7) (const_int 23)])))] + "TARGET_ALTIVEC" +{ + if (BYTES_BIG_ENDIAN) + return "vmrghb %0,%1,%2"; + else + return "vmrglb %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vmrghb_direct" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMRGH_DIRECT))] + "TARGET_ALTIVEC" + "vmrghb %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_expand "altivec_vmrghh" + [(use (match_operand:V8HI 0 "register_operand" "")) + (use (match_operand:V8HI 1 "register_operand" "")) + (use (match_operand:V8HI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13), + GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15)); + x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]); + } + else + { + v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9), + GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11)); + x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]); + } + + x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v)); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vmrghh_internal" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")) + (parallel [(const_int 0) (const_int 8) + (const_int 1) (const_int 9) + (const_int 2) (const_int 10) + (const_int 3) (const_int 11)])))] + "TARGET_ALTIVEC" +{ + if (BYTES_BIG_ENDIAN) + return "vmrghh %0,%1,%2"; + else + return "vmrglh %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vmrghh_direct" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMRGH_DIRECT))] + "TARGET_ALTIVEC" + "vmrghh %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_expand "altivec_vmrghw" + [(use (match_operand:V4SI 0 "register_operand" "")) + (use (match_operand:V4SI 1 "register_operand" "")) + (use (match_operand:V4SI 2 "register_operand" ""))] + "VECTOR_MEM_ALTIVEC_P (V4SImode)" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7)); + x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]); + } + else + { + v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5)); + x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]); + } + + x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v)); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vmrghw_internal" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5)])))] + "VECTOR_MEM_ALTIVEC_P (V4SImode)" +{ + if (BYTES_BIG_ENDIAN) + return "vmrghw %0,%1,%2"; + else + return "vmrglw %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vmrghw_direct" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VMRGH_DIRECT))] + "TARGET_ALTIVEC" + "vmrghw %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_insn "*altivec_vmrghsf" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v")) + (parallel [(const_int 0) (const_int 4) + (const_int 1) (const_int 5)])))] + "VECTOR_MEM_ALTIVEC_P (V4SFmode)" +{ + if (BYTES_BIG_ENDIAN) + return "vmrghw %0,%1,%2"; + else + return "vmrglw %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_expand "altivec_vmrglb" + [(use (match_operand:V16QI 0 "register_operand" "")) + (use (match_operand:V16QI 1 "register_operand" "")) + (use (match_operand:V16QI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17), + GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19), + GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21), + GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23)); + x = gen_rtx_VEC_CONCAT (V32QImode, operands[2], operands[1]); + } + else + { + v = gen_rtvec (16, GEN_INT (8), GEN_INT (24), GEN_INT (9), GEN_INT (25), + GEN_INT (10), GEN_INT (26), GEN_INT (11), GEN_INT (27), + GEN_INT (12), GEN_INT (28), GEN_INT (13), GEN_INT (29), + GEN_INT (14), GEN_INT (30), GEN_INT (15), GEN_INT (31)); + x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]); + } + + x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v)); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vmrglb_internal" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (vec_select:V16QI + (vec_concat:V32QI + (match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")) + (parallel [(const_int 8) (const_int 24) + (const_int 9) (const_int 25) + (const_int 10) (const_int 26) + (const_int 11) (const_int 27) + (const_int 12) (const_int 28) + (const_int 13) (const_int 29) + (const_int 14) (const_int 30) + (const_int 15) (const_int 31)])))] + "TARGET_ALTIVEC" +{ + if (BYTES_BIG_ENDIAN) + return "vmrglb %0,%1,%2"; + else + return "vmrghb %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vmrglb_direct" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMRGL_DIRECT))] + "TARGET_ALTIVEC" + "vmrglb %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_expand "altivec_vmrglh" + [(use (match_operand:V8HI 0 "register_operand" "")) + (use (match_operand:V8HI 1 "register_operand" "")) + (use (match_operand:V8HI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9), + GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11)); + x = gen_rtx_VEC_CONCAT (V16HImode, operands[2], operands[1]); + } + else + { + v = gen_rtvec (8, GEN_INT (4), GEN_INT (12), GEN_INT (5), GEN_INT (13), + GEN_INT (6), GEN_INT (14), GEN_INT (7), GEN_INT (15)); + x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2]); + } + + x = gen_rtx_VEC_SELECT (V8HImode, x, gen_rtx_PARALLEL (VOIDmode, v)); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vmrglh_internal" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (vec_select:V8HI + (vec_concat:V16HI + (match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")) + (parallel [(const_int 4) (const_int 12) + (const_int 5) (const_int 13) + (const_int 6) (const_int 14) + (const_int 7) (const_int 15)])))] + "TARGET_ALTIVEC" +{ + if (BYTES_BIG_ENDIAN) + return "vmrglh %0,%1,%2"; + else + return "vmrghh %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vmrglh_direct" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMRGL_DIRECT))] + "TARGET_ALTIVEC" + "vmrglh %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_expand "altivec_vmrglw" + [(use (match_operand:V4SI 0 "register_operand" "")) + (use (match_operand:V4SI 1 "register_operand" "")) + (use (match_operand:V4SI 2 "register_operand" ""))] + "VECTOR_MEM_ALTIVEC_P (V4SImode)" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + v = gen_rtvec (4, GEN_INT (0), GEN_INT (4), GEN_INT (1), GEN_INT (5)); + x = gen_rtx_VEC_CONCAT (V8SImode, operands[2], operands[1]); + } + else + { + v = gen_rtvec (4, GEN_INT (2), GEN_INT (6), GEN_INT (3), GEN_INT (7)); + x = gen_rtx_VEC_CONCAT (V8SImode, operands[1], operands[2]); + } + + x = gen_rtx_VEC_SELECT (V4SImode, x, gen_rtx_PARALLEL (VOIDmode, v)); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vmrglw_internal" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")) + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] + "VECTOR_MEM_ALTIVEC_P (V4SImode)" +{ + if (BYTES_BIG_ENDIAN) + return "vmrglw %0,%1,%2"; + else + return "vmrghw %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vmrglw_direct" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VMRGL_DIRECT))] + "TARGET_ALTIVEC" + "vmrglw %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_insn "*altivec_vmrglsf" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (vec_select:V4SF + (vec_concat:V8SF + (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v")) + (parallel [(const_int 2) (const_int 6) + (const_int 3) (const_int 7)])))] + "VECTOR_MEM_ALTIVEC_P (V4SFmode)" +{ + if (BYTES_BIG_ENDIAN) + return "vmrglw %0,%1,%2"; + else + return "vmrghw %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +;; Power8 vector merge even/odd +(define_insn "p8_vmrgew" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")) + (parallel [(const_int 0) (const_int 4) + (const_int 2) (const_int 6)])))] + "TARGET_P8_VECTOR" +{ + if (BYTES_BIG_ENDIAN) + return "vmrgew %0,%1,%2"; + else + return "vmrgow %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "p8_vmrgow" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (vec_select:V4SI + (vec_concat:V8SI + (match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")) + (parallel [(const_int 1) (const_int 5) + (const_int 3) (const_int 7)])))] + "TARGET_P8_VECTOR" +{ + if (BYTES_BIG_ENDIAN) + return "vmrgow %0,%1,%2"; + else + return "vmrgew %0,%2,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "p8_vmrgew_v4sf_direct" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v")] + UNSPEC_VMRGEW_DIRECT))] + "TARGET_P8_VECTOR" + "vmrgew %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_expand "vec_widen_umult_even_v16qi" + [(use (match_operand:V8HI 0 "register_operand" "")) + (use (match_operand:V16QI 1 "register_operand" "")) + (use (match_operand:V16QI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2])); + else + emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "vec_widen_smult_even_v16qi" + [(use (match_operand:V8HI 0 "register_operand" "")) + (use (match_operand:V16QI 1 "register_operand" "")) + (use (match_operand:V16QI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2])); + else + emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "vec_widen_umult_even_v8hi" + [(use (match_operand:V4SI 0 "register_operand" "")) + (use (match_operand:V8HI 1 "register_operand" "")) + (use (match_operand:V8HI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2])); + else + emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "vec_widen_smult_even_v8hi" + [(use (match_operand:V4SI 0 "register_operand" "")) + (use (match_operand:V8HI 1 "register_operand" "")) + (use (match_operand:V8HI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2])); + else + emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "vec_widen_umult_odd_v16qi" + [(use (match_operand:V8HI 0 "register_operand" "")) + (use (match_operand:V16QI 1 "register_operand" "")) + (use (match_operand:V16QI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_vmuloub (operands[0], operands[1], operands[2])); + else + emit_insn (gen_altivec_vmuleub (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "vec_widen_smult_odd_v16qi" + [(use (match_operand:V8HI 0 "register_operand" "")) + (use (match_operand:V16QI 1 "register_operand" "")) + (use (match_operand:V16QI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_vmulosb (operands[0], operands[1], operands[2])); + else + emit_insn (gen_altivec_vmulesb (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "vec_widen_umult_odd_v8hi" + [(use (match_operand:V4SI 0 "register_operand" "")) + (use (match_operand:V8HI 1 "register_operand" "")) + (use (match_operand:V8HI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_vmulouh (operands[0], operands[1], operands[2])); + else + emit_insn (gen_altivec_vmuleuh (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_expand "vec_widen_smult_odd_v8hi" + [(use (match_operand:V4SI 0 "register_operand" "")) + (use (match_operand:V8HI 1 "register_operand" "")) + (use (match_operand:V8HI 2 "register_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_vmulosh (operands[0], operands[1], operands[2])); + else + emit_insn (gen_altivec_vmulesh (operands[0], operands[1], operands[2])); + DONE; +}) + +(define_insn "altivec_vmuleub" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMULEUB))] + "TARGET_ALTIVEC" + "vmuleub %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmuloub" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMULOUB))] + "TARGET_ALTIVEC" + "vmuloub %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmulesb" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMULESB))] + "TARGET_ALTIVEC" + "vmulesb %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmulosb" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMULOSB))] + "TARGET_ALTIVEC" + "vmulosb %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmuleuh" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMULEUH))] + "TARGET_ALTIVEC" + "vmuleuh %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmulouh" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMULOUH))] + "TARGET_ALTIVEC" + "vmulouh %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmulesh" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMULESH))] + "TARGET_ALTIVEC" + "vmulesh %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vmulosh" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMULOSH))] + "TARGET_ALTIVEC" + "vmulosh %0,%1,%2" + [(set_attr "type" "veccomplex")]) + + +;; Vector pack/unpack +(define_insn "altivec_vpkpx" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VPKPX))] + "TARGET_ALTIVEC" + "* + { + if (VECTOR_ELT_ORDER_BIG) + return \"vpkpx %0,%1,%2\"; + else + return \"vpkpx %0,%2,%1\"; + }" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vpksss" + [(set (match_operand: 0 "register_operand" "=v") + (unspec: [(match_operand:VP 1 "register_operand" "v") + (match_operand:VP 2 "register_operand" "v")] + UNSPEC_VPACK_SIGN_SIGN_SAT))] + "" + "* + { + if (VECTOR_ELT_ORDER_BIG) + return \"vpksss %0,%1,%2\"; + else + return \"vpksss %0,%2,%1\"; + }" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vpksus" + [(set (match_operand: 0 "register_operand" "=v") + (unspec: [(match_operand:VP 1 "register_operand" "v") + (match_operand:VP 2 "register_operand" "v")] + UNSPEC_VPACK_SIGN_UNS_SAT))] + "" + "* + { + if (VECTOR_ELT_ORDER_BIG) + return \"vpksus %0,%1,%2\"; + else + return \"vpksus %0,%2,%1\"; + }" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vpkuus" + [(set (match_operand: 0 "register_operand" "=v") + (unspec: [(match_operand:VP 1 "register_operand" "v") + (match_operand:VP 2 "register_operand" "v")] + UNSPEC_VPACK_UNS_UNS_SAT))] + "" + "* + { + if (VECTOR_ELT_ORDER_BIG) + return \"vpkuus %0,%1,%2\"; + else + return \"vpkuus %0,%2,%1\"; + }" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vpkuum" + [(set (match_operand: 0 "register_operand" "=v") + (unspec: [(match_operand:VP 1 "register_operand" "v") + (match_operand:VP 2 "register_operand" "v")] + UNSPEC_VPACK_UNS_UNS_MOD))] + "" + "* + { + if (VECTOR_ELT_ORDER_BIG) + return \"vpkuum %0,%1,%2\"; + else + return \"vpkuum %0,%2,%1\"; + }" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vpkuum_direct" + [(set (match_operand: 0 "register_operand" "=v") + (unspec: [(match_operand:VP 1 "register_operand" "v") + (match_operand:VP 2 "register_operand" "v")] + UNSPEC_VPACK_UNS_UNS_MOD_DIRECT))] + "" + "* + { + if (BYTES_BIG_ENDIAN) + return \"vpkuum %0,%1,%2\"; + else + return \"vpkuum %0,%2,%1\"; + }" + [(set_attr "type" "vecperm")]) + +(define_insn "*altivec_vrl" + [(set (match_operand:VI2 0 "register_operand" "=v") + (rotate:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vrl %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_vrlmi" + [(set (match_operand:VIlong 0 "register_operand" "=v") + (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "0") + (match_operand:VIlong 2 "register_operand" "v") + (match_operand:VIlong 3 "register_operand" "v")] + UNSPEC_VRLMI))] + "TARGET_P9_VECTOR" + "vrlmi %0,%2,%3" + [(set_attr "type" "veclogical")]) + +(define_insn "altivec_vrlnm" + [(set (match_operand:VIlong 0 "register_operand" "=v") + (unspec:VIlong [(match_operand:VIlong 1 "register_operand" "v") + (match_operand:VIlong 2 "register_operand" "v")] + UNSPEC_VRLNM))] + "TARGET_P9_VECTOR" + "vrlnm %0,%1,%2" + [(set_attr "type" "veclogical")]) + +(define_insn "altivec_vsl" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSLV4SI))] + "TARGET_ALTIVEC" + "vsl %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vslo" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSLO))] + "TARGET_ALTIVEC" + "vslo %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_insn "vslv" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VSLV))] + "TARGET_P9_VECTOR" + "vslv %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "vsrv" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VSRV))] + "TARGET_P9_VECTOR" + "vsrv %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*altivec_vsl" + [(set (match_operand:VI2 0 "register_operand" "=v") + (ashift:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vsl %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*altivec_vsr" + [(set (match_operand:VI2 0 "register_operand" "=v") + (lshiftrt:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vsr %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "*altivec_vsra" + [(set (match_operand:VI2 0 "register_operand" "=v") + (ashiftrt:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v")))] + "" + "vsra %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_vsr" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSR))] + "TARGET_ALTIVEC" + "vsr %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vsro" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSRO))] + "TARGET_ALTIVEC" + "vsro %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vsum4ubs" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSUM4UBS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "TARGET_ALTIVEC" + "vsum4ubs %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_insn "altivec_vsum4ss" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSUM4S)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "TARGET_ALTIVEC" + "vsum4ss %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +;; FIXME: For the following two patterns, the scratch should only be +;; allocated for !VECTOR_ELT_ORDER_BIG, and the instructions should +;; be emitted separately. +(define_insn "altivec_vsum2sws" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSUM2SWS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR)) + (clobber (match_scratch:V4SI 3 "=v"))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + return "vsum2sws %0,%1,%2"; + else + return "vsldoi %3,%2,%2,12\n\tvsum2sws %3,%1,%3\n\tvsldoi %0,%3,%3,4"; +} + [(set_attr "type" "veccomplex") + (set (attr "length") + (if_then_else + (match_test "VECTOR_ELT_ORDER_BIG") + (const_string "4") + (const_string "12")))]) + +(define_insn "altivec_vsumsws" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSUMSWS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR)) + (clobber (match_scratch:V4SI 3 "=v"))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + return "vsumsws %0,%1,%2"; + else + return "vspltw %3,%2,0\n\tvsumsws %3,%1,%3\n\tvsldoi %0,%3,%3,12"; +} + [(set_attr "type" "veccomplex") + (set (attr "length") + (if_then_else + (match_test "(VECTOR_ELT_ORDER_BIG)") + (const_string "4") + (const_string "12")))]) + +(define_insn "altivec_vsumsws_direct" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:V4SI 2 "register_operand" "v")] + UNSPEC_VSUMSWS_DIRECT)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "TARGET_ALTIVEC" + "vsumsws %0,%1,%2" + [(set_attr "type" "veccomplex")]) + +(define_expand "altivec_vspltb" + [(use (match_operand:V16QI 0 "register_operand" "")) + (use (match_operand:V16QI 1 "register_operand" "")) + (use (match_operand:QI 2 "u5bit_cint_operand" ""))] + "TARGET_ALTIVEC" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. We have to reflect + the actual selected index for the splat in the RTL. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + operands[2] = GEN_INT (15 - INTVAL (operands[2])); + + v = gen_rtvec (1, operands[2]); + x = gen_rtx_VEC_SELECT (QImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); + x = gen_rtx_VEC_DUPLICATE (V16QImode, x); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vspltb_internal" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (vec_duplicate:V16QI + (vec_select:QI (match_operand:V16QI 1 "register_operand" "v") + (parallel + [(match_operand:QI 2 "u5bit_cint_operand" "")]))))] + "TARGET_ALTIVEC" +{ + /* For true LE, this adjusts the selected index. For LE with + -maltivec=be, this reverses what was done in the define_expand + because the instruction already has big-endian bias. */ + if (!BYTES_BIG_ENDIAN) + operands[2] = GEN_INT (15 - INTVAL (operands[2])); + + return "vspltb %0,%1,%2"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vspltb_direct" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:QI 2 "u5bit_cint_operand" "i")] + UNSPEC_VSPLT_DIRECT))] + "TARGET_ALTIVEC" + "vspltb %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_expand "altivec_vsplth" + [(use (match_operand:V8HI 0 "register_operand" "")) + (use (match_operand:V8HI 1 "register_operand" "")) + (use (match_operand:QI 2 "u5bit_cint_operand" ""))] + "TARGET_ALTIVEC" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. We have to reflect + the actual selected index for the splat in the RTL. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + operands[2] = GEN_INT (7 - INTVAL (operands[2])); + + v = gen_rtvec (1, operands[2]); + x = gen_rtx_VEC_SELECT (HImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); + x = gen_rtx_VEC_DUPLICATE (V8HImode, x); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vsplth_internal" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (vec_duplicate:V8HI + (vec_select:HI (match_operand:V8HI 1 "register_operand" "v") + (parallel + [(match_operand:QI 2 "u5bit_cint_operand" "")]))))] + "TARGET_ALTIVEC" +{ + /* For true LE, this adjusts the selected index. For LE with + -maltivec=be, this reverses what was done in the define_expand + because the instruction already has big-endian bias. */ + if (!BYTES_BIG_ENDIAN) + operands[2] = GEN_INT (7 - INTVAL (operands[2])); + + return "vsplth %0,%1,%2"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vsplth_direct" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:QI 2 "u5bit_cint_operand" "i")] + UNSPEC_VSPLT_DIRECT))] + "TARGET_ALTIVEC" + "vsplth %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_expand "altivec_vspltw" + [(use (match_operand:V4SI 0 "register_operand" "")) + (use (match_operand:V4SI 1 "register_operand" "")) + (use (match_operand:QI 2 "u5bit_cint_operand" ""))] + "TARGET_ALTIVEC" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. We have to reflect + the actual selected index for the splat in the RTL. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + operands[2] = GEN_INT (3 - INTVAL (operands[2])); + + v = gen_rtvec (1, operands[2]); + x = gen_rtx_VEC_SELECT (SImode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); + x = gen_rtx_VEC_DUPLICATE (V4SImode, x); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vspltw_internal" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (vec_duplicate:V4SI + (vec_select:SI (match_operand:V4SI 1 "register_operand" "v") + (parallel + [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))] + "TARGET_ALTIVEC" +{ + /* For true LE, this adjusts the selected index. For LE with + -maltivec=be, this reverses what was done in the define_expand + because the instruction already has big-endian bias. */ + if (!BYTES_BIG_ENDIAN) + operands[2] = GEN_INT (3 - INTVAL (operands[2])); + + return "vspltw %0,%1,%2"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vspltw_direct" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:QI 2 "u5bit_cint_operand" "i")] + UNSPEC_VSPLT_DIRECT))] + "TARGET_ALTIVEC" + "vspltw %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_expand "altivec_vspltsf" + [(use (match_operand:V4SF 0 "register_operand" "")) + (use (match_operand:V4SF 1 "register_operand" "")) + (use (match_operand:QI 2 "u5bit_cint_operand" ""))] + "TARGET_ALTIVEC" +{ + rtvec v; + rtx x; + + /* Special handling for LE with -maltivec=be. We have to reflect + the actual selected index for the splat in the RTL. */ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + operands[2] = GEN_INT (3 - INTVAL (operands[2])); + + v = gen_rtvec (1, operands[2]); + x = gen_rtx_VEC_SELECT (SFmode, operands[1], gen_rtx_PARALLEL (VOIDmode, v)); + x = gen_rtx_VEC_DUPLICATE (V4SFmode, x); + emit_insn (gen_rtx_SET (operands[0], x)); + DONE; +}) + +(define_insn "*altivec_vspltsf_internal" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (vec_duplicate:V4SF + (vec_select:SF (match_operand:V4SF 1 "register_operand" "v") + (parallel + [(match_operand:QI 2 "u5bit_cint_operand" "i")]))))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" +{ + /* For true LE, this adjusts the selected index. For LE with + -maltivec=be, this reverses what was done in the define_expand + because the instruction already has big-endian bias. */ + if (!BYTES_BIG_ENDIAN) + operands[2] = GEN_INT (3 - INTVAL (operands[2])); + + return "vspltw %0,%1,%2"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vspltis" + [(set (match_operand:VI 0 "register_operand" "=v") + (vec_duplicate:VI + (match_operand:QI 1 "s5bit_cint_operand" "i")))] + "TARGET_ALTIVEC" + "vspltis %0,%1" + [(set_attr "type" "vecperm")]) + +(define_insn "*altivec_vrfiz" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vrfiz %0,%1" + [(set_attr "type" "vecfloat")]) + +(define_expand "altivec_vperm_" + [(set (match_operand:VM 0 "register_operand" "") + (unspec:VM [(match_operand:VM 1 "register_operand" "") + (match_operand:VM 2 "register_operand" "") + (match_operand:V16QI 3 "register_operand" "")] + UNSPEC_VPERM))] + "TARGET_ALTIVEC" +{ + if (!VECTOR_ELT_ORDER_BIG) + { + altivec_expand_vec_perm_le (operands); + DONE; + } +}) + +;; Slightly prefer vperm, since the target does not overlap the source +(define_insn "*altivec_vperm__internal" + [(set (match_operand:VM 0 "register_operand" "=v,?wo") + (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") + (match_operand:VM 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] + UNSPEC_VPERM))] + "TARGET_ALTIVEC" + "@ + vperm %0,%1,%2,%3 + xxperm %x0,%x1,%x3" + [(set_attr "type" "vecperm") + (set_attr "length" "4")]) + +(define_insn "altivec_vperm_v8hiv16qi" + [(set (match_operand:V16QI 0 "register_operand" "=v,?wo") + (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v,wo") + (match_operand:V8HI 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] + UNSPEC_VPERM))] + "TARGET_ALTIVEC" + "@ + vperm %0,%1,%2,%3 + xxperm %x0,%x1,%x3" + [(set_attr "type" "vecperm") + (set_attr "length" "4")]) + +(define_expand "altivec_vperm__uns" + [(set (match_operand:VM 0 "register_operand" "") + (unspec:VM [(match_operand:VM 1 "register_operand" "") + (match_operand:VM 2 "register_operand" "") + (match_operand:V16QI 3 "register_operand" "")] + UNSPEC_VPERM_UNS))] + "TARGET_ALTIVEC" +{ + if (!VECTOR_ELT_ORDER_BIG) + { + altivec_expand_vec_perm_le (operands); + DONE; + } +}) + +(define_insn "*altivec_vperm__uns_internal" + [(set (match_operand:VM 0 "register_operand" "=v,?wo") + (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") + (match_operand:VM 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] + UNSPEC_VPERM_UNS))] + "TARGET_ALTIVEC" + "@ + vperm %0,%1,%2,%3 + xxperm %x0,%x1,%x3" + [(set_attr "type" "vecperm") + (set_attr "length" "4")]) + +(define_expand "vec_permv16qi" + [(set (match_operand:V16QI 0 "register_operand" "") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "") + (match_operand:V16QI 2 "register_operand" "") + (match_operand:V16QI 3 "register_operand" "")] + UNSPEC_VPERM))] + "TARGET_ALTIVEC" +{ + if (!BYTES_BIG_ENDIAN) { + altivec_expand_vec_perm_le (operands); + DONE; + } +}) + +(define_expand "vec_perm_constv16qi" + [(match_operand:V16QI 0 "register_operand" "") + (match_operand:V16QI 1 "register_operand" "") + (match_operand:V16QI 2 "register_operand" "") + (match_operand:V16QI 3 "" "")] + "TARGET_ALTIVEC" +{ + if (altivec_expand_vec_perm_const (operands)) + DONE; + else + FAIL; +}) + +(define_insn "*altivec_vpermr__internal" + [(set (match_operand:VM 0 "register_operand" "=v,?wo") + (unspec:VM [(match_operand:VM 1 "register_operand" "v,wo") + (match_operand:VM 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] + UNSPEC_VPERMR))] + "TARGET_P9_VECTOR" + "@ + vpermr %0,%2,%1,%3 + xxpermr %x0,%x1,%x3" + [(set_attr "type" "vecperm") + (set_attr "length" "4")]) + +(define_insn "altivec_vrfip" ; ceil + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] + UNSPEC_FRIP))] + "TARGET_ALTIVEC" + "vrfip %0,%1" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vrfin" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] + UNSPEC_VRFIN))] + "TARGET_ALTIVEC" + "vrfin %0,%1" + [(set_attr "type" "vecfloat")]) + +(define_insn "*altivec_vrfim" ; floor + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] + UNSPEC_FRIM))] + "TARGET_ALTIVEC" + "vrfim %0,%1" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vcfux" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:QI 2 "immediate_operand" "i")] + UNSPEC_VCFUX))] + "TARGET_ALTIVEC" + "vcfux %0,%1,%2" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vcfsx" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") + (match_operand:QI 2 "immediate_operand" "i")] + UNSPEC_VCFSX))] + "TARGET_ALTIVEC" + "vcfsx %0,%1,%2" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vctuxs" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") + (match_operand:QI 2 "immediate_operand" "i")] + UNSPEC_VCTUXS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "TARGET_ALTIVEC" + "vctuxs %0,%1,%2" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vctsxs" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") + (match_operand:QI 2 "immediate_operand" "i")] + UNSPEC_VCTSXS)) + (set (reg:SI VSCR_REGNO) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] + "TARGET_ALTIVEC" + "vctsxs %0,%1,%2" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vlogefp" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] + UNSPEC_VLOGEFP))] + "TARGET_ALTIVEC" + "vlogefp %0,%1" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vexptefp" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] + UNSPEC_VEXPTEFP))] + "TARGET_ALTIVEC" + "vexptefp %0,%1" + [(set_attr "type" "vecfloat")]) + +(define_insn "*altivec_vrsqrtefp" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] + UNSPEC_RSQRT))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vrsqrtefp %0,%1" + [(set_attr "type" "vecfloat")]) + +(define_insn "altivec_vrefp" + [(set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] + UNSPEC_FRES))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vrefp %0,%1" + [(set_attr "type" "vecfloat")]) + +(define_expand "altivec_copysign_v4sf3" + [(use (match_operand:V4SF 0 "register_operand" "")) + (use (match_operand:V4SF 1 "register_operand" "")) + (use (match_operand:V4SF 2 "register_operand" ""))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + " +{ + rtx mask = gen_reg_rtx (V4SImode); + rtvec v = rtvec_alloc (4); + unsigned HOST_WIDE_INT mask_val = ((unsigned HOST_WIDE_INT)1) << 31; + + RTVEC_ELT (v, 0) = GEN_INT (mask_val); + RTVEC_ELT (v, 1) = GEN_INT (mask_val); + RTVEC_ELT (v, 2) = GEN_INT (mask_val); + RTVEC_ELT (v, 3) = GEN_INT (mask_val); + + emit_insn (gen_vec_initv4si (mask, gen_rtx_PARALLEL (V4SImode, v))); + emit_insn (gen_vector_select_v4sf (operands[0], operands[1], operands[2], + gen_lowpart (V4SFmode, mask))); + DONE; +}") + +(define_insn "altivec_vsldoi_" + [(set (match_operand:VM 0 "register_operand" "=v") + (unspec:VM [(match_operand:VM 1 "register_operand" "v") + (match_operand:VM 2 "register_operand" "v") + (match_operand:QI 3 "immediate_operand" "i")] + UNSPEC_VSLDOI))] + "TARGET_ALTIVEC" + "vsldoi %0,%1,%2,%3" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vupkhs" + [(set (match_operand:VP 0 "register_operand" "=v") + (unspec:VP [(match_operand: 1 "register_operand" "v")] + UNSPEC_VUNPACK_HI_SIGN))] + "" +{ + if (VECTOR_ELT_ORDER_BIG) + return "vupkhs %0,%1"; + else + return "vupkls %0,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "*altivec_vupkhs_direct" + [(set (match_operand:VP 0 "register_operand" "=v") + (unspec:VP [(match_operand: 1 "register_operand" "v")] + UNSPEC_VUNPACK_HI_SIGN_DIRECT))] + "" + "vupkhs %0,%1" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vupkls" + [(set (match_operand:VP 0 "register_operand" "=v") + (unspec:VP [(match_operand: 1 "register_operand" "v")] + UNSPEC_VUNPACK_LO_SIGN))] + "" +{ + if (VECTOR_ELT_ORDER_BIG) + return "vupkls %0,%1"; + else + return "vupkhs %0,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "*altivec_vupkls_direct" + [(set (match_operand:VP 0 "register_operand" "=v") + (unspec:VP [(match_operand: 1 "register_operand" "v")] + UNSPEC_VUNPACK_LO_SIGN_DIRECT))] + "" + "vupkls %0,%1" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vupkhpx" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] + UNSPEC_VUPKHPX))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + return "vupkhpx %0,%1"; + else + return "vupklpx %0,%1"; +} + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vupklpx" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] + UNSPEC_VUPKLPX))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + return "vupklpx %0,%1"; + else + return "vupkhpx %0,%1"; +} + [(set_attr "type" "vecperm")]) + +;; Compare vectors producing a vector result and a predicate, setting CR6 to +;; indicate a combined status +(define_insn "*altivec_vcmpequ_p" + [(set (reg:CC CR6_REGNO) + (unspec:CC [(eq:CC (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v"))] + UNSPEC_PREDICATE)) + (set (match_operand:VI2 0 "register_operand" "=v") + (eq:VI2 (match_dup 1) + (match_dup 2)))] + "" + "vcmpequ. %0,%1,%2" + [(set_attr "type" "veccmpfx")]) + +(define_insn "*altivec_vcmpgts_p" + [(set (reg:CC CR6_REGNO) + (unspec:CC [(gt:CC (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v"))] + UNSPEC_PREDICATE)) + (set (match_operand:VI2 0 "register_operand" "=v") + (gt:VI2 (match_dup 1) + (match_dup 2)))] + "" + "vcmpgts. %0,%1,%2" + [(set_attr "type" "veccmpfx")]) + +(define_insn "*altivec_vcmpgtu_p" + [(set (reg:CC CR6_REGNO) + (unspec:CC [(gtu:CC (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "register_operand" "v"))] + UNSPEC_PREDICATE)) + (set (match_operand:VI2 0 "register_operand" "=v") + (gtu:VI2 (match_dup 1) + (match_dup 2)))] + "" + "vcmpgtu. %0,%1,%2" + [(set_attr "type" "veccmpfx")]) + +(define_insn "*altivec_vcmpeqfp_p" + [(set (reg:CC CR6_REGNO) + (unspec:CC [(eq:CC (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v"))] + UNSPEC_PREDICATE)) + (set (match_operand:V4SF 0 "register_operand" "=v") + (eq:V4SF (match_dup 1) + (match_dup 2)))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vcmpeqfp. %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "*altivec_vcmpgtfp_p" + [(set (reg:CC CR6_REGNO) + (unspec:CC [(gt:CC (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v"))] + UNSPEC_PREDICATE)) + (set (match_operand:V4SF 0 "register_operand" "=v") + (gt:V4SF (match_dup 1) + (match_dup 2)))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vcmpgtfp. %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "*altivec_vcmpgefp_p" + [(set (reg:CC CR6_REGNO) + (unspec:CC [(ge:CC (match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v"))] + UNSPEC_PREDICATE)) + (set (match_operand:V4SF 0 "register_operand" "=v") + (ge:V4SF (match_dup 1) + (match_dup 2)))] + "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" + "vcmpgefp. %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "altivec_vcmpbfp_p" + [(set (reg:CC CR6_REGNO) + (unspec:CC [(match_operand:V4SF 1 "register_operand" "v") + (match_operand:V4SF 2 "register_operand" "v")] + UNSPEC_VCMPBFP)) + (set (match_operand:V4SF 0 "register_operand" "=v") + (unspec:V4SF [(match_dup 1) + (match_dup 2)] + UNSPEC_VCMPBFP))] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" + "vcmpbfp. %0,%1,%2" + [(set_attr "type" "veccmp")]) + +(define_insn "altivec_mtvscr" + [(set (reg:SI VSCR_REGNO) + (unspec_volatile:SI + [(match_operand:V4SI 0 "register_operand" "v")] UNSPECV_MTVSCR))] + "TARGET_ALTIVEC" + "mtvscr %0" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_mfvscr" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec_volatile:V8HI [(reg:SI VSCR_REGNO)] UNSPECV_MFVSCR))] + "TARGET_ALTIVEC" + "mfvscr %0" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dssall" + [(unspec_volatile [(const_int 0)] UNSPECV_DSSALL)] + "TARGET_ALTIVEC" + "dssall" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dss" + [(unspec_volatile [(match_operand:QI 0 "immediate_operand" "i")] + UNSPECV_DSS)] + "TARGET_ALTIVEC" + "dss %0" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dst" + [(unspec [(match_operand 0 "register_operand" "b") + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DST)] + "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" + "dst %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dstt" + [(unspec [(match_operand 0 "register_operand" "b") + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTT)] + "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" + "dstt %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dstst" + [(unspec [(match_operand 0 "register_operand" "b") + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTST)] + "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" + "dstst %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_insn "altivec_dststt" + [(unspec [(match_operand 0 "register_operand" "b") + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "immediate_operand" "i")] UNSPEC_DSTSTT)] + "TARGET_ALTIVEC && GET_MODE (operands[0]) == Pmode" + "dststt %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +(define_expand "altivec_lvsl" + [(use (match_operand:V16QI 0 "register_operand" "")) + (use (match_operand:V16QI 1 "memory_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_lvsl_direct (operands[0], operands[1])); + else + { + int i; + rtx mask, perm[16], constv, vperm; + mask = gen_reg_rtx (V16QImode); + emit_insn (gen_altivec_lvsl_direct (mask, operands[1])); + for (i = 0; i < 16; ++i) + perm[i] = GEN_INT (i); + constv = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)); + constv = force_reg (V16QImode, constv); + vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv), + UNSPEC_VPERM); + emit_insn (gen_rtx_SET (operands[0], vperm)); + } + DONE; +}) + +(define_insn "altivec_lvsl_direct" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] + UNSPEC_LVSL))] + "TARGET_ALTIVEC" + "lvsl %0,%y1" + [(set_attr "type" "vecload")]) + +(define_expand "altivec_lvsr" + [(use (match_operand:V16QI 0 "register_operand" "")) + (use (match_operand:V16QI 1 "memory_operand" ""))] + "TARGET_ALTIVEC" +{ + if (VECTOR_ELT_ORDER_BIG) + emit_insn (gen_altivec_lvsr_direct (operands[0], operands[1])); + else + { + int i; + rtx mask, perm[16], constv, vperm; + mask = gen_reg_rtx (V16QImode); + emit_insn (gen_altivec_lvsr_direct (mask, operands[1])); + for (i = 0; i < 16; ++i) + perm[i] = GEN_INT (i); + constv = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)); + constv = force_reg (V16QImode, constv); + vperm = gen_rtx_UNSPEC (V16QImode, gen_rtvec (3, mask, mask, constv), + UNSPEC_VPERM); + emit_insn (gen_rtx_SET (operands[0], vperm)); + } + DONE; +}) + +(define_insn "altivec_lvsr_direct" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "Z")] + UNSPEC_LVSR))] + "TARGET_ALTIVEC" + "lvsr %0,%y1" + [(set_attr "type" "vecload")]) + +(define_expand "build_vector_mask_for_load" + [(set (match_operand:V16QI 0 "register_operand" "") + (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))] + "TARGET_ALTIVEC" + " +{ + rtx addr; + rtx temp; + + gcc_assert (GET_CODE (operands[1]) == MEM); + + addr = XEXP (operands[1], 0); + temp = gen_reg_rtx (GET_MODE (addr)); + emit_insn (gen_rtx_SET (temp, gen_rtx_NEG (GET_MODE (addr), addr))); + emit_insn (gen_altivec_lvsr (operands[0], + replace_equiv_address (operands[1], temp))); + DONE; +}") + +;; Parallel some of the LVE* and STV*'s with unspecs because some have +;; identical rtl but different instructions-- and gcc gets confused. + +(define_expand "altivec_lvex" + [(parallel + [(set (match_operand:VI 0 "register_operand" "=v") + (match_operand:VI 1 "memory_operand" "Z")) + (unspec [(const_int 0)] UNSPEC_LVE)])] + "TARGET_ALTIVEC" +{ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + altivec_expand_lvx_be (operands[0], operands[1], mode, UNSPEC_LVE); + DONE; + } +}) + +(define_insn "*altivec_lvex_internal" + [(parallel + [(set (match_operand:VI 0 "register_operand" "=v") + (match_operand:VI 1 "memory_operand" "Z")) + (unspec [(const_int 0)] UNSPEC_LVE)])] + "TARGET_ALTIVEC" + "lvex %0,%y1" + [(set_attr "type" "vecload")]) + +(define_insn "*altivec_lvesfx" + [(parallel + [(set (match_operand:V4SF 0 "register_operand" "=v") + (match_operand:V4SF 1 "memory_operand" "Z")) + (unspec [(const_int 0)] UNSPEC_LVE)])] + "TARGET_ALTIVEC" + "lvewx %0,%y1" + [(set_attr "type" "vecload")]) + +(define_expand "altivec_lvxl_" + [(parallel + [(set (match_operand:VM2 0 "register_operand" "=v") + (match_operand:VM2 1 "memory_operand" "Z")) + (unspec [(const_int 0)] UNSPEC_SET_VSCR)])] + "TARGET_ALTIVEC" +{ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + altivec_expand_lvx_be (operands[0], operands[1], mode, UNSPEC_SET_VSCR); + DONE; + } +}) + +(define_insn "*altivec_lvxl__internal" + [(parallel + [(set (match_operand:VM2 0 "register_operand" "=v") + (match_operand:VM2 1 "memory_operand" "Z")) + (unspec [(const_int 0)] UNSPEC_SET_VSCR)])] + "TARGET_ALTIVEC" + "lvxl %0,%y1" + [(set_attr "type" "vecload")]) + +; This version of lvx is used only in cases where we need to force an lvx +; over any other load, and we don't care about losing CSE opportunities. +; Its primary use is for prologue register saves. +(define_insn "altivec_lvx__internal" + [(parallel + [(set (match_operand:VM2 0 "register_operand" "=v") + (match_operand:VM2 1 "memory_operand" "Z")) + (unspec [(const_int 0)] UNSPEC_LVX)])] + "TARGET_ALTIVEC" + "lvx %0,%y1" + [(set_attr "type" "vecload")]) + +; The next two patterns embody what lvx should usually look like. +(define_insn "altivec_lvx__2op" + [(set (match_operand:VM2 0 "register_operand" "=v") + (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "register_operand" "r")) + (const_int -16))))] + "TARGET_ALTIVEC && TARGET_64BIT" + "lvx %0,%1,%2" + [(set_attr "type" "vecload")]) + +(define_insn "altivec_lvx__1op" + [(set (match_operand:VM2 0 "register_operand" "=v") + (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r") + (const_int -16))))] + "TARGET_ALTIVEC && TARGET_64BIT" + "lvx %0,0,%1" + [(set_attr "type" "vecload")]) + +; 32-bit versions of the above. +(define_insn "altivec_lvx__2op_si" + [(set (match_operand:VM2 0 "register_operand" "=v") + (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "register_operand" "r")) + (const_int -16))))] + "TARGET_ALTIVEC && TARGET_32BIT" + "lvx %0,%1,%2" + [(set_attr "type" "vecload")]) + +(define_insn "altivec_lvx__1op_si" + [(set (match_operand:VM2 0 "register_operand" "=v") + (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r") + (const_int -16))))] + "TARGET_ALTIVEC && TARGET_32BIT" + "lvx %0,0,%1" + [(set_attr "type" "vecload")]) + +; This version of stvx is used only in cases where we need to force an stvx +; over any other store, and we don't care about losing CSE opportunities. +; Its primary use is for epilogue register restores. +(define_insn "altivec_stvx__internal" + [(parallel + [(set (match_operand:VM2 0 "memory_operand" "=Z") + (match_operand:VM2 1 "register_operand" "v")) + (unspec [(const_int 0)] UNSPEC_STVX)])] + "TARGET_ALTIVEC" + "stvx %1,%y0" + [(set_attr "type" "vecstore")]) + +; The next two patterns embody what stvx should usually look like. +(define_insn "altivec_stvx__2op" + [(set (mem:VM2 (and:DI (plus:DI (match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "register_operand" "r")) + (const_int -16))) + (match_operand:VM2 0 "register_operand" "v"))] + "TARGET_ALTIVEC && TARGET_64BIT" + "stvx %0,%1,%2" + [(set_attr "type" "vecstore")]) + +(define_insn "altivec_stvx__1op" + [(set (mem:VM2 (and:DI (match_operand:DI 1 "register_operand" "r") + (const_int -16))) + (match_operand:VM2 0 "register_operand" "v"))] + "TARGET_ALTIVEC && TARGET_64BIT" + "stvx %0,0,%1" + [(set_attr "type" "vecstore")]) + +; 32-bit versions of the above. +(define_insn "altivec_stvx__2op_si" + [(set (mem:VM2 (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "register_operand" "r")) + (const_int -16))) + (match_operand:VM2 0 "register_operand" "v"))] + "TARGET_ALTIVEC && TARGET_32BIT" + "stvx %0,%1,%2" + [(set_attr "type" "vecstore")]) + +(define_insn "altivec_stvx__1op_si" + [(set (mem:VM2 (and:SI (match_operand:SI 1 "register_operand" "r") + (const_int -16))) + (match_operand:VM2 0 "register_operand" "v"))] + "TARGET_ALTIVEC && TARGET_32BIT" + "stvx %0,0,%1" + [(set_attr "type" "vecstore")]) + +(define_expand "altivec_stvxl_" + [(parallel + [(set (match_operand:VM2 0 "memory_operand" "=Z") + (match_operand:VM2 1 "register_operand" "v")) + (unspec [(const_int 0)] UNSPEC_STVXL)])] + "TARGET_ALTIVEC" +{ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + altivec_expand_stvx_be (operands[0], operands[1], mode, UNSPEC_STVXL); + DONE; + } +}) + +(define_insn "*altivec_stvxl__internal" + [(parallel + [(set (match_operand:VM2 0 "memory_operand" "=Z") + (match_operand:VM2 1 "register_operand" "v")) + (unspec [(const_int 0)] UNSPEC_STVXL)])] + "TARGET_ALTIVEC" + "stvxl %1,%y0" + [(set_attr "type" "vecstore")]) + +(define_expand "altivec_stvex" + [(set (match_operand: 0 "memory_operand" "=Z") + (unspec: [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))] + "TARGET_ALTIVEC" +{ + if (!BYTES_BIG_ENDIAN && VECTOR_ELT_ORDER_BIG) + { + altivec_expand_stvex_be (operands[0], operands[1], mode, UNSPEC_STVE); + DONE; + } +}) + +(define_insn "*altivec_stvex_internal" + [(set (match_operand: 0 "memory_operand" "=Z") + (unspec: [(match_operand:VI 1 "register_operand" "v")] UNSPEC_STVE))] + "TARGET_ALTIVEC" + "stvex %1,%y0" + [(set_attr "type" "vecstore")]) + +(define_insn "*altivec_stvesfx" + [(set (match_operand:SF 0 "memory_operand" "=Z") + (unspec:SF [(match_operand:V4SF 1 "register_operand" "v")] UNSPEC_STVE))] + "TARGET_ALTIVEC" + "stvewx %1,%y0" + [(set_attr "type" "vecstore")]) + +;; Generate +;; xxlxor/vxor SCRATCH0,SCRATCH0,SCRATCH0 +;; vsubu?m SCRATCH2,SCRATCH1,%1 +;; vmaxs? %0,%1,SCRATCH2" +(define_expand "abs2" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 4) + (minus:VI2 (match_dup 2) + (match_operand:VI2 1 "register_operand" "v"))) + (set (match_operand:VI2 0 "register_operand" "=v") + (smax:VI2 (match_dup 1) (match_dup 4)))] + "" +{ + int i, n_elt = GET_MODE_NUNITS (mode); + rtvec v = rtvec_alloc (n_elt); + + /* Create an all 0 constant. */ + for (i = 0; i < n_elt; ++i) + RTVEC_ELT (v, i) = const0_rtx; + + operands[2] = gen_reg_rtx (mode); + operands[3] = gen_rtx_CONST_VECTOR (mode, v); + operands[4] = gen_reg_rtx (mode); +}) + +;; Generate +;; vspltisw SCRATCH1,0 +;; vsubu?m SCRATCH2,SCRATCH1,%1 +;; vmins? %0,%1,SCRATCH2" +(define_expand "nabs2" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 4) + (minus:VI2 (match_dup 2) + (match_operand:VI2 1 "register_operand" "v"))) + (set (match_operand:VI2 0 "register_operand" "=v") + (smin:VI2 (match_dup 1) (match_dup 4)))] + "" +{ + int i; + int n_elt = GET_MODE_NUNITS (mode); + + rtvec v = rtvec_alloc (n_elt); + + /* Create an all 0 constant. */ + for (i = 0; i < n_elt; ++i) + RTVEC_ELT (v, i) = const0_rtx; + + operands[2] = gen_reg_rtx (mode); + operands[3] = gen_rtx_CONST_VECTOR (mode, v); + operands[4] = gen_reg_rtx (mode); +}) + +;; Generate +;; vspltisw SCRATCH1,-1 +;; vslw SCRATCH2,SCRATCH1,SCRATCH1 +;; vandc %0,%1,SCRATCH2 +(define_expand "altivec_absv4sf2" + [(set (match_dup 2) + (vec_duplicate:V4SI (const_int -1))) + (set (match_dup 3) + (ashift:V4SI (match_dup 2) (match_dup 2))) + (set (match_operand:V4SF 0 "register_operand" "=v") + (and:V4SF (not:V4SF (subreg:V4SF (match_dup 3) 0)) + (match_operand:V4SF 1 "register_operand" "v")))] + "TARGET_ALTIVEC" +{ + operands[2] = gen_reg_rtx (V4SImode); + operands[3] = gen_reg_rtx (V4SImode); +}) + +;; Generate +;; vspltis? SCRATCH0,0 +;; vsubs?s SCRATCH2,SCRATCH1,%1 +;; vmaxs? %0,%1,SCRATCH2" +(define_expand "altivec_abss_" + [(set (match_dup 2) (vec_duplicate:VI (const_int 0))) + (parallel [(set (match_dup 3) + (unspec:VI [(match_dup 2) + (match_operand:VI 1 "register_operand" "v")] + UNSPEC_VSUBS)) + (set (reg:SI VSCR_REGNO) + (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))]) + (set (match_operand:VI 0 "register_operand" "=v") + (smax:VI (match_dup 1) (match_dup 3)))] + "TARGET_ALTIVEC" +{ + operands[2] = gen_reg_rtx (GET_MODE (operands[0])); + operands[3] = gen_reg_rtx (GET_MODE (operands[0])); +}) + +(define_expand "reduc_plus_scal_" + [(set (match_operand: 0 "register_operand" "=v") + (unspec:VIshort [(match_operand:VIshort 1 "register_operand" "v")] + UNSPEC_REDUC_PLUS))] + "TARGET_ALTIVEC" +{ + rtx vzero = gen_reg_rtx (V4SImode); + rtx vtmp1 = gen_reg_rtx (V4SImode); + rtx vtmp2 = gen_reg_rtx (mode); + rtx dest = gen_lowpart (V4SImode, vtmp2); + int elt = VECTOR_ELT_ORDER_BIG ? GET_MODE_NUNITS (mode) - 1 : 0; + + emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); + emit_insn (gen_altivec_vsum4ss (vtmp1, operands[1], vzero)); + emit_insn (gen_altivec_vsumsws_direct (dest, vtmp1, vzero)); + rs6000_expand_vector_extract (operands[0], vtmp2, GEN_INT (elt)); + DONE; +}) + +(define_insn "*p9_neg2" + [(set (match_operand:VNEG 0 "altivec_register_operand" "=v") + (neg:VNEG (match_operand:VNEG 1 "altivec_register_operand" "v")))] + "TARGET_P9_VECTOR" + "vneg %0,%1" + [(set_attr "type" "vecsimple")]) + +(define_expand "neg2" + [(set (match_operand:VI2 0 "register_operand" "") + (neg:VI2 (match_operand:VI2 1 "register_operand" "")))] + "" +{ + if (!TARGET_P9_VECTOR || (mode != V4SImode && mode != V2DImode)) + { + rtx vzero; + + vzero = gen_reg_rtx (GET_MODE (operands[0])); + emit_move_insn (vzero, CONST0_RTX (mode)); + emit_insn (gen_sub3 (operands[0], vzero, operands[1])); + DONE; + } +}) + +(define_expand "udot_prod" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") + (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v") + (match_operand:VIshort 2 "register_operand" "v")] + UNSPEC_VMSUMU)))] + "TARGET_ALTIVEC" + " +{ + emit_insn (gen_altivec_vmsumum (operands[0], operands[1], operands[2], operands[3])); + DONE; +}") + +(define_expand "sdot_prodv8hi" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (plus:V4SI (match_operand:V4SI 3 "register_operand" "v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMSUMSHM)))] + "TARGET_ALTIVEC" + " +{ + emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], operands[2], operands[3])); + DONE; +}") + +(define_expand "widen_usum3" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") + (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")] + UNSPEC_VMSUMU)))] + "TARGET_ALTIVEC" + " +{ + rtx vones = gen_reg_rtx (GET_MODE (operands[1])); + + emit_insn (gen_altivec_vspltis (vones, const1_rtx)); + emit_insn (gen_altivec_vmsumum (operands[0], operands[1], vones, operands[2])); + DONE; +}") + +(define_expand "widen_ssumv16qi3" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") + (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v")] + UNSPEC_VMSUMM)))] + "TARGET_ALTIVEC" + " +{ + rtx vones = gen_reg_rtx (V16QImode); + + emit_insn (gen_altivec_vspltisb (vones, const1_rtx)); + emit_insn (gen_altivec_vmsummbm (operands[0], operands[1], vones, operands[2])); + DONE; +}") + +(define_expand "widen_ssumv8hi3" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (plus:V4SI (match_operand:V4SI 2 "register_operand" "v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] + UNSPEC_VMSUMSHM)))] + "TARGET_ALTIVEC" + " +{ + rtx vones = gen_reg_rtx (V8HImode); + + emit_insn (gen_altivec_vspltish (vones, const1_rtx)); + emit_insn (gen_altivec_vmsumshm (operands[0], operands[1], vones, operands[2])); + DONE; +}") + +(define_expand "vec_unpacks_hi_" + [(set (match_operand:VP 0 "register_operand" "=v") + (unspec:VP [(match_operand: 1 "register_operand" "v")] + UNSPEC_VUNPACK_HI_SIGN_DIRECT))] + "" + "") + +(define_expand "vec_unpacks_lo_" + [(set (match_operand:VP 0 "register_operand" "=v") + (unspec:VP [(match_operand: 1 "register_operand" "v")] + UNSPEC_VUNPACK_LO_SIGN_DIRECT))] + "" + "") + +(define_insn "vperm_v8hiv4si" + [(set (match_operand:V4SI 0 "register_operand" "=v,?wo") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v,wo") + (match_operand:V4SI 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] + UNSPEC_VPERMSI))] + "TARGET_ALTIVEC" + "@ + vperm %0,%1,%2,%3 + xxperm %x0,%x1,%x3" + [(set_attr "type" "vecperm") + (set_attr "length" "4")]) + +(define_insn "vperm_v16qiv8hi" + [(set (match_operand:V8HI 0 "register_operand" "=v,?wo") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v,wo") + (match_operand:V8HI 2 "register_operand" "v,0") + (match_operand:V16QI 3 "register_operand" "v,wo")] + UNSPEC_VPERMHI))] + "TARGET_ALTIVEC" + "@ + vperm %0,%1,%2,%3 + xxperm %x0,%x1,%x3" + [(set_attr "type" "vecperm") + (set_attr "length" "4")]) + + +(define_expand "vec_unpacku_hi_v16qi" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] + UNSPEC_VUPKHUB))] + "TARGET_ALTIVEC" + " +{ + rtx vzero = gen_reg_rtx (V8HImode); + rtx mask = gen_reg_rtx (V16QImode); + rtvec v = rtvec_alloc (16); + bool be = BYTES_BIG_ENDIAN; + + emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); + + RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); + RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 0 : 16); + RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 6); + RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); + RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); + RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 2 : 16); + RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 4); + RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); + RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); + RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 4 : 16); + RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 2); + RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); + RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); + RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 6 : 16); + RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 0); + RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); + + emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v))); + emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); + DONE; +}") + +(define_expand "vec_unpacku_hi_v8hi" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] + UNSPEC_VUPKHUH))] + "TARGET_ALTIVEC" + " +{ + rtx vzero = gen_reg_rtx (V4SImode); + rtx mask = gen_reg_rtx (V16QImode); + rtvec v = rtvec_alloc (16); + bool be = BYTES_BIG_ENDIAN; + + emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); + + RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 7); + RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 6); + RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 0 : 17); + RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 1 : 16); + RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 5); + RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 4); + RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 2 : 17); + RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 3 : 16); + RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 3); + RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 2); + RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 4 : 17); + RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 5 : 16); + RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 1); + RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 0); + RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 6 : 17); + RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 7 : 16); + + emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v))); + emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); + DONE; +}") + +(define_expand "vec_unpacku_lo_v16qi" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] + UNSPEC_VUPKLUB))] + "TARGET_ALTIVEC" + " +{ + rtx vzero = gen_reg_rtx (V8HImode); + rtx mask = gen_reg_rtx (V16QImode); + rtvec v = rtvec_alloc (16); + bool be = BYTES_BIG_ENDIAN; + + emit_insn (gen_altivec_vspltish (vzero, const0_rtx)); + + RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); + RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 8 : 16); + RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 16 : 14); + RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); + RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); + RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 10 : 16); + RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 16 : 12); + RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); + RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); + RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 12 : 16); + RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 16 : 10); + RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); + RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); + RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 14 : 16); + RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 16 : 8); + RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); + + emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v))); + emit_insn (gen_vperm_v16qiv8hi (operands[0], operands[1], vzero, mask)); + DONE; +}") + +(define_expand "vec_unpacku_lo_v8hi" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] + UNSPEC_VUPKLUH))] + "TARGET_ALTIVEC" + " +{ + rtx vzero = gen_reg_rtx (V4SImode); + rtx mask = gen_reg_rtx (V16QImode); + rtvec v = rtvec_alloc (16); + bool be = BYTES_BIG_ENDIAN; + + emit_insn (gen_altivec_vspltisw (vzero, const0_rtx)); + + RTVEC_ELT (v, 0) = gen_rtx_CONST_INT (QImode, be ? 16 : 15); + RTVEC_ELT (v, 1) = gen_rtx_CONST_INT (QImode, be ? 17 : 14); + RTVEC_ELT (v, 2) = gen_rtx_CONST_INT (QImode, be ? 8 : 17); + RTVEC_ELT (v, 3) = gen_rtx_CONST_INT (QImode, be ? 9 : 16); + RTVEC_ELT (v, 4) = gen_rtx_CONST_INT (QImode, be ? 16 : 13); + RTVEC_ELT (v, 5) = gen_rtx_CONST_INT (QImode, be ? 17 : 12); + RTVEC_ELT (v, 6) = gen_rtx_CONST_INT (QImode, be ? 10 : 17); + RTVEC_ELT (v, 7) = gen_rtx_CONST_INT (QImode, be ? 11 : 16); + RTVEC_ELT (v, 8) = gen_rtx_CONST_INT (QImode, be ? 16 : 11); + RTVEC_ELT (v, 9) = gen_rtx_CONST_INT (QImode, be ? 17 : 10); + RTVEC_ELT (v, 10) = gen_rtx_CONST_INT (QImode, be ? 12 : 17); + RTVEC_ELT (v, 11) = gen_rtx_CONST_INT (QImode, be ? 13 : 16); + RTVEC_ELT (v, 12) = gen_rtx_CONST_INT (QImode, be ? 16 : 9); + RTVEC_ELT (v, 13) = gen_rtx_CONST_INT (QImode, be ? 17 : 8); + RTVEC_ELT (v, 14) = gen_rtx_CONST_INT (QImode, be ? 14 : 17); + RTVEC_ELT (v, 15) = gen_rtx_CONST_INT (QImode, be ? 15 : 16); + + emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v))); + emit_insn (gen_vperm_v8hiv4si (operands[0], operands[1], vzero, mask)); + DONE; +}") + +(define_expand "vec_widen_umult_hi_v16qi" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMULWHUB))] + "TARGET_ALTIVEC" + " +{ + rtx ve = gen_reg_rtx (V8HImode); + rtx vo = gen_reg_rtx (V8HImode); + + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo)); + } + else + { + emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve)); + } + DONE; +}") + +(define_expand "vec_widen_umult_lo_v16qi" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMULWLUB))] + "TARGET_ALTIVEC" + " +{ + rtx ve = gen_reg_rtx (V8HImode); + rtx vo = gen_reg_rtx (V8HImode); + + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vmuleub (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmuloub (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo)); + } + else + { + emit_insn (gen_altivec_vmuloub (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmuleub (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve)); + } + DONE; +}") + +(define_expand "vec_widen_smult_hi_v16qi" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMULWHSB))] + "TARGET_ALTIVEC" + " +{ + rtx ve = gen_reg_rtx (V8HImode); + rtx vo = gen_reg_rtx (V8HImode); + + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrghh_direct (operands[0], ve, vo)); + } + else + { + emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrghh_direct (operands[0], vo, ve)); + } + DONE; +}") + +(define_expand "vec_widen_smult_lo_v16qi" + [(set (match_operand:V8HI 0 "register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VMULWLSB))] + "TARGET_ALTIVEC" + " +{ + rtx ve = gen_reg_rtx (V8HImode); + rtx vo = gen_reg_rtx (V8HImode); + + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vmulesb (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulosb (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrglh_direct (operands[0], ve, vo)); + } + else + { + emit_insn (gen_altivec_vmulosb (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulesb (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrglh_direct (operands[0], vo, ve)); + } + DONE; +}") + +(define_expand "vec_widen_umult_hi_v8hi" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMULWHUH))] + "TARGET_ALTIVEC" + " +{ + rtx ve = gen_reg_rtx (V4SImode); + rtx vo = gen_reg_rtx (V4SImode); + + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo)); + } + else + { + emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve)); + } + DONE; +}") + +(define_expand "vec_widen_umult_lo_v8hi" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMULWLUH))] + "TARGET_ALTIVEC" + " +{ + rtx ve = gen_reg_rtx (V4SImode); + rtx vo = gen_reg_rtx (V4SImode); + + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vmuleuh (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulouh (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo)); + } + else + { + emit_insn (gen_altivec_vmulouh (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmuleuh (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve)); + } + DONE; +}") + +(define_expand "vec_widen_smult_hi_v8hi" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMULWHSH))] + "TARGET_ALTIVEC" + " +{ + rtx ve = gen_reg_rtx (V4SImode); + rtx vo = gen_reg_rtx (V4SImode); + + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrghw_direct (operands[0], ve, vo)); + } + else + { + emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrghw_direct (operands[0], vo, ve)); + } + DONE; +}") + +(define_expand "vec_widen_smult_lo_v8hi" + [(set (match_operand:V4SI 0 "register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") + (match_operand:V8HI 2 "register_operand" "v")] + UNSPEC_VMULWLSH))] + "TARGET_ALTIVEC" + " +{ + rtx ve = gen_reg_rtx (V4SImode); + rtx vo = gen_reg_rtx (V4SImode); + + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vmulesh (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulosh (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrglw_direct (operands[0], ve, vo)); + } + else + { + emit_insn (gen_altivec_vmulosh (ve, operands[1], operands[2])); + emit_insn (gen_altivec_vmulesh (vo, operands[1], operands[2])); + emit_insn (gen_altivec_vmrglw_direct (operands[0], vo, ve)); + } + DONE; +}") + +(define_expand "vec_pack_trunc_" + [(set (match_operand: 0 "register_operand" "=v") + (unspec: [(match_operand:VP 1 "register_operand" "v") + (match_operand:VP 2 "register_operand" "v")] + UNSPEC_VPACK_UNS_UNS_MOD))] + "" + "") + +(define_expand "mulv16qi3" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (mult:V16QI (match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")))] + "TARGET_ALTIVEC" + " +{ + rtx even = gen_reg_rtx (V8HImode); + rtx odd = gen_reg_rtx (V8HImode); + rtx mask = gen_reg_rtx (V16QImode); + rtvec v = rtvec_alloc (16); + int i; + + for (i = 0; i < 8; ++i) { + RTVEC_ELT (v, 2 * i) + = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 1 : 31 - 2 * i); + RTVEC_ELT (v, 2 * i + 1) + = gen_rtx_CONST_INT (QImode, BYTES_BIG_ENDIAN ? 2 * i + 17 : 15 - 2 * i); + } + + emit_insn (gen_vec_initv16qi (mask, gen_rtx_PARALLEL (V16QImode, v))); + emit_insn (gen_altivec_vmulesb (even, operands[1], operands[2])); + emit_insn (gen_altivec_vmulosb (odd, operands[1], operands[2])); + emit_insn (gen_altivec_vperm_v8hiv16qi (operands[0], even, odd, mask)); + DONE; +}") + +(define_expand "altivec_negv4sf2" + [(use (match_operand:V4SF 0 "register_operand" "")) + (use (match_operand:V4SF 1 "register_operand" ""))] + "TARGET_ALTIVEC" + " +{ + rtx neg0; + + /* Generate [-0.0, -0.0, -0.0, -0.0]. */ + neg0 = gen_reg_rtx (V4SImode); + emit_insn (gen_altivec_vspltisw (neg0, constm1_rtx)); + emit_insn (gen_vashlv4si3 (neg0, neg0, neg0)); + + /* XOR */ + emit_insn (gen_xorv4sf3 (operands[0], + gen_lowpart (V4SFmode, neg0), operands[1])); + + DONE; +}") + +;; Vector SIMD PEM v2.06c defines LVLX, LVLXL, LVRX, LVRXL, +;; STVLX, STVLXL, STVVRX, STVRXL are available only on Cell. +(define_insn "altivec_lvlx" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] + UNSPEC_LVLX))] + "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" + "lvlx %0,%y1" + [(set_attr "type" "vecload")]) + +(define_insn "altivec_lvlxl" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] + UNSPEC_LVLXL))] + "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" + "lvlxl %0,%y1" + [(set_attr "type" "vecload")]) + +(define_insn "altivec_lvrx" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] + UNSPEC_LVRX))] + "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" + "lvrx %0,%y1" + [(set_attr "type" "vecload")]) + +(define_insn "altivec_lvrxl" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:BLK 1 "memory_operand" "Z")] + UNSPEC_LVRXL))] + "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" + "lvrxl %0,%y1" + [(set_attr "type" "vecload")]) + +(define_insn "altivec_stvlx" + [(parallel + [(set (match_operand:V16QI 0 "memory_operand" "=Z") + (match_operand:V16QI 1 "register_operand" "v")) + (unspec [(const_int 0)] UNSPEC_STVLX)])] + "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" + "stvlx %1,%y0" + [(set_attr "type" "vecstore")]) + +(define_insn "altivec_stvlxl" + [(parallel + [(set (match_operand:V16QI 0 "memory_operand" "=Z") + (match_operand:V16QI 1 "register_operand" "v")) + (unspec [(const_int 0)] UNSPEC_STVLXL)])] + "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" + "stvlxl %1,%y0" + [(set_attr "type" "vecstore")]) + +(define_insn "altivec_stvrx" + [(parallel + [(set (match_operand:V16QI 0 "memory_operand" "=Z") + (match_operand:V16QI 1 "register_operand" "v")) + (unspec [(const_int 0)] UNSPEC_STVRX)])] + "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" + "stvrx %1,%y0" + [(set_attr "type" "vecstore")]) + +(define_insn "altivec_stvrxl" + [(parallel + [(set (match_operand:V16QI 0 "memory_operand" "=Z") + (match_operand:V16QI 1 "register_operand" "v")) + (unspec [(const_int 0)] UNSPEC_STVRXL)])] + "TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL" + "stvrxl %1,%y0" + [(set_attr "type" "vecstore")]) + +(define_expand "vec_unpacks_float_hi_v8hi" + [(set (match_operand:V4SF 0 "register_operand" "") + (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] + UNSPEC_VUPKHS_V4SF))] + "TARGET_ALTIVEC" + " +{ + rtx tmp = gen_reg_rtx (V4SImode); + + emit_insn (gen_vec_unpacks_hi_v8hi (tmp, operands[1])); + emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); + DONE; +}") + +(define_expand "vec_unpacks_float_lo_v8hi" + [(set (match_operand:V4SF 0 "register_operand" "") + (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] + UNSPEC_VUPKLS_V4SF))] + "TARGET_ALTIVEC" + " +{ + rtx tmp = gen_reg_rtx (V4SImode); + + emit_insn (gen_vec_unpacks_lo_v8hi (tmp, operands[1])); + emit_insn (gen_altivec_vcfsx (operands[0], tmp, const0_rtx)); + DONE; +}") + +(define_expand "vec_unpacku_float_hi_v8hi" + [(set (match_operand:V4SF 0 "register_operand" "") + (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] + UNSPEC_VUPKHU_V4SF))] + "TARGET_ALTIVEC" + " +{ + rtx tmp = gen_reg_rtx (V4SImode); + + emit_insn (gen_vec_unpacku_hi_v8hi (tmp, operands[1])); + emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); + DONE; +}") + +(define_expand "vec_unpacku_float_lo_v8hi" + [(set (match_operand:V4SF 0 "register_operand" "") + (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "")] + UNSPEC_VUPKLU_V4SF))] + "TARGET_ALTIVEC" + " +{ + rtx tmp = gen_reg_rtx (V4SImode); + + emit_insn (gen_vec_unpacku_lo_v8hi (tmp, operands[1])); + emit_insn (gen_altivec_vcfux (operands[0], tmp, const0_rtx)); + DONE; +}") + + +;; Power8/power9 vector instructions encoded as Altivec instructions + +;; Vector count leading zeros +(define_insn "*p8v_clz2" + [(set (match_operand:VI2 0 "register_operand" "=v") + (clz:VI2 (match_operand:VI2 1 "register_operand" "v")))] + "TARGET_P8_VECTOR" + "vclz %0,%1" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +;; Vector absolute difference unsigned +(define_expand "vadu3" + [(set (match_operand:VI 0 "register_operand") + (unspec:VI [(match_operand:VI 1 "register_operand") + (match_operand:VI 2 "register_operand")] + UNSPEC_VADU))] + "TARGET_P9_VECTOR") + +;; Vector absolute difference unsigned +(define_insn "*p9_vadu3" + [(set (match_operand:VI 0 "register_operand" "=v") + (unspec:VI [(match_operand:VI 1 "register_operand" "v") + (match_operand:VI 2 "register_operand" "v")] + UNSPEC_VADU))] + "TARGET_P9_VECTOR" + "vabsdu %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +;; Vector count trailing zeros +(define_insn "*p9v_ctz2" + [(set (match_operand:VI2 0 "register_operand" "=v") + (ctz:VI2 (match_operand:VI2 1 "register_operand" "v")))] + "TARGET_P9_VECTOR" + "vctz %0,%1" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +;; Vector population count +(define_insn "*p8v_popcount2" + [(set (match_operand:VI2 0 "register_operand" "=v") + (popcount:VI2 (match_operand:VI2 1 "register_operand" "v")))] + "TARGET_P8_VECTOR" + "vpopcnt %0,%1" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +;; Vector parity +(define_insn "*p9v_parity2" + [(set (match_operand:VParity 0 "register_operand" "=v") + (parity:VParity (match_operand:VParity 1 "register_operand" "v")))] + "TARGET_P9_VECTOR" + "vprtyb %0,%1" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +;; Vector Gather Bits by Bytes by Doubleword +(define_insn "p8v_vgbbd" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] + UNSPEC_VGBBD))] + "TARGET_P8_VECTOR" + "vgbbd %0,%1" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + + +;; 128-bit binary integer arithmetic +;; We have a special container type (V1TImode) to allow operations using the +;; ISA 2.07 128-bit binary support to target the VMX/altivec registers without +;; having to worry about the register allocator deciding GPRs are better. + +(define_insn "altivec_vadduqm" + [(set (match_operand:V1TI 0 "register_operand" "=v") + (plus:V1TI (match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v")))] + "TARGET_VADDUQM" + "vadduqm %0,%1,%2" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +(define_insn "altivec_vaddcuq" + [(set (match_operand:V1TI 0 "register_operand" "=v") + (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v")] + UNSPEC_VADDCUQ))] + "TARGET_VADDUQM" + "vaddcuq %0,%1,%2" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +(define_insn "altivec_vsubuqm" + [(set (match_operand:V1TI 0 "register_operand" "=v") + (minus:V1TI (match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v")))] + "TARGET_VADDUQM" + "vsubuqm %0,%1,%2" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +(define_insn "altivec_vsubcuq" + [(set (match_operand:V1TI 0 "register_operand" "=v") + (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v")] + UNSPEC_VSUBCUQ))] + "TARGET_VADDUQM" + "vsubcuq %0,%1,%2" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +(define_insn "altivec_vaddeuqm" + [(set (match_operand:V1TI 0 "register_operand" "=v") + (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v") + (match_operand:V1TI 3 "register_operand" "v")] + UNSPEC_VADDEUQM))] + "TARGET_VADDUQM" + "vaddeuqm %0,%1,%2,%3" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +(define_insn "altivec_vaddecuq" + [(set (match_operand:V1TI 0 "register_operand" "=v") + (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v") + (match_operand:V1TI 3 "register_operand" "v")] + UNSPEC_VADDECUQ))] + "TARGET_VADDUQM" + "vaddecuq %0,%1,%2,%3" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +(define_insn "altivec_vsubeuqm" + [(set (match_operand:V1TI 0 "register_operand" "=v") + (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v") + (match_operand:V1TI 3 "register_operand" "v")] + UNSPEC_VSUBEUQM))] + "TARGET_VADDUQM" + "vsubeuqm %0,%1,%2,%3" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +(define_insn "altivec_vsubecuq" + [(set (match_operand:V1TI 0 "register_operand" "=v") + (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v") + (match_operand:V1TI 3 "register_operand" "v")] + UNSPEC_VSUBECUQ))] + "TARGET_VADDUQM" + "vsubecuq %0,%1,%2,%3" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +;; We use V2DI as the output type to simplify converting the permute +;; bits into an integer +(define_insn "altivec_vbpermq" + [(set (match_operand:V2DI 0 "register_operand" "=v") + (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VBPERMQ))] + "TARGET_P8_VECTOR" + "vbpermq %0,%1,%2" + [(set_attr "type" "vecperm")]) + +; One of the vector API interfaces requires returning vector unsigned char. +(define_insn "altivec_vbpermq2" + [(set (match_operand:V16QI 0 "register_operand" "=v") + (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VBPERMQ))] + "TARGET_P8_VECTOR" + "vbpermq %0,%1,%2" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vbpermd" + [(set (match_operand:V2DI 0 "register_operand" "=v") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v") + (match_operand:V16QI 2 "register_operand" "v")] + UNSPEC_VBPERMD))] + "TARGET_P9_VECTOR" + "vbpermd %0,%1,%2" + [(set_attr "type" "vecsimple")]) + +;; Decimal Integer operations +(define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB]) + +(define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add") + (UNSPEC_BCDSUB "sub")]) + +(define_code_iterator BCD_TEST [eq lt gt unordered]) + +(define_insn "bcd" + [(set (match_operand:V1TI 0 "gpc_reg_operand" "=v") + (unspec:V1TI [(match_operand:V1TI 1 "gpc_reg_operand" "v") + (match_operand:V1TI 2 "gpc_reg_operand" "v") + (match_operand:QI 3 "const_0_to_1_operand" "n")] + UNSPEC_BCD_ADD_SUB)) + (clobber (reg:CCFP CR6_REGNO))] + "TARGET_P8_VECTOR" + "bcd. %0,%1,%2,%3" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we +;; can use the unordered test for BCD nans and add/subtracts that overflow. An +;; UNORDERED test on an integer type (like V1TImode) is not defined. The type +;; probably should be one that can go in the VMX (Altivec) registers, so we +;; can't use DDmode or DFmode. +(define_insn "*bcd_test" + [(set (reg:CCFP CR6_REGNO) + (compare:CCFP + (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v") + (match_operand:QI 3 "const_0_to_1_operand" "i")] + UNSPEC_BCD_ADD_SUB) + (match_operand:V2DF 4 "zero_constant" "j"))) + (clobber (match_scratch:V1TI 0 "=v"))] + "TARGET_P8_VECTOR" + "bcd. %0,%1,%2,%3" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +(define_insn "*bcd_test2" + [(set (match_operand:V1TI 0 "register_operand" "=v") + (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v") + (match_operand:V1TI 2 "register_operand" "v") + (match_operand:QI 3 "const_0_to_1_operand" "i")] + UNSPEC_BCD_ADD_SUB)) + (set (reg:CCFP CR6_REGNO) + (compare:CCFP + (unspec:V2DF [(match_dup 1) + (match_dup 2) + (match_dup 3)] + UNSPEC_BCD_ADD_SUB) + (match_operand:V2DF 4 "zero_constant" "j")))] + "TARGET_P8_VECTOR" + "bcd. %0,%1,%2,%3" + [(set_attr "length" "4") + (set_attr "type" "vecsimple")]) + +(define_insn "darn_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(const_int 0)] UNSPEC_DARN_32))] + "TARGET_P9_MISC" + "darn %0,0" + [(set_attr "type" "integer")]) + +(define_insn "darn_raw" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))] + "TARGET_P9_MISC && TARGET_64BIT" + "darn %0,2" + [(set_attr "type" "integer")]) + +(define_insn "darn" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_DARN))] + "TARGET_P9_MISC && TARGET_64BIT" + "darn %0,1" + [(set_attr "type" "integer")]) + +;; Test byte within range. +;; +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the range specified by operand 2. +;; The bytes of operand 2 are organized as xx:xx:hi:lo. +;; +;; Return in target register operand 0 a value of 1 if lo <= vv and +;; vv <= hi. Otherwise, set register operand 0 to 0. +;; +;; Though the instructions to which this expansion maps operate on +;; 64-bit registers, the current implementation only operates on +;; SI-mode operands as the high-order bits provide no information +;; that is not already available in the low-order bits. To avoid the +;; costs of data widening operations, future enhancements might allow +;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. +(define_expand "cmprb" + [(set (match_dup 3) + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPRB)) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (lt (match_dup 3) + (const_int 0)) + (const_int -1) + (if_then_else (gt (match_dup 3) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC" +{ + operands[3] = gen_reg_rtx (CCmode); +}) + +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the range specified by operand 2. +;; The bytes of operand 2 are organized as xx:xx:hi:lo. +;; +;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if +;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other +;; 3 bits of the target CR register are all set to 0. +(define_insn "*cmprb_internal" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPRB))] + "TARGET_P9_MISC" + "cmprb %0,0,%1,%2" + [(set_attr "type" "logical")]) + +;; Set operand 0 register to -1 if the LT bit (0x8) of condition +;; register operand 1 is on. Otherwise, set operand 0 register to 1 +;; if the GT bit (0x4) of condition register operand 1 is on. +;; Otherwise, set operand 0 to 0. Note that the result stored into +;; register operand 0 is non-zero iff either the LT or GT bits are on +;; within condition register operand 1. +(define_insn "setb_signed" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") + (const_int 0)) + (const_int -1) + (if_then_else (gt (match_dup 1) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC" + "setb %0,%1" + [(set_attr "type" "logical")]) + +(define_insn "setb_unsigned" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") + (const_int 0)) + (const_int -1) + (if_then_else (gtu (match_dup 1) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC" + "setb %0,%1" + [(set_attr "type" "logical")]) + +;; Test byte within two ranges. +;; +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the range specified by operand 2. +;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. +;; +;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and +;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register +;; operand 0 to 0. +;; +;; Though the instructions to which this expansion maps operate on +;; 64-bit registers, the current implementation only operates on +;; SI-mode operands as the high-order bits provide no information +;; that is not already available in the low-order bits. To avoid the +;; costs of data widening operations, future enhancements might allow +;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. +(define_expand "cmprb2" + [(set (match_dup 3) + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPRB2)) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (lt (match_dup 3) + (const_int 0)) + (const_int -1) + (if_then_else (gt (match_dup 3) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC" +{ + operands[3] = gen_reg_rtx (CCmode); +}) + +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the ranges specified by operand 2. +;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. +;; +;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if +;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). +;; Otherwise, set the GT bit to 0. The other 3 bits of the target +;; CR register are all set to 0. +(define_insn "*cmprb2_internal" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPRB2))] + "TARGET_P9_MISC" + "cmprb %0,1,%1,%2" + [(set_attr "type" "logical")]) + +;; Test byte membership within set of 8 bytes. +;; +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the set specified by operand 2. +;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. +;; +;; Return in target register operand 0 a value of 1 if vv equals one +;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set +;; register operand 0 to 0. Note that the 8 byte values held within +;; operand 2 need not be unique. +;; +;; Though the instructions to which this expansion maps operate on +;; 64-bit registers, the current implementation requires that operands +;; 0 and 1 have mode SI as the high-order bits provide no information +;; that is not already available in the low-order bits. To avoid the +;; costs of data widening operations, future enhancements might allow +;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. +(define_expand "cmpeqb" + [(set (match_dup 3) + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPEQB)) + (set (match_operand:SI 0 "gpc_reg_operand" "=r") + (if_then_else:SI (lt (match_dup 3) + (const_int 0)) + (const_int -1) + (if_then_else (gt (match_dup 3) + (const_int 0)) + (const_int 1) + (const_int 0))))] + "TARGET_P9_MISC && TARGET_64BIT" +{ + operands[3] = gen_reg_rtx (CCmode); +}) + +;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx +;; represents a byte whose value is ignored in this context and +;; vv, the least significant byte, holds the byte value that is to +;; be tested for membership within the set specified by operand 2. +;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. +;; +;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv +;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, +;; set the GT bit to zero. The other 3 bits of the target CR register +;; are all set to 0. +(define_insn "*cmpeqb_internal" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "gpc_reg_operand" "r")] + UNSPEC_CMPEQB))] + "TARGET_P9_MISC && TARGET_64BIT" + "cmpeqb %0,%1,%2" + [(set_attr "type" "logical")]) + +(define_expand "bcd_" + [(parallel [(set (reg:CCFP CR6_REGNO) + (compare:CCFP + (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "") + (match_operand:V1TI 2 "register_operand" "") + (match_operand:QI 3 "const_0_to_1_operand" "")] + UNSPEC_BCD_ADD_SUB) + (match_dup 4))) + (clobber (match_scratch:V1TI 5 ""))]) + (set (match_operand:SI 0 "register_operand" "") + (BCD_TEST:SI (reg:CCFP CR6_REGNO) + (const_int 0)))] + "TARGET_P8_VECTOR" +{ + operands[4] = CONST0_RTX (V2DFmode); +}) + +;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and +;; the bcdadd/bcdsub that tests the value. The combiner won't work since +;; CR6 is a hard coded register. Unfortunately, all of the Altivec predicate +;; support is hard coded to use the fixed register CR6 instead of creating +;; a register class for CR6. + +(define_peephole2 + [(parallel [(set (match_operand:V1TI 0 "register_operand" "") + (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "") + (match_operand:V1TI 2 "register_operand" "") + (match_operand:QI 3 "const_0_to_1_operand" "")] + UNSPEC_BCD_ADD_SUB)) + (clobber (reg:CCFP CR6_REGNO))]) + (parallel [(set (reg:CCFP CR6_REGNO) + (compare:CCFP + (unspec:V2DF [(match_dup 1) + (match_dup 2) + (match_dup 3)] + UNSPEC_BCD_ADD_SUB) + (match_operand:V2DF 4 "zero_constant" ""))) + (clobber (match_operand:V1TI 5 "register_operand" ""))])] + "TARGET_P8_VECTOR" + [(parallel [(set (match_dup 0) + (unspec:V1TI [(match_dup 1) + (match_dup 2) + (match_dup 3)] + UNSPEC_BCD_ADD_SUB)) + (set (reg:CCFP CR6_REGNO) + (compare:CCFP + (unspec:V2DF [(match_dup 1) + (match_dup 2) + (match_dup 3)] + UNSPEC_BCD_ADD_SUB) + (match_dup 4)))])]) diff --git a/gcc/config/powerpcspe/biarch64.h b/gcc/config/powerpcspe/biarch64.h new file mode 100644 index 00000000000..8a11ca8e17d --- /dev/null +++ b/gcc/config/powerpcspe/biarch64.h @@ -0,0 +1,26 @@ +/* Definitions of target machine for GNU compiler, for 32/64 bit powerpc. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Specify this in a cover file to provide bi-architecture (32/64) support. */ +#define RS6000_BI_ARCH 1 diff --git a/gcc/config/powerpcspe/bmi2intrin.h b/gcc/config/powerpcspe/bmi2intrin.h new file mode 100644 index 00000000000..fc634c1ed60 --- /dev/null +++ b/gcc/config/powerpcspe/bmi2intrin.h @@ -0,0 +1,169 @@ +/* Copyright (C) 2011-2017 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* This header is distributed to simplify porting x86_64 code that + makes explicit use of Intel intrinsics to powerpc64le. + It is the user's responsibility to determine if the results are + acceptable and make additional changes as necessary. + Note that much code that uses Intel intrinsics can be rewritten in + standard C or GNU C extensions, which are more portable and better + optimized across multiple targets. */ + +#if !defined _X86INTRIN_H_INCLUDED +# error "Never use directly; include instead." +#endif + +#ifndef _BMI2INTRIN_H_INCLUDED +#define _BMI2INTRIN_H_INCLUDED + +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_bzhi_u32 (unsigned int __X, unsigned int __Y) +{ + return ((__X << (32 - __Y)) >> (32 - __Y)); +} + +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mulx_u32 (unsigned int __X, unsigned int __Y, unsigned int *__P) +{ + unsigned long long __res = (unsigned long long) __X * __Y; + *__P = (unsigned int) (__res >> 32); + return (unsigned int) __res; +} + +#ifdef __PPC64__ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_bzhi_u64 (unsigned long long __X, unsigned long long __Y) +{ + return ((__X << (64 - __Y)) >> (64 - __Y)); +} + +/* __int128 requires base 64-bit. */ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mulx_u64 (unsigned long long __X, unsigned long long __Y, + unsigned long long *__P) +{ + unsigned __int128 __res = (unsigned __int128) __X * __Y; + *__P = (unsigned long long) (__res >> 64); + return (unsigned long long) __res; +} + +#ifdef _ARCH_PWR7 +/* popcount and bpermd require power7 minimum. */ +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_pdep_u64 (unsigned long long __X, unsigned long long __M) +{ + unsigned long result = 0x0UL; + const unsigned long mask = 0x8000000000000000UL; + unsigned long m = __M; + unsigned long c, t; + unsigned long p; + + /* The pop-count of the mask gives the number of the bits from + source to process. This is also needed to shift bits from the + source into the correct position for the result. */ + p = 64 - __builtin_popcountl (__M); + + /* The loop is for the number of '1' bits in the mask and clearing + each mask bit as it is processed. */ + while (m != 0) + { + c = __builtin_clzl (m); + t = __X << (p - c); + m ^= (mask >> c); + result |= (t & (mask >> c)); + p++; + } + return (result); +} + +extern __inline unsigned long long +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_pext_u64 (unsigned long long __X, unsigned long long __M) +{ + unsigned long p = 0x4040404040404040UL; // initial bit permute control + const unsigned long mask = 0x8000000000000000UL; + unsigned long m = __M; + unsigned long c; + unsigned long result; + + /* if the mask is constant and selects 8 bits or less we can use + the Power8 Bit permute instruction. */ + if (__builtin_constant_p (__M) && (__builtin_popcountl (__M) <= 8)) + { + /* Also if the pext mask is constant, then the popcount is + constant, we can evaluate the following loop at compile + time and use a constant bit permute vector. */ + for (long i = 0; i < __builtin_popcountl (__M); i++) + { + c = __builtin_clzl (m); + p = (p << 8) | c; + m ^= (mask >> c); + } + result = __builtin_bpermd (p, __X); + } + else + { + p = 64 - __builtin_popcountl (__M); + result = 0; + /* We could a use a for loop here, but that combined with + -funroll-loops can expand to a lot of code. The while + loop avoids unrolling and the compiler commons the xor + from clearing the mask bit with the (m != 0) test. The + result is a more compact loop setup and body. */ + while (m != 0) + { + unsigned long t; + c = __builtin_clzl (m); + t = (__X & (mask >> c)) >> (p - c); + m ^= (mask >> c); + result |= (t); + p++; + } + } + return (result); +} + +/* these 32-bit implementations depend on 64-bit pdep/pext + which depend on _ARCH_PWR7. */ +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_pdep_u32 (unsigned int __X, unsigned int __Y) +{ + return _pdep_u64 (__X, __Y); +} + +extern __inline unsigned int +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_pext_u32 (unsigned int __X, unsigned int __Y) +{ + return _pext_u64 (__X, __Y); +} +#endif /* _ARCH_PWR7 */ +#endif /* __PPC64__ */ + +#endif /* _BMI2INTRIN_H_INCLUDED */ diff --git a/gcc/config/powerpcspe/bmiintrin.h b/gcc/config/powerpcspe/bmiintrin.h new file mode 100644 index 00000000000..28671ca0d32 --- /dev/null +++ b/gcc/config/powerpcspe/bmiintrin.h @@ -0,0 +1,187 @@ +/* Copyright (C) 2010-2017 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* This header is distributed to simplify porting x86_64 code that + makes explicit use of Intel intrinsics to powerpc64le. + It is the user's responsibility to determine if the results are + acceptable and make additional changes as necessary. + Note that much code that uses Intel intrinsics can be rewritten in + standard C or GNU C extensions, which are more portable and better + optimized across multiple targets. */ + +#if !defined _X86INTRIN_H_INCLUDED +# error "Never use directly; include instead." +#endif + +#ifndef _BMIINTRIN_H_INCLUDED +#define _BMIINTRIN_H_INCLUDED + +extern __inline unsigned short __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__tzcnt_u16 (unsigned short __X) +{ + return __builtin_ctz (__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__andn_u32 (unsigned int __X, unsigned int __Y) +{ + return (~__X & __Y); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_bextr_u32 (unsigned int __X, unsigned int __P, unsigned int __L) +{ + return ((__X << (32 - (__L + __P))) >> (32 - __L)); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bextr_u32 (unsigned int __X, unsigned int __Y) +{ + unsigned int __P, __L; + __P = __Y & 0xFF; + __L = (__Y >> 8) & 0xFF; + return (_bextr_u32 (__X, __P, __L)); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsi_u32 (unsigned int __X) +{ + return (__X & -__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsi_u32 (unsigned int __X) +{ + return __blsi_u32 (__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsmsk_u32 (unsigned int __X) +{ + return (__X ^ (__X - 1)); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsmsk_u32 (unsigned int __X) +{ + return __blsmsk_u32 (__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsr_u32 (unsigned int __X) +{ + return (__X & (__X - 1)); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsr_u32 (unsigned int __X) +{ + return __blsr_u32 (__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__tzcnt_u32 (unsigned int __X) +{ + return __builtin_ctz (__X); +} + +extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_tzcnt_u32 (unsigned int __X) +{ + return __builtin_ctz (__X); +} + +/* use the 64-bit shift, rotate, and count leading zeros instructions + for long long. */ +#ifdef __PPC64__ +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__andn_u64 (unsigned long long __X, unsigned long long __Y) +{ + return (~__X & __Y); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_bextr_u64 (unsigned long long __X, unsigned int __P, unsigned int __L) +{ + return ((__X << (64 - (__L + __P))) >> (64 - __L)); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__bextr_u64 (unsigned long long __X, unsigned long long __Y) +{ + unsigned int __P, __L; + __P = __Y & 0xFF; + __L = (__Y & 0xFF00) >> 8; + return (_bextr_u64 (__X, __P, __L)); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsi_u64 (unsigned long long __X) +{ + return __X & -__X; +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsi_u64 (unsigned long long __X) +{ + return __blsi_u64 (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsmsk_u64 (unsigned long long __X) +{ + return (__X ^ (__X - 1)); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsmsk_u64 (unsigned long long __X) +{ + return __blsmsk_u64 (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__blsr_u64 (unsigned long long __X) +{ + return (__X & (__X - 1)); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_blsr_u64 (unsigned long long __X) +{ + return __blsr_u64 (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +__tzcnt_u64 (unsigned long long __X) +{ + return __builtin_ctzll (__X); +} + +extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_tzcnt_u64 (unsigned long long __X) +{ + return __builtin_ctzll (__X); +} +#endif /* __PPC64__ */ + +#endif /* _BMIINTRIN_H_INCLUDED */ diff --git a/gcc/config/powerpcspe/cell.md b/gcc/config/powerpcspe/cell.md new file mode 100644 index 00000000000..a92e82acecf --- /dev/null +++ b/gcc/config/powerpcspe/cell.md @@ -0,0 +1,423 @@ +;; Scheduling description for cell processor. +;; Copyright (C) 2001-2017 Free Software Foundation, Inc. +;; Contributed by Sony Computer Entertainment, Inc., + + +;; This file is free software; you can redistribute it and/or modify it under +;; the terms of the GNU General Public License as published by the Free +;; Software Foundation; either version 3 of the License, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +;; for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; Sources: BE BOOK4 (/sfs/enc/doc/PPU_BookIV_DD3.0_latest.pdf) + +;; BE Architecture *DD3.0 and DD3.1* +;; This file simulate PPU processor unit backend of pipeline, maualP24. +;; manual P27, stall and flush points +;; IU, XU, VSU, dispatcher decodes and dispatch 2 insns per cycle in program +;; order, the grouped address are aligned by 8 +;; This file only simulate one thread situation +;; XU executes all fixed point insns(3 units, a simple alu, a complex unit, +;; and load/store unit) +;; VSU executes all scalar floating points insn(a float unit), +;; VMX insns(VMX unit, 4 sub units, simple, permute, complex, floating point) + +;; Dual issue combination + +;; FXU LSU BR VMX VMX +;; (sx,cx,vsu_fp,fp_arith) (perm,vsu_ls,fp_ls) +;;FXU X +;;LSU X X X +;;BR X +;;VMX(sx,cx,vsu_fp,fp_arth) X +;;VMX(perm,vsu_ls, fp_ls) X +;; X are illegal combination. + +;; Dual issue exceptions: +;;(1) nop-pipelined FXU instr in slot 0 +;;(2) non-pipelined FPU inst in slot 0 +;; CSI instr(contex-synchronizing insn) +;; Microcode insn + +;; BRU unit: bru(none register stall), bru_cr(cr register stall) +;; VSU unit: vus(vmx simple), vup(vmx permute), vuc(vmx complex), +;; vuf(vmx float), fpu(floats). fpu_div is hypothetical, it is for +;; nonpipelined simulation +;; micr insns will stall at least 7 cycles to get the first instr from ROM, +;; micro instructions are not dual issued. + +;; slot0 is older than slot1 +;; non-pipelined insn need to be in slot1 to avoid 1cycle stall + +;; There different stall point +;; IB2, only stall one thread if stall here, so try to stall here as much as +;; we can +;; condition(1) insert nop, OR and ORI instruction form +;; condition(2) flush happens, in case of: RAW, WAW, D-ERAT miss, or +;; CR0-access while stdcx, or stwcx +;; IS2 stall ;; Page91 for details +;; VQ8 stall +;; IS2 stall can be activated by VQ8 stall and trying to issue a vsu instr to +;; the vsu issue queue + +;;(define_automaton "cellxu") + +;;(define_cpu_unit "fxu_cell,lsu_cell,bru_cell,vsu1_cell,vsu2_cell" "cellxu") + +;; ndfa +(define_automaton "cellxu,cellvsu,cellbru,cell_mis") + +(define_cpu_unit "fxu_cell,lsu_cell" "cellxu") +(define_cpu_unit "bru_cell" "cellbru") +(define_cpu_unit "vsu1_cell,vsu2_cell" "cellvsu") + +(define_cpu_unit "slot0,slot1" "cell_mis") + +(absence_set "slot0" "slot1") + +(define_reservation "nonpipeline" "fxu_cell+lsu_cell+vsu1_cell+vsu2_cell") +(define_reservation "slot01" "slot0|slot1") + + +;; Load/store +;; lmw, lswi, lswx are only generated for optimize for space, MC, +;; these instr are not simulated +(define_insn_reservation "cell-load" 2 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "no") + (eq_attr "cpu" "cell")) + "slot01,lsu_cell") + +;; ldux, ldu, lbzux, lbzu, hardware breaks it down to two instrs, +;; if with 32bytes alignment, CMC +(define_insn_reservation "cell-load-ux" 2 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "cpu" "cell")) + "slot01,fxu_cell+lsu_cell") + +;; lha, lhax, lhau, lhaux, lwa, lwax, lwaux, MC, latency unknown +;; 11/7, 11/8, 11/12 +(define_insn_reservation "cell-load-ext" 2 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "cpu" "cell")) + "slot01,fxu_cell+lsu_cell") + +;;lfs,lfsx,lfd,lfdx, 1 cycle +(define_insn_reservation "cell-fpload" 1 + (and (eq_attr "type" "fpload") + (eq_attr "update" "no") + (eq_attr "cpu" "cell")) + "vsu2_cell+lsu_cell+slot01") + +;; lfsu,lfsux,lfdu,lfdux 1cycle(fpr) 2 cycle(gpr) +(define_insn_reservation "cell-fpload-update" 1 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (eq_attr "cpu" "cell")) + "fxu_cell+vsu2_cell+lsu_cell+slot01") + +(define_insn_reservation "cell-vecload" 2 + (and (eq_attr "type" "vecload") + (eq_attr "cpu" "cell")) + "slot01,vsu2_cell+lsu_cell") + +;;st? stw(MC) +(define_insn_reservation "cell-store" 1 + (and (eq_attr "type" "store") + (eq_attr "update" "no") + (eq_attr "cpu" "cell")) + "lsu_cell+slot01") + +;;stdux, stdu, (hardware breaks into store and add) 2 for update reg +(define_insn_reservation "cell-store-update" 1 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "cpu" "cell")) + "fxu_cell+lsu_cell+slot01") + +(define_insn_reservation "cell-fpstore" 1 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "no") + (eq_attr "cpu" "cell")) + "vsu2_cell+lsu_cell+slot01") + +(define_insn_reservation "cell-fpstore-update" 1 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "yes") + (eq_attr "cpu" "cell")) + "vsu2_cell+fxu_cell+lsu_cell+slot01") + +(define_insn_reservation "cell-vecstore" 1 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "cell")) + "vsu2_cell+lsu_cell+slot01") + +;; Integer latency is 2 cycles +(define_insn_reservation "cell-integer" 2 + (and (ior (eq_attr "type" "integer,trap,cntlz,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no")) + (and (eq_attr "type" "insert") + (eq_attr "size" "64"))) + (eq_attr "cpu" "cell")) + "slot01,fxu_cell") + +;; Two integer latency is 4 cycles +(define_insn_reservation "cell-two" 4 + (and (eq_attr "type" "two") + (eq_attr "cpu" "cell")) + "slot01,fxu_cell,fxu_cell*2") + +;; Three integer latency is 6 cycles +(define_insn_reservation "cell-three" 6 + (and (eq_attr "type" "three") + (eq_attr "cpu" "cell")) + "slot01,fxu_cell,fxu_cell*4") + +;; rlwimi, alter cr0 +(define_insn_reservation "cell-insert" 2 + (and (eq_attr "type" "insert") + (eq_attr "size" "32") + (eq_attr "cpu" "cell")) + "slot01,fxu_cell") + +;; cmpi, cmpli, cmpla, add, addo, sub, subo, alter cr0 +(define_insn_reservation "cell-cmp" 1 + (and (eq_attr "type" "cmp") + (eq_attr "cpu" "cell")) + "fxu_cell+slot01") + +;; add, addo, sub, subo, alter cr0, rldcli, rlwinm +(define_insn_reservation "cell-fast-cmp" 2 + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes") + (eq_attr "cpu" "cell") + (eq_attr "cell_micro" "not")) + "slot01,fxu_cell") + +(define_insn_reservation "cell-cmp-microcoded" 9 + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes") + (eq_attr "cpu" "cell") + (eq_attr "cell_micro" "always")) + "slot0+slot1,fxu_cell,fxu_cell*7") + +;; mulld +(define_insn_reservation "cell-lmul" 15 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "64") + (eq_attr "cpu" "cell")) + "slot1,nonpipeline,nonpipeline*13") + +;; mulld. is microcoded +(define_insn_reservation "cell-lmul-cmp" 22 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "size" "64") + (eq_attr "cpu" "cell")) + "slot0+slot1,nonpipeline,nonpipeline*20") + +;; mulli, 6 cycles +(define_insn_reservation "cell-imul23" 6 + (and (eq_attr "type" "mul") + (eq_attr "size" "8,16") + (eq_attr "cpu" "cell")) + "slot1,nonpipeline,nonpipeline*4") + +;; mullw, 9 +(define_insn_reservation "cell-imul" 9 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "32") + (eq_attr "cpu" "cell")) + "slot1,nonpipeline,nonpipeline*7") + +;; divide +(define_insn_reservation "cell-idiv" 32 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "cell")) + "slot1,nonpipeline,nonpipeline*30") + +(define_insn_reservation "cell-ldiv" 64 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "cell")) + "slot1,nonpipeline,nonpipeline*62") + +;;mflr and mfctr are pipelined +(define_insn_reservation "cell-mfjmpr" 1 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "cell")) + "slot01+bru_cell") + +;;mtlr and mtctr, +;;mtspr fully pipelined +(define_insn_reservation "cell-mtjmpr" 1 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "cell")) + "bru_cell+slot01") + +;; Branches +;; b, ba, bl, bla, unconditional branch always predicts correctly n/a latency +;; bcctr, bcctrl, latency 2, actually adjust by be to 4 +(define_insn_reservation "cell-branch" 1 + (and (eq_attr "type" "branch") + (eq_attr "cpu" "cell")) + "bru_cell+slot1") + +(define_insn_reservation "cell-branchreg" 1 + (and (eq_attr "type" "jmpreg") + (eq_attr "cpu" "cell")) + "bru_cell+slot1") + +;; cr hazard +;; page 90, special cases for CR hazard, only one instr can access cr per cycle +;; if insn reads CR following a stwcx, pipeline stall till stwcx finish +(define_insn_reservation "cell-crlogical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "cell")) + "bru_cell+slot01") + +;; mfcrf and mfcr is about 34 cycles and nonpipelined +(define_insn_reservation "cell-mfcr" 34 + (and (eq_attr "type" "mfcrf,mfcr") + (eq_attr "cpu" "cell")) + "slot1,nonpipeline,nonpipeline*32") + +;; mtcrf (1 field) +(define_insn_reservation "cell-mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "cell")) + "fxu_cell+slot01") + +; Basic FP latency is 10 cycles, thoughput is 1/cycle +(define_insn_reservation "cell-fp" 10 + (and (eq_attr "type" "fp,fpsimple,dmul") + (eq_attr "cpu" "cell")) + "slot01,vsu1_cell,vsu1_cell*8") + +(define_insn_reservation "cell-fpcompare" 1 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "cell")) + "vsu1_cell+slot01") + +;; sdiv thoughput 1/74, not pipelined but only in the FPU +(define_insn_reservation "cell-sdiv" 74 + (and (eq_attr "type" "sdiv,ddiv") + (eq_attr "cpu" "cell")) + "slot1,nonpipeline,nonpipeline*72") + +;; fsqrt thoughput 1/84, not pipelined but only in the FPU +(define_insn_reservation "cell-sqrt" 84 + (and (eq_attr "type" "ssqrt,dsqrt") + (eq_attr "cpu" "cell")) + "slot1,nonpipeline,nonpipeline*82") + +; VMX +(define_insn_reservation "cell-vecsimple" 4 + (and (eq_attr "type" "vecsimple,veclogical,vecmove") + (eq_attr "cpu" "cell")) + "slot01,vsu1_cell,vsu1_cell*2") + +;; mult, div, madd +(define_insn_reservation "cell-veccomplex" 10 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "cell")) + "slot01,vsu1_cell,vsu1_cell*8") + +;; TODO: add support for recording instructions +(define_insn_reservation "cell-veccmp" 4 + (and (eq_attr "type" "veccmp,veccmpfx") + (eq_attr "cpu" "cell")) + "slot01,vsu1_cell,vsu1_cell*2") + +(define_insn_reservation "cell-vecfloat" 12 + (and (eq_attr "type" "vecfloat") + (eq_attr "cpu" "cell")) + "slot01,vsu1_cell,vsu1_cell*10") + +(define_insn_reservation "cell-vecperm" 4 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "cell")) + "slot01,vsu2_cell,vsu2_cell*2") + +;; New for 4.2, syncs + +(define_insn_reservation "cell-sync" 11 + (and (eq_attr "type" "sync") + (eq_attr "cpu" "cell")) + "slot01,lsu_cell,lsu_cell*9") + +(define_insn_reservation "cell-isync" 11 + (and (eq_attr "type" "isync") + (eq_attr "cpu" "cell")) + "slot01,lsu_cell,lsu_cell*9") + +(define_insn_reservation "cell-load_l" 11 + (and (eq_attr "type" "load_l") + (eq_attr "cpu" "cell")) + "slot01,lsu_cell,lsu_cell*9") + +(define_insn_reservation "cell-store_c" 11 + (and (eq_attr "type" "store_c") + (eq_attr "cpu" "cell")) + "slot01,lsu_cell,lsu_cell*9") + +;; RAW register dependency + +;; addi r3, r3, 1 +;; lw r4,offset(r3) +;; there are 5 cycle deplay for r3 bypassing +;; there are 5 cycle delay for a dependent load after a load +(define_bypass 5 "cell-integer" "cell-load") +(define_bypass 5 "cell-integer" "cell-load-ext") +(define_bypass 5 "cell-load,cell-load-ext" "cell-load,cell-load-ext") + +;; there is a 6 cycle delay after a fp compare until you can use the cr. +(define_bypass 6 "cell-fpcompare" "cell-branch,cell-branchreg,cell-mfcr,cell-crlogical") + +;; VXU float RAW +(define_bypass 11 "cell-vecfloat" "cell-vecfloat") + +;; VXU and FPU +(define_bypass 6 "cell-veccomplex" "cell-vecsimple") +;;(define_bypass 6 "cell-veccompare" "cell-branch,cell-branchreg") +(define_bypass 3 "cell-vecfloat" "cell-veccomplex") +; this is not correct, +;; this is a stall in general and not dependent on result +(define_bypass 13 "cell-vecstore" "cell-fpstore") +; this is not correct, this can never be true, not dependent on result +(define_bypass 7 "cell-fp" "cell-fpload") +;; vsu1 should avoid writing to the same target register as vsu2 insn +;; within 12 cycles. + +;; WAW hazard + +;; the target of VSU estimate should not be reused within 10 dispatch groups +;; the target of VSU float should not be reused within 8 dispatch groups +;; the target of VSU complex should not be reused within 5 dispatch groups +;; FP LOAD should not reuse an FPU Arithmetic target with 6 dispatch gropus + +;; mtctr-bcctr/bcctrl, branch target ctr register shadow update at +;; ex4 stage(10 cycles) +(define_bypass 10 "cell-mtjmpr" "cell-branchreg") + +;;Things are not simulated: +;; update instruction, update address gpr are not simulated +;; vrefp, vrsqrtefp have latency(14), currently simulated as 12 cycle float +;; insns + diff --git a/gcc/config/powerpcspe/constraints.md b/gcc/config/powerpcspe/constraints.md new file mode 100644 index 00000000000..44f45d8b676 --- /dev/null +++ b/gcc/config/powerpcspe/constraints.md @@ -0,0 +1,323 @@ +;; Constraint definitions for RS6000 +;; Copyright (C) 2006-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; Available constraint letters: e k q t u A B C D S T + +;; Register constraints + +(define_register_constraint "f" "rs6000_constraints[RS6000_CONSTRAINT_f]" + "@internal") + +(define_register_constraint "d" "rs6000_constraints[RS6000_CONSTRAINT_d]" + "@internal") + +(define_register_constraint "b" "BASE_REGS" + "@internal") + +(define_register_constraint "h" "SPECIAL_REGS" + "@internal") + +(define_register_constraint "c" "CTR_REGS" + "@internal") + +(define_register_constraint "l" "LINK_REGS" + "@internal") + +(define_register_constraint "v" "ALTIVEC_REGS" + "@internal") + +(define_register_constraint "x" "CR0_REGS" + "@internal") + +(define_register_constraint "y" "CR_REGS" + "@internal") + +(define_register_constraint "z" "CA_REGS" + "@internal") + +;; Use w as a prefix to add VSX modes +;; any VSX register +(define_register_constraint "wa" "rs6000_constraints[RS6000_CONSTRAINT_wa]" + "Any VSX register if the -mvsx option was used or NO_REGS.") + +(define_register_constraint "wb" "rs6000_constraints[RS6000_CONSTRAINT_wb]" + "Altivec register if the -mpower9-dform option was used or NO_REGS.") + +;; NOTE: For compatibility, "wc" is reserved to represent individual CR bits. +;; It is currently used for that purpose in LLVM. + +(define_register_constraint "wd" "rs6000_constraints[RS6000_CONSTRAINT_wd]" + "VSX vector register to hold vector double data or NO_REGS.") + +(define_register_constraint "we" "rs6000_constraints[RS6000_CONSTRAINT_we]" + "VSX register if the -mpower9-vector -m64 options were used or NO_REGS.") + +(define_register_constraint "wf" "rs6000_constraints[RS6000_CONSTRAINT_wf]" + "VSX vector register to hold vector float data or NO_REGS.") + +(define_register_constraint "wg" "rs6000_constraints[RS6000_CONSTRAINT_wg]" + "If -mmfpgpr was used, a floating point register or NO_REGS.") + +(define_register_constraint "wh" "rs6000_constraints[RS6000_CONSTRAINT_wh]" + "Floating point register if direct moves are available, or NO_REGS.") + +(define_register_constraint "wi" "rs6000_constraints[RS6000_CONSTRAINT_wi]" + "FP or VSX register to hold 64-bit integers for VSX insns or NO_REGS.") + +(define_register_constraint "wj" "rs6000_constraints[RS6000_CONSTRAINT_wj]" + "FP or VSX register to hold 64-bit integers for direct moves or NO_REGS.") + +(define_register_constraint "wk" "rs6000_constraints[RS6000_CONSTRAINT_wk]" + "FP or VSX register to hold 64-bit doubles for direct moves or NO_REGS.") + +(define_register_constraint "wl" "rs6000_constraints[RS6000_CONSTRAINT_wl]" + "Floating point register if the LFIWAX instruction is enabled or NO_REGS.") + +(define_register_constraint "wm" "rs6000_constraints[RS6000_CONSTRAINT_wm]" + "VSX register if direct move instructions are enabled, or NO_REGS.") + +;; NO_REGs register constraint, used to merge mov{sd,sf}, since movsd can use +;; direct move directly, and movsf can't to move between the register sets. +;; There is a mode_attr that resolves to wm for SDmode and wn for SFmode +(define_register_constraint "wn" "NO_REGS" "No register (NO_REGS).") + +(define_register_constraint "wo" "rs6000_constraints[RS6000_CONSTRAINT_wo]" + "VSX register if the -mpower9-vector option was used or NO_REGS.") + +(define_register_constraint "wp" "rs6000_constraints[RS6000_CONSTRAINT_wp]" + "VSX register to use for IEEE 128-bit fp TFmode, or NO_REGS.") + +(define_register_constraint "wq" "rs6000_constraints[RS6000_CONSTRAINT_wq]" + "VSX register to use for IEEE 128-bit fp KFmode, or NO_REGS.") + +(define_register_constraint "wr" "rs6000_constraints[RS6000_CONSTRAINT_wr]" + "General purpose register if 64-bit instructions are enabled or NO_REGS.") + +(define_register_constraint "ws" "rs6000_constraints[RS6000_CONSTRAINT_ws]" + "VSX vector register to hold scalar double values or NO_REGS.") + +(define_register_constraint "wt" "rs6000_constraints[RS6000_CONSTRAINT_wt]" + "VSX vector register to hold 128 bit integer or NO_REGS.") + +(define_register_constraint "wu" "rs6000_constraints[RS6000_CONSTRAINT_wu]" + "Altivec register to use for float/32-bit int loads/stores or NO_REGS.") + +(define_register_constraint "wv" "rs6000_constraints[RS6000_CONSTRAINT_wv]" + "Altivec register to use for double loads/stores or NO_REGS.") + +(define_register_constraint "ww" "rs6000_constraints[RS6000_CONSTRAINT_ww]" + "FP or VSX register to perform float operations under -mvsx or NO_REGS.") + +(define_register_constraint "wx" "rs6000_constraints[RS6000_CONSTRAINT_wx]" + "Floating point register if the STFIWX instruction is enabled or NO_REGS.") + +(define_register_constraint "wy" "rs6000_constraints[RS6000_CONSTRAINT_wy]" + "FP or VSX register to perform ISA 2.07 float ops or NO_REGS.") + +(define_register_constraint "wz" "rs6000_constraints[RS6000_CONSTRAINT_wz]" + "Floating point register if the LFIWZX instruction is enabled or NO_REGS.") + +(define_register_constraint "wA" "rs6000_constraints[RS6000_CONSTRAINT_wA]" + "BASE_REGS if 64-bit instructions are enabled or NO_REGS.") + +;; wB needs ISA 2.07 VUPKHSW +(define_constraint "wB" + "Signed 5-bit constant integer that can be loaded into an altivec register." + (and (match_code "const_int") + (and (match_test "TARGET_P8_VECTOR") + (match_operand 0 "s5bit_cint_operand")))) + +(define_constraint "wD" + "Int constant that is the element number of the 64-bit scalar in a vector." + (and (match_code "const_int") + (match_test "TARGET_VSX && (ival == VECTOR_ELEMENT_SCALAR_64BIT)"))) + +(define_constraint "wE" + "Vector constant that can be loaded with the XXSPLTIB instruction." + (match_test "xxspltib_constant_nosplit (op, mode)")) + +;; Extended fusion store +(define_memory_constraint "wF" + "Memory operand suitable for power9 fusion load/stores" + (match_operand 0 "fusion_addis_mem_combo_load")) + +;; Fusion gpr load. +(define_memory_constraint "wG" + "Memory operand suitable for TOC fusion memory references" + (match_operand 0 "toc_fusion_mem_wrapped")) + +(define_register_constraint "wH" "rs6000_constraints[RS6000_CONSTRAINT_wH]" + "Altivec register to hold 32-bit integers or NO_REGS.") + +(define_register_constraint "wI" "rs6000_constraints[RS6000_CONSTRAINT_wI]" + "FPR register to hold 32-bit integers or NO_REGS.") + +(define_register_constraint "wJ" "rs6000_constraints[RS6000_CONSTRAINT_wJ]" + "FPR register to hold 8/16-bit integers or NO_REGS.") + +(define_register_constraint "wK" "rs6000_constraints[RS6000_CONSTRAINT_wK]" + "Altivec register to hold 8/16-bit integers or NO_REGS.") + +(define_constraint "wL" + "Int constant that is the element number mfvsrld accesses in a vector." + (and (match_code "const_int") + (and (match_test "TARGET_DIRECT_MOVE_128") + (match_test "(ival == VECTOR_ELEMENT_MFVSRLD_64BIT)")))) + +;; Generate the XXORC instruction to set a register to all 1's +(define_constraint "wM" + "Match vector constant with all 1's if the XXLORC instruction is available" + (and (match_test "TARGET_P8_VECTOR") + (match_operand 0 "all_ones_constant"))) + +;; ISA 3.0 vector d-form addresses +(define_memory_constraint "wO" + "Memory operand suitable for the ISA 3.0 vector d-form instructions." + (match_operand 0 "vsx_quad_dform_memory_operand")) + +;; Lq/stq validates the address for load/store quad +(define_memory_constraint "wQ" + "Memory operand suitable for the load/store quad instructions" + (match_operand 0 "quad_memory_operand")) + +(define_constraint "wS" + "Vector constant that can be loaded with XXSPLTIB & sign extension." + (match_test "xxspltib_constant_split (op, mode)")) + +;; ISA 3.0 DS-form instruction that has the bottom 2 bits 0 and no update form. +;; Used by LXSD/STXSD/LXSSP/STXSSP. In contrast to "Y", the multiple-of-four +;; offset is enforced for 32-bit too. +(define_memory_constraint "wY" + "Offsettable memory operand, with bottom 2 bits 0" + (and (match_code "mem") + (not (match_test "update_address_mem (op, mode)")) + (match_test "mem_operand_ds_form (op, mode)"))) + +;; Altivec style load/store that ignores the bottom bits of the address +(define_memory_constraint "wZ" + "Indexed or indirect memory operand, ignoring the bottom 4 bits" + (match_operand 0 "altivec_indexed_or_indirect_operand")) + +;; Integer constraints + +(define_constraint "I" + "A signed 16-bit constant" + (and (match_code "const_int") + (match_test "((unsigned HOST_WIDE_INT) ival + 0x8000) < 0x10000"))) + +(define_constraint "J" + "high-order 16 bits nonzero" + (and (match_code "const_int") + (match_test "(ival & (~ (unsigned HOST_WIDE_INT) 0xffff0000)) == 0"))) + +(define_constraint "K" + "low-order 16 bits nonzero" + (and (match_code "const_int") + (match_test "(ival & (~ (HOST_WIDE_INT) 0xffff)) == 0"))) + +(define_constraint "L" + "signed 16-bit constant shifted left 16 bits" + (and (match_code "const_int") + (match_test "((ival & 0xffff) == 0 + && (ival >> 31 == -1 || ival >> 31 == 0))"))) + +(define_constraint "M" + "constant greater than 31" + (and (match_code "const_int") + (match_test "ival > 31"))) + +(define_constraint "N" + "positive constant that is an exact power of two" + (and (match_code "const_int") + (match_test "ival > 0 && exact_log2 (ival) >= 0"))) + +(define_constraint "O" + "constant zero" + (and (match_code "const_int") + (match_test "ival == 0"))) + +(define_constraint "P" + "constant whose negation is signed 16-bit constant" + (and (match_code "const_int") + (match_test "((- (unsigned HOST_WIDE_INT) ival) + 0x8000) < 0x10000"))) + +;; Floating-point constraints + +(define_constraint "G" + "Constant that can be copied into GPR with two insns for DF/DI + and one for SF." + (and (match_code "const_double") + (match_test "num_insns_constant (op, mode) + == (mode == SFmode ? 1 : 2)"))) + +(define_constraint "H" + "DF/DI constant that takes three insns." + (and (match_code "const_double") + (match_test "num_insns_constant (op, mode) == 3"))) + +;; Memory constraints + +(define_memory_constraint "es" + "A ``stable'' memory operand; that is, one which does not include any +automodification of the base register. Unlike @samp{m}, this constraint +can be used in @code{asm} statements that might access the operand +several times, or that might not access it at all." + (and (match_code "mem") + (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC"))) + +(define_memory_constraint "Q" + "Memory operand that is an offset from a register (it is usually better +to use @samp{m} or @samp{es} in @code{asm} statements)" + (and (match_code "mem") + (match_test "GET_CODE (XEXP (op, 0)) == REG"))) + +(define_memory_constraint "Y" + "memory operand for 8 byte and 16 byte gpr load/store" + (and (match_code "mem") + (match_test "mem_operand_gpr (op, mode)"))) + +(define_memory_constraint "Z" + "Memory operand that is an indexed or indirect from a register (it is +usually better to use @samp{m} or @samp{es} in @code{asm} statements)" + (match_operand 0 "indexed_or_indirect_operand")) + +;; Address constraints + +(define_address_constraint "a" + "Indexed or indirect address operand" + (match_operand 0 "indexed_or_indirect_address")) + +(define_constraint "R" + "AIX TOC entry" + (match_test "legitimate_constant_pool_address_p (op, QImode, false)")) + +;; General constraints + +(define_constraint "U" + "V.4 small data reference" + (and (match_test "DEFAULT_ABI == ABI_V4") + (match_test "small_data_operand (op, mode)"))) + +(define_constraint "W" + "vector constant that does not require memory" + (match_operand 0 "easy_vector_constant")) + +(define_constraint "j" + "Zero vector constant" + (match_test "op == const0_rtx || op == CONST0_RTX (mode)")) diff --git a/gcc/config/powerpcspe/crypto.md b/gcc/config/powerpcspe/crypto.md new file mode 100644 index 00000000000..5892f8918f2 --- /dev/null +++ b/gcc/config/powerpcspe/crypto.md @@ -0,0 +1,110 @@ +;; Cryptographic instructions added in ISA 2.07 +;; Copyright (C) 2012-2017 Free Software Foundation, Inc. +;; Contributed by Michael Meissner (meissner@linux.vnet.ibm.com) + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; NOTE: Although this file contains all the instructions from +;; section 5.11 of ISA 2.07, only those in sections 5.11.1 and +;; 5.11.2 are in Category:Vector.Crypto. Those are the only +;; ones controlled by -m[no-]crypto. + +;; FIXME: The builtin names for the instructions in this file +;; are likely to be deprecated in favor of other names to be +;; agreed upon with the XL compilers and LLVM. + +(define_c_enum "unspec" + [UNSPEC_VCIPHER + UNSPEC_VNCIPHER + UNSPEC_VCIPHERLAST + UNSPEC_VNCIPHERLAST + UNSPEC_VSBOX + UNSPEC_VSHASIGMA + UNSPEC_VPERMXOR + UNSPEC_VPMSUM]) + +;; Iterator for VPMSUM/VPERMXOR +(define_mode_iterator CR_mode [V16QI V8HI V4SI V2DI]) + +(define_mode_attr CR_char [(V16QI "b") + (V8HI "h") + (V4SI "w") + (V2DI "d")]) + +;; Iterator for VSHASIGMAD/VSHASIGMAW +(define_mode_iterator CR_hash [V4SI V2DI]) + +;; Iterator for the other crypto functions +(define_int_iterator CR_code [UNSPEC_VCIPHER + UNSPEC_VNCIPHER + UNSPEC_VCIPHERLAST + UNSPEC_VNCIPHERLAST]) + +(define_int_attr CR_insn [(UNSPEC_VCIPHER "vcipher") + (UNSPEC_VNCIPHER "vncipher") + (UNSPEC_VCIPHERLAST "vcipherlast") + (UNSPEC_VNCIPHERLAST "vncipherlast")]) + +;; 2 operand crypto instructions +(define_insn "crypto_" + [(set (match_operand:V2DI 0 "register_operand" "=v") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v") + (match_operand:V2DI 2 "register_operand" "v")] + CR_code))] + "TARGET_CRYPTO" + " %0,%1,%2" + [(set_attr "type" "crypto")]) + +(define_insn "crypto_vpmsum" + [(set (match_operand:CR_mode 0 "register_operand" "=v") + (unspec:CR_mode [(match_operand:CR_mode 1 "register_operand" "v") + (match_operand:CR_mode 2 "register_operand" "v")] + UNSPEC_VPMSUM))] + "TARGET_P8_VECTOR" + "vpmsum %0,%1,%2" + [(set_attr "type" "crypto")]) + +;; 3 operand crypto instructions +(define_insn "crypto_vpermxor_" + [(set (match_operand:CR_mode 0 "register_operand" "=v") + (unspec:CR_mode [(match_operand:CR_mode 1 "register_operand" "v") + (match_operand:CR_mode 2 "register_operand" "v") + (match_operand:CR_mode 3 "register_operand" "v")] + UNSPEC_VPERMXOR))] + "TARGET_P8_VECTOR" + "vpermxor %0,%1,%2,%3" + [(set_attr "type" "vecperm")]) + +;; 1 operand crypto instruction +(define_insn "crypto_vsbox" + [(set (match_operand:V2DI 0 "register_operand" "=v") + (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "v")] + UNSPEC_VSBOX))] + "TARGET_CRYPTO" + "vsbox %0,%1" + [(set_attr "type" "crypto")]) + +;; Hash crypto instructions +(define_insn "crypto_vshasigma" + [(set (match_operand:CR_hash 0 "register_operand" "=v") + (unspec:CR_hash [(match_operand:CR_hash 1 "register_operand" "v") + (match_operand:SI 2 "const_0_to_1_operand" "n") + (match_operand:SI 3 "const_0_to_15_operand" "n")] + UNSPEC_VSHASIGMA))] + "TARGET_CRYPTO" + "vshasigma %0,%1,%2,%3" + [(set_attr "type" "vecsimple")]) diff --git a/gcc/config/powerpcspe/darwin.h b/gcc/config/powerpcspe/darwin.h new file mode 100644 index 00000000000..61e5e836de0 --- /dev/null +++ b/gcc/config/powerpcspe/darwin.h @@ -0,0 +1,422 @@ +/* Target definitions for PowerPC running Darwin (Mac OS X). + Copyright (C) 1997-2017 Free Software Foundation, Inc. + Contributed by Apple Computer Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#undef DARWIN_PPC +#define DARWIN_PPC 1 + +/* The "Darwin ABI" is mostly like AIX, but with some key differences. */ + +#define DEFAULT_ABI ABI_DARWIN + +#ifdef IN_LIBGCC2 +#undef TARGET_64BIT +#ifdef __powerpc64__ +#define TARGET_64BIT 1 +#else +#define TARGET_64BIT 0 +#endif +#endif + +/* The object file format is Mach-O. */ + +#define TARGET_OBJECT_FORMAT OBJECT_MACHO + +/* Size of the Obj-C jump buffer. */ +#define OBJC_JBLEN ((TARGET_64BIT) ? (26*2 + 18*2 + 129 + 1) : (26 + 18*2 + 129 + 1)) + +/* We're not ever going to do TOCs. */ + +#define TARGET_TOC 0 +#define TARGET_NO_TOC 1 + +/* Override the default rs6000 definition. */ +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int") + +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + if (!TARGET_64BIT) builtin_define ("__ppc__"); \ + if (TARGET_64BIT) builtin_define ("__ppc64__"); \ + builtin_define ("__POWERPC__"); \ + builtin_define ("__NATURAL_ALIGNMENT__"); \ + darwin_cpp_builtins (pfile); \ + } \ + while (0) + +/* Generate branch islands stubs if this is true. */ +extern int darwin_emit_branch_islands; + +#define SUBTARGET_OVERRIDE_OPTIONS darwin_rs6000_override_options () + +#define C_COMMON_OVERRIDE_OPTIONS do { \ + /* On powerpc, __cxa_get_exception_ptr is available starting in the \ + 10.4.6 libstdc++.dylib. */ \ + if (strverscmp (darwin_macosx_version_min, "10.4.6") < 0 \ + && flag_use_cxa_get_exception_ptr == 2) \ + flag_use_cxa_get_exception_ptr = 0; \ + if (flag_mkernel) \ + flag_no_builtin = 1; \ + SUBTARGET_C_COMMON_OVERRIDE_OPTIONS; \ +} while (0) + +/* Darwin has 128-bit long double support in libc in 10.4 and later. + Default to 128-bit long doubles even on earlier platforms for ABI + consistency; arithmetic will work even if libc and libm support is + not available. */ + +#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128 + + +/* We want -fPIC by default, unless we're using -static to compile for + the kernel or some such. The "-faltivec" option should have been + called "-maltivec" all along. */ + +#define CC1_SPEC "\ + %(cc1_cpu) \ + %{g: %{!fno-eliminate-unused-debug-symbols: -feliminate-unused-debug-symbols }} \ + %{static: %{Zdynamic: %e conflicting code gen style switches are used}}\ + %{!mkernel:%{!static:%{!mdynamic-no-pic:-fPIC}}} \ + %{faltivec:-maltivec -include altivec.h} %{fno-altivec:-mno-altivec} \ + % 10.4 mmacosx-version-min= crt2.o%s)}" + +#undef SUBTARGET_EXTRA_SPECS +#define SUBTARGET_EXTRA_SPECS \ + DARWIN_EXTRA_SPECS \ + { "darwin_arch", DARWIN_ARCH_SPEC }, \ + { "darwin_crt2", DARWIN_CRT2_SPEC }, \ + { "darwin_subarch", DARWIN_SUBARCH_SPEC }, + +/* Output a .machine directive. */ +#undef TARGET_ASM_FILE_START +#define TARGET_ASM_FILE_START rs6000_darwin_file_start + +/* Make both r2 and r13 available for allocation. */ +#define FIXED_R2 0 +#define FIXED_R13 0 + +/* Base register for access to local variables of the function. */ + +#undef HARD_FRAME_POINTER_REGNUM +#define HARD_FRAME_POINTER_REGNUM 30 + +#undef RS6000_PIC_OFFSET_TABLE_REGNUM +#define RS6000_PIC_OFFSET_TABLE_REGNUM 31 + +/* Pad the outgoing args area to 16 bytes instead of the usual 8. */ + +#undef STARTING_FRAME_OFFSET +#define STARTING_FRAME_OFFSET \ + (FRAME_GROWS_DOWNWARD \ + ? 0 \ + : (RS6000_ALIGN (crtl->outgoing_args_size, 16) \ + + RS6000_SAVE_AREA)) + +#undef STACK_DYNAMIC_OFFSET +#define STACK_DYNAMIC_OFFSET(FUNDECL) \ + (RS6000_ALIGN (crtl->outgoing_args_size, 16) \ + + (STACK_POINTER_OFFSET)) + +/* Darwin uses a function call if everything needs to be saved/restored. */ + +#undef WORLD_SAVE_P +#define WORLD_SAVE_P(INFO) ((INFO)->world_save_p) + +/* We don't use these on Darwin, they are just place-holders. */ +#define SAVE_FP_PREFIX "" +#define SAVE_FP_SUFFIX "" +#define RESTORE_FP_PREFIX "" +#define RESTORE_FP_SUFFIX "" + +/* The assembler wants the alternate register names, but without + leading percent sign. */ +#undef REGISTER_NAMES +#define REGISTER_NAMES \ +{ \ + "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", \ + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \ + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ + "mq", "lr", "ctr", "ap", \ + "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ + "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", "vscr", \ + "spe_acc", "spefscr", \ + "sfp", \ + "tfhar", "tfiar", "texasr", \ + "rh0", "rh1", "rh2", "rh3", "rh4", "rh5", "rh6", "rh7", \ + "rh8", "rh9", "rh10", "rh11", "rh12", "rh13", "rh14", "rh15", \ + "rh16", "rh17", "rh18", "rh19", "rh20", "rh21", "rh22", "rh23", \ + "rh24", "rh25", "rh26", "rh27", "rh28", "rh29", "rh30", "rh31" \ +} + +/* This outputs NAME to FILE. */ + +#undef RS6000_OUTPUT_BASENAME +#define RS6000_OUTPUT_BASENAME(FILE, NAME) \ + assemble_name (FILE, NAME) + +/* Globalizing directive for a label. */ +#undef GLOBAL_ASM_OP +#define GLOBAL_ASM_OP "\t.globl " +#undef TARGET_ASM_GLOBALIZE_LABEL + +/* This is how to output an internal label prefix. rs6000.c uses this + when generating traceback tables. */ +/* Not really used for Darwin? */ + +#undef ASM_OUTPUT_INTERNAL_LABEL_PREFIX +#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \ + fprintf (FILE, "%s", PREFIX) + +/* Override the standard rs6000 definition. */ + +#undef ASM_COMMENT_START +#define ASM_COMMENT_START ";" + +/* This is how to output an assembler line that says to advance + the location counter to a multiple of 2**LOG bytes using the + "nop" instruction as padding. */ + +#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \ + do \ + { \ + if ((LOG) < 3) \ + { \ + ASM_OUTPUT_ALIGN (FILE,LOG); \ + } \ + else /* nop == ori r0,r0,0 */ \ + fprintf (FILE, "\t.align32 %d,0x60000000\n", (LOG)); \ + } while (0) + +#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN +/* This is supported in cctools 465 and later. The macro test + above prevents using it in earlier build environments. */ +#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \ + if ((LOG) != 0) \ + { \ + if ((MAX_SKIP) == 0) \ + fprintf ((FILE), "\t.p2align %d\n", (LOG)); \ + else \ + fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \ + } +#endif + +/* Generate insns to call the profiler. */ + +#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL) + +/* Function name to call to do profiling. */ + +#define RS6000_MCOUNT "*mcount" + +/* Default processor: G4, and G5 for 64-bit. */ + +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_PPC7400 +#undef PROCESSOR_DEFAULT64 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER4 + +/* Default target flag settings. Despite the fact that STMW/LMW + serializes, it's still a big code size win to use them. Use FSEL by + default as well. */ + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_MULTIPLE | MASK_PPC_GFXOPT) + +/* Darwin always uses IBM long double, never IEEE long double. */ +#undef TARGET_IEEEQUAD +#define TARGET_IEEEQUAD 0 + +/* Since Darwin doesn't do TOCs, stub this out. */ + +#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) ((void)X, (void)MODE, 0) + +/* Unlike most other PowerPC targets, chars are signed, for + consistency with other Darwin architectures. */ + +#undef DEFAULT_SIGNED_CHAR +#define DEFAULT_SIGNED_CHAR (1) + +/* 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 + in some cases it is preferable to use a more restrictive class. + + On the RS/6000, we have to return NO_REGS when we want to reload a + floating-point CONST_DOUBLE to force it to be copied to memory. + + Don't allow R0 when loading the address of, or otherwise furtling with, + a SYMBOL_REF. */ + +#undef PREFERRED_RELOAD_CLASS +#define PREFERRED_RELOAD_CLASS(X,CLASS) \ + ((CONSTANT_P (X) \ + && reg_classes_intersect_p ((CLASS), FLOAT_REGS)) \ + ? NO_REGS \ + : ((GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == HIGH) \ + && reg_class_subset_p (BASE_REGS, (CLASS))) \ + ? BASE_REGS \ + : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \ + && (CLASS) == NON_SPECIAL_REGS) \ + ? GENERAL_REGS \ + : (CLASS)) + +/* Compute field alignment. + This implements the 'power' alignment rule by pegging the alignment of + items (beyond the first aggregate field) to 32 bits. The pegging is + suppressed for vector and long double items (both 128 in size). + There is a dummy use of the FIELD argument to avoid an unused variable + warning (see PR59496). */ +#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \ + ((void) (FIELD), \ + (TARGET_ALIGN_NATURAL \ + ? (COMPUTED) \ + : (COMPUTED) == 128 \ + ? 128 \ + : MIN ((COMPUTED), 32))) + +/* Darwin increases natural record alignment to doubleword if the first + field is an FP double while the FP fields remain word aligned. */ +#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \ + ((TREE_CODE (STRUCT) == RECORD_TYPE \ + || TREE_CODE (STRUCT) == UNION_TYPE \ + || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \ + && TARGET_ALIGN_NATURAL == 0 \ + ? darwin_rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \ + : (TREE_CODE (STRUCT) == VECTOR_TYPE \ + && ALTIVEC_VECTOR_MODE (TYPE_MODE (STRUCT))) \ + ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \ + : MAX ((COMPUTED), (SPECIFIED))) + +/* Specify padding for the last element of a block move between + registers and memory. FIRST is nonzero if this is the only + element. */ +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \ + (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE)) + +#define DOUBLE_INT_ASM_OP "\t.quad\t" + +/* For binary compatibility with 2.95; Darwin C APIs use bool from + stdbool.h, which was an int-sized enum in 2.95. Users can explicitly + choose to have sizeof(bool)==1 with the -mone-byte-bool switch. */ +#define BOOL_TYPE_SIZE (darwin_one_byte_bool ? CHAR_TYPE_SIZE : INT_TYPE_SIZE) + +#undef REGISTER_TARGET_PRAGMAS +#define REGISTER_TARGET_PRAGMAS() \ + do \ + { \ + DARWIN_REGISTER_TARGET_PRAGMAS(); \ + targetm.resolve_overloaded_builtin = altivec_resolve_overloaded_builtin; \ + } \ + while (0) + +#ifdef IN_LIBGCC2 +#include +#endif + +/* True, iff we're generating fast turn around debugging code. When + true, we arrange for function prologues to start with 5 nops so + that gdb may insert code to redirect them, and for data to be + accessed indirectly. The runtime uses this indirection to forward + references for data to the original instance of that data. */ + +#define TARGET_FIX_AND_CONTINUE (darwin_fix_and_continue) + +/* This is the reserved direct dispatch address for Objective-C. */ +#define OFFS_MSGSEND_FAST 0xFFFEFF00 + +/* This is the reserved ivar address Objective-C. */ +#define OFFS_ASSIGNIVAR_FAST 0xFFFEFEC0 + +/* Old versions of Mac OS/Darwin don't have C99 functions available. */ +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION darwin_libc_has_function + +/* When generating kernel code or kexts, we don't use Altivec by + default, as kernel code doesn't save/restore those registers. */ +#define OS_MISSING_ALTIVEC (flag_mkernel || flag_apple_kext) + +/* Darwin has support for section anchors on powerpc*. + It is disabled for any section containing a "zero-sized item" (because these + are re-written as size=1 to be compatible with the OSX ld64). + The re-writing would interfere with the computation of anchor offsets. + Therefore, we place zero-sized items in their own sections and make such + sections unavailable to section anchoring. */ + +#undef TARGET_ASM_OUTPUT_ANCHOR +#define TARGET_ASM_OUTPUT_ANCHOR darwin_asm_output_anchor + +#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P +#define TARGET_USE_ANCHORS_FOR_SYMBOL_P darwin_use_anchors_for_symbol_p + +#undef DARWIN_SECTION_ANCHORS +#define DARWIN_SECTION_ANCHORS 1 + +/* PPC Darwin has to rename some of the long double builtins. */ +#undef SUBTARGET_INIT_BUILTINS +#define SUBTARGET_INIT_BUILTINS \ +do { \ + darwin_patch_builtins (); \ + rs6000_builtin_decls[(unsigned) (RS6000_BUILTIN_CFSTRING)] \ + = darwin_init_cfstring_builtins ((unsigned) (RS6000_BUILTIN_CFSTRING)); \ +} while(0) + +/* So far, there is no rs6000_fold_builtin, if one is introduced, then + this will need to be modified similar to the x86 case. */ +#define TARGET_FOLD_BUILTIN SUBTARGET_FOLD_BUILTIN + +/* Use standard DWARF numbering for DWARF debugging information. */ +#define RS6000_USE_DWARF_NUMBERING + diff --git a/gcc/config/powerpcspe/darwin.md b/gcc/config/powerpcspe/darwin.md new file mode 100644 index 00000000000..fde67fd268d --- /dev/null +++ b/gcc/config/powerpcspe/darwin.md @@ -0,0 +1,480 @@ +/* Machine description patterns for PowerPC running Darwin (Mac OS X). + Copyright (C) 2004-2017 Free Software Foundation, Inc. + Contributed by Apple Computer Inc. + +This file is part of GCC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . */ + +(define_insn "adddi3_high" + [(set (match_operand:DI 0 "gpc_reg_operand" "=b") + (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b") + (high:DI (match_operand 2 "" ""))))] + "TARGET_MACHO && TARGET_64BIT" + "addis %0,%1,ha16(%2)" + [(set_attr "length" "4")]) + +(define_insn "movdf_low_si" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") + (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") + (match_operand 2 "" ""))))] + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_64BIT" + "* +{ + switch (which_alternative) + { + case 0: + return \"lfd %0,lo16(%2)(%1)\"; + case 1: + { + if (TARGET_POWERPC64 && TARGET_32BIT) + /* Note, old assemblers didn't support relocation here. */ + return \"ld %0,lo16(%2)(%1)\"; + else + { + output_asm_insn (\"la %0,lo16(%2)(%1)\", operands); + output_asm_insn (\"lwz %L0,4(%0)\", operands); + return (\"lwz %0,0(%0)\"); + } + } + default: + gcc_unreachable (); + } +}" + [(set_attr "type" "load") + (set_attr "length" "4,12")]) + + +(define_insn "movdf_low_di" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") + (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") + (match_operand 2 "" ""))))] + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" + "* +{ + switch (which_alternative) + { + case 0: + return \"lfd %0,lo16(%2)(%1)\"; + case 1: + return \"ld %0,lo16(%2)(%1)\"; + default: + gcc_unreachable (); + } +}" + [(set_attr "type" "load") + (set_attr "length" "4,4")]) + +(define_insn "movdf_low_st_si" + [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") + (match_operand 2 "" ""))) + (match_operand:DF 0 "gpc_reg_operand" "f"))] + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" + "stfd %0,lo16(%2)(%1)" + [(set_attr "type" "store") + (set_attr "length" "4")]) + +(define_insn "movdf_low_st_di" + [(set (mem:DF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") + (match_operand 2 "" ""))) + (match_operand:DF 0 "gpc_reg_operand" "f"))] + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" + "stfd %0,lo16(%2)(%1)" + [(set_attr "type" "store") + (set_attr "length" "4")]) + +(define_insn "movsf_low_si" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") + (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") + (match_operand 2 "" ""))))] + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" + "@ + lfs %0,lo16(%2)(%1) + lwz %0,lo16(%2)(%1)" + [(set_attr "type" "load") + (set_attr "length" "4")]) + +(define_insn "movsf_low_di" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") + (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") + (match_operand 2 "" ""))))] + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" + "@ + lfs %0,lo16(%2)(%1) + lwz %0,lo16(%2)(%1)" + [(set_attr "type" "load") + (set_attr "length" "4")]) + +(define_insn "movsf_low_st_si" + [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") + (match_operand 2 "" ""))) + (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" + "@ + stfs %0,lo16(%2)(%1) + stw %0,lo16(%2)(%1)" + [(set_attr "type" "store") + (set_attr "length" "4")]) + +(define_insn "movsf_low_st_di" + [(set (mem:SF (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") + (match_operand 2 "" ""))) + (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_64BIT" + "@ + stfs %0,lo16(%2)(%1) + stw %0,lo16(%2)(%1)" + [(set_attr "type" "store") + (set_attr "length" "4")]) + +;; 64-bit MachO load/store support +(define_insn "movdi_low" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,*!d") + (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") + (match_operand 2 "" ""))))] + "TARGET_MACHO && TARGET_64BIT" + "@ + ld %0,lo16(%2)(%1) + lfd %0,lo16(%2)(%1)" + [(set_attr "type" "load") + (set_attr "length" "4")]) + +(define_insn "movsi_low_st" + [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") + (match_operand 2 "" ""))) + (match_operand:SI 0 "gpc_reg_operand" "r"))] + "TARGET_MACHO && ! TARGET_64BIT" + "stw %0,lo16(%2)(%1)" + [(set_attr "type" "store") + (set_attr "length" "4")]) + +(define_insn "movdi_low_st" + [(set (mem:DI (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b,b") + (match_operand 2 "" ""))) + (match_operand:DI 0 "gpc_reg_operand" "r,*!d"))] + "TARGET_MACHO && TARGET_64BIT" + "@ + std %0,lo16(%2)(%1) + stfd %0,lo16(%2)(%1)" + [(set_attr "type" "store") + (set_attr "length" "4")]) + +;; Mach-O PIC trickery. +(define_expand "macho_high" + [(set (match_operand 0 "" "") + (high (match_operand 1 "" "")))] + "TARGET_MACHO" +{ + if (TARGET_64BIT) + emit_insn (gen_macho_high_di (operands[0], operands[1])); + else + emit_insn (gen_macho_high_si (operands[0], operands[1])); + + DONE; +}) + +(define_insn "macho_high_si" + [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") + (high:SI (match_operand 1 "" "")))] + "TARGET_MACHO && ! TARGET_64BIT" + "lis %0,ha16(%1)") + + +(define_insn "macho_high_di" + [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") + (high:DI (match_operand 1 "" "")))] + "TARGET_MACHO && TARGET_64BIT" + "lis %0,ha16(%1)") + +(define_expand "macho_low" + [(set (match_operand 0 "" "") + (lo_sum (match_operand 1 "" "") + (match_operand 2 "" "")))] + "TARGET_MACHO" +{ + if (TARGET_64BIT) + emit_insn (gen_macho_low_di (operands[0], operands[1], operands[2])); + else + emit_insn (gen_macho_low_si (operands[0], operands[1], operands[2])); + + DONE; +}) + +(define_insn "macho_low_si" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") + (match_operand 2 "" "")))] + "TARGET_MACHO && ! TARGET_64BIT" + "la %0,lo16(%2)(%1)") + +(define_insn "macho_low_di" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") + (match_operand 2 "" "")))] + "TARGET_MACHO && TARGET_64BIT" + "la %0,lo16(%2)(%1)") + +(define_split + [(set (mem:V4SI (plus:DI (match_operand:DI 0 "gpc_reg_operand" "") + (match_operand:DI 1 "short_cint_operand" ""))) + (match_operand:V4SI 2 "register_operand" "")) + (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] + "TARGET_MACHO && TARGET_64BIT" + [(set (match_dup 3) (plus:DI (match_dup 0) (match_dup 1))) + (set (mem:V4SI (match_dup 3)) + (match_dup 2))] + "") + +(define_expand "load_macho_picbase" + [(set (reg:SI LR_REGNO) + (unspec [(match_operand 0 "" "")] + UNSPEC_LD_MPIC))] + "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" +{ + if (TARGET_32BIT) + emit_insn (gen_load_macho_picbase_si (operands[0])); + else + emit_insn (gen_load_macho_picbase_di (operands[0])); + + DONE; +}) + +(define_insn "load_macho_picbase_si" + [(set (reg:SI LR_REGNO) + (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") + (pc)] UNSPEC_LD_MPIC))] + "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" +{ +#if TARGET_MACHO + machopic_should_output_picbase_label (); /* Update for new func. */ +#else + gcc_unreachable (); +#endif + return "bcl 20,31,%0\\n%0:"; +} + [(set_attr "type" "branch") + (set_attr "cannot_copy" "yes") + (set_attr "length" "4")]) + +(define_insn "load_macho_picbase_di" + [(set (reg:DI LR_REGNO) + (unspec:DI [(match_operand:DI 0 "immediate_operand" "s") + (pc)] UNSPEC_LD_MPIC))] + "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT" +{ +#if TARGET_MACHO + machopic_should_output_picbase_label (); /* Update for new func. */ +#else + gcc_unreachable (); +#endif + return "bcl 20,31,%0\\n%0:"; +} + [(set_attr "type" "branch") + (set_attr "cannot_copy" "yes") + (set_attr "length" "4")]) + +(define_expand "macho_correct_pic" + [(set (match_operand 0 "" "") + (plus (match_operand 1 "" "") + (unspec [(match_operand 2 "" "") + (match_operand 3 "" "")] + UNSPEC_MPIC_CORRECT)))] + "DEFAULT_ABI == ABI_DARWIN" +{ + if (TARGET_32BIT) + emit_insn (gen_macho_correct_pic_si (operands[0], operands[1], operands[2], + operands[3])); + else + emit_insn (gen_macho_correct_pic_di (operands[0], operands[1], operands[2], + operands[3])); + + DONE; +}) + +(define_insn "macho_correct_pic_si" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (unspec:SI [(match_operand:SI 2 "immediate_operand" "s") + (match_operand:SI 3 "immediate_operand" "s")] + UNSPEC_MPIC_CORRECT)))] + "DEFAULT_ABI == ABI_DARWIN" + "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" + [(set_attr "length" "8")]) + +(define_insn "macho_correct_pic_di" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (plus:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (unspec:DI [(match_operand:DI 2 "immediate_operand" "s") + (match_operand:DI 3 "immediate_operand" "s")] + 16)))] + "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" + "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)" + [(set_attr "length" "8")]) + +(define_insn "*call_indirect_nonlocal_darwin64" + [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l,c,*l")) + (match_operand 1 "" "g,g,g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) + (clobber (reg:SI LR_REGNO))] + "DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT" +{ + return "b%T0l"; +} + [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") + (set_attr "length" "4,4,8,8")]) + +(define_insn "*call_nonlocal_darwin64" + [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s")) + (match_operand 1 "" "g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,n")) + (clobber (reg:SI LR_REGNO))] + "(DEFAULT_ABI == ABI_DARWIN) + && (INTVAL (operands[2]) & CALL_LONG) == 0" +{ +#if TARGET_MACHO + return output_call(insn, operands, 0, 2); +#else + gcc_unreachable (); +#endif +} + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +(define_insn "*call_value_indirect_nonlocal_darwin64" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:DI 1 "register_operand" "c,*l,c,*l")) + (match_operand 2 "" "g,g,g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) + (clobber (reg:SI LR_REGNO))] + "DEFAULT_ABI == ABI_DARWIN" +{ + return "b%T1l"; +} + [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") + (set_attr "length" "4,4,8,8")]) + +(define_insn "*call_value_nonlocal_darwin64" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s")) + (match_operand 2 "" "g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (clobber (reg:SI LR_REGNO))] + "(DEFAULT_ABI == ABI_DARWIN) + && (INTVAL (operands[3]) & CALL_LONG) == 0" +{ +#if TARGET_MACHO + return output_call(insn, operands, 1, 3); +#else + gcc_unreachable (); +#endif +} + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +(define_expand "reload_macho_picbase" + [(set (reg:SI LR_REGNO) + (unspec [(match_operand 0 "" "")] + UNSPEC_RELD_MPIC))] + "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" +{ + if (TARGET_32BIT) + emit_insn (gen_reload_macho_picbase_si (operands[0])); + else + emit_insn (gen_reload_macho_picbase_di (operands[0])); + + DONE; +}) + +(define_insn "reload_macho_picbase_si" + [(set (reg:SI LR_REGNO) + (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") + (pc)] UNSPEC_RELD_MPIC))] + "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" +{ +#if TARGET_MACHO + if (machopic_should_output_picbase_label ()) + { + static char tmp[64]; + const char *cnam = machopic_get_function_picbase (); + snprintf (tmp, 64, "bcl 20,31,%s\\n%s:\\n%%0:", cnam, cnam); + return tmp; + } + else +#else + gcc_unreachable (); +#endif + return "bcl 20,31,%0\\n%0:"; +} + [(set_attr "type" "branch") + (set_attr "cannot_copy" "yes") + (set_attr "length" "4")]) + +(define_insn "reload_macho_picbase_di" + [(set (reg:DI LR_REGNO) + (unspec:DI [(match_operand:DI 0 "immediate_operand" "s") + (pc)] UNSPEC_RELD_MPIC))] + "(DEFAULT_ABI == ABI_DARWIN) && flag_pic && TARGET_64BIT" +{ +#if TARGET_MACHO + if (machopic_should_output_picbase_label ()) + { + static char tmp[64]; + const char *cnam = machopic_get_function_picbase (); + snprintf (tmp, 64, "bcl 20,31,%s\\n%s:\\n%%0:", cnam, cnam); + return tmp; + } + else +#else + gcc_unreachable (); +#endif + return "bcl 20,31,%0\\n%0:"; +} + [(set_attr "type" "branch") + (set_attr "cannot_copy" "yes") + (set_attr "length" "4")]) + +;; We need to restore the PIC register, at the site of nonlocal label. + +(define_insn_and_split "nonlocal_goto_receiver" + [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)] + "TARGET_MACHO && flag_pic" + "#" + "&& reload_completed" + [(const_int 0)] +{ +#if TARGET_MACHO + if (crtl->uses_pic_offset_table) + { + static unsigned n = 0; + rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); + rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); + rtx tmplrtx; + char tmplab[20]; + + ASM_GENERATE_INTERNAL_LABEL(tmplab, "Lnlgr", ++n); + tmplrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); + + emit_insn (gen_reload_macho_picbase (tmplrtx)); + emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); + emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplrtx)); + } + else + /* Not using PIC reg, no reload needed. */ + emit_note (NOTE_INSN_DELETED); +#else + gcc_unreachable (); +#endif + DONE; +}) diff --git a/gcc/config/powerpcspe/darwin.opt b/gcc/config/powerpcspe/darwin.opt new file mode 100644 index 00000000000..aca1c3ee67d --- /dev/null +++ b/gcc/config/powerpcspe/darwin.opt @@ -0,0 +1,42 @@ +; Darwin options for PPC port. +; +; Copyright (C) 2005-2017 Free Software Foundation, Inc. +; Contributed by Aldy Hernandez . +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 3, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +; License for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING3. If not see +; . + +Waltivec-long-deprecated +Driver Alias(mwarn-altivec-long) + +faltivec +Driver + +; -ffix-and-continue and -findirect-data are for compatibility for old +; compilers. +ffix-and-continue +Driver RejectNegative Alias(mfix-and-continue) + +findirect-data +Driver RejectNegative Alias(mfix-and-continue) + +m64 +Target RejectNegative Negative(m32) Mask(64BIT) Var(rs6000_isa_flags) +Generate 64-bit code. + +m32 +Target RejectNegative Negative(m64) InverseMask(64BIT) Var(rs6000_isa_flags) +Generate 32-bit code. diff --git a/gcc/config/powerpcspe/darwin64.h b/gcc/config/powerpcspe/darwin64.h new file mode 100644 index 00000000000..79d780cd71b --- /dev/null +++ b/gcc/config/powerpcspe/darwin64.h @@ -0,0 +1,32 @@ +/* Target definitions for PowerPC running Darwin (Mac OS X). + Copyright (C) 2006-2017 Free Software Foundation, Inc. + Contributed by Apple Computer Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_POWERPC64 | MASK_64BIT \ + | MASK_MULTIPLE | MASK_PPC_GFXOPT) + +#undef DARWIN_ARCH_SPEC +#define DARWIN_ARCH_SPEC "%{m32:ppc;:ppc64}" + +#undef DARWIN_SUBARCH_SPEC +#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC + +#undef DARWIN_CRT2_SPEC +#define DARWIN_CRT2_SPEC "" diff --git a/gcc/config/powerpcspe/darwin7.h b/gcc/config/powerpcspe/darwin7.h new file mode 100644 index 00000000000..f5e9f893030 --- /dev/null +++ b/gcc/config/powerpcspe/darwin7.h @@ -0,0 +1,32 @@ +/* Target definitions for Darwin 7.x (Mac OS X) systems. + Copyright (C) 2004-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Machine dependent libraries. Include libmx when compiling for + Darwin 7.0 and above, but before libSystem, since the functions are + actually in libSystem but for 7.x compatibility we want them to be + looked for in libmx first. Include libmx by default because otherwise + libstdc++ isn't usable. */ + +#undef LIB_SPEC +#define LIB_SPEC "%{!static:\ + %:version-compare(!< 10.3 mmacosx-version-min= -lmx)\ + -lSystem}" + +#undef DEF_MIN_OSX_VERSION +#define DEF_MIN_OSX_VERSION "10.3.9" diff --git a/gcc/config/powerpcspe/darwin8.h b/gcc/config/powerpcspe/darwin8.h new file mode 100644 index 00000000000..bccf998de7c --- /dev/null +++ b/gcc/config/powerpcspe/darwin8.h @@ -0,0 +1,31 @@ +/* Target definitions for Darwin 8.0 and above (Mac OS X) systems. + Copyright (C) 2004-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Machine dependent libraries. Include libmx when compiling on + Darwin 7.0 and above, but before libSystem, since the functions are + actually in libSystem but for 7.x compatibility we want them to be + looked for in libmx first---but only do this if 7.x compatibility + is a concern, which it's not in 64-bit mode. Include + libSystemStubs when compiling on (not necessarily for) 8.0 and + above and not 64-bit long double. */ + +#undef LIB_SPEC +#define LIB_SPEC "%{!static:\ + %{!mlong-double-64:%{pg:-lSystemStubs_profile;:-lSystemStubs}} \ + %{!m64:%:version-compare(>< 10.3 10.4 mmacosx-version-min= -lmx)} -lSystem}" diff --git a/gcc/config/powerpcspe/default64.h b/gcc/config/powerpcspe/default64.h new file mode 100644 index 00000000000..ebce9f25aae --- /dev/null +++ b/gcc/config/powerpcspe/default64.h @@ -0,0 +1,31 @@ +/* Definitions of target machine for GNU compiler, + for 64 bit powerpc linux defaulting to -m64. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#define RS6000_CPU(NAME, CPU, FLAGS) +#include "rs6000-cpus.def" +#undef RS6000_CPU + +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (ISA_2_7_MASKS_SERVER | MASK_POWERPC64 | MASK_64BIT | MASK_LITTLE_ENDIAN) +#else +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 | MASK_64BIT) +#endif diff --git a/gcc/config/powerpcspe/dfp.md b/gcc/config/powerpcspe/dfp.md new file mode 100644 index 00000000000..790f2e43d49 --- /dev/null +++ b/gcc/config/powerpcspe/dfp.md @@ -0,0 +1,419 @@ +;; Decimal Floating Point (DFP) patterns. +;; Copyright (C) 2007-2017 Free Software Foundation, Inc. +;; Contributed by Ben Elliston (bje@au.ibm.com) and Peter Bergner +;; (bergner@vnet.ibm.com). + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; +;; UNSPEC usage +;; + +(define_c_enum "unspec" + [UNSPEC_MOVSD_LOAD + UNSPEC_MOVSD_STORE + ]) + + +(define_insn "movsd_store" + [(set (match_operand:DD 0 "nonimmediate_operand" "=m") + (unspec:DD [(match_operand:SD 1 "input_operand" "d")] + UNSPEC_MOVSD_STORE))] + "(gpc_reg_operand (operands[0], DDmode) + || gpc_reg_operand (operands[1], SDmode)) + && TARGET_HARD_FLOAT && TARGET_FPRS" + "stfd%U0%X0 %1,%0" + [(set_attr "type" "fpstore") + (set_attr "length" "4")]) + +(define_insn "movsd_load" + [(set (match_operand:SD 0 "nonimmediate_operand" "=f") + (unspec:SD [(match_operand:DD 1 "input_operand" "m")] + UNSPEC_MOVSD_LOAD))] + "(gpc_reg_operand (operands[0], SDmode) + || gpc_reg_operand (operands[1], DDmode)) + && TARGET_HARD_FLOAT && TARGET_FPRS" + "lfd%U1%X1 %0,%1" + [(set_attr "type" "fpload") + (set_attr "length" "4")]) + +;; Hardware support for decimal floating point operations. + +(define_insn "extendsddd2" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))] + "TARGET_DFP" + "dctdp %0,%1" + [(set_attr "type" "dfp")]) + +(define_expand "extendsdtd2" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))] + "TARGET_DFP" +{ + rtx tmp = gen_reg_rtx (DDmode); + emit_insn (gen_extendsddd2 (tmp, operands[1])); + emit_insn (gen_extendddtd2 (operands[0], tmp)); + DONE; +}) + +(define_insn "truncddsd2" + [(set (match_operand:SD 0 "gpc_reg_operand" "=f") + (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "drsp %0,%1" + [(set_attr "type" "dfp")]) + +(define_expand "negdd2" + [(set (match_operand:DD 0 "gpc_reg_operand" "") + (neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "") + +(define_insn "*negdd2_fpr" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "fneg %0,%1" + [(set_attr "type" "fpsimple")]) + +(define_expand "absdd2" + [(set (match_operand:DD 0 "gpc_reg_operand" "") + (abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "") + +(define_insn "*absdd2_fpr" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "fabs %0,%1" + [(set_attr "type" "fpsimple")]) + +(define_insn "*nabsdd2_fpr" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "fnabs %0,%1" + [(set_attr "type" "fpsimple")]) + +(define_expand "negtd2" + [(set (match_operand:TD 0 "gpc_reg_operand" "") + (neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "") + +(define_insn "*negtd2_fpr" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d") + (neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "@ + fneg %0,%1 + fneg %0,%1\;fmr %L0,%L1" + [(set_attr "type" "fpsimple") + (set_attr "length" "4,8")]) + +(define_expand "abstd2" + [(set (match_operand:TD 0 "gpc_reg_operand" "") + (abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "") + +(define_insn "*abstd2_fpr" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d") + (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "@ + fabs %0,%1 + fabs %0,%1\;fmr %L0,%L1" + [(set_attr "type" "fpsimple") + (set_attr "length" "4,8")]) + +(define_insn "*nabstd2_fpr" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d") + (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d"))))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "@ + fnabs %0,%1 + fnabs %0,%1\;fmr %L0,%L1" + [(set_attr "type" "fpsimple") + (set_attr "length" "4,8")]) + +;; Hardware support for decimal floating point operations. + +(define_insn "extendddtd2" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dctqpq %0,%1" + [(set_attr "type" "dfp")]) + +;; The result of drdpq is an even/odd register pair with the converted +;; value in the even register and zero in the odd register. +;; FIXME: Avoid the register move by using a reload constraint to ensure +;; that the result is the first of the pair receiving the result of drdpq. + +(define_insn "trunctddd2" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "d"))) + (clobber (match_scratch:TD 2 "=d"))] + "TARGET_DFP" + "drdpq %2,%1\;fmr %0,%2" + [(set_attr "type" "dfp") + (set_attr "length" "8")]) + +(define_insn "adddd3" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (plus:DD (match_operand:DD 1 "gpc_reg_operand" "%d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dadd %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "addtd3" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (plus:TD (match_operand:TD 1 "gpc_reg_operand" "%d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "daddq %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "subdd3" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (minus:DD (match_operand:DD 1 "gpc_reg_operand" "d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dsub %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "subtd3" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (minus:TD (match_operand:TD 1 "gpc_reg_operand" "d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dsubq %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "muldd3" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (mult:DD (match_operand:DD 1 "gpc_reg_operand" "%d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dmul %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "multd3" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (mult:TD (match_operand:TD 1 "gpc_reg_operand" "%d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dmulq %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "divdd3" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (div:DD (match_operand:DD 1 "gpc_reg_operand" "d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "ddiv %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "divtd3" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (div:TD (match_operand:TD 1 "gpc_reg_operand" "d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "ddivq %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "*cmpdd_internal1" + [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") + (compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d") + (match_operand:DD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dcmpu %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "*cmptd_internal1" + [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") + (compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d") + (match_operand:TD 2 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dcmpuq %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "floatdidd2" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))] + "TARGET_DFP && TARGET_POPCNTD" + "dcffix %0,%1" + [(set_attr "type" "dfp")]) + +(define_insn "floatditd2" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dcffixq %0,%1" + [(set_attr "type" "dfp")]) + +;; Convert a decimal64 to a decimal64 whose value is an integer. +;; This is the first stage of converting it to an integer type. + +(define_insn "ftruncdd2" + [(set (match_operand:DD 0 "gpc_reg_operand" "=d") + (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "drintn. 0,%0,%1,1" + [(set_attr "type" "dfp")]) + +;; Convert a decimal64 whose value is an integer to an actual integer. +;; This is the second stage of converting decimal float to integer type. + +(define_insn "fixdddi2" + [(set (match_operand:DI 0 "gpc_reg_operand" "=d") + (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dctfix %0,%1" + [(set_attr "type" "dfp")]) + +;; Convert a decimal128 to a decimal128 whose value is an integer. +;; This is the first stage of converting it to an integer type. + +(define_insn "ftrunctd2" + [(set (match_operand:TD 0 "gpc_reg_operand" "=d") + (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "drintnq. 0,%0,%1,1" + [(set_attr "type" "dfp")]) + +;; Convert a decimal128 whose value is an integer to an actual integer. +;; This is the second stage of converting decimal float to integer type. + +(define_insn "fixtddi2" + [(set (match_operand:DI 0 "gpc_reg_operand" "=d") + (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))] + "TARGET_DFP" + "dctfixq %0,%1" + [(set_attr "type" "dfp")]) + + +;; Decimal builtin support + +(define_c_enum "unspec" + [UNSPEC_DDEDPD + UNSPEC_DENBCD + UNSPEC_DXEX + UNSPEC_DIEX + UNSPEC_DSCLI + UNSPEC_DTSTSFI + UNSPEC_DSCRI]) + +(define_code_iterator DFP_TEST [eq lt gt unordered]) + +(define_mode_iterator D64_D128 [DD TD]) + +(define_mode_attr dfp_suffix [(DD "") + (TD "q")]) + +(define_insn "dfp_ddedpd_" + [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") + (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_3_operand" "i") + (match_operand:D64_D128 2 "gpc_reg_operand" "d")] + UNSPEC_DDEDPD))] + "TARGET_DFP" + "ddedpd %1,%0,%2" + [(set_attr "type" "dfp")]) + +(define_insn "dfp_denbcd_" + [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") + (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_1_operand" "i") + (match_operand:D64_D128 2 "gpc_reg_operand" "d")] + UNSPEC_DENBCD))] + "TARGET_DFP" + "denbcd %1,%0,%2" + [(set_attr "type" "dfp")]) + +(define_insn "dfp_dxex_" + [(set (match_operand:DI 0 "gpc_reg_operand" "=d") + (unspec:DI [(match_operand:D64_D128 1 "gpc_reg_operand" "d")] + UNSPEC_DXEX))] + "TARGET_DFP" + "dxex %0,%1" + [(set_attr "type" "dfp")]) + +(define_insn "dfp_diex_" + [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") + (unspec:D64_D128 [(match_operand:DI 1 "gpc_reg_operand" "d") + (match_operand:D64_D128 2 "gpc_reg_operand" "d")] + UNSPEC_DXEX))] + "TARGET_DFP" + "diex %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_expand "dfptstsfi__" + [(set (match_dup 3) + (compare:CCFP + (unspec:D64_D128 + [(match_operand:SI 1 "const_int_operand" "n") + (match_operand:D64_D128 2 "gpc_reg_operand" "d")] + UNSPEC_DTSTSFI) + (match_dup 4))) + (set (match_operand:SI 0 "register_operand" "") + (DFP_TEST:SI (match_dup 3) + (const_int 0))) + ] + "TARGET_P9_MISC" +{ + operands[3] = gen_reg_rtx (CCFPmode); + operands[4] = const0_rtx; +}) + +(define_insn "*dfp_sgnfcnc_" + [(set (match_operand:CCFP 0 "" "=y") + (compare:CCFP + (unspec:D64_D128 [(match_operand:SI 1 "const_int_operand" "n") + (match_operand:D64_D128 2 "gpc_reg_operand" "d")] + UNSPEC_DTSTSFI) + (match_operand:SI 3 "zero_constant" "j")))] + "TARGET_P9_MISC" +{ + /* If immediate operand is greater than 63, it will behave as if + the value had been 63. The code generator does not support + immediate operand values greater than 63. */ + if (!(IN_RANGE (INTVAL (operands[1]), 0, 63))) + operands[1] = GEN_INT (63); + return "dtstsfi %0,%1,%2"; +} + [(set_attr "type" "fp")]) + +(define_insn "dfp_dscli_" + [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") + (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d") + (match_operand:QI 2 "immediate_operand" "i")] + UNSPEC_DSCLI))] + "TARGET_DFP" + "dscli %0,%1,%2" + [(set_attr "type" "dfp")]) + +(define_insn "dfp_dscri_" + [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") + (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d") + (match_operand:QI 2 "immediate_operand" "i")] + UNSPEC_DSCRI))] + "TARGET_DFP" + "dscri %0,%1,%2" + [(set_attr "type" "dfp")]) diff --git a/gcc/config/powerpcspe/driver-powerpcspe.c b/gcc/config/powerpcspe/driver-powerpcspe.c new file mode 100644 index 00000000000..8215abbd625 --- /dev/null +++ b/gcc/config/powerpcspe/driver-powerpcspe.c @@ -0,0 +1,539 @@ +/* Subroutines for the gcc driver. + Copyright (C) 2007-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include + +#ifdef _AIX +# include +#endif + +#ifdef __linux__ +# include +#endif + +#if defined (__APPLE__) || (__FreeBSD__) +# include +# include +#endif + +const char *host_detect_local_cpu (int argc, const char **argv); + +#if GCC_VERSION >= 0 + +/* Returns parameters that describe L1_ASSOC associative cache of size + L1_SIZEKB with lines of size L1_LINE, and L2_SIZEKB. */ + +static char * +describe_cache (unsigned l1_sizekb, unsigned l1_line, + unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb) +{ + char l1size[1000], line[1000], l2size[1000]; + + /* At the moment, gcc middle-end does not use the information about the + associativity of the cache. */ + + sprintf (l1size, "--param l1-cache-size=%u", l1_sizekb); + sprintf (line, "--param l1-cache-line-size=%u", l1_line); + sprintf (l2size, "--param l2-cache-size=%u", l2_sizekb); + + return concat (l1size, " ", line, " ", l2size, " ", NULL); +} + +#ifdef __APPLE__ + +/* Returns the description of caches on Darwin. */ + +static char * +detect_caches_darwin (void) +{ + unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb; + size_t len = 4; + static int l1_size_name[2] = { CTL_HW, HW_L1DCACHESIZE }; + static int l1_line_name[2] = { CTL_HW, HW_CACHELINE }; + static int l2_size_name[2] = { CTL_HW, HW_L2CACHESIZE }; + + sysctl (l1_size_name, 2, &l1_sizekb, &len, NULL, 0); + sysctl (l1_line_name, 2, &l1_line, &len, NULL, 0); + sysctl (l2_size_name, 2, &l2_sizekb, &len, NULL, 0); + l1_assoc = 0; + + return describe_cache (l1_sizekb / 1024, l1_line, l1_assoc, + l2_sizekb / 1024); +} + +static const char * +detect_processor_darwin (void) +{ + unsigned int proc; + size_t len = 4; + + sysctlbyname ("hw.cpusubtype", &proc, &len, NULL, 0); + + if (len > 0) + switch (proc) + { + case 1: + return "601"; + case 2: + return "602"; + case 3: + return "603"; + case 4: + case 5: + return "603e"; + case 6: + return "604"; + case 7: + return "604e"; + case 8: + return "620"; + case 9: + return "750"; + case 10: + return "7400"; + case 11: + return "7450"; + case 100: + return "970"; + default: + return "powerpc"; + } + + return "powerpc"; +} + +#endif /* __APPLE__ */ + +#ifdef __FreeBSD__ + +/* Returns the description of caches on FreeBSD PPC. */ + +static char * +detect_caches_freebsd (void) +{ + unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb; + size_t len = 4; + + /* Currently, as of FreeBSD-7.0, there is only the cacheline_size + available via sysctl. */ + sysctlbyname ("machdep.cacheline_size", &l1_line, &len, NULL, 0); + + l1_sizekb = 32; + l1_assoc = 0; + l2_sizekb = 512; + + return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb); +} + +/* Currently returns default powerpc. */ +static const char * +detect_processor_freebsd (void) +{ + return "powerpc"; +} + +#endif /* __FreeBSD__ */ + +#ifdef __linux__ + +/* Returns AT_PLATFORM if present, otherwise generic PowerPC. */ + +static const char * +elf_platform (void) +{ + int fd; + + fd = open ("/proc/self/auxv", O_RDONLY); + + if (fd != -1) + { + char buf[1024]; + ElfW(auxv_t) *av; + ssize_t n; + + n = read (fd, buf, sizeof (buf)); + close (fd); + + if (n > 0) + { + for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av) + switch (av->a_type) + { + case AT_PLATFORM: + return (const char *) av->a_un.a_val; + + default: + break; + } + } + } + return NULL; +} + +/* Returns AT_DCACHEBSIZE if present, otherwise generic 32. */ + +static int +elf_dcachebsize (void) +{ + int fd; + + fd = open ("/proc/self/auxv", O_RDONLY); + + if (fd != -1) + { + char buf[1024]; + ElfW(auxv_t) *av; + ssize_t n; + + n = read (fd, buf, sizeof (buf)); + close (fd); + + if (n > 0) + { + for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av) + switch (av->a_type) + { + case AT_DCACHEBSIZE: + return av->a_un.a_val; + + default: + break; + } + } + } + return 32; +} + +/* Returns the description of caches on Linux. */ + +static char * +detect_caches_linux (void) +{ + unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb; + const char *platform; + + platform = elf_platform (); + + if (platform != NULL) + { + l1_line = 128; + + if (platform[5] == '6') + /* POWER6 and POWER6x */ + l1_sizekb = 64; + else + l1_sizekb = 32; + } + else + { + l1_line = elf_dcachebsize (); + l1_sizekb = 32; + } + + l1_assoc = 0; + l2_sizekb = 512; + + return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb); +} + +static const char * +detect_processor_linux (void) +{ + const char *platform; + + platform = elf_platform (); + + if (platform != NULL) + return platform; + else + return "powerpc"; +} + +#endif /* __linux__ */ + +#ifdef _AIX +/* Returns the description of caches on AIX. */ + +static char * +detect_caches_aix (void) +{ + unsigned l1_sizekb, l1_line, l1_assoc, l2_sizekb; + + l1_sizekb = _system_configuration.dcache_size / 1024; + l1_line = _system_configuration.dcache_line; + l1_assoc = _system_configuration.dcache_asc; + l2_sizekb = _system_configuration.L2_cache_size / 1024; + + return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb); +} + + +/* Returns the processor implementation on AIX. */ + +static const char * +detect_processor_aix (void) +{ + switch (_system_configuration.implementation) + { + case 0x0008: + return "601"; + + case 0x0020: + return "603"; + + case 0x0010: + return "604"; + + case 0x0040: + return "620"; + + case 0x0080: + return "630"; + + case 0x0100: + case 0x0200: + case 0x0400: + return "rs64"; + + case 0x0800: + return "power4"; + + case 0x2000: + if (_system_configuration.version == 0x0F0000) + return "power5"; + else + return "power5+"; + + case 0x4000: + return "power6"; + + case 0x8000: + return "power7"; + + case 0x10000: + return "power8"; + + case 0x20000: + return "power9"; + + default: + return "powerpc"; + } +} +#endif /* _AIX */ + + +/* + * Array to map -mcpu=native names to the switches passed to the assembler. + * This list mirrors the specs in ASM_CPU_SPEC, and any changes made here + * should be made there as well. + */ + +struct asm_name { + const char *cpu; + const char *asm_sw; +}; + +static const struct asm_name asm_names[] = { +#if defined (_AIX) + { "power3", "-m620" }, + { "power4", "-mpwr4" }, + { "power5", "-mpwr5" }, + { "power5+", "-mpwr5x" }, + { "power6", "-mpwr6" }, + { "power6x", "-mpwr6" }, + { "power7", "-mpwr7" }, + { "power8", "-mpwr8" }, + { "power9", "-mpwr9" }, + { "powerpc", "-mppc" }, + { "rs64a", "-mppc" }, + { "603", "-m603" }, + { "603e", "-m603" }, + { "604", "-m604" }, + { "604e", "-m604" }, + { "620", "-m620" }, + { "630", "-m620" }, + { "970", "-m970" }, + { "G5", "-m970" }, + { NULL, "\ +%{!maix64: \ +%{mpowerpc64: -mppc64} \ +%{maltivec: -m970} \ +%{!maltivec: %{!mpowerpc64: %(asm_default)}}}" }, + +#else + { "cell", "-mcell" }, + { "power3", "-mppc64" }, + { "power4", "-mpower4" }, + { "power5", "%(asm_cpu_power5)" }, + { "power5+", "%(asm_cpu_power5)" }, + { "power6", "%(asm_cpu_power6) -maltivec" }, + { "power6x", "%(asm_cpu_power6) -maltivec" }, + { "power7", "%(asm_cpu_power7)" }, + { "power8", "%(asm_cpu_power8)" }, + { "power9", "%(asm_cpu_power9)" }, + { "powerpc", "-mppc" }, + { "rs64a", "-mppc64" }, + { "401", "-mppc" }, + { "403", "-m403" }, + { "405", "-m405" }, + { "405fp", "-m405" }, + { "440", "-m440" }, + { "440fp", "-m440" }, + { "464", "-m440" }, + { "464fp", "-m440" }, + { "505", "-mppc" }, + { "601", "-m601" }, + { "602", "-mppc" }, + { "603", "-mppc" }, + { "603e", "-mppc" }, + { "ec603e", "-mppc" }, + { "604", "-mppc" }, + { "604e", "-mppc" }, + { "620", "-mppc64" }, + { "630", "-mppc64" }, + { "740", "-mppc" }, + { "750", "-mppc" }, + { "G3", "-mppc" }, + { "7400", "-mppc -maltivec" }, + { "7450", "-mppc -maltivec" }, + { "G4", "-mppc -maltivec" }, + { "801", "-mppc" }, + { "821", "-mppc" }, + { "823", "-mppc" }, + { "860", "-mppc" }, + { "970", "-mpower4 -maltivec" }, + { "G5", "-mpower4 -maltivec" }, + { "8540", "-me500" }, + { "8548", "-me500" }, + { "e300c2", "-me300" }, + { "e300c3", "-me300" }, + { "e500mc", "-me500mc" }, + { NULL, "\ +%{mpowerpc64*: -mppc64} \ +%{!mpowerpc64*: %(asm_default)}" }, +#endif +}; + +/* This will be called by the spec parser in gcc.c when it sees + a %:local_cpu_detect(args) construct. Currently it will be called + with either "arch" or "tune" as argument depending on if -march=native + or -mtune=native is to be substituted. + + Additionally it will be called with "asm" to select the appropriate flags + for the assembler. + + It returns a string containing new command line parameters to be + put at the place of the above two options, depending on what CPU + this is executed. + + ARGC and ARGV are set depending on the actual arguments given + in the spec. */ +const char * +host_detect_local_cpu (int argc, const char **argv) +{ + const char *cpu = NULL; + const char *cache = ""; + const char *options = ""; + bool arch; + bool assembler; + size_t i; + + if (argc < 1) + return NULL; + + arch = strcmp (argv[0], "cpu") == 0; + assembler = (!arch && strcmp (argv[0], "asm") == 0); + if (!arch && !assembler && strcmp (argv[0], "tune")) + return NULL; + + if (! assembler) + { +#if defined (_AIX) + cache = detect_caches_aix (); +#elif defined (__APPLE__) + cache = detect_caches_darwin (); +#elif defined (__FreeBSD__) + cache = detect_caches_freebsd (); + /* FreeBSD PPC does not provide any cache information yet. */ + cache = ""; +#elif defined (__linux__) + cache = detect_caches_linux (); + /* PPC Linux does not provide any cache information yet. */ + cache = ""; +#else + cache = ""; +#endif + } + +#if defined (_AIX) + cpu = detect_processor_aix (); +#elif defined (__APPLE__) + cpu = detect_processor_darwin (); +#elif defined (__FreeBSD__) + cpu = detect_processor_freebsd (); +#elif defined (__linux__) + cpu = detect_processor_linux (); +#else + cpu = "powerpc"; +#endif + + if (assembler) + { + for (i = 0; i < sizeof (asm_names) / sizeof (asm_names[0]); i++) + { + if (!asm_names[i].cpu || !strcmp (asm_names[i].cpu, cpu)) + return asm_names[i].asm_sw; + } + + return NULL; + } + + return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL); +} + +#else /* GCC_VERSION */ + +/* If we aren't compiling with GCC we just provide a minimal + default value. */ +const char * +host_detect_local_cpu (int argc, const char **argv) +{ + const char *cpu; + bool arch; + + if (argc < 1) + return NULL; + + arch = strcmp (argv[0], "cpu") == 0; + if (!arch && strcmp (argv[0], "tune")) + return NULL; + + if (arch) + cpu = "powerpc"; + + return concat ("-m", argv[0], "=", cpu, NULL); +} + +#endif /* GCC_VERSION */ + diff --git a/gcc/config/powerpcspe/e300c2c3.md b/gcc/config/powerpcspe/e300c2c3.md new file mode 100644 index 00000000000..f014f817d8a --- /dev/null +++ b/gcc/config/powerpcspe/e300c2c3.md @@ -0,0 +1,193 @@ +;; Pipeline description for Motorola PowerPC e300c3 core. +;; Copyright (C) 2008-2017 Free Software Foundation, Inc. +;; Contributed by Edmar Wienskoski (edmar@freescale.com) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "ppce300c3_most,ppce300c3_long,ppce300c3_retire") +(define_cpu_unit "ppce300c3_decode_0,ppce300c3_decode_1" "ppce300c3_most") + +;; We don't simulate general issue queue (GIC). If we have SU insn +;; and then SU1 insn, they can not be issued on the same cycle +;; (although SU1 insn and then SU insn can be issued) because the SU +;; insn will go to SU1 from GIC0 entry. Fortunately, the first cycle +;; multipass insn scheduling will find the situation and issue the SU1 +;; insn and then the SU insn. +(define_cpu_unit "ppce300c3_issue_0,ppce300c3_issue_1" "ppce300c3_most") + +;; We could describe completion buffers slots in combination with the +;; retirement units and the order of completion but the result +;; automaton would behave in the same way because we can not describe +;; real latency time with taking in order completion into account. +;; Actually we could define the real latency time by querying reserved +;; automaton units but the current scheduler uses latency time before +;; issuing insns and making any reservations. +;; +;; So our description is aimed to achieve a insn schedule in which the +;; insns would not wait in the completion buffer. +(define_cpu_unit "ppce300c3_retire_0,ppce300c3_retire_1" "ppce300c3_retire") + +;; Branch unit: +(define_cpu_unit "ppce300c3_bu" "ppce300c3_most") + +;; IU: +(define_cpu_unit "ppce300c3_iu0_stage0,ppce300c3_iu1_stage0" "ppce300c3_most") + +;; IU: This used to describe non-pipelined division. +(define_cpu_unit "ppce300c3_mu_div" "ppce300c3_long") + +;; SRU: +(define_cpu_unit "ppce300c3_sru_stage0" "ppce300c3_most") + +;; Here we simplified LSU unit description not describing the stages. +(define_cpu_unit "ppce300c3_lsu" "ppce300c3_most") + +;; FPU: +(define_cpu_unit "ppce300c3_fpu" "ppce300c3_most") + +;; The following units are used to make automata deterministic +(define_cpu_unit "present_ppce300c3_decode_0" "ppce300c3_most") +(define_cpu_unit "present_ppce300c3_issue_0" "ppce300c3_most") +(define_cpu_unit "present_ppce300c3_retire_0" "ppce300c3_retire") +(define_cpu_unit "present_ppce300c3_iu0_stage0" "ppce300c3_most") + +;; The following sets to make automata deterministic when option ndfa is used. +(presence_set "present_ppce300c3_decode_0" "ppce300c3_decode_0") +(presence_set "present_ppce300c3_issue_0" "ppce300c3_issue_0") +(presence_set "present_ppce300c3_retire_0" "ppce300c3_retire_0") +(presence_set "present_ppce300c3_iu0_stage0" "ppce300c3_iu0_stage0") + +;; Some useful abbreviations. +(define_reservation "ppce300c3_decode" + "ppce300c3_decode_0|ppce300c3_decode_1+present_ppce300c3_decode_0") +(define_reservation "ppce300c3_issue" + "ppce300c3_issue_0|ppce300c3_issue_1+present_ppce300c3_issue_0") +(define_reservation "ppce300c3_retire" + "ppce300c3_retire_0|ppce300c3_retire_1+present_ppce300c3_retire_0") +(define_reservation "ppce300c3_iu_stage0" + "ppce300c3_iu0_stage0|ppce300c3_iu1_stage0+present_ppce300c3_iu0_stage0") + +;; Compares can be executed either one of the IU or SRU +(define_insn_reservation "ppce300c3_cmp" 1 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes"))) + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+(ppce300c3_iu_stage0|ppce300c3_sru_stage0) \ + +ppce300c3_retire") + +;; Other one cycle IU insns +(define_insn_reservation "ppce300c3_iu" 1 + (and (ior (eq_attr "type" "integer,insert,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0+ppce300c3_retire") + +;; Branch. Actually this latency time is not used by the scheduler. +(define_insn_reservation "ppce300c3_branch" 1 + (and (eq_attr "type" "jmpreg,branch") + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_bu,ppce300c3_retire") + +;; Multiply is non-pipelined but can be executed in any IU +(define_insn_reservation "ppce300c3_multiply" 2 + (and (eq_attr "type" "mul") + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0, \ + ppce300c3_iu_stage0+ppce300c3_retire") + +;; Divide. We use the average latency time here. We omit reserving a +;; retire unit because of the result automata will be huge. +(define_insn_reservation "ppce300c3_divide" 20 + (and (eq_attr "type" "div") + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_iu_stage0+ppce300c3_mu_div,\ + ppce300c3_mu_div*19") + +;; CR logical +(define_insn_reservation "ppce300c3_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") + +;; Mfcr +(define_insn_reservation "ppce300c3_mfcr" 1 + (and (eq_attr "type" "mfcr") + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") + +;; Mtcrf +(define_insn_reservation "ppce300c3_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") + +;; Mtjmpr +(define_insn_reservation "ppce300c3_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_sru_stage0+ppce300c3_retire") + +;; Float point instructions +(define_insn_reservation "ppce300c3_fpcompare" 3 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppce300c3")) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire") + +(define_insn_reservation "ppce300c3_fp" 3 + (and (eq_attr "type" "fp,fpsimple") + (eq_attr "cpu" "ppce300c3")) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,nothing,ppce300c3_retire") + +(define_insn_reservation "ppce300c3_dmul" 4 + (and (eq_attr "type" "dmul") + (eq_attr "cpu" "ppce300c3")) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu,nothing,ppce300c3_retire") + +; Divides are not pipelined +(define_insn_reservation "ppce300c3_sdiv" 18 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppce300c3")) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu*17") + +(define_insn_reservation "ppce300c3_ddiv" 33 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppce300c3")) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_fpu,ppce300c3_fpu*32") + +;; Loads +(define_insn_reservation "ppce300c3_load" 2 + (and (eq_attr "type" "load") + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") + +(define_insn_reservation "ppce300c3_fpload" 2 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppce300c3")) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") + +;; Stores. +(define_insn_reservation "ppce300c3_store" 2 + (and (eq_attr "type" "store") + (ior (eq_attr "cpu" "ppce300c2") (eq_attr "cpu" "ppce300c3"))) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") + +(define_insn_reservation "ppce300c3_fpstore" 2 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppce300c3")) + "ppce300c3_decode,ppce300c3_issue+ppce300c3_lsu,ppce300c3_retire") diff --git a/gcc/config/powerpcspe/e500.h b/gcc/config/powerpcspe/e500.h new file mode 100644 index 00000000000..3da9a6ecff2 --- /dev/null +++ b/gcc/config/powerpcspe/e500.h @@ -0,0 +1,45 @@ +/* Enable E500 support. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#undef TARGET_SPE_ABI +#undef TARGET_SPE +#undef TARGET_FPRS +#undef TARGET_E500_SINGLE +#undef TARGET_E500_DOUBLE +#undef CHECK_E500_OPTIONS + +#define TARGET_SPE_ABI rs6000_spe_abi +#define TARGET_SPE rs6000_spe +#define TARGET_FPRS (rs6000_float_gprs == 0) +#define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1) +#define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2) +#define CHECK_E500_OPTIONS \ + do { \ + if (TARGET_SPE || TARGET_SPE_ABI \ + || TARGET_E500_SINGLE || TARGET_E500_DOUBLE) \ + { \ + if (TARGET_ALTIVEC) \ + error ("AltiVec and SPE instructions cannot coexist"); \ + if (TARGET_VSX) \ + error ("VSX and SPE instructions cannot coexist"); \ + if (TARGET_64BIT) \ + error ("64-bit SPE not supported"); \ + if (TARGET_HARD_FLOAT && TARGET_FPRS) \ + error ("E500 and FPRs not supported"); \ + } \ + } while (0) diff --git a/gcc/config/powerpcspe/e500mc.md b/gcc/config/powerpcspe/e500mc.md new file mode 100644 index 00000000000..9878aaacba8 --- /dev/null +++ b/gcc/config/powerpcspe/e500mc.md @@ -0,0 +1,198 @@ +;; Pipeline description for Motorola PowerPC e500mc core. +;; Copyright (C) 2008-2017 Free Software Foundation, Inc. +;; Contributed by Edmar Wienskoski (edmar@freescale.com) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . +;; +;; e500mc 32-bit SU(2), LSU, FPU, BPU +;; Max issue 3 insns/clock cycle (includes 1 branch) +;; FP is half clocked, timings of other instructions are as in the e500v2. + +(define_automaton "e500mc_most,e500mc_long,e500mc_retire") +(define_cpu_unit "e500mc_decode_0,e500mc_decode_1" "e500mc_most") +(define_cpu_unit "e500mc_issue_0,e500mc_issue_1" "e500mc_most") +(define_cpu_unit "e500mc_retire_0,e500mc_retire_1" "e500mc_retire") + +;; SU. +(define_cpu_unit "e500mc_su0_stage0,e500mc_su1_stage0" "e500mc_most") + +;; MU. +(define_cpu_unit "e500mc_mu_stage0,e500mc_mu_stage1" "e500mc_most") +(define_cpu_unit "e500mc_mu_stage2,e500mc_mu_stage3" "e500mc_most") + +;; Non-pipelined division. +(define_cpu_unit "e500mc_mu_div" "e500mc_long") + +;; LSU. +(define_cpu_unit "e500mc_lsu" "e500mc_most") + +;; FPU. +(define_cpu_unit "e500mc_fpu" "e500mc_most") + +;; Branch unit. +(define_cpu_unit "e500mc_bu" "e500mc_most") + +;; The following units are used to make the automata deterministic. +(define_cpu_unit "present_e500mc_decode_0" "e500mc_most") +(define_cpu_unit "present_e500mc_issue_0" "e500mc_most") +(define_cpu_unit "present_e500mc_retire_0" "e500mc_retire") +(define_cpu_unit "present_e500mc_su0_stage0" "e500mc_most") + +;; The following sets to make automata deterministic when option ndfa is used. +(presence_set "present_e500mc_decode_0" "e500mc_decode_0") +(presence_set "present_e500mc_issue_0" "e500mc_issue_0") +(presence_set "present_e500mc_retire_0" "e500mc_retire_0") +(presence_set "present_e500mc_su0_stage0" "e500mc_su0_stage0") + +;; Some useful abbreviations. +(define_reservation "e500mc_decode" + "e500mc_decode_0|e500mc_decode_1+present_e500mc_decode_0") +(define_reservation "e500mc_issue" + "e500mc_issue_0|e500mc_issue_1+present_e500mc_issue_0") +(define_reservation "e500mc_retire" + "e500mc_retire_0|e500mc_retire_1+present_e500mc_retire_0") +(define_reservation "e500mc_su_stage0" + "e500mc_su0_stage0|e500mc_su1_stage0+present_e500mc_su0_stage0") + +;; Simple SU insns. +(define_insn_reservation "e500mc_su" 1 + (and (eq_attr "type" "integer,add,logical,insert,cmp,\ + shift,trap,cntlz,exts,isel") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") + +(define_insn_reservation "e500mc_two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\ + e500mc_issue+e500mc_su_stage0+e500mc_retire") + +(define_insn_reservation "e500mc_three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire,\ + e500mc_issue+e500mc_su_stage0+e500mc_retire,\ + e500mc_issue+e500mc_su_stage0+e500mc_retire") + +;; Multiply. +(define_insn_reservation "e500mc_multiply" 4 + (and (eq_attr "type" "mul") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_mu_stage0,e500mc_mu_stage1,\ + e500mc_mu_stage2,e500mc_mu_stage3+e500mc_retire") + +;; Divide. We use the average latency time here. +(define_insn_reservation "e500mc_divide" 14 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_mu_stage0+e500mc_mu_div,\ + e500mc_mu_div*13") + +;; Branch. +(define_insn_reservation "e500mc_branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_bu,e500mc_retire") + +;; CR logical. +(define_insn_reservation "e500mc_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_bu,e500mc_retire") + +;; Mfcr. +(define_insn_reservation "e500mc_mfcr" 1 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire") + +;; Mtcrf. +(define_insn_reservation "e500mc_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su1_stage0+e500mc_retire") + +;; Mtjmpr. +(define_insn_reservation "e500mc_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") + +;; Brinc. +(define_insn_reservation "e500mc_brinc" 1 + (and (eq_attr "type" "brinc") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_su_stage0+e500mc_retire") + +;; Loads. +(define_insn_reservation "e500mc_load" 3 + (and (eq_attr "type" "load,load_l,sync") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") + +(define_insn_reservation "e500mc_fpload" 4 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_lsu,nothing*2,e500mc_retire") + +;; Stores. +(define_insn_reservation "e500mc_store" 3 + (and (eq_attr "type" "store,store_c") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") + +(define_insn_reservation "e500mc_fpstore" 3 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_lsu,nothing,e500mc_retire") + +;; The following ignores the retire unit to avoid a large automata. + +;; Simple FP. +(define_insn_reservation "e500mc_simple_float" 8 + (and (eq_attr "type" "fpsimple") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu") +; "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire") + +;; FP. +(define_insn_reservation "e500mc_float" 8 + (and (eq_attr "type" "fp") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu") +; "e500mc_decode,e500mc_issue+e500mc_fpu,nothing*6,e500mc_retire") + +(define_insn_reservation "e500mc_fpcompare" 8 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu") + +(define_insn_reservation "e500mc_dmul" 10 + (and (eq_attr "type" "dmul") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu") + +;; FP divides are not pipelined. +(define_insn_reservation "e500mc_sdiv" 36 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*35") + +(define_insn_reservation "e500mc_ddiv" 66 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppce500mc")) + "e500mc_decode,e500mc_issue+e500mc_fpu,e500mc_fpu*65") diff --git a/gcc/config/powerpcspe/e500mc64.md b/gcc/config/powerpcspe/e500mc64.md new file mode 100644 index 00000000000..366b4c49791 --- /dev/null +++ b/gcc/config/powerpcspe/e500mc64.md @@ -0,0 +1,200 @@ +;; Pipeline description for Freescale PowerPC e500mc64 core. +;; Copyright (C) 2009-2017 Free Software Foundation, Inc. +;; Contributed by Edmar Wienskoski (edmar@freescale.com) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . +;; +;; e500mc64 64-bit SU(2), LSU, FPU, BPU +;; Max issue 3 insns/clock cycle (includes 1 branch) + +(define_automaton "e500mc64_most,e500mc64_long,e500mc64_retire") +(define_cpu_unit "e500mc64_decode_0,e500mc64_decode_1" "e500mc64_most") +(define_cpu_unit "e500mc64_issue_0,e500mc64_issue_1" "e500mc64_most") +(define_cpu_unit "e500mc64_retire_0,e500mc64_retire_1" "e500mc64_retire") + +;; SU. +(define_cpu_unit "e500mc64_su0_stage0,e500mc64_su1_stage0" "e500mc64_most") + +;; MU. +(define_cpu_unit "e500mc64_mu_stage0,e500mc64_mu_stage1" "e500mc64_most") +(define_cpu_unit "e500mc64_mu_stage2,e500mc64_mu_stage3" "e500mc64_most") + +;; Non-pipelined division. +(define_cpu_unit "e500mc64_mu_div" "e500mc64_long") + +;; LSU. +(define_cpu_unit "e500mc64_lsu" "e500mc64_most") + +;; FPU. +(define_cpu_unit "e500mc64_fpu" "e500mc64_most") + +;; Branch unit. +(define_cpu_unit "e500mc64_bu" "e500mc64_most") + +;; The following units are used to make the automata deterministic. +(define_cpu_unit "present_e500mc64_decode_0" "e500mc64_most") +(define_cpu_unit "present_e500mc64_issue_0" "e500mc64_most") +(define_cpu_unit "present_e500mc64_retire_0" "e500mc64_retire") +(define_cpu_unit "present_e500mc64_su0_stage0" "e500mc64_most") + +;; The following sets to make automata deterministic when option ndfa is used. +(presence_set "present_e500mc64_decode_0" "e500mc64_decode_0") +(presence_set "present_e500mc64_issue_0" "e500mc64_issue_0") +(presence_set "present_e500mc64_retire_0" "e500mc64_retire_0") +(presence_set "present_e500mc64_su0_stage0" "e500mc64_su0_stage0") + +;; Some useful abbreviations. +(define_reservation "e500mc64_decode" + "e500mc64_decode_0|e500mc64_decode_1+present_e500mc64_decode_0") +(define_reservation "e500mc64_issue" + "e500mc64_issue_0|e500mc64_issue_1+present_e500mc64_issue_0") +(define_reservation "e500mc64_retire" + "e500mc64_retire_0|e500mc64_retire_1+present_e500mc64_retire_0") +(define_reservation "e500mc64_su_stage0" + "e500mc64_su0_stage0|e500mc64_su1_stage0+present_e500mc64_su0_stage0") + +;; Simple SU insns. +(define_insn_reservation "e500mc64_su" 1 + (and (ior (eq_attr "type" "integer,insert,cntlz") + (and (eq_attr "type" "add,logical,exts") + (eq_attr "dot" "no")) + (and (eq_attr "type" "shift") + (eq_attr "dot" "no") + (eq_attr "var_shift" "no"))) + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +(define_insn_reservation "e500mc64_su2" 2 + (and (ior (eq_attr "type" "cmp,trap") + (and (eq_attr "type" "add,logical,exts") + (eq_attr "dot" "yes")) + (and (eq_attr "type" "shift") + (eq_attr "dot" "yes") + (eq_attr "var_shift" "no"))) + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0,e500mc64_retire") + +(define_insn_reservation "e500mc64_delayed" 2 + (and (eq_attr "type" "shift") + (eq_attr "var_shift" "yes") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0,e500mc64_retire") + +(define_insn_reservation "e500mc64_two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +(define_insn_reservation "e500mc64_three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire,\ + e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Multiply. +(define_insn_reservation "e500mc64_multiply" 4 + (and (eq_attr "type" "mul") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0,e500mc64_mu_stage1,\ + e500mc64_mu_stage2,e500mc64_mu_stage3+e500mc64_retire") + +;; Divide. We use the average latency time here. +(define_insn_reservation "e500mc64_divide" 14 + (and (eq_attr "type" "div") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_mu_stage0+e500mc64_mu_div,\ + e500mc64_mu_div*13") + +;; Branch. +(define_insn_reservation "e500mc64_branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_bu,e500mc64_retire") + +;; CR logical. +(define_insn_reservation "e500mc64_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_bu,e500mc64_retire") + +;; Mfcr. +(define_insn_reservation "e500mc64_mfcr" 4 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0,e500mc64_su1_stage0*3+e500mc64_retire") + +;; Mtcrf. +(define_insn_reservation "e500mc64_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su1_stage0+e500mc64_retire") + +;; Mtjmpr. +(define_insn_reservation "e500mc64_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Brinc. +(define_insn_reservation "e500mc64_brinc" 1 + (and (eq_attr "type" "brinc") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_su_stage0+e500mc64_retire") + +;; Loads. +(define_insn_reservation "e500mc64_load" 3 + (and (eq_attr "type" "load,load_l,sync") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +(define_insn_reservation "e500mc64_fpload" 4 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing*2,e500mc64_retire") + +;; Stores. +(define_insn_reservation "e500mc64_store" 3 + (and (eq_attr "type" "store,store_c") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +(define_insn_reservation "e500mc64_fpstore" 3 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_lsu,nothing,e500mc64_retire") + +;; The following ignores the retire unit to avoid a large automata. + +;; FP. +(define_insn_reservation "e500mc64_float" 7 + (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu") +; "e500mc64_decode,e500mc64_issue+e500mc64_fpu,nothing*5,e500mc64_retire") + +;; FP divides are not pipelined. +(define_insn_reservation "e500mc64_sdiv" 20 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*19") + +(define_insn_reservation "e500mc64_ddiv" 35 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppce500mc64")) + "e500mc64_decode,e500mc64_issue+e500mc64_fpu,e500mc64_fpu*34") diff --git a/gcc/config/powerpcspe/e5500.md b/gcc/config/powerpcspe/e5500.md new file mode 100644 index 00000000000..d66f8a58421 --- /dev/null +++ b/gcc/config/powerpcspe/e5500.md @@ -0,0 +1,190 @@ +;; Pipeline description for Freescale PowerPC e5500 core. +;; Copyright (C) 2012-2017 Free Software Foundation, Inc. +;; Contributed by Edmar Wienskoski (edmar@freescale.com) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . +;; +;; e5500 64-bit SFX(2), CFX, LSU, FPU, BU +;; Max issue 3 insns/clock cycle (includes 1 branch) + +(define_automaton "e5500_most,e5500_long") +(define_cpu_unit "e5500_decode_0,e5500_decode_1" "e5500_most") + +;; SFX. +(define_cpu_unit "e5500_sfx_0,e5500_sfx_1" "e5500_most") + +;; CFX. +(define_cpu_unit "e5500_cfx_stage0,e5500_cfx_stage1" "e5500_most") + +;; Non-pipelined division. +(define_cpu_unit "e5500_cfx_div" "e5500_long") + +;; LSU. +(define_cpu_unit "e5500_lsu" "e5500_most") + +;; FPU. +(define_cpu_unit "e5500_fpu" "e5500_long") + +;; BU. +(define_cpu_unit "e5500_bu" "e5500_most") + +;; The following units are used to make the automata deterministic. +(define_cpu_unit "present_e5500_decode_0" "e5500_most") +(define_cpu_unit "present_e5500_sfx_0" "e5500_most") +(presence_set "present_e5500_decode_0" "e5500_decode_0") +(presence_set "present_e5500_sfx_0" "e5500_sfx_0") + +;; Some useful abbreviations. +(define_reservation "e5500_decode" + "e5500_decode_0|e5500_decode_1+present_e5500_decode_0") +(define_reservation "e5500_sfx" + "e5500_sfx_0|e5500_sfx_1+present_e5500_sfx_0") + +;; SFX. +(define_insn_reservation "e5500_sfx" 1 + (and (ior (eq_attr "type" "integer,insert,cntlz") + (and (eq_attr "type" "add,logical,exts") + (eq_attr "dot" "no")) + (and (eq_attr "type" "shift") + (eq_attr "var_shift" "no"))) + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_sfx") + +(define_insn_reservation "e5500_sfx2" 2 + (and (ior (eq_attr "type" "cmp,trap") + (and (eq_attr "type" "add,logical,exts") + (eq_attr "dot" "yes")) + (and (eq_attr "type" "shift") + (eq_attr "dot" "yes") + (eq_attr "var_shift" "no"))) + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_sfx") + +(define_insn_reservation "e5500_delayed" 2 + (and (eq_attr "type" "shift") + (eq_attr "var_shift" "yes") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_sfx*2") + +(define_insn_reservation "e5500_two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_decode+e5500_sfx,e5500_sfx") + +(define_insn_reservation "e5500_three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,(e5500_decode+e5500_sfx)*2,e5500_sfx") + +;; SFX - Mfcr. +(define_insn_reservation "e5500_mfcr" 4 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_sfx_0*4") + +;; SFX - Mtcrf. +(define_insn_reservation "e5500_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_sfx_0") + +;; SFX - Mtjmpr. +(define_insn_reservation "e5500_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_sfx") + +;; CFX - Multiply. +(define_insn_reservation "e5500_multiply" 4 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "32") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_cfx_stage0,e5500_cfx_stage1") + +(define_insn_reservation "e5500_multiply_i" 5 + (and (eq_attr "type" "mul") + (ior (eq_attr "dot" "yes") + (eq_attr "size" "8,16")) + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_cfx_stage0,\ + e5500_cfx_stage0+e5500_cfx_stage1,e5500_cfx_stage1") + +;; CFX - Divide. +(define_insn_reservation "e5500_divide" 16 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_cfx_stage0+e5500_cfx_div,\ + e5500_cfx_div*15") + +(define_insn_reservation "e5500_divide_d" 26 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_cfx_stage0+e5500_cfx_div,\ + e5500_cfx_div*25") + +;; LSU - Loads. +(define_insn_reservation "e5500_load" 3 + (and (eq_attr "type" "load,load_l,sync") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_lsu") + +(define_insn_reservation "e5500_fpload" 4 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_lsu") + +;; LSU - Stores. +(define_insn_reservation "e5500_store" 3 + (and (eq_attr "type" "store,store_c") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_lsu") + +(define_insn_reservation "e5500_fpstore" 3 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_lsu") + +;; FP. +(define_insn_reservation "e5500_float" 7 + (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_fpu") + +(define_insn_reservation "e5500_sdiv" 20 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_fpu*20") + +(define_insn_reservation "e5500_ddiv" 35 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_fpu*35") + +;; BU. +(define_insn_reservation "e5500_branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_bu") + +;; BU - CR logical. +(define_insn_reservation "e5500_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppce5500")) + "e5500_decode,e5500_bu") diff --git a/gcc/config/powerpcspe/e6500.md b/gcc/config/powerpcspe/e6500.md new file mode 100644 index 00000000000..779aa4f8c45 --- /dev/null +++ b/gcc/config/powerpcspe/e6500.md @@ -0,0 +1,228 @@ +;; Pipeline description for Freescale PowerPC e6500 core. +;; Copyright (C) 2012-2017 Free Software Foundation, Inc. +;; Contributed by Edmar Wienskoski (edmar@freescale.com) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . +;; +;; e6500 64-bit SFX(2), CFX, LSU, FPU, BU, VSFX, VCFX, VFPU, VPERM +;; Max issue 3 insns/clock cycle (includes 1 branch) + +(define_automaton "e6500_most,e6500_long,e6500_vec") +(define_cpu_unit "e6500_decode_0,e6500_decode_1" "e6500_most") + +;; SFX. +(define_cpu_unit "e6500_sfx_0,e6500_sfx_1" "e6500_most") + +;; CFX. +(define_cpu_unit "e6500_cfx_stage0,e6500_cfx_stage1" "e6500_most") + +;; Non-pipelined division. +(define_cpu_unit "e6500_cfx_div" "e6500_long") + +;; LSU. +(define_cpu_unit "e6500_lsu" "e6500_most") + +;; FPU. +(define_cpu_unit "e6500_fpu" "e6500_long") + +;; BU. +(define_cpu_unit "e6500_bu" "e6500_most") + +;; Altivec unit +(define_cpu_unit "e6500_vec,e6500_vecperm" "e6500_vec") + +;; The following units are used to make the automata deterministic. +(define_cpu_unit "present_e6500_decode_0" "e6500_most") +(define_cpu_unit "present_e6500_sfx_0" "e6500_most") +(presence_set "present_e6500_decode_0" "e6500_decode_0") +(presence_set "present_e6500_sfx_0" "e6500_sfx_0") + +;; Some useful abbreviations. +(define_reservation "e6500_decode" + "e6500_decode_0|e6500_decode_1+present_e6500_decode_0") +(define_reservation "e6500_sfx" + "e6500_sfx_0|e6500_sfx_1+present_e6500_sfx_0") + +;; SFX. +(define_insn_reservation "e6500_sfx" 1 + (and (ior (eq_attr "type" "integer,insert,cntlz") + (and (eq_attr "type" "add,logical,exts") + (eq_attr "dot" "no")) + (and (eq_attr "type" "shift") + (eq_attr "dot" "no") + (eq_attr "var_shift" "no"))) + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_sfx") + +(define_insn_reservation "e6500_sfx2" 2 + (and (ior (eq_attr "type" "cmp,trap") + (and (eq_attr "type" "add,logical,exts") + (eq_attr "dot" "yes")) + (and (eq_attr "type" "shift") + (eq_attr "dot" "yes") + (eq_attr "var_shift" "no"))) + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_sfx") + +(define_insn_reservation "e6500_delayed" 2 + (and (eq_attr "type" "shift") + (eq_attr "var_shift" "yes") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_sfx*2") + +(define_insn_reservation "e6500_two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_decode+e6500_sfx,e6500_sfx") + +(define_insn_reservation "e6500_three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,(e6500_decode+e6500_sfx)*2,e6500_sfx") + +;; SFX - Mfcr. +(define_insn_reservation "e6500_mfcr" 4 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_sfx_0*4") + +;; SFX - Mtcrf. +(define_insn_reservation "e6500_mtcrf" 1 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_sfx_0") + +;; SFX - Mtjmpr. +(define_insn_reservation "e6500_mtjmpr" 1 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_sfx") + +;; CFX - Multiply. +(define_insn_reservation "e6500_multiply" 4 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "32") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_cfx_stage0,e6500_cfx_stage1") + +(define_insn_reservation "e6500_multiply_i" 5 + (and (eq_attr "type" "mul") + (ior (eq_attr "dot" "yes") + (eq_attr "size" "8,16")) + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_cfx_stage0,\ + e6500_cfx_stage0+e6500_cfx_stage1,e6500_cfx_stage1") + +;; CFX - Divide. +(define_insn_reservation "e6500_divide" 16 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_cfx_stage0+e6500_cfx_div,\ + e6500_cfx_div*15") + +(define_insn_reservation "e6500_divide_d" 26 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_cfx_stage0+e6500_cfx_div,\ + e6500_cfx_div*25") + +;; LSU - Loads. +(define_insn_reservation "e6500_load" 3 + (and (eq_attr "type" "load,load_l,sync") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_lsu") + +(define_insn_reservation "e6500_fpload" 4 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_lsu") + +(define_insn_reservation "e6500_vecload" 4 + (and (eq_attr "type" "vecload") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_lsu") + +;; LSU - Stores. +(define_insn_reservation "e6500_store" 3 + (and (eq_attr "type" "store,store_c") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_lsu") + +(define_insn_reservation "e6500_fpstore" 3 + (and (eq_attr "type" "fpstore") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_lsu") + +(define_insn_reservation "e6500_vecstore" 4 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_lsu") + +;; FP. +(define_insn_reservation "e6500_float" 7 + (and (eq_attr "type" "fpsimple,fp,fpcompare,dmul") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_fpu") + +(define_insn_reservation "e6500_sdiv" 20 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_fpu*20") + +(define_insn_reservation "e6500_ddiv" 35 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_fpu*35") + +;; BU. +(define_insn_reservation "e6500_branch" 1 + (and (eq_attr "type" "jmpreg,branch,isync") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_bu") + +;; BU - CR logical. +(define_insn_reservation "e6500_cr_logical" 1 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_bu") + +;; VSFX. +(define_insn_reservation "e6500_vecsimple" 1 + (and (eq_attr "type" "vecsimple,veclogical,vecmove,veccmp,veccmpfx") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_vec") + +;; VCFX. +(define_insn_reservation "e6500_veccomplex" 4 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_vec") + +;; VFPU. +(define_insn_reservation "e6500_vecfloat" 6 + (and (eq_attr "type" "vecfloat") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_vec") + +;; VPERM. +(define_insn_reservation "e6500_vecperm" 2 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "ppce6500")) + "e6500_decode,e6500_vecperm") diff --git a/gcc/config/powerpcspe/eabi.h b/gcc/config/powerpcspe/eabi.h new file mode 100644 index 00000000000..ae1a73c03d9 --- /dev/null +++ b/gcc/config/powerpcspe/eabi.h @@ -0,0 +1,41 @@ +/* Core target definitions for GNU compiler + for IBM RS/6000 PowerPC targeted to embedded ELF systems. + Copyright (C) 1995-2017 Free Software Foundation, Inc. + Contributed by Cygnus Support. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* Add -meabi to target flags. */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT MASK_EABI + +/* Invoke an initializer function to set up the GOT. */ +#define NAME__MAIN "__eabi" +#define INVOKE__main + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define_std ("PPC"); \ + builtin_define ("__embedded__"); \ + builtin_assert ("system=embedded"); \ + builtin_assert ("cpu=powerpc"); \ + builtin_assert ("machine=powerpc"); \ + TARGET_OS_SYSV_CPP_BUILTINS (); \ + } \ + while (0) diff --git a/gcc/config/powerpcspe/eabialtivec.h b/gcc/config/powerpcspe/eabialtivec.h new file mode 100644 index 00000000000..a8fc9f0a825 --- /dev/null +++ b/gcc/config/powerpcspe/eabialtivec.h @@ -0,0 +1,27 @@ +/* Core target definitions for GNU compiler + for PowerPC targeted systems with AltiVec support. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Aldy Hernandez (aldyh@redhat.com). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* Add -meabi and -maltivec to target flags. */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_EABI | MASK_ALTIVEC) + +#undef SUBSUBTARGET_OVERRIDE_OPTIONS +#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1 diff --git a/gcc/config/powerpcspe/eabisim.h b/gcc/config/powerpcspe/eabisim.h new file mode 100644 index 00000000000..fda50ba1408 --- /dev/null +++ b/gcc/config/powerpcspe/eabisim.h @@ -0,0 +1,51 @@ +/* Support for GCC on simulated PowerPC systems targeted to embedded ELF + systems. + Copyright (C) 1995-2017 Free Software Foundation, Inc. + Contributed by Cygnus Support. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define_std ("PPC"); \ + builtin_define ("__embedded__"); \ + builtin_define ("__simulator__"); \ + builtin_assert ("system=embedded"); \ + builtin_assert ("system=simulator"); \ + builtin_assert ("cpu=powerpc"); \ + builtin_assert ("machine=powerpc"); \ + TARGET_OS_SYSV_CPP_BUILTINS (); \ + } \ + while (0) + +/* Make the simulator the default */ +#undef LIB_DEFAULT_SPEC +#define LIB_DEFAULT_SPEC "%(lib_sim)" + +#undef STARTFILE_DEFAULT_SPEC +#define STARTFILE_DEFAULT_SPEC "%(startfile_sim)" + +#undef ENDFILE_DEFAULT_SPEC +#define ENDFILE_DEFAULT_SPEC "%(endfile_sim)" + +#undef LINK_START_DEFAULT_SPEC +#define LINK_START_DEFAULT_SPEC "%(link_start_sim)" + +#undef LINK_OS_DEFAULT_SPEC +#define LINK_OS_DEFAULT_SPEC "%(link_os_sim)" diff --git a/gcc/config/powerpcspe/eabispe.h b/gcc/config/powerpcspe/eabispe.h new file mode 100644 index 00000000000..db8030a791b --- /dev/null +++ b/gcc/config/powerpcspe/eabispe.h @@ -0,0 +1,26 @@ +/* Core target definitions for GNU compiler + for PowerPC embedded targeted systems with SPE support. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + Contributed by Aldy Hernandez (aldyh@redhat.com). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_STRICT_ALIGN | MASK_EABI) + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mppc -mspe -me500" diff --git a/gcc/config/powerpcspe/freebsd.h b/gcc/config/powerpcspe/freebsd.h new file mode 100644 index 00000000000..5201dd791b5 --- /dev/null +++ b/gcc/config/powerpcspe/freebsd.h @@ -0,0 +1,79 @@ +/* Definitions for PowerPC running FreeBSD using the ELF format + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by David E. O'Brien and BSDi. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* Override the defaults, which exist to force the proper definition. */ + +#undef CPP_OS_DEFAULT_SPEC +#define CPP_OS_DEFAULT_SPEC "%(cpp_os_freebsd)" + +#undef STARTFILE_DEFAULT_SPEC +#define STARTFILE_DEFAULT_SPEC "%(startfile_freebsd)" + +#undef ENDFILE_DEFAULT_SPEC +#define ENDFILE_DEFAULT_SPEC "%(endfile_freebsd)" + +#undef LIB_DEFAULT_SPEC +#define LIB_DEFAULT_SPEC "%(lib_freebsd)" + +#undef LINK_START_DEFAULT_SPEC +#define LINK_START_DEFAULT_SPEC "%(link_start_freebsd)" + +#undef LINK_OS_DEFAULT_SPEC +#define LINK_OS_DEFAULT_SPEC "%(link_os_freebsd)" + +/* XXX: This is wrong for many platforms in sysv4.h. + We should work on getting that definition fixed. */ +#undef LINK_SHLIB_SPEC +#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}" + + +/************************[ Target stuff ]***********************************/ + +/* Define the actual types of some ANSI-mandated types. + Needs to agree with . GCC defaults come from c-decl.c, + c-common.c, and config//.h. */ + +#undef SIZE_TYPE +#define SIZE_TYPE "unsigned int" + +/* rs6000.h gets this wrong for FreeBSD. We use the GCC defaults instead. */ +#undef WCHAR_TYPE + +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE 32 + +/* Override rs6000.h definition. */ +#undef ASM_APP_ON +#define ASM_APP_ON "#APP\n" + +/* Override rs6000.h definition. */ +#undef ASM_APP_OFF +#define ASM_APP_OFF "#NO_APP\n" + +/* We don't need to generate entries in .fixup, except when + -mrelocatable or -mrelocatable-lib is given. */ +#undef RELOCATABLE_NEEDS_FIXUP +#define RELOCATABLE_NEEDS_FIXUP \ + (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE) + +/* Use standard DWARF numbering for DWARF debugging information. */ +#define RS6000_USE_DWARF_NUMBERING + +#define POWERPC_FREEBSD diff --git a/gcc/config/powerpcspe/freebsd64.h b/gcc/config/powerpcspe/freebsd64.h new file mode 100644 index 00000000000..d75ac2b9a5d --- /dev/null +++ b/gcc/config/powerpcspe/freebsd64.h @@ -0,0 +1,433 @@ +/* Definitions for 64-bit PowerPC running FreeBSD using the ELF format + Copyright (C) 2012-2017 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* Override the defaults, which exist to force the proper definition. */ + +#ifdef IN_LIBGCC2 +#undef TARGET_64BIT +#ifdef __powerpc64__ +#define TARGET_64BIT 1 +#else +#define TARGET_64BIT 0 +#endif +#endif + +#undef TARGET_AIX +#define TARGET_AIX TARGET_64BIT + +#ifdef HAVE_LD_NO_DOT_SYMS +/* New ABI uses a local sym for the function entry point. */ +extern int dot_symbols; +#undef DOT_SYMBOLS +#define DOT_SYMBOLS dot_symbols +#endif + +#define TARGET_USES_LINUX64_OPT 1 +#ifdef HAVE_LD_LARGE_TOC +#undef TARGET_CMODEL +#define TARGET_CMODEL rs6000_current_cmodel +#define SET_CMODEL(opt) rs6000_current_cmodel = opt +#else +#define SET_CMODEL(opt) do {} while (0) +#endif + +/* Until now the 970 is the only Processor where FreeBSD 64-bit runs on. */ +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_POWER4 +#undef PROCESSOR_DEFAULT64 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER4 + +/* We don't need to generate entries in .fixup, except when + -mrelocatable or -mrelocatable-lib is given. */ +#undef RELOCATABLE_NEEDS_FIXUP +#define RELOCATABLE_NEEDS_FIXUP \ + (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE) + +#undef RS6000_ABI_NAME +#define RS6000_ABI_NAME "freebsd" + +#define INVALID_64BIT "-m%s not supported in this configuration" +#define INVALID_32BIT INVALID_64BIT + +/* Use LINUX64 instead of FREEBSD64 for compat with e.g. sysv4le.h */ +#ifdef LINUX64_DEFAULT_ABI_ELFv2 +#define ELFv2_ABI_CHECK (rs6000_elf_abi != 1) +#else +#define ELFv2_ABI_CHECK (rs6000_elf_abi == 2) +#endif + +#undef SUBSUBTARGET_OVERRIDE_OPTIONS +#define SUBSUBTARGET_OVERRIDE_OPTIONS \ + do \ + { \ + if (!global_options_set.x_rs6000_alignment_flags) \ + rs6000_alignment_flags = MASK_ALIGN_NATURAL; \ + if (TARGET_64BIT) \ + { \ + if (DEFAULT_ABI != ABI_AIX) \ + { \ + rs6000_current_abi = ABI_AIX; \ + error (INVALID_64BIT, "call"); \ + } \ + dot_symbols = !strcmp (rs6000_abi_name, "aixdesc"); \ + if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE) \ + { \ + rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \ + error (INVALID_64BIT, "relocatable"); \ + } \ + if (ELFv2_ABI_CHECK) \ + { \ + rs6000_current_abi = ABI_ELFv2; \ + if (dot_symbols) \ + error ("-mcall-aixdesc incompatible with -mabi=elfv2"); \ + } \ + if (rs6000_isa_flags & OPTION_MASK_EABI) \ + { \ + rs6000_isa_flags &= ~OPTION_MASK_EABI; \ + error (INVALID_64BIT, "eabi"); \ + } \ + if (TARGET_PROTOTYPE) \ + { \ + target_prototype = 0; \ + error (INVALID_64BIT, "prototype"); \ + } \ + if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0) \ + { \ + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ + error ("-m64 requires a PowerPC64 cpu"); \ + } \ + if ((rs6000_isa_flags_explicit \ + & OPTION_MASK_MINIMAL_TOC) != 0) \ + { \ + if (global_options_set.x_rs6000_current_cmodel \ + && rs6000_current_cmodel != CMODEL_SMALL) \ + error ("-mcmodel incompatible with other toc options"); \ + SET_CMODEL (CMODEL_SMALL); \ + } \ + else \ + { \ + if (!global_options_set.x_rs6000_current_cmodel) \ + SET_CMODEL (CMODEL_MEDIUM); \ + if (rs6000_current_cmodel != CMODEL_SMALL) \ + { \ + TARGET_NO_FP_IN_TOC = 0; \ + TARGET_NO_SUM_IN_TOC = 0; \ + } \ + } \ + } \ + } \ + while (0) + +#undef ASM_DEFAULT_SPEC +#undef ASM_SPEC +#undef LINK_OS_FREEBSD_SPEC + +#define ASM_DEFAULT_SPEC "-mppc%{!m32:64}" +#define ASM_SPEC "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)" +#define LINK_OS_FREEBSD_SPEC "%{m32:%(link_os_freebsd_spec32)}%{!m32:%(link_os_freebsd_spec64)}" + +#define ASM_SPEC32 "-a32 \ +%{mrelocatable} %{mrelocatable-lib} %{" FPIE_OR_FPIC_SPEC ":-K PIC} \ +%{memb} %{!memb: %{msdata=eabi: -memb}} \ +%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \ + %{mcall-freebsd: -mbig} \ + %{mcall-i960-old: -mlittle} \ + %{mcall-linux: -mbig} \ + %{mcall-gnu: -mbig} \ + %{mcall-netbsd: -mbig} \ +}}}}" + +#define ASM_SPEC64 "-a64" + +#define ASM_SPEC_COMMON "%(asm_cpu) \ +%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}} \ +%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}" + +#undef SUBSUBTARGET_EXTRA_SPECS +#define SUBSUBTARGET_EXTRA_SPECS \ + { "asm_spec_common", ASM_SPEC_COMMON }, \ + { "asm_spec32", ASM_SPEC32 }, \ + { "asm_spec64", ASM_SPEC64 }, \ + { "link_os_freebsd_spec32", LINK_OS_FREEBSD_SPEC32 }, \ + { "link_os_freebsd_spec64", LINK_OS_FREEBSD_SPEC64 }, + +#define LINK_OS_FREEBSD_SPEC_DEF "\ + %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \ + %{v:-V} \ + %{assert*} %{R*} %{rpath*} %{defsym*} \ + %{shared:-Bshareable %{h*} %{soname*}} \ + %{!shared: \ + %{!static: \ + %{rdynamic: -export-dynamic} \ + %{!dynamic-linker:-dynamic-linker " FBSD_DYNAMIC_LINKER "}} \ + %{static:-Bstatic}} \ + %{symbolic:-Bsymbolic}" + +#define LINK_OS_FREEBSD_SPEC32 "-melf32ppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF + +#define LINK_OS_FREEBSD_SPEC64 "-melf64ppc_fbsd " LINK_OS_FREEBSD_SPEC_DEF + +#undef MULTILIB_DEFAULTS +#define MULTILIB_DEFAULTS { "m64" } + +/* PowerPC-64 FreeBSD increases natural record alignment to doubleword if + the first field is an FP double, only if in power alignment mode. */ +#undef ROUND_TYPE_ALIGN +#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \ + ((TARGET_64BIT \ + && (TREE_CODE (STRUCT) == RECORD_TYPE \ + || TREE_CODE (STRUCT) == UNION_TYPE \ + || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \ + && TARGET_ALIGN_NATURAL == 0) \ + ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \ + : MAX ((COMPUTED), (SPECIFIED))) + +/* Use the default for compiling target libs. */ +#ifdef IN_TARGET_LIBS +#undef TARGET_ALIGN_NATURAL +#define TARGET_ALIGN_NATURAL 1 +#endif + +/* Indicate that jump tables go in the text section. */ +#undef JUMP_TABLES_IN_TEXT_SECTION +#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT + +/* The linux ppc64 ABI isn't explicit on whether aggregates smaller + than a doubleword should be padded upward or downward. You could + reasonably assume that they follow the normal rules for structure + layout treating the parameter area as any other block of memory, + then map the reg param area to registers. i.e. pad upward. + Setting both of the following defines results in this behavior. + Setting just the first one will result in aggregates that fit in a + doubleword being padded downward, and others being padded upward. + Not a bad idea as this results in struct { int x; } being passed + the same way as an int. */ +#define AGGREGATE_PADDING_FIXED TARGET_64BIT +#define AGGREGATES_PAD_UPWARD_ALWAYS 0 + +/* Specify padding for the last element of a block move between + registers and memory. FIRST is nonzero if this is the only + element. */ +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \ + (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE)) + +/* FreeBSD doesn't support saving and restoring 64-bit regs with a 32-bit + kernel. This is supported when running on a 64-bit kernel with + COMPAT_FREEBSD32, but tell GCC it isn't so that our 32-bit binaries + are compatible. */ +#define OS_MISSING_POWERPC64 !TARGET_64BIT + +#undef FBSD_TARGET_CPU_CPP_BUILTINS +#define FBSD_TARGET_CPU_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("__PPC__"); \ + builtin_define ("__ppc__"); \ + builtin_define ("__powerpc__"); \ + if (TARGET_64BIT) \ + { \ + builtin_define ("__arch64__"); \ + builtin_define ("__LP64__"); \ + builtin_define ("__PPC64__"); \ + builtin_define ("__powerpc64__"); \ + builtin_assert ("cpu=powerpc64"); \ + builtin_assert ("machine=powerpc64"); \ + } \ + else \ + { \ + builtin_define_std ("PPC"); \ + builtin_define_std ("powerpc"); \ + builtin_assert ("cpu=powerpc"); \ + builtin_assert ("machine=powerpc"); \ + TARGET_OS_SYSV_CPP_BUILTINS (); \ + } \ + } \ + while (0) + +#undef CPP_OS_DEFAULT_SPEC +#define CPP_OS_DEFAULT_SPEC "%(cpp_os_freebsd)" + +#undef CPP_OS_FREEBSD_SPEC +#define CPP_OS_FREEBSD_SPEC "" + +#undef STARTFILE_DEFAULT_SPEC +#define STARTFILE_DEFAULT_SPEC "%(startfile_freebsd)" + +#undef ENDFILE_DEFAULT_SPEC +#define ENDFILE_DEFAULT_SPEC "%(endfile_freebsd)" + +#undef LIB_DEFAULT_SPEC +#define LIB_DEFAULT_SPEC "%(lib_freebsd)" + +#undef LINK_START_DEFAULT_SPEC +#define LINK_START_DEFAULT_SPEC "%(link_start_freebsd)" + +#undef LINK_OS_DEFAULT_SPEC +#define LINK_OS_DEFAULT_SPEC "%(link_os_freebsd)" + +/* XXX: This is wrong for many platforms in sysv4.h. + We should work on getting that definition fixed. */ +#undef LINK_SHLIB_SPEC +#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}" + + +/************************[ Target stuff ]***********************************/ + +/* Define the actual types of some ANSI-mandated types. + Needs to agree with . GCC defaults come from c-decl.c, + c-common.c, and config//.h. */ + + +#undef SIZE_TYPE +#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int") + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int") + +/* rs6000.h gets this wrong for FreeBSD. We use the GCC defaults instead. */ +#undef WCHAR_TYPE + +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE 32 + + +/* Override rs6000.h definition. */ +#undef ASM_APP_ON +#define ASM_APP_ON "#APP\n" + +/* Override rs6000.h definition. */ +#undef ASM_APP_OFF +#define ASM_APP_OFF "#NO_APP\n" + +/* Function profiling bits */ +#undef RS6000_MCOUNT +#define RS6000_MCOUNT "_mcount" + +#define PROFILE_HOOK(LABEL) \ + do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0) + +/* _init and _fini functions are built from bits spread across many + object files, each potentially with a different TOC pointer. For + that reason, place a nop after the call so that the linker can + restore the TOC pointer if a TOC adjusting call stub is needed. */ +#ifdef __powerpc64__ +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ + asm (SECTION_OP "\n" \ +" bl " #FUNC "\n" \ +" nop\n" \ +" .previous"); +#endif + +/* FP save and restore routines. */ +#undef SAVE_FP_PREFIX +#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_") +#undef SAVE_FP_SUFFIX +#define SAVE_FP_SUFFIX "" +#undef RESTORE_FP_PREFIX +#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_") +#undef RESTORE_FP_SUFFIX +#define RESTORE_FP_SUFFIX "" + +/* Select a format to encode pointers in exception handling data. CODE + is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is + true if the symbol may be affected by dynamic relocations. */ +#undef ASM_PREFERRED_EH_DATA_FORMAT +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ + (TARGET_64BIT || flag_pic \ + ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \ + | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4)) \ + : DW_EH_PE_absptr) + +/* Static stack checking is supported by means of probes. */ +#define STACK_CHECK_STATIC_BUILTIN 1 + +/* The default value isn't sufficient in 64-bit mode. */ +#define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024) + +/* Use standard DWARF numbering for DWARF debugging information. */ +#define RS6000_USE_DWARF_NUMBERING + +/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */ +#undef ADJUST_FIELD_ALIGN +#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \ + (rs6000_special_adjust_field_align_p ((TYPE), (COMPUTED)) \ + ? 128 \ + : (TARGET_64BIT \ + && TARGET_ALIGN_NATURAL == 0 \ + && TYPE_MODE (strip_array_types (TYPE)) == DFmode) \ + ? MIN ((COMPUTED), 32) \ + : (COMPUTED)) + +#undef TOC_SECTION_ASM_OP +#define TOC_SECTION_ASM_OP \ + (TARGET_64BIT \ + ? "\t.section\t\".toc\",\"aw\"" \ + : "\t.section\t\".got\",\"aw\"") + +#undef MINIMAL_TOC_SECTION_ASM_OP +#define MINIMAL_TOC_SECTION_ASM_OP \ + (TARGET_64BIT \ + ? "\t.section\t\".toc1\",\"aw\"" \ + : (flag_pic \ + ? "\t.section\t\".got2\",\"aw\"" \ + : "\t.section\t\".got1\",\"aw\"")) + +/* This is how to declare the size of a function. */ +#undef ASM_DECLARE_FUNCTION_SIZE +#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ + do \ + { \ + if (!flag_inhibit_size_directive) \ + { \ + fputs ("\t.size\t", (FILE)); \ + if (TARGET_64BIT && DOT_SYMBOLS) \ + putc ('.', (FILE)); \ + assemble_name ((FILE), (FNAME)); \ + fputs (",.-", (FILE)); \ + rs6000_output_function_entry (FILE, FNAME); \ + putc ('\n', (FILE)); \ + } \ + } \ + while (0) + +#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P +#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \ + (TARGET_TOC \ + && (GET_CODE (X) == SYMBOL_REF \ + || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ + && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ + || GET_CODE (X) == LABEL_REF \ + || (GET_CODE (X) == CONST_INT \ + && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \ + || (GET_CODE (X) == CONST_DOUBLE \ + && ((TARGET_64BIT \ + && (TARGET_MINIMAL_TOC \ + || (SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ + && ! TARGET_NO_FP_IN_TOC))) \ + || (!TARGET_64BIT \ + && !TARGET_NO_FP_IN_TOC \ + && SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ + && BITS_PER_WORD == HOST_BITS_PER_INT))))) + +/* Use --as-needed -lgcc_s for eh support. */ +#ifdef HAVE_LD_AS_NEEDED +#define USE_LD_AS_NEEDED 1 +#endif + +#define POWERPC_FREEBSD diff --git a/gcc/config/powerpcspe/genopt.sh b/gcc/config/powerpcspe/genopt.sh new file mode 100755 index 00000000000..f04c00127c1 --- /dev/null +++ b/gcc/config/powerpcspe/genopt.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# Generate powerpcspe-tables.opt from the list of CPUs in powerpcspe-cpus.def. +# Copyright (C) 2011-2017 Free Software Foundation, Inc. +# +# This file is part of GCC. +# +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +cat <. + +Enum +Name(rs6000_cpu_opt_value) Type(int) +Known CPUs (for use with the -mcpu= and -mtune= options): + +EnumValue +Enum(rs6000_cpu_opt_value) String(native) Value(RS6000_CPU_OPTION_NATIVE) DriverOnly + +EOF + +awk -F'[(, ]+' ' +BEGIN { + value = 0 +} + +/^RS6000_CPU/ { + name = $2 + gsub("\"", "", name) + print "EnumValue" + print "Enum(rs6000_cpu_opt_value) String(" name ") Value(" value ")" + print "" + value++ +}' $1/powerpcspe-cpus.def diff --git a/gcc/config/powerpcspe/host-darwin.c b/gcc/config/powerpcspe/host-darwin.c new file mode 100644 index 00000000000..da90e2f6452 --- /dev/null +++ b/gcc/config/powerpcspe/host-darwin.c @@ -0,0 +1,153 @@ +/* Darwin/powerpc host-specific hook definitions. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic.h" +#include +#include "hosthooks.h" +#include "hosthooks-def.h" +#include "config/host-darwin.h" + +static void segv_crash_handler (int); +static void segv_handler (int, siginfo_t *, void *); +static void darwin_rs6000_extra_signals (void); + +#ifndef HAVE_DECL_SIGALTSTACK +/* This doesn't have a prototype in signal.h in 10.2.x and earlier, + fixed in later releases. */ +extern int sigaltstack(const struct sigaltstack *, struct sigaltstack *); +#endif + +/* The fields of the mcontext_t type have acquired underscores in later + OS versions. */ +#ifdef HAS_MCONTEXT_T_UNDERSCORES +#define MC_FLD(x) __ ## x +#else +#define MC_FLD(x) x +#endif + +#undef HOST_HOOKS_EXTRA_SIGNALS +#define HOST_HOOKS_EXTRA_SIGNALS darwin_rs6000_extra_signals + +/* On Darwin/powerpc, hitting the stack limit turns into a SIGSEGV. + This code detects the difference between hitting the stack limit and + a true wild pointer dereference by looking at the instruction that + faulted; only a few kinds of instruction are used to access below + the previous bottom of the stack. */ + +static void +segv_crash_handler (int sig ATTRIBUTE_UNUSED) +{ + internal_error ("Segmentation Fault (code)"); +} + +static void +segv_handler (int sig ATTRIBUTE_UNUSED, + siginfo_t *sip ATTRIBUTE_UNUSED, + void *scp) +{ + ucontext_t *uc = (ucontext_t *)scp; + sigset_t sigset; + unsigned faulting_insn; + + /* The fault might have happened when trying to run some instruction, in + which case the next line will segfault _again_. Handle this case. */ + signal (SIGSEGV, segv_crash_handler); + sigemptyset (&sigset); + sigaddset (&sigset, SIGSEGV); + sigprocmask (SIG_UNBLOCK, &sigset, NULL); + + faulting_insn = *(unsigned *)uc->uc_mcontext->MC_FLD(ss).MC_FLD(srr0); + + /* Note that this only has to work for GCC, so we don't have to deal + with all the possible cases (GCC has no AltiVec code, for + instance). It's complicated because Darwin allows stores to + below the stack pointer, and the prologue code takes advantage of + this. */ + + if ((faulting_insn & 0xFFFF8000) == 0x94218000 /* stwu %r1, -xxx(%r1) */ + || (faulting_insn & 0xFC1F03FF) == 0x7C01016E /* stwux xxx, %r1, xxx */ + || (faulting_insn & 0xFC1F8000) == 0x90018000 /* stw xxx, -yyy(%r1) */ + || (faulting_insn & 0xFC1F8000) == 0xD8018000 /* stfd xxx, -yyy(%r1) */ + || (faulting_insn & 0xFC1F8000) == 0xBC018000 /* stmw xxx, -yyy(%r1) */) + { + char *shell_name; + + fnotice (stderr, "Out of stack space.\n"); + shell_name = getenv ("SHELL"); + if (shell_name != NULL) + shell_name = strrchr (shell_name, '/'); + if (shell_name != NULL) + { + static const char * shell_commands[][2] = { + { "sh", "ulimit -S -s unlimited" }, + { "bash", "ulimit -S -s unlimited" }, + { "tcsh", "limit stacksize unlimited" }, + { "csh", "limit stacksize unlimited" }, + /* zsh doesn't have "unlimited", this will work under the + default configuration. */ + { "zsh", "limit stacksize 32m" } + }; + size_t i; + + for (i = 0; i < ARRAY_SIZE (shell_commands); i++) + if (strcmp (shell_commands[i][0], shell_name + 1) == 0) + { + fnotice (stderr, + "Try running '%s' in the shell to raise its limit.\n", + shell_commands[i][1]); + } + } + + if (global_dc->abort_on_error) + fancy_abort (__FILE__, __LINE__, __FUNCTION__); + + exit (FATAL_EXIT_CODE); + } + + fprintf (stderr, "[address=%08lx pc=%08x]\n", + uc->uc_mcontext->MC_FLD(es).MC_FLD(dar), + uc->uc_mcontext->MC_FLD(ss).MC_FLD(srr0)); + internal_error ("Segmentation Fault"); + exit (FATAL_EXIT_CODE); +} + +static void +darwin_rs6000_extra_signals (void) +{ + struct sigaction sact; + stack_t sigstk; + + sigstk.ss_sp = (char*)xmalloc (SIGSTKSZ); + sigstk.ss_size = SIGSTKSZ; + sigstk.ss_flags = 0; + if (sigaltstack (&sigstk, NULL) < 0) + fatal_error (input_location, "While setting up signal stack: %m"); + + sigemptyset(&sact.sa_mask); + sact.sa_flags = SA_ONSTACK | SA_SIGINFO; + sact.sa_sigaction = segv_handler; + if (sigaction (SIGSEGV, &sact, 0) < 0) + fatal_error (input_location, "While setting up signal handler: %m"); +} + + +const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; diff --git a/gcc/config/powerpcspe/host-ppc64-darwin.c b/gcc/config/powerpcspe/host-ppc64-darwin.c new file mode 100644 index 00000000000..381fe1673ae --- /dev/null +++ b/gcc/config/powerpcspe/host-ppc64-darwin.c @@ -0,0 +1,30 @@ +/* ppc64-darwin host-specific hook definitions. + Copyright (C) 2006-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "hosthooks.h" +#include "hosthooks-def.h" +#include "config/host-darwin.h" + +/* Darwin doesn't do anything special for ppc64 hosts; this file exists just + to include config/host-darwin.h. */ + +const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER; diff --git a/gcc/config/powerpcspe/htm.md b/gcc/config/powerpcspe/htm.md new file mode 100644 index 00000000000..de769f7db3c --- /dev/null +++ b/gcc/config/powerpcspe/htm.md @@ -0,0 +1,296 @@ +;; Hardware Transactional Memory (HTM) patterns. +;; Copyright (C) 2013-2017 Free Software Foundation, Inc. +;; Contributed by Peter Bergner . + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_constants + [(TFHAR_SPR 128) + (TFIAR_SPR 129) + (TEXASR_SPR 130) + (TEXASRU_SPR 131) + (MAX_HTM_OPERANDS 4) + ]) + +;; +;; UNSPEC usage +;; + +(define_c_enum "unspec" + [UNSPEC_HTM_FENCE + ]) + +;; +;; UNSPEC_VOLATILE usage +;; + +(define_c_enum "unspecv" + [UNSPECV_HTM_TABORT + UNSPECV_HTM_TABORTXC + UNSPECV_HTM_TABORTXCI + UNSPECV_HTM_TBEGIN + UNSPECV_HTM_TCHECK + UNSPECV_HTM_TEND + UNSPECV_HTM_TRECHKPT + UNSPECV_HTM_TRECLAIM + UNSPECV_HTM_TSR + UNSPECV_HTM_TTEST + UNSPECV_HTM_MFSPR + UNSPECV_HTM_MTSPR + ]) + +(define_expand "tabort" + [(parallel + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand:SI 0 "base_reg_operand" "b")] + UNSPECV_HTM_TABORT)) + (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[2]) = 1; +}) + +(define_insn "*tabort" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand:SI 0 "base_reg_operand" "b")] + UNSPECV_HTM_TABORT)) + (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tabort. %0" + [(set_attr "type" "htmsimple") + (set_attr "length" "4")]) + +(define_expand "tabortc" + [(parallel + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") + (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r")] + UNSPECV_HTM_TABORTXC)) + (set (match_dup 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[4] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[4]) = 1; +}) + +(define_insn "*tabortc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") + (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r")] + UNSPECV_HTM_TABORTXC)) + (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tabortc. %0,%1,%2" + [(set_attr "type" "htmsimple") + (set_attr "length" "4")]) + +(define_expand "tabortci" + [(parallel + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") + (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand 2 "s5bit_cint_operand" "n")] + UNSPECV_HTM_TABORTXCI)) + (set (match_dup 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[4] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[4]) = 1; +}) + +(define_insn "*tabortci" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") + (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand 2 "s5bit_cint_operand" "n")] + UNSPECV_HTM_TABORTXCI)) + (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tabortci. %0,%1,%2" + [(set_attr "type" "htmsimple") + (set_attr "length" "4")]) + +(define_expand "tbegin" + [(parallel + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] + UNSPECV_HTM_TBEGIN)) + (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[2]) = 1; +}) + +(define_insn "*tbegin" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] + UNSPECV_HTM_TBEGIN)) + (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tbegin. %0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +(define_expand "tcheck" + [(parallel + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TCHECK)) + (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[1]) = 1; +}) + +(define_insn "*tcheck" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TCHECK)) + (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tcheck %0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +(define_expand "tend" + [(parallel + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] + UNSPECV_HTM_TEND)) + (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[2]) = 1; +}) + +(define_insn "*tend" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] + UNSPECV_HTM_TEND)) + (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tend. %0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +(define_expand "trechkpt" + [(parallel + [(set (match_operand:CC 0 "cc_reg_operand" "=x") + (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TRECHKPT)) + (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[1]) = 1; +}) + +(define_insn "*trechkpt" + [(set (match_operand:CC 0 "cc_reg_operand" "=x") + (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TRECHKPT)) + (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "trechkpt." + [(set_attr "type" "htmsimple") + (set_attr "length" "4")]) + +(define_expand "treclaim" + [(parallel + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] + UNSPECV_HTM_TRECLAIM)) + (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[2]) = 1; +}) + +(define_insn "*treclaim" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] + UNSPECV_HTM_TRECLAIM)) + (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "treclaim. %0" + [(set_attr "type" "htmsimple") + (set_attr "length" "4")]) + +(define_expand "tsr" + [(parallel + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] + UNSPECV_HTM_TSR)) + (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[2]) = 1; +}) + +(define_insn "*tsr" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] + UNSPECV_HTM_TSR)) + (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tsr. %0" + [(set_attr "type" "htmsimple") + (set_attr "length" "4")]) + +(define_expand "ttest" + [(parallel + [(set (match_operand:CC 0 "cc_reg_operand" "=x") + (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TTEST)) + (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])] + "TARGET_HTM" +{ + operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); + MEM_VOLATILE_P (operands[1]) = 1; +}) + +(define_insn "*ttest" + [(set (match_operand:CC 0 "cc_reg_operand" "=x") + (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TTEST)) + (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tabortwci. 0,1,0" + [(set_attr "type" "htmsimple") + (set_attr "length" "4")]) + +(define_insn "htm_mfspr_" + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (unspec_volatile:GPR [(match_operand 1 "u10bit_cint_operand" "n") + (match_operand:GPR 2 "htm_spr_reg_operand" "")] + UNSPECV_HTM_MFSPR))] + "TARGET_HTM" + "mfspr %0,%1"; + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +(define_insn "htm_mtspr_" + [(set (match_operand:GPR 2 "htm_spr_reg_operand" "") + (unspec_volatile:GPR [(match_operand:GPR 0 "gpc_reg_operand" "r") + (match_operand 1 "u10bit_cint_operand" "n")] + UNSPECV_HTM_MTSPR))] + "TARGET_HTM" + "mtspr %1,%0"; + [(set_attr "type" "htm") + (set_attr "length" "4")]) diff --git a/gcc/config/powerpcspe/htmintrin.h b/gcc/config/powerpcspe/htmintrin.h new file mode 100644 index 00000000000..55d5a661811 --- /dev/null +++ b/gcc/config/powerpcspe/htmintrin.h @@ -0,0 +1,131 @@ +/* Hardware Transactional Memory (HTM) intrinsics. + Copyright (C) 2013-2017 Free Software Foundation, Inc. + Contributed by Peter Bergner . + + This file is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This file is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#ifndef __HTM__ +# error "HTM instruction set not enabled" +#endif /* __HTM__ */ + +#ifndef _HTMINTRIN_H +#define _HTMINTRIN_H + +#include + +typedef uint64_t texasr_t; +typedef uint32_t texasru_t; +typedef uint32_t texasrl_t; +typedef uintptr_t tfiar_t; +typedef uintptr_t tfhar_t; + +#define _HTM_STATE(CR0) ((CR0 >> 1) & 0x3) +#define _HTM_NONTRANSACTIONAL 0x0 +#define _HTM_SUSPENDED 0x1 +#define _HTM_TRANSACTIONAL 0x2 + +/* The following macros use the IBM bit numbering for BITNUM + as used in the ISA documentation. */ + +#define _TEXASR_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \ + (((TEXASR) >> (63-(BITNUM))) & ((1<<(SIZE))-1)) +#define _TEXASRU_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \ + (((TEXASR) >> (31-(BITNUM))) & ((1<<(SIZE))-1)) + +#define _TEXASR_FAILURE_CODE(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 7, 8) +#define _TEXASRU_FAILURE_CODE(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 8) + +#define _TEXASR_FAILURE_PERSISTENT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 7, 1) +#define _TEXASRU_FAILURE_PERSISTENT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 1) + +#define _TEXASR_DISALLOWED(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 8, 1) +#define _TEXASRU_DISALLOWED(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 8, 1) + +#define _TEXASR_NESTING_OVERFLOW(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 9, 1) +#define _TEXASRU_NESTING_OVERFLOW(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 9, 1) + +#define _TEXASR_FOOTPRINT_OVERFLOW(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 10, 1) +#define _TEXASRU_FOOTPRINT_OVERFLOW(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 10, 1) + +#define _TEXASR_SELF_INDUCED_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 11, 1) +#define _TEXASRU_SELF_INDUCED_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 11, 1) + +#define _TEXASR_NON_TRANSACTIONAL_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 12, 1) +#define _TEXASRU_NON_TRANSACTIONAL_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 12, 1) + +#define _TEXASR_TRANSACTION_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 13, 1) +#define _TEXASRU_TRANSACTION_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 13, 1) + +#define _TEXASR_TRANSLATION_INVALIDATION_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 14, 1) +#define _TEXASRU_TRANSLATION_INVALIDATION_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 14, 1) + +#define _TEXASR_IMPLEMENTAION_SPECIFIC(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 15, 1) +#define _TEXASRU_IMPLEMENTAION_SPECIFIC(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 15, 1) + +#define _TEXASR_INSTRUCTION_FETCH_CONFLICT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 16, 1) +#define _TEXASRU_INSTRUCTION_FETCH_CONFLICT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 16, 1) + +#define _TEXASR_ABORT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 31, 1) +#define _TEXASRU_ABORT(TEXASRU) \ + _TEXASRU_EXTRACT_BITS(TEXASRU, 31, 1) + + +#define _TEXASR_SUSPENDED(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 32, 1) + +#define _TEXASR_PRIVILEGE(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 35, 2) + +#define _TEXASR_FAILURE_SUMMARY(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 36, 1) + +#define _TEXASR_TFIAR_EXACT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 37, 1) + +#define _TEXASR_ROT(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 38, 1) + +#define _TEXASR_TRANSACTION_LEVEL(TEXASR) \ + _TEXASR_EXTRACT_BITS(TEXASR, 63, 12) + +#endif /* _HTMINTRIN_H */ diff --git a/gcc/config/powerpcspe/htmxlintrin.h b/gcc/config/powerpcspe/htmxlintrin.h new file mode 100644 index 00000000000..d6fc583b482 --- /dev/null +++ b/gcc/config/powerpcspe/htmxlintrin.h @@ -0,0 +1,214 @@ +/* XL compiler Hardware Transactional Memory (HTM) execution intrinsics. + Copyright (C) 2013-2017 Free Software Foundation, Inc. + Contributed by Peter Bergner . + + This file is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your option) + any later version. + + This file is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#ifndef __HTM__ +# error "HTM instruction set not enabled" +#endif /* __HTM__ */ + +#ifndef _HTMXLINTRIN_H +#define _HTMXLINTRIN_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define _TEXASR_PTR(TM_BUF) \ + ((texasr_t *)((TM_BUF)+0)) +#define _TEXASRU_PTR(TM_BUF) \ + ((texasru_t *)((TM_BUF)+0)) +#define _TEXASRL_PTR(TM_BUF) \ + ((texasrl_t *)((TM_BUF)+4)) +#define _TFIAR_PTR(TM_BUF) \ + ((tfiar_t *)((TM_BUF)+8)) + +typedef char TM_buff_type[16]; + +/* Compatibility macro with s390. This macro can be used to determine + whether a transaction was successfully started from the __TM_begin() + and __TM_simple_begin() intrinsic functions below. */ +#define _HTM_TBEGIN_STARTED 1 + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_simple_begin (void) +{ + if (__builtin_expect (__builtin_tbegin (0), 1)) + return _HTM_TBEGIN_STARTED; + return 0; +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_begin (void* const TM_buff) +{ + *_TEXASRL_PTR (TM_buff) = 0; + if (__builtin_expect (__builtin_tbegin (0), 1)) + return _HTM_TBEGIN_STARTED; +#ifdef __powerpc64__ + *_TEXASR_PTR (TM_buff) = __builtin_get_texasr (); +#else + *_TEXASRU_PTR (TM_buff) = __builtin_get_texasru (); + *_TEXASRL_PTR (TM_buff) = __builtin_get_texasr (); +#endif + *_TFIAR_PTR (TM_buff) = __builtin_get_tfiar (); + return 0; +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_end (void) +{ + unsigned char status = _HTM_STATE (__builtin_tend (0)); + if (__builtin_expect (status, _HTM_TRANSACTIONAL)) + return 1; + return 0; +} + +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_abort (void) +{ + __builtin_tabort (0); +} + +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_named_abort (unsigned char const code) +{ + __builtin_tabort (code); +} + +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_resume (void) +{ + __builtin_tresume (); +} + +extern __inline void +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_suspend (void) +{ + __builtin_tsuspend (); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_user_abort (void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_ABORT (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_named_user_abort (void* const TM_buff, unsigned char *code) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + + *code = _TEXASRU_FAILURE_CODE (texasru); + return _TEXASRU_ABORT (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_illegal (void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_DISALLOWED (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_footprint_exceeded (void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_FOOTPRINT_OVERFLOW (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_nesting_depth (void* const TM_buff) +{ + texasrl_t texasrl; + + if (_HTM_STATE (__builtin_ttest ()) == _HTM_NONTRANSACTIONAL) + { + texasrl = *_TEXASRL_PTR (TM_buff); + if (!_TEXASR_FAILURE_SUMMARY (texasrl)) + texasrl = 0; + } + else + texasrl = (texasrl_t) __builtin_get_texasr (); + + return _TEXASR_TRANSACTION_LEVEL (texasrl); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_nested_too_deep(void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_NESTING_OVERFLOW (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_conflict(void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + /* Return TEXASR bits 11 (Self-Induced Conflict) through + 14 (Translation Invalidation Conflict). */ + return (_TEXASRU_EXTRACT_BITS (texasru, 14, 4)) ? 1 : 0; +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_is_failure_persistent(void* const TM_buff) +{ + texasru_t texasru = *_TEXASRU_PTR (TM_buff); + return _TEXASRU_FAILURE_PERSISTENT (texasru); +} + +extern __inline long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_failure_address(void* const TM_buff) +{ + return *_TFIAR_PTR (TM_buff); +} + +extern __inline long long +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__TM_failure_code(void* const TM_buff) +{ + return *_TEXASR_PTR (TM_buff); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _HTMXLINTRIN_H */ diff --git a/gcc/config/powerpcspe/linux.h b/gcc/config/powerpcspe/linux.h new file mode 100644 index 00000000000..684afd6c190 --- /dev/null +++ b/gcc/config/powerpcspe/linux.h @@ -0,0 +1,140 @@ +/* Definitions of target machine for GNU compiler, + for PowerPC machines running Linux. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + Contributed by Michael Meissner (meissner@cygnus.com). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit + process. */ +#define OS_MISSING_POWERPC64 1 + +/* We use glibc _mcount for profiling. */ +#define NO_PROFILE_COUNTERS 1 + +#ifdef SINGLE_LIBC +#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC) +#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC) +#undef OPTION_MUSL +#define OPTION_MUSL (DEFAULT_LIBC == LIBC_MUSL) +#else +#define OPTION_GLIBC (linux_libc == LIBC_GLIBC) +#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC) +#define OPTION_BIONIC (linux_libc == LIBC_BIONIC) +#undef OPTION_MUSL +#define OPTION_MUSL (linux_libc == LIBC_MUSL) +#endif + +/* Determine what functions are present at the runtime; + this includes full c99 runtime and sincos. */ +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define_std ("PPC"); \ + builtin_define_std ("powerpc"); \ + builtin_assert ("cpu=powerpc"); \ + builtin_assert ("machine=powerpc"); \ + TARGET_OS_SYSV_CPP_BUILTINS (); \ + } \ + while (0) + +#undef CPP_OS_DEFAULT_SPEC +#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)" + +#undef LINK_SHLIB_SPEC +#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}" + +#undef LIB_DEFAULT_SPEC +#define LIB_DEFAULT_SPEC "%(lib_linux)" + +#undef STARTFILE_DEFAULT_SPEC +#define STARTFILE_DEFAULT_SPEC "%(startfile_linux)" + +#undef ENDFILE_DEFAULT_SPEC +#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)" + +#undef LINK_START_DEFAULT_SPEC +#define LINK_START_DEFAULT_SPEC "%(link_start_linux)" + +#undef LINK_OS_DEFAULT_SPEC +#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" + +#undef DEFAULT_ASM_ENDIAN +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#define DEFAULT_ASM_ENDIAN " -mlittle" +#define LINK_OS_LINUX_EMUL ENDIAN_SELECT(" -m elf32ppclinux", \ + " -m elf32lppclinux", \ + " -m elf32lppclinux") +#else +#define DEFAULT_ASM_ENDIAN " -mbig" +#define LINK_OS_LINUX_EMUL ENDIAN_SELECT(" -m elf32ppclinux", \ + " -m elf32lppclinux", \ + " -m elf32ppclinux") +#endif + +#undef LINK_OS_LINUX_SPEC +#define LINK_OS_LINUX_SPEC LINK_OS_LINUX_EMUL " %{!shared: %{!static: \ + %{rdynamic:-export-dynamic} \ + -dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}" + +/* For backward compatibility, we must continue to use the AIX + structure return convention. */ +#undef DRAFT_V4_STRUCT_RET +#define DRAFT_V4_STRUCT_RET 1 + +/* We are 32-bit all the time, so optimize a little. */ +#undef TARGET_64BIT +#define TARGET_64BIT 0 + +/* We don't need to generate entries in .fixup, except when + -mrelocatable or -mrelocatable-lib is given. */ +#undef RELOCATABLE_NEEDS_FIXUP +#define RELOCATABLE_NEEDS_FIXUP \ + (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE) + +#ifdef TARGET_LIBC_PROVIDES_SSP +/* ppc32 glibc provides __stack_chk_guard in -0x7008(2). */ +#define TARGET_THREAD_SSP_OFFSET -0x7008 +#endif + +#define POWERPC_LINUX + +/* ppc linux has 128-bit long double support in glibc 2.4 and later. */ +#ifdef TARGET_DEFAULT_LONG_DOUBLE_128 +#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128 +#endif + +/* Static stack checking is supported by means of probes. */ +#define STACK_CHECK_STATIC_BUILTIN 1 + +/* Software floating point support for exceptions and rounding modes + depends on the C library in use. */ +#undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P +#define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \ + rs6000_linux_float_exceptions_rounding_supported_p + +/* Support for TARGET_ATOMIC_ASSIGN_EXPAND_FENV without FPRs depends + on glibc 2.19 or greater. */ +#if TARGET_GLIBC_MAJOR > 2 \ + || (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 19) +#define RS6000_GLIBC_ATOMIC_FENV 1 +#endif diff --git a/gcc/config/powerpcspe/linux64.h b/gcc/config/powerpcspe/linux64.h new file mode 100644 index 00000000000..71e35b709ad --- /dev/null +++ b/gcc/config/powerpcspe/linux64.h @@ -0,0 +1,642 @@ +/* Definitions of target machine for GNU compiler, + for 64 bit PowerPC linux. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#ifndef RS6000_BI_ARCH + +#undef TARGET_64BIT +#define TARGET_64BIT 1 + +#define DEFAULT_ARCH64_P 1 +#define RS6000_BI_ARCH_P 0 + +#else + +#define DEFAULT_ARCH64_P (TARGET_DEFAULT & MASK_64BIT) +#define RS6000_BI_ARCH_P 1 + +#endif + +#ifdef IN_LIBGCC2 +#undef TARGET_64BIT +#ifdef __powerpc64__ +#define TARGET_64BIT 1 +#else +#define TARGET_64BIT 0 +#endif +#endif + +#undef TARGET_AIX +#define TARGET_AIX TARGET_64BIT + +#ifdef HAVE_LD_NO_DOT_SYMS +/* New ABI uses a local sym for the function entry point. */ +extern int dot_symbols; +#undef DOT_SYMBOLS +#define DOT_SYMBOLS dot_symbols +#endif + +#define TARGET_PROFILE_KERNEL profile_kernel + +#undef TARGET_KEEP_LEAF_WHEN_PROFILED +#define TARGET_KEEP_LEAF_WHEN_PROFILED rs6000_keep_leaf_when_profiled + +#define TARGET_USES_LINUX64_OPT 1 +#ifdef HAVE_LD_LARGE_TOC +#undef TARGET_CMODEL +#define TARGET_CMODEL rs6000_current_cmodel +#define SET_CMODEL(opt) rs6000_current_cmodel = opt +#else +#define SET_CMODEL(opt) do {} while (0) +#endif + +#undef PROCESSOR_DEFAULT +#define PROCESSOR_DEFAULT PROCESSOR_POWER7 +#undef PROCESSOR_DEFAULT64 +#define PROCESSOR_DEFAULT64 PROCESSOR_POWER8 + +/* We don't need to generate entries in .fixup, except when + -mrelocatable or -mrelocatable-lib is given. */ +#undef RELOCATABLE_NEEDS_FIXUP +#define RELOCATABLE_NEEDS_FIXUP \ + (rs6000_isa_flags & rs6000_isa_flags_explicit & OPTION_MASK_RELOCATABLE) + +#undef RS6000_ABI_NAME +#define RS6000_ABI_NAME "linux" + +#define INVALID_64BIT "-m%s not supported in this configuration" +#define INVALID_32BIT INVALID_64BIT + +#ifdef LINUX64_DEFAULT_ABI_ELFv2 +#define ELFv2_ABI_CHECK (rs6000_elf_abi != 1) +#else +#define ELFv2_ABI_CHECK (rs6000_elf_abi == 2) +#endif + +#undef SUBSUBTARGET_OVERRIDE_OPTIONS +#define SUBSUBTARGET_OVERRIDE_OPTIONS \ + do \ + { \ + if (!global_options_set.x_rs6000_alignment_flags) \ + rs6000_alignment_flags = MASK_ALIGN_NATURAL; \ + if (rs6000_isa_flags & OPTION_MASK_64BIT) \ + { \ + if (DEFAULT_ABI != ABI_AIX) \ + { \ + rs6000_current_abi = ABI_AIX; \ + error (INVALID_64BIT, "call"); \ + } \ + dot_symbols = !strcmp (rs6000_abi_name, "aixdesc"); \ + if (ELFv2_ABI_CHECK) \ + { \ + rs6000_current_abi = ABI_ELFv2; \ + if (dot_symbols) \ + error ("-mcall-aixdesc incompatible with -mabi=elfv2"); \ + } \ + if (rs6000_isa_flags & OPTION_MASK_RELOCATABLE) \ + { \ + rs6000_isa_flags &= ~OPTION_MASK_RELOCATABLE; \ + error (INVALID_64BIT, "relocatable"); \ + } \ + if (rs6000_isa_flags & OPTION_MASK_EABI) \ + { \ + rs6000_isa_flags &= ~OPTION_MASK_EABI; \ + error (INVALID_64BIT, "eabi"); \ + } \ + if (TARGET_PROTOTYPE) \ + { \ + target_prototype = 0; \ + error (INVALID_64BIT, "prototype"); \ + } \ + if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) == 0) \ + { \ + rs6000_isa_flags |= OPTION_MASK_POWERPC64; \ + error ("-m64 requires a PowerPC64 cpu"); \ + } \ + if ((rs6000_isa_flags_explicit \ + & OPTION_MASK_MINIMAL_TOC) != 0) \ + { \ + if (global_options_set.x_rs6000_current_cmodel \ + && rs6000_current_cmodel != CMODEL_SMALL) \ + error ("-mcmodel incompatible with other toc options"); \ + SET_CMODEL (CMODEL_SMALL); \ + } \ + else \ + { \ + if (!global_options_set.x_rs6000_current_cmodel) \ + SET_CMODEL (CMODEL_MEDIUM); \ + if (rs6000_current_cmodel != CMODEL_SMALL) \ + { \ + if (!global_options_set.x_TARGET_NO_FP_IN_TOC) \ + TARGET_NO_FP_IN_TOC \ + = rs6000_current_cmodel == CMODEL_MEDIUM; \ + if (!global_options_set.x_TARGET_NO_SUM_IN_TOC) \ + TARGET_NO_SUM_IN_TOC = 0; \ + } \ + } \ + } \ + else \ + { \ + if (!RS6000_BI_ARCH_P) \ + error (INVALID_32BIT, "32"); \ + if (TARGET_PROFILE_KERNEL) \ + { \ + TARGET_PROFILE_KERNEL = 0; \ + error (INVALID_32BIT, "profile-kernel"); \ + } \ + if (global_options_set.x_rs6000_current_cmodel) \ + { \ + SET_CMODEL (CMODEL_SMALL); \ + error (INVALID_32BIT, "cmodel"); \ + } \ + } \ + } \ + while (0) + +#undef ASM_DEFAULT_SPEC +#undef ASM_SPEC +#undef LINK_OS_LINUX_SPEC +#undef LINK_SECURE_PLT_SPEC + +#ifndef RS6000_BI_ARCH +#define ASM_DEFAULT_SPEC "-mppc64" +#define ASM_SPEC "%(asm_spec64) %(asm_spec_common)" +#define LINK_OS_LINUX_SPEC "%(link_os_linux_spec64)" +#define LINK_SECURE_PLT_SPEC "" +#else +#if DEFAULT_ARCH64_P +#define ASM_DEFAULT_SPEC "-mppc%{!m32:64}" +#define ASM_SPEC "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)" +#define LINK_OS_LINUX_SPEC "%{m32:%(link_os_linux_spec32)}%{!m32:%(link_os_linux_spec64)}" +#define LINK_SECURE_PLT_SPEC "%{m32: " LINK_SECURE_PLT_DEFAULT_SPEC "}" +#else +#define ASM_DEFAULT_SPEC "-mppc%{m64:64}" +#define ASM_SPEC "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)" +#define LINK_OS_LINUX_SPEC "%{!m64:%(link_os_linux_spec32)}%{m64:%(link_os_linux_spec64)}" +#define LINK_SECURE_PLT_SPEC "%{!m64: " LINK_SECURE_PLT_DEFAULT_SPEC "}" +#endif +#endif + +#define ASM_SPEC32 "-a32 \ +%{mrelocatable} %{mrelocatable-lib} %{" FPIE_OR_FPIC_SPEC ":-K PIC} \ +%{memb|msdata=eabi: -memb}" + +#define ASM_SPEC64 "-a64" + +#define ASM_SPEC_COMMON "%(asm_cpu) \ +%{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" \ + ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN) + +#undef SUBSUBTARGET_EXTRA_SPECS +#define SUBSUBTARGET_EXTRA_SPECS \ + { "asm_spec_common", ASM_SPEC_COMMON }, \ + { "asm_spec32", ASM_SPEC32 }, \ + { "asm_spec64", ASM_SPEC64 }, \ + { "link_os_linux_spec32", LINK_OS_LINUX_SPEC32 }, \ + { "link_os_linux_spec64", LINK_OS_LINUX_SPEC64 }, \ + { "link_os_extra_spec32", LINK_OS_EXTRA_SPEC32 }, \ + { "link_os_extra_spec64", LINK_OS_EXTRA_SPEC64 }, \ + { "link_os_new_dtags", LINK_OS_NEW_DTAGS_SPEC }, \ + { "include_extra", INCLUDE_EXTRA_SPEC }, \ + { "dynamic_linker_prefix", DYNAMIC_LINKER_PREFIX }, + +/* Optional specs used for overriding the system include directory, default + -rpath links, and prefix for the dynamic linker. Normally, there are not + defined, but if the user configure with the --with-advance-toolchain= + option, the advance-toolchain.h file will override these. */ +#ifndef INCLUDE_EXTRA_SPEC +#define INCLUDE_EXTRA_SPEC "" +#endif + +#ifndef LINK_OS_EXTRA_SPEC32 +#define LINK_OS_EXTRA_SPEC32 "" +#endif + +#ifndef LINK_OS_EXTRA_SPEC64 +#define LINK_OS_EXTRA_SPEC64 "" +#endif + +#ifndef LINK_OS_NEW_DTAGS_SPEC +#define LINK_OS_NEW_DTAGS_SPEC "" +#endif + +#ifndef DYNAMIC_LINKER_PREFIX +#define DYNAMIC_LINKER_PREFIX "" +#endif + +#undef MULTILIB_DEFAULTS +#if DEFAULT_ARCH64_P +#define MULTILIB_DEFAULTS { "m64" } +#else +#define MULTILIB_DEFAULTS { "m32" } +#endif + +/* Split stack is only supported for 64 bit, and requires glibc >= 2.18. */ +#if TARGET_GLIBC_MAJOR * 1000 + TARGET_GLIBC_MINOR >= 2018 +# ifndef RS6000_BI_ARCH +# define TARGET_CAN_SPLIT_STACK +# else +# if DEFAULT_ARCH64_P +/* Supported, and the default is -m64 */ +# define TARGET_CAN_SPLIT_STACK_64BIT 1 +# else +/* Supported, and the default is -m32 */ +# define TARGET_CAN_SPLIT_STACK_64BIT 0 +# endif +# endif +#endif + +#ifndef RS6000_BI_ARCH + +/* 64-bit PowerPC Linux always has a TOC. */ +#undef TARGET_TOC +#define TARGET_TOC 1 + +/* Some things from sysv4.h we don't do when 64 bit. */ +#undef OPTION_RELOCATABLE +#define OPTION_RELOCATABLE 0 +#undef OPTION_EABI +#define OPTION_EABI 0 +#undef OPTION_PROTOTYPE +#define OPTION_PROTOTYPE 0 +#undef RELOCATABLE_NEEDS_FIXUP +#define RELOCATABLE_NEEDS_FIXUP 0 + +#endif + +/* We use glibc _mcount for profiling. */ +#define NO_PROFILE_COUNTERS 1 +#define PROFILE_HOOK(LABEL) \ + do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0) + +/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */ +#undef ADJUST_FIELD_ALIGN +#define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \ + (rs6000_special_adjust_field_align_p ((TYPE), (COMPUTED)) \ + ? 128 \ + : (TARGET_64BIT \ + && TARGET_ALIGN_NATURAL == 0 \ + && TYPE_MODE (strip_array_types (TYPE)) == DFmode) \ + ? MIN ((COMPUTED), 32) \ + : (COMPUTED)) + +/* PowerPC64 Linux increases natural record alignment to doubleword if + the first field is an FP double, only if in power alignment mode. */ +#undef ROUND_TYPE_ALIGN +#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \ + ((TARGET_64BIT \ + && (TREE_CODE (STRUCT) == RECORD_TYPE \ + || TREE_CODE (STRUCT) == UNION_TYPE \ + || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \ + && TARGET_ALIGN_NATURAL == 0) \ + ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \ + : MAX ((COMPUTED), (SPECIFIED))) + +/* Use the default for compiling target libs. */ +#ifdef IN_TARGET_LIBS +#undef TARGET_ALIGN_NATURAL +#define TARGET_ALIGN_NATURAL 1 +#endif + +/* Indicate that jump tables go in the text section. */ +#undef JUMP_TABLES_IN_TEXT_SECTION +#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT + +/* The linux ppc64 ABI isn't explicit on whether aggregates smaller + than a doubleword should be padded upward or downward. You could + reasonably assume that they follow the normal rules for structure + layout treating the parameter area as any other block of memory, + then map the reg param area to registers. i.e. pad upward. + Setting both of the following defines results in this behavior. + Setting just the first one will result in aggregates that fit in a + doubleword being padded downward, and others being padded upward. + Not a bad idea as this results in struct { int x; } being passed + the same way as an int. */ +#define AGGREGATE_PADDING_FIXED TARGET_64BIT +#define AGGREGATES_PAD_UPWARD_ALWAYS 0 + +/* Specify padding for the last element of a block move between + registers and memory. FIRST is nonzero if this is the only + element. */ +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \ + (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE)) + +/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit + process. */ +#define OS_MISSING_POWERPC64 !TARGET_64BIT + +#ifdef SINGLE_LIBC +#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC) +#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC) +#undef OPTION_MUSL +#define OPTION_MUSL (DEFAULT_LIBC == LIBC_MUSL) +#else +#define OPTION_GLIBC (linux_libc == LIBC_GLIBC) +#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC) +#define OPTION_BIONIC (linux_libc == LIBC_BIONIC) +#undef OPTION_MUSL +#define OPTION_MUSL (linux_libc == LIBC_MUSL) +#endif + +/* Determine what functions are present at the runtime; + this includes full c99 runtime and sincos. */ +#undef TARGET_LIBC_HAS_FUNCTION +#define TARGET_LIBC_HAS_FUNCTION linux_libc_has_function + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + if (TARGET_64BIT) \ + { \ + builtin_define ("__PPC__"); \ + builtin_define ("__PPC64__"); \ + builtin_define ("__powerpc__"); \ + builtin_define ("__powerpc64__"); \ + if (!DOT_SYMBOLS) \ + builtin_define ("_CALL_LINUX"); \ + builtin_assert ("cpu=powerpc64"); \ + builtin_assert ("machine=powerpc64"); \ + } \ + else \ + { \ + builtin_define_std ("PPC"); \ + builtin_define_std ("powerpc"); \ + builtin_assert ("cpu=powerpc"); \ + builtin_assert ("machine=powerpc"); \ + TARGET_OS_SYSV_CPP_BUILTINS (); \ + } \ + } \ + while (0) + +#undef CPP_OS_DEFAULT_SPEC +#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux) %(include_extra)" + +#undef LINK_SHLIB_SPEC +#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}" + +#undef LIB_DEFAULT_SPEC +#define LIB_DEFAULT_SPEC "%(lib_linux)" + +#undef STARTFILE_DEFAULT_SPEC +#define STARTFILE_DEFAULT_SPEC "%(startfile_linux)" + +#undef ENDFILE_DEFAULT_SPEC +#define ENDFILE_DEFAULT_SPEC "%(endfile_linux)" + +#undef LINK_START_DEFAULT_SPEC +#define LINK_START_DEFAULT_SPEC "%(link_start_linux)" + +#undef LINK_OS_DEFAULT_SPEC +#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)" + +#define GLIBC_DYNAMIC_LINKER32 "%(dynamic_linker_prefix)/lib/ld.so.1" + +#ifdef LINUX64_DEFAULT_ABI_ELFv2 +#define GLIBC_DYNAMIC_LINKER64 \ +"%{mabi=elfv1:%(dynamic_linker_prefix)/lib64/ld64.so.1;" \ +":%(dynamic_linker_prefix)/lib64/ld64.so.2}" +#else +#define GLIBC_DYNAMIC_LINKER64 \ +"%{mabi=elfv2:%(dynamic_linker_prefix)/lib64/ld64.so.2;" \ +":%(dynamic_linker_prefix)/lib64/ld64.so.1}" +#endif + +#define MUSL_DYNAMIC_LINKER32 \ + "/lib/ld-musl-powerpc" MUSL_DYNAMIC_LINKER_E "%{msoft-float:-sf}.so.1" +#define MUSL_DYNAMIC_LINKER64 \ + "/lib/ld-musl-powerpc64" MUSL_DYNAMIC_LINKER_E "%{msoft-float:-sf}.so.1" + +#define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0" +#define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0" +#if DEFAULT_LIBC == LIBC_UCLIBC +#define CHOOSE_DYNAMIC_LINKER(G, U, M) \ + "%{mglibc:" G ";:%{mmusl:" M ";:" U "}}" +#elif DEFAULT_LIBC == LIBC_GLIBC +#define CHOOSE_DYNAMIC_LINKER(G, U, M) \ + "%{muclibc:" U ";:%{mmusl:" M ";:" G "}}" +#elif DEFAULT_LIBC == LIBC_MUSL +#define CHOOSE_DYNAMIC_LINKER(G, U, M) \ + "%{mglibc:" G ";:%{muclibc:" U ";:" M "}}" +#else +#error "Unsupported DEFAULT_LIBC" +#endif +#define GNU_USER_DYNAMIC_LINKER32 \ + CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, \ + MUSL_DYNAMIC_LINKER32) +#define GNU_USER_DYNAMIC_LINKER64 \ + CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \ + MUSL_DYNAMIC_LINKER64) + +#undef DEFAULT_ASM_ENDIAN +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#define DEFAULT_ASM_ENDIAN " -mlittle" +#define LINK_OS_LINUX_EMUL32 ENDIAN_SELECT(" -m elf32ppclinux", \ + " -m elf32lppclinux", \ + " -m elf32lppclinux") +#define LINK_OS_LINUX_EMUL64 ENDIAN_SELECT(" -m elf64ppc", \ + " -m elf64lppc", \ + " -m elf64lppc") +#else +#define DEFAULT_ASM_ENDIAN " -mbig" +#define LINK_OS_LINUX_EMUL32 ENDIAN_SELECT(" -m elf32ppclinux", \ + " -m elf32lppclinux", \ + " -m elf32ppclinux") +#define LINK_OS_LINUX_EMUL64 ENDIAN_SELECT(" -m elf64ppc", \ + " -m elf64lppc", \ + " -m elf64ppc") +#endif + +#define LINK_OS_LINUX_SPEC32 LINK_OS_LINUX_EMUL32 " %{!shared: %{!static: \ + %{rdynamic:-export-dynamic} \ + -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}} \ + %(link_os_extra_spec32)" + +#define LINK_OS_LINUX_SPEC64 LINK_OS_LINUX_EMUL64 " %{!shared: %{!static: \ + %{rdynamic:-export-dynamic} \ + -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "}} \ + %(link_os_extra_spec64)" + +#undef TOC_SECTION_ASM_OP +#define TOC_SECTION_ASM_OP \ + (TARGET_64BIT \ + ? "\t.section\t\".toc\",\"aw\"" \ + : "\t.section\t\".got\",\"aw\"") + +#undef MINIMAL_TOC_SECTION_ASM_OP +#define MINIMAL_TOC_SECTION_ASM_OP \ + (TARGET_64BIT \ + ? "\t.section\t\".toc1\",\"aw\"" \ + : (flag_pic \ + ? "\t.section\t\".got2\",\"aw\"" \ + : "\t.section\t\".got1\",\"aw\"")) + +/* Must be at least as big as our pointer type. */ +#undef SIZE_TYPE +#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int") + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int") + +#undef WCHAR_TYPE +#define WCHAR_TYPE (TARGET_64BIT ? "int" : "long int") +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE 32 + +#undef RS6000_MCOUNT +#define RS6000_MCOUNT "_mcount" + +#ifdef __powerpc64__ +/* _init and _fini functions are built from bits spread across many + object files, each potentially with a different TOC pointer. For + that reason, place a nop after the call so that the linker can + restore the TOC pointer if a TOC adjusting call stub is needed. */ +#if DOT_SYMBOLS +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ + asm (SECTION_OP "\n" \ +" bl ." #FUNC "\n" \ +" nop\n" \ +" .previous"); +#else +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ + asm (SECTION_OP "\n" \ +" bl " #FUNC "\n" \ +" nop\n" \ +" .previous"); +#endif +#endif + +/* FP save and restore routines. */ +#undef SAVE_FP_PREFIX +#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_") +#undef SAVE_FP_SUFFIX +#define SAVE_FP_SUFFIX "" +#undef RESTORE_FP_PREFIX +#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_") +#undef RESTORE_FP_SUFFIX +#define RESTORE_FP_SUFFIX "" + +/* Dwarf2 debugging. */ +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG + +/* This is how to declare the size of a function. */ +#undef ASM_DECLARE_FUNCTION_SIZE +#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ + do \ + { \ + if (!flag_inhibit_size_directive) \ + { \ + fputs ("\t.size\t", (FILE)); \ + if (TARGET_64BIT && DOT_SYMBOLS) \ + putc ('.', (FILE)); \ + assemble_name ((FILE), (FNAME)); \ + fputs (",.-", (FILE)); \ + rs6000_output_function_entry (FILE, FNAME); \ + putc ('\n', (FILE)); \ + } \ + } \ + while (0) + +/* Return nonzero if this entry is to be written into the constant + pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF + or a CONST containing one of them. If -mfp-in-toc (the default), + we also do this for floating-point constants. We actually can only + do this if the FP formats of the target and host machines are the + same, but we can't check that since not every file that uses + the macros includes real.h. We also do this when we can write the + entry into the TOC and the entry is not larger than a TOC entry. */ + +#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P +#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \ + (TARGET_TOC \ + && (GET_CODE (X) == SYMBOL_REF \ + || (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \ + && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \ + || GET_CODE (X) == LABEL_REF \ + || (GET_CODE (X) == CONST_INT \ + && GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \ + || (GET_CODE (X) == CONST_DOUBLE \ + && ((TARGET_64BIT \ + && (TARGET_MINIMAL_TOC \ + || (SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ + && ! TARGET_NO_FP_IN_TOC))) \ + || (!TARGET_64BIT \ + && !TARGET_NO_FP_IN_TOC \ + && SCALAR_FLOAT_MODE_P (GET_MODE (X)) \ + && BITS_PER_WORD == HOST_BITS_PER_INT))))) + +/* Select a format to encode pointers in exception handling data. CODE + is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is + true if the symbol may be affected by dynamic relocations. */ +#undef ASM_PREFERRED_EH_DATA_FORMAT +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ + (TARGET_64BIT || flag_pic \ + ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \ + | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4)) \ + : DW_EH_PE_absptr) + +/* For backward compatibility, we must continue to use the AIX + structure return convention. */ +#undef DRAFT_V4_STRUCT_RET +#define DRAFT_V4_STRUCT_RET (!TARGET_64BIT) + +#ifdef TARGET_LIBC_PROVIDES_SSP +/* ppc32 glibc provides __stack_chk_guard in -0x7008(2), + ppc64 glibc provides it at -0x7010(13). */ +#define TARGET_THREAD_SSP_OFFSET (TARGET_64BIT ? -0x7010 : -0x7008) +#endif + +#define POWERPC_LINUX + +/* ppc{32,64} linux has 128-bit long double support in glibc 2.4 and later. */ +#ifdef TARGET_DEFAULT_LONG_DOUBLE_128 +#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128 +#endif + +/* Static stack checking is supported by means of probes. */ +#define STACK_CHECK_STATIC_BUILTIN 1 + +/* The default value isn't sufficient in 64-bit mode. */ +#define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024) + +/* Software floating point support for exceptions and rounding modes + depends on the C library in use. */ +#undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P +#define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \ + rs6000_linux_float_exceptions_rounding_supported_p + +/* Support for TARGET_ATOMIC_ASSIGN_EXPAND_FENV without FPRs depends + on glibc 2.19 or greater. */ +#if TARGET_GLIBC_MAJOR > 2 \ + || (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 19) +#define RS6000_GLIBC_ATOMIC_FENV 1 +#endif + +/* The IEEE 128-bit emulator is only built on Linux systems. Flag that we + should enable the type handling for KFmode on VSX systems even if we are not + enabling the __float128 keyword. */ +#undef TARGET_FLOAT128_ENABLE_TYPE +#define TARGET_FLOAT128_ENABLE_TYPE 1 diff --git a/gcc/config/powerpcspe/linux64.opt b/gcc/config/powerpcspe/linux64.opt new file mode 100644 index 00000000000..b0ca976fe18 --- /dev/null +++ b/gcc/config/powerpcspe/linux64.opt @@ -0,0 +1,42 @@ +; Options for 64-bit PowerPC Linux. +; +; Copyright (C) 2005-2017 Free Software Foundation, Inc. +; Contributed by Aldy Hernandez . +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 3, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +; License for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING3. If not see +; . + +mprofile-kernel +Target Report Var(profile_kernel) Save +Call mcount for profiling before a function prologue. + +mcmodel= +Target RejectNegative Joined Enum(rs6000_cmodel) Var(rs6000_current_cmodel) +Select code model. + +Enum +Name(rs6000_cmodel) Type(enum rs6000_cmodel) +Known code models (for use with the -mcmodel= option): + +EnumValue +Enum(rs6000_cmodel) String(small) Value(CMODEL_SMALL) + +EnumValue +Enum(rs6000_cmodel) String(medium) Value(CMODEL_MEDIUM) + +EnumValue +Enum(rs6000_cmodel) String(large) Value(CMODEL_LARGE) + diff --git a/gcc/config/powerpcspe/linuxaltivec.h b/gcc/config/powerpcspe/linuxaltivec.h new file mode 100644 index 00000000000..fddb18d8e22 --- /dev/null +++ b/gcc/config/powerpcspe/linuxaltivec.h @@ -0,0 +1,32 @@ +/* Definitions of target machine for GNU compiler, + for AltiVec enhanced PowerPC machines running GNU/Linux. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Aldy Hernandez (aldyh@redhat.com). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* Override rs6000.h and sysv4.h definition. */ +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_ALTIVEC | MASK_LITTLE_ENDIAN) +#else +#undef TARGET_DEFAULT +#define TARGET_DEFAULT MASK_ALTIVEC +#endif + +#undef SUBSUBTARGET_OVERRIDE_OPTIONS +#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1 diff --git a/gcc/config/powerpcspe/linuxspe.h b/gcc/config/powerpcspe/linuxspe.h new file mode 100644 index 00000000000..92efabfe664 --- /dev/null +++ b/gcc/config/powerpcspe/linuxspe.h @@ -0,0 +1,32 @@ +/* Definitions of target machine for GNU compiler, + for PowerPC e500 machines running GNU/Linux. + Copyright (C) 2003-2017 Free Software Foundation, Inc. + Contributed by Aldy Hernandez (aldy@quesejoda.com). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* Override rs6000.h and sysv4.h definition. */ +#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN) +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_STRICT_ALIGN | MASK_LITTLE_ENDIAN) +#else +#undef TARGET_DEFAULT +#define TARGET_DEFAULT MASK_STRICT_ALIGN +#endif + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mppc -mspe -me500" diff --git a/gcc/config/powerpcspe/lynx.h b/gcc/config/powerpcspe/lynx.h new file mode 100644 index 00000000000..2f9356f969d --- /dev/null +++ b/gcc/config/powerpcspe/lynx.h @@ -0,0 +1,120 @@ +/* Definitions for Rs6000 running LynxOS. + Copyright (C) 1995-2017 Free Software Foundation, Inc. + Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.com) + Rewritten by Adam Nemet, LynuxWorks Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* Undefine the definition to enable the LynxOS default from the + top-level lynx.h. */ + +#undef SUBTARGET_EXTRA_SPECS + +/* Get rid off the spec definitions from rs6000/sysv4.h. */ + +#undef CPP_SPEC +#define CPP_SPEC \ +"%{msoft-float: -D_SOFT_FLOAT} \ + %(cpp_cpu) \ + %(cpp_os_lynx)" + +/* LynxOS only supports big-endian on PPC so we override the + definition from sysv4.h. Since the LynxOS 4.0 compiler was set to + return every structure in memory regardless of their size we have + to emulate the same behavior here with disabling the SVR4 structure + returning. */ + +#undef CC1_SPEC +#define CC1_SPEC \ +"%{G*} %{mno-sdata:-msdata=none} \ + %{maltivec:-mabi=altivec} \ + -maix-struct-return" + +#undef ASM_SPEC +#define ASM_SPEC \ +"%(asm_cpu) \ + %{,assembler|,assembler-with-cpp: %{mregnames} %{mno-regnames}}" + +#undef STARTFILE_SPEC +#undef ENDFILE_SPEC +#undef LIB_SPEC +#undef LINK_SPEC +#define LINK_SPEC \ +"%{!msdata=none:%{G*}} %{msdata=none:-G0} \ + %(link_os_lynx)" + +/* Override the definition from sysv4.h. */ + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("__BIG_ENDIAN__"); \ + builtin_define ("__powerpc__"); \ + builtin_assert ("cpu=powerpc"); \ + builtin_assert ("machine=powerpc"); \ + builtin_define ("__PPC__"); \ + } \ + while (0) + +/* Override the rs6000.h definition. */ + +#undef ASM_APP_ON +#define ASM_APP_ON "#APP\n" + +/* Override the rs6000.h definition. */ + +#undef ASM_APP_OFF +#define ASM_APP_OFF "#NO_APP\n" + +/* LynxOS does not do anything with .fixup plus let's not create + writable section for linkonce.r and linkonce.t. */ + +#undef RELOCATABLE_NEEDS_FIXUP + +/* Override these from rs6000.h with the generic definition. */ + +#undef SIZE_TYPE +#undef ASM_OUTPUT_ALIGN +#undef PREFERRED_DEBUGGING_TYPE + +/* The file rs6000.c defines TARGET_HAVE_TLS unconditionally to the + value of HAVE_AS_TLS. HAVE_AS_TLS is true as gas support for TLS + is detected by configure. Override the definition to false. */ + +#undef HAVE_AS_TLS +#define HAVE_AS_TLS 0 + +/* Use standard DWARF numbering for DWARF debugging information. */ +#define RS6000_USE_DWARF_NUMBERING + +#ifdef CRT_BEGIN +/* This function is part of crtbegin*.o which is at the beginning of + the link and is called from .fini which is usually toward the end + of the executable. Make it longcall so that we don't limit the + text size of the executables to 32M. */ + +static void __do_global_dtors_aux (void) __attribute__ ((longcall)); +#endif /* CRT_BEGIN */ + +#ifdef CRT_END +/* Similarly here. This function resides in crtend*.o which is toward + to end of the link and is called from .init which is at the + beginning. */ + +static void __do_global_ctors_aux (void) __attribute__ ((longcall)); +#endif /* CRT_END */ diff --git a/gcc/config/powerpcspe/milli.exp b/gcc/config/powerpcspe/milli.exp new file mode 100644 index 00000000000..ea3a2b757fe --- /dev/null +++ b/gcc/config/powerpcspe/milli.exp @@ -0,0 +1,7 @@ +#! +__mulh 0x3100 +__mull 0x3180 +__divss 0x3200 +__divus 0x3280 +__quoss 0x3300 +__quous 0x3380 diff --git a/gcc/config/powerpcspe/mpc.md b/gcc/config/powerpcspe/mpc.md new file mode 100644 index 00000000000..d302b73a0ea --- /dev/null +++ b/gcc/config/powerpcspe/mpc.md @@ -0,0 +1,112 @@ +;; Scheduling description for Motorola PowerPC processor cores. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "mpc,mpcfp") +(define_cpu_unit "iu_mpc,mciu_mpc" "mpc") +(define_cpu_unit "fpu_mpc" "mpcfp") +(define_cpu_unit "lsu_mpc,bpu_mpc" "mpc") + +;; MPCCORE 32-bit SCIU, MCIU, LSU, FPU, BPU +;; 505/801/821/823 + +(define_insn_reservation "mpccore-load" 2 + (and (eq_attr "type" "load,load_l,store_c,sync") + (eq_attr "cpu" "mpccore")) + "lsu_mpc") + +(define_insn_reservation "mpccore-store" 2 + (and (eq_attr "type" "store,fpstore") + (eq_attr "cpu" "mpccore")) + "lsu_mpc") + +(define_insn_reservation "mpccore-fpload" 2 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "mpccore")) + "lsu_mpc") + +(define_insn_reservation "mpccore-integer" 1 + (and (ior (eq_attr "type" "integer,insert,trap,cntlz,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "mpccore")) + "iu_mpc") + +(define_insn_reservation "mpccore-two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "mpccore")) + "iu_mpc,iu_mpc") + +(define_insn_reservation "mpccore-three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "mpccore")) + "iu_mpc,iu_mpc,iu_mpc") + +(define_insn_reservation "mpccore-imul" 2 + (and (eq_attr "type" "mul") + (eq_attr "cpu" "mpccore")) + "mciu_mpc") + +; Divide latency varies greatly from 2-11, use 6 as average +(define_insn_reservation "mpccore-idiv" 6 + (and (eq_attr "type" "div") + (eq_attr "cpu" "mpccore")) + "mciu_mpc*6") + +(define_insn_reservation "mpccore-compare" 3 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "mpccore")) + "iu_mpc,nothing,bpu_mpc") + +(define_insn_reservation "mpccore-fpcompare" 2 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "mpccore")) + "fpu_mpc,bpu_mpc") + +(define_insn_reservation "mpccore-fp" 4 + (and (eq_attr "type" "fp,fpsimple") + (eq_attr "cpu" "mpccore")) + "fpu_mpc*2") + +(define_insn_reservation "mpccore-dmul" 5 + (and (eq_attr "type" "dmul") + (eq_attr "cpu" "mpccore")) + "fpu_mpc*5") + +(define_insn_reservation "mpccore-sdiv" 10 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "mpccore")) + "fpu_mpc*10") + +(define_insn_reservation "mpccore-ddiv" 17 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "mpccore")) + "fpu_mpc*17") + +(define_insn_reservation "mpccore-mtjmpr" 4 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "mpccore")) + "bpu_mpc") + +(define_insn_reservation "mpccore-jmpreg" 1 + (and (eq_attr "type" "jmpreg,branch,cr_logical,delayed_cr,mfcr,mtcr,isync") + (eq_attr "cpu" "mpccore")) + "bpu_mpc") + diff --git a/gcc/config/powerpcspe/netbsd.h b/gcc/config/powerpcspe/netbsd.h new file mode 100644 index 00000000000..3eb8baa5ffd --- /dev/null +++ b/gcc/config/powerpcspe/netbsd.h @@ -0,0 +1,92 @@ +/* Definitions of target machine for GNU compiler, + for PowerPC NetBSD systems. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + Contributed by Wasabi Systems, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#undef TARGET_OS_CPP_BUILTINS /* FIXME: sysv4.h should not define this! */ +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + NETBSD_OS_CPP_BUILTINS_ELF(); \ + builtin_define ("__powerpc__"); \ + builtin_assert ("cpu=powerpc"); \ + builtin_assert ("machine=powerpc"); \ + } \ + while (0) + +/* Override the default from rs6000.h to avoid conflicts with macros + defined in NetBSD header files. */ + +#undef RS6000_CPU_CPP_ENDIAN_BUILTINS +#define RS6000_CPU_CPP_ENDIAN_BUILTINS() \ + do \ + { \ + if (BYTES_BIG_ENDIAN) \ + { \ + builtin_define ("__BIG_ENDIAN__"); \ + builtin_assert ("machine=bigendian"); \ + } \ + else \ + { \ + builtin_define ("__LITTLE_ENDIAN__"); \ + builtin_assert ("machine=littleendian"); \ + } \ + } \ + while (0) + +/* Make GCC agree with . */ + +#undef SIZE_TYPE +#define SIZE_TYPE "unsigned int" + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "int" + +/* Undo the spec mess from sysv4.h, and just define the specs + the way NetBSD systems actually expect. */ + +#undef CPP_SPEC +#define CPP_SPEC NETBSD_CPP_SPEC + +#undef LINK_SPEC +#define LINK_SPEC \ + "%{!msdata=none:%{G*}} %{msdata=none:-G0} \ + %(netbsd_link_spec)" + +#define NETBSD_ENTRY_POINT "_start" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC NETBSD_STARTFILE_SPEC + +#undef ENDFILE_SPEC +#define ENDFILE_SPEC "%(netbsd_endfile_spec)" + +#undef LIB_SPEC +#define LIB_SPEC NETBSD_LIB_SPEC + +#undef SUBTARGET_EXTRA_SPECS +#define SUBTARGET_EXTRA_SPECS \ + { "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \ + { "netbsd_entry_point", NETBSD_ENTRY_POINT }, \ + { "netbsd_endfile_spec", NETBSD_ENDFILE_SPEC }, + + +/* Use standard DWARF numbering for DWARF debugging information. */ +#define RS6000_USE_DWARF_NUMBERING + diff --git a/gcc/config/powerpcspe/option-defaults.h b/gcc/config/powerpcspe/option-defaults.h new file mode 100644 index 00000000000..09ddc36a16d --- /dev/null +++ b/gcc/config/powerpcspe/option-defaults.h @@ -0,0 +1,64 @@ +/* Definitions of default options for config/rs6000 configurations. + Copyright (C) 1992-2017 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* This header needs to be included after any other headers affecting + TARGET_DEFAULT. */ + +#if TARGET_AIX_OS +#define OPT_64 "maix64" +#define OPT_32 "maix32" +#else +#define OPT_64 "m64" +#define OPT_32 "m32" +#endif + +#ifndef OPTION_MASK_64BIT +#define OPTION_MASK_64BIT 0 +#define MASK_64BIT 0 +#endif + +#if TARGET_DEFAULT & OPTION_MASK_64BIT +#define OPT_ARCH64 "!" OPT_32 +#define OPT_ARCH32 OPT_32 +#else +#define OPT_ARCH64 OPT_64 +#define OPT_ARCH32 "!" OPT_64 +#endif + +/* Support for a compile-time default CPU, et cetera. The rules are: + --with-cpu is ignored if -mcpu is specified; likewise --with-cpu-32 + and --with-cpu-64. + --with-tune is ignored if -mtune or -mcpu is specified; likewise + --with-tune-32 and --with-tune-64. + --with-float is ignored if -mhard-float or -msoft-float are + specified. */ +#define OPTION_DEFAULT_SPECS \ + {"abi", "%{!mabi=elfv*:-mabi=%(VALUE)}" }, \ + {"tune", "%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}" }, \ + {"tune_32", "%{" OPT_ARCH32 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \ + {"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:%{!mcpu=*:-mtune=%(VALUE)}}}" }, \ + {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \ + {"cpu_32", "%{" OPT_ARCH32 ":%{!mcpu=*:-mcpu=%(VALUE)}}" }, \ + {"cpu_64", "%{" OPT_ARCH64 ":%{!mcpu=*:-mcpu=%(VALUE)}}" }, \ + {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" } diff --git a/gcc/config/powerpcspe/paired.h b/gcc/config/powerpcspe/paired.h new file mode 100644 index 00000000000..e51162bf8e2 --- /dev/null +++ b/gcc/config/powerpcspe/paired.h @@ -0,0 +1,75 @@ +/* PowerPC 750CL user include file. + Copyright (C) 2007-2017 Free Software Foundation, Inc. + Contributed by Revital Eres (eres@il.ibm.com). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#ifndef _PAIRED_H +#define _PAIRED_H + +#define vector __attribute__((vector_size(8))) + +#define paired_msub __builtin_paired_msub +#define paired_madd __builtin_paired_madd +#define paired_nmsub __builtin_paired_nmsub +#define paired_nmadd __builtin_paired_nmadd +#define paired_sum0 __builtin_paired_sum0 +#define paired_sum1 __builtin_paired_sum1 +#define paired_div __builtin_paired_divv2sf3 +#define paired_add __builtin_paired_addv2sf3 +#define paired_sub __builtin_paired_subv2sf3 +#define paired_mul __builtin_paired_mulv2sf3 +#define paired_muls0 __builtin_paired_muls0 +#define paired_muls1 __builtin_paired_muls1 +#define paired_madds0 __builtin_paired_madds0 +#define paired_madds1 __builtin_paired_madds1 +#define paired_merge00 __builtin_paired_merge00 +#define paired_merge01 __builtin_paired_merge01 +#define paired_merge10 __builtin_paired_merge10 +#define paired_merge11 __builtin_paired_merge11 +#define paired_abs __builtin_paired_absv2sf2 +#define paired_nabs __builtin_paired_nabsv2sf2 +#define paired_neg __builtin_paired_negv2sf2 +#define paired_sqrt __builtin_paired_sqrtv2sf2 +#define paired_res __builtin_paired_resv2sf2 +#define paired_stx __builtin_paired_stx +#define paired_lx __builtin_paired_lx +#define paired_cmpu0 __builtin_paired_cmpu0 +#define paired_cmpu1 __builtin_paired_cmpu1 +#define paired_sel __builtin_paired_selv2sf4 + +/* Condition register codes for Paired predicates. */ +#define LT 0 +#define GT 1 +#define EQ 2 +#define UN 3 + +#define paired_cmpu0_un(a,b) __builtin_paired_cmpu0 (UN, (a), (b)) +#define paired_cmpu0_eq(a,b) __builtin_paired_cmpu0 (EQ, (a), (b)) +#define paired_cmpu0_lt(a,b) __builtin_paired_cmpu0 (LT, (a), (b)) +#define paired_cmpu0_gt(a,b) __builtin_paired_cmpu0 (GT, (a), (b)) +#define paired_cmpu1_un(a,b) __builtin_paired_cmpu1 (UN, (a), (b)) +#define paired_cmpu1_eq(a,b) __builtin_paired_cmpu1 (EQ, (a), (b)) +#define paired_cmpu1_lt(a,b) __builtin_paired_cmpu1 (LT, (a), (b)) +#define paired_cmpu1_gt(a,b) __builtin_paired_cmpu1 (GT, (a), (b)) + +#endif /* _PAIRED_H */ diff --git a/gcc/config/powerpcspe/paired.md b/gcc/config/powerpcspe/paired.md new file mode 100644 index 00000000000..09123eec887 --- /dev/null +++ b/gcc/config/powerpcspe/paired.md @@ -0,0 +1,505 @@ +;; PowerPC paired single and double hummer description +;; Copyright (C) 2007-2017 Free Software Foundation, Inc. +;; Contributed by David Edelsohn and Revital Eres +;; + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program; see the file COPYING3. If not see +;; . + +(define_c_enum "unspec" + [UNSPEC_INTERHI_V2SF + UNSPEC_INTERLO_V2SF + UNSPEC_EXTEVEN_V2SF + UNSPEC_EXTODD_V2SF + ]) + +(define_insn "paired_negv2sf2" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" + "ps_neg %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "sqrtv2sf2" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (sqrt:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" + "ps_rsqrte %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "paired_absv2sf2" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" + "ps_abs %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "nabsv2sf2" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (neg:V2SF (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f"))))] + "TARGET_PAIRED_FLOAT" + "ps_nabs %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "paired_addv2sf3" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" + "ps_add %0,%1,%2" + [(set_attr "type" "fp")]) + +(define_insn "paired_subv2sf3" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" + "ps_sub %0,%1,%2" + [(set_attr "type" "fp")]) + +(define_insn "paired_mulv2sf3" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" + "ps_mul %0,%1,%2" + [(set_attr "type" "fp")]) + +(define_insn "resv2sf2" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] + "TARGET_PAIRED_FLOAT && flag_finite_math_only" + "ps_res %0,%1" + [(set_attr "type" "fp")]) + +(define_insn "paired_divv2sf3" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" + "ps_div %0,%1,%2" + [(set_attr "type" "sdiv")]) + +(define_insn "paired_madds0" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_concat:V2SF + (fma:SF + (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") + (parallel [(const_int 0)])) + (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f") + (parallel [(const_int 0)])) + (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f") + (parallel [(const_int 0)]))) + (fma:SF + (vec_select:SF (match_dup 1) + (parallel [(const_int 1)])) + (vec_select:SF (match_dup 2) + (parallel [(const_int 0)])) + (vec_select:SF (match_dup 3) + (parallel [(const_int 1)])))))] + "TARGET_PAIRED_FLOAT" + "ps_madds0 %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "paired_madds1" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_concat:V2SF + (fma:SF + (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") + (parallel [(const_int 0)])) + (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f") + (parallel [(const_int 1)])) + (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f") + (parallel [(const_int 0)]))) + (fma:SF + (vec_select:SF (match_dup 1) + (parallel [(const_int 1)])) + (vec_select:SF (match_dup 2) + (parallel [(const_int 1)])) + (vec_select:SF (match_dup 3) + (parallel [(const_int 1)])))))] + "TARGET_PAIRED_FLOAT" + "ps_madds1 %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "*paired_madd" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (fma:V2SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f") + (match_operand:V2SF 3 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" + "ps_madd %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "*paired_msub" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (fma:V2SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f") + (neg:V2SF (match_operand:V2SF 3 "gpc_reg_operand" "f"))))] + "TARGET_PAIRED_FLOAT" + "ps_msub %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "*paired_nmadd" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (neg:V2SF + (fma:V2SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f") + (match_operand:V2SF 3 "gpc_reg_operand" "f"))))] + "TARGET_PAIRED_FLOAT" + "ps_nmadd %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "*paired_nmsub" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (neg:V2SF + (fma:V2SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f") + (neg:V2SF (match_operand:V2SF 3 "gpc_reg_operand" "f")))))] + "TARGET_PAIRED_FLOAT" + "ps_nmsub %0,%1,%2,%3" + [(set_attr "type" "dmul")]) + +(define_insn "selv2sf4" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_concat:V2SF + (if_then_else:SF (ge (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") + (parallel [(const_int 0)])) + (match_operand:SF 4 "zero_fp_constant" "F")) + (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f") + (parallel [(const_int 0)])) + (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f") + (parallel [(const_int 0)]))) + (if_then_else:SF (ge (vec_select:SF (match_dup 1) + (parallel [(const_int 1)])) + (match_dup 4)) + (vec_select:SF (match_dup 2) + (parallel [(const_int 1)])) + (vec_select:SF (match_dup 3) + (parallel [(const_int 1)])))))] + + "TARGET_PAIRED_FLOAT" + "ps_sel %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "*movv2sf_paired" + [(set (match_operand:V2SF 0 "nonimmediate_operand" "=Z,f,f,Y,r,r,f") + (match_operand:V2SF 1 "input_operand" "f,Z,f,r,Y,r,W"))] + "TARGET_PAIRED_FLOAT + && (register_operand (operands[0], V2SFmode) + || register_operand (operands[1], V2SFmode))" +{ + switch (which_alternative) + { + case 0: return "psq_stx %1,%y0,0,0"; + case 1: return "psq_lx %0,%y1,0,0"; + case 2: return "ps_mr %0,%1"; + case 3: return "#"; + case 4: return "#"; + case 5: return "#"; + case 6: return "#"; + default: gcc_unreachable (); + } +} + [(set_attr "type" "fpstore,fpload,fp,*,*,*,*")]) + +(define_insn "paired_stx" + [(set (match_operand:V2SF 0 "memory_operand" "=Z") + (match_operand:V2SF 1 "gpc_reg_operand" "f"))] + "TARGET_PAIRED_FLOAT" + "psq_stx %1,%y0,0,0" + [(set_attr "type" "fpstore")]) + +(define_insn "paired_lx" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (match_operand:V2SF 1 "memory_operand" "Z"))] + "TARGET_PAIRED_FLOAT" + "psq_lx %0,%y1,0,0" + [(set_attr "type" "fpload")]) + + +(define_split + [(set (match_operand:V2SF 0 "nonimmediate_operand" "") + (match_operand:V2SF 1 "input_operand" ""))] + "TARGET_PAIRED_FLOAT && reload_completed + && gpr_or_gpr_p (operands[0], operands[1])" + [(pc)] + { + rs6000_split_multireg_move (operands[0], operands[1]); DONE; + }) + +(define_insn "paired_cmpu0" + [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") + (compare:CCFP (vec_select:SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (parallel [(const_int 0)])) + (vec_select:SF + (match_operand:V2SF 2 "gpc_reg_operand" "f") + (parallel [(const_int 0)]))))] + "TARGET_PAIRED_FLOAT" + "ps_cmpu0 %0,%1,%2" + [(set_attr "type" "fpcompare")]) + +(define_insn "paired_cmpu1" + [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") + (compare:CCFP (vec_select:SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (parallel [(const_int 1)])) + (vec_select:SF + (match_operand:V2SF 2 "gpc_reg_operand" "f") + (parallel [(const_int 1)]))))] + "TARGET_PAIRED_FLOAT" + "ps_cmpu1 %0,%1,%2" + [(set_attr "type" "fpcompare")]) + +(define_insn "paired_merge00" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_select:V2SF + (vec_concat:V4SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")) + (parallel [(const_int 0) (const_int 2)])))] + "TARGET_PAIRED_FLOAT" + "ps_merge00 %0, %1, %2" + [(set_attr "type" "fp")]) + +(define_insn "paired_merge01" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_select:V2SF + (vec_concat:V4SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")) + (parallel [(const_int 0) (const_int 3)])))] + "TARGET_PAIRED_FLOAT" + "ps_merge01 %0, %1, %2" + [(set_attr "type" "fp")]) + +(define_insn "paired_merge10" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_select:V2SF + (vec_concat:V4SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")) + (parallel [(const_int 1) (const_int 2)])))] + "TARGET_PAIRED_FLOAT" + "ps_merge10 %0, %1, %2" + [(set_attr "type" "fp")]) + +(define_insn "paired_merge11" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_select:V2SF + (vec_concat:V4SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")) + (parallel [(const_int 1) (const_int 3)])))] + "TARGET_PAIRED_FLOAT" + "ps_merge11 %0, %1, %2" + [(set_attr "type" "fp")]) + +(define_expand "vec_perm_constv2sf" + [(match_operand:V2SF 0 "gpc_reg_operand" "") + (match_operand:V2SF 1 "gpc_reg_operand" "") + (match_operand:V2SF 2 "gpc_reg_operand" "") + (match_operand:V2SI 3 "" "")] + "TARGET_PAIRED_FLOAT" +{ + if (rs6000_expand_vec_perm_const (operands)) + DONE; + else + FAIL; +}) + +(define_insn "paired_sum0" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_concat:V2SF (plus:SF (vec_select:SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (parallel [(const_int 0)])) + (vec_select:SF + (match_operand:V2SF 2 "gpc_reg_operand" "f") + (parallel [(const_int 1)]))) + (vec_select:SF + (match_operand:V2SF 3 "gpc_reg_operand" "f") + (parallel [(const_int 1)]))))] + "TARGET_PAIRED_FLOAT" + "ps_sum0 %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "paired_sum1" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_concat:V2SF (vec_select:SF + (match_operand:V2SF 2 "gpc_reg_operand" "f") + (parallel [(const_int 1)])) + (plus:SF (vec_select:SF + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (parallel [(const_int 0)])) + (vec_select:SF + (match_operand:V2SF 3 "gpc_reg_operand" "f") + (parallel [(const_int 1)])))))] + "TARGET_PAIRED_FLOAT" + "ps_sum1 %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "paired_muls0" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f") + (vec_duplicate:V2SF + (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") + (parallel [(const_int 0)])))))] + "TARGET_PAIRED_FLOAT" + "ps_muls0 %0, %1, %2" + [(set_attr "type" "fp")]) + + +(define_insn "paired_muls1" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f") + (vec_duplicate:V2SF + (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") + (parallel [(const_int 1)])))))] + "TARGET_PAIRED_FLOAT" + "ps_muls1 %0, %1, %2" + [(set_attr "type" "fp")]) + +(define_expand "vec_initv2sf" + [(match_operand:V2SF 0 "gpc_reg_operand" "=f") + (match_operand 1 "" "")] + "TARGET_PAIRED_FLOAT" +{ + paired_expand_vector_init (operands[0], operands[1]); + DONE; +}) + +(define_insn "*vconcatsf" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (vec_concat:V2SF + (match_operand:SF 1 "gpc_reg_operand" "f") + (match_operand:SF 2 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" + "ps_merge00 %0, %1, %2" + [(set_attr "type" "fp")]) + +(define_expand "sminv2sf3" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (smin:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" +{ + rtx tmp = gen_reg_rtx (V2SFmode); + + emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2])); + emit_insn (gen_selv2sf4 (operands[0], tmp, operands[2], operands[1], CONST0_RTX (SFmode))); + DONE; +}) + +(define_expand "smaxv2sf3" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (smax:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT" +{ + rtx tmp = gen_reg_rtx (V2SFmode); + + emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2])); + emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], operands[2], CONST0_RTX (SFmode))); + DONE; +}) + +(define_expand "reduc_smax_scal_v2sf" + [(match_operand:SF 0 "gpc_reg_operand" "=f") + (match_operand:V2SF 1 "gpc_reg_operand" "f")] + "TARGET_PAIRED_FLOAT" +{ + rtx tmp_swap = gen_reg_rtx (V2SFmode); + rtx tmp = gen_reg_rtx (V2SFmode); + rtx vec_res = gen_reg_rtx (V2SFmode); + rtx di_res = gen_reg_rtx (DImode); + + emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1])); + emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap)); + emit_insn (gen_selv2sf4 (vec_res, tmp, operands[1], tmp_swap, + CONST0_RTX (SFmode))); + emit_move_insn (di_res, simplify_gen_subreg (DImode, vec_res, V2SFmode, 0)); + emit_move_insn (operands[0], simplify_gen_subreg (SFmode, di_res, DImode, + BYTES_BIG_ENDIAN ? 4 : 0)); + + DONE; +}) + +(define_expand "reduc_smin_scal_v2sf" + [(match_operand:SF 0 "gpc_reg_operand" "=f") + (match_operand:V2SF 1 "gpc_reg_operand" "f")] + "TARGET_PAIRED_FLOAT" +{ + rtx tmp_swap = gen_reg_rtx (V2SFmode); + rtx tmp = gen_reg_rtx (V2SFmode); + rtx vec_res = gen_reg_rtx (V2SFmode); + rtx di_res = gen_reg_rtx (DImode); + + emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1])); + emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap)); + emit_insn (gen_selv2sf4 (vec_res, tmp, tmp_swap, operands[1], + CONST0_RTX (SFmode))); + emit_move_insn (di_res, simplify_gen_subreg (DImode, vec_res, V2SFmode, 0)); + emit_move_insn (operands[0], simplify_gen_subreg (SFmode, di_res, DImode, + BYTES_BIG_ENDIAN ? 4 : 0)); + + DONE; +}) + +(define_expand "reduc_plus_scal_v2sf" + [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + (match_operand:V2SF 1 "gpc_reg_operand" "f"))] + "TARGET_PAIRED_FLOAT" +{ + rtx vec_res = gen_reg_rtx (V2SFmode); + rtx di_res = gen_reg_rtx (DImode); + + emit_insn (gen_paired_sum1 (vec_res, operands[1], operands[1], operands[1])); + emit_move_insn (di_res, simplify_gen_subreg (DImode, vec_res, V2SFmode, 0)); + emit_move_insn (operands[0], simplify_gen_subreg (SFmode, di_res, DImode, + BYTES_BIG_ENDIAN ? 4 : 0)); + DONE; +}) + +(define_expand "movmisalignv2sf" + [(set (match_operand:V2SF 0 "nonimmediate_operand" "") + (match_operand:V2SF 1 "any_operand" ""))] + "TARGET_PAIRED_FLOAT" +{ + paired_expand_vector_move (operands); + DONE; +}) + +(define_expand "vcondv2sfv2sf" + [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") + (if_then_else:V2SF + (match_operator 3 "gpc_reg_operand" + [(match_operand:V2SF 4 "gpc_reg_operand" "f") + (match_operand:V2SF 5 "gpc_reg_operand" "f")]) + (match_operand:V2SF 1 "gpc_reg_operand" "f") + (match_operand:V2SF 2 "gpc_reg_operand" "f")))] + "TARGET_PAIRED_FLOAT && flag_unsafe_math_optimizations" +{ + if (paired_emit_vector_cond_expr (operands[0], operands[1], operands[2], + operands[3], operands[4], operands[5])) + DONE; + else + FAIL; +}) diff --git a/gcc/config/powerpcspe/power4.md b/gcc/config/powerpcspe/power4.md new file mode 100644 index 00000000000..962e1699376 --- /dev/null +++ b/gcc/config/powerpcspe/power4.md @@ -0,0 +1,451 @@ +;; Scheduling description for IBM Power4 and PowerPC 970 processors. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; Sources: IBM Red Book and White Paper on POWER4 + +;; The POWER4 has 2 iu, 2 fpu, 2 lsu per engine (2 engines per chip). +;; Instructions that update more than one register get broken into two +;; (split) or more internal ops. The chip can issue up to 5 +;; internal ops per cycle. + +(define_automaton "power4iu,power4fpu,power4vec,power4misc") + +(define_cpu_unit "iu1_power4,iu2_power4" "power4iu") +(define_cpu_unit "lsu1_power4,lsu2_power4" "power4misc") +(define_cpu_unit "fpu1_power4,fpu2_power4" "power4fpu") +(define_cpu_unit "bpu_power4,cru_power4" "power4misc") +(define_cpu_unit "vec_power4,vecperm_power4" "power4vec") +(define_cpu_unit "du1_power4,du2_power4,du3_power4,du4_power4,du5_power4" + "power4misc") + +(define_reservation "lsq_power4" + "(du1_power4,lsu1_power4)\ + |(du2_power4,lsu2_power4)\ + |(du3_power4,lsu2_power4)\ + |(du4_power4,lsu1_power4)") + +(define_reservation "lsuq_power4" + "((du1_power4+du2_power4,lsu1_power4)\ + |(du2_power4+du3_power4,lsu2_power4)\ + |(du3_power4+du4_power4,lsu2_power4))\ + +(nothing,iu2_power4|nothing,iu1_power4)") + +(define_reservation "iq_power4" + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (iu1_power4|iu2_power4)") + +(define_reservation "fpq_power4" + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (fpu1_power4|fpu2_power4)") + +(define_reservation "vq_power4" + "(du1_power4,vec_power4)\ + |(du2_power4,vec_power4)\ + |(du3_power4,vec_power4)\ + |(du4_power4,vec_power4)") + +(define_reservation "vpq_power4" + "(du1_power4,vecperm_power4)\ + |(du2_power4,vecperm_power4)\ + |(du3_power4,vecperm_power4)\ + |(du4_power4,vecperm_power4)") + + +; Dispatch slots are allocated in order conforming to program order. +(absence_set "du1_power4" "du2_power4,du3_power4,du4_power4,du5_power4") +(absence_set "du2_power4" "du3_power4,du4_power4,du5_power4") +(absence_set "du3_power4" "du4_power4,du5_power4") +(absence_set "du4_power4" "du5_power4") + + +; Load/store +(define_insn_reservation "power4-load" 4 ; 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "no") + (eq_attr "cpu" "power4")) + "lsq_power4") + +(define_insn_reservation "power4-load-ext" 5 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "no") + (eq_attr "cpu" "power4")) + "(du1_power4+du2_power4,lsu1_power4\ + |du2_power4+du3_power4,lsu2_power4\ + |du3_power4+du4_power4,lsu2_power4),\ + nothing,nothing,\ + (iu2_power4|iu1_power4)") + +(define_insn_reservation "power4-load-ext-update" 5 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4+du3_power4+du4_power4,\ + lsu1_power4+iu2_power4,nothing,nothing,iu2_power4") + +(define_insn_reservation "power4-load-ext-update-indexed" 5 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4+du3_power4+du4_power4,\ + iu1_power4,lsu2_power4+iu1_power4,nothing,nothing,iu2_power4") + +(define_insn_reservation "power4-load-update-indexed" 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4+du3_power4+du4_power4,\ + iu1_power4,lsu2_power4+iu2_power4") + +(define_insn_reservation "power4-load-update" 4 ; 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power4")) + "lsuq_power4") + +(define_insn_reservation "power4-fpload" 6 ; 5 + (and (eq_attr "type" "fpload") + (eq_attr "update" "no") + (eq_attr "cpu" "power4")) + "lsq_power4") + +(define_insn_reservation "power4-fpload-update" 6 ; 5 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (eq_attr "cpu" "power4")) + "lsuq_power4") + +(define_insn_reservation "power4-vecload" 6 ; 5 + (and (eq_attr "type" "vecload") + (eq_attr "cpu" "power4")) + "lsq_power4") + +(define_insn_reservation "power4-store" 12 + (and (eq_attr "type" "store") + (eq_attr "update" "no") + (eq_attr "cpu" "power4")) + "((du1_power4,lsu1_power4)\ + |(du2_power4,lsu2_power4)\ + |(du3_power4,lsu2_power4)\ + |(du4_power4,lsu1_power4)),\ + (iu1_power4|iu2_power4)") + +(define_insn_reservation "power4-store-update" 12 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power4")) + "((du1_power4+du2_power4,lsu1_power4)\ + |(du2_power4+du3_power4,lsu2_power4)\ + |(du3_power4+du4_power4,lsu2_power4))+\ + ((nothing,iu1_power4,iu2_power4)\ + |(nothing,iu2_power4,iu2_power4)\ + |(nothing,iu2_power4,iu1_power4))") + +(define_insn_reservation "power4-store-update-indexed" 12 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4+du3_power4+du4_power4,\ + iu1_power4,lsu2_power4+iu2_power4,iu2_power4") + +(define_insn_reservation "power4-fpstore" 12 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "no") + (eq_attr "cpu" "power4")) + "((du1_power4,lsu1_power4)\ + |(du2_power4,lsu2_power4)\ + |(du3_power4,lsu2_power4)\ + |(du4_power4,lsu1_power4)),\ + (fpu1_power4|fpu2_power4)") + +(define_insn_reservation "power4-fpstore-update" 12 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "yes") + (eq_attr "cpu" "power4")) + "((du1_power4+du2_power4,lsu1_power4)\ + |(du2_power4+du3_power4,lsu2_power4)\ + |(du3_power4+du4_power4,lsu2_power4))\ + +(nothing,(iu1_power4|iu2_power4),(fpu1_power4|fpu2_power4))") + +(define_insn_reservation "power4-vecstore" 12 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "power4")) + "(du1_power4,lsu1_power4,vec_power4)\ + |(du2_power4,lsu2_power4,vec_power4)\ + |(du3_power4,lsu2_power4,vec_power4)\ + |(du4_power4,lsu1_power4,vec_power4)") + +(define_insn_reservation "power4-llsc" 11 + (and (eq_attr "type" "load_l,store_c,sync") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4+du3_power4+du4_power4,lsu1_power4") + + +; Integer latency is 2 cycles +(define_insn_reservation "power4-integer" 2 + (and (ior (eq_attr "type" "integer,trap,cntlz,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no")) + (and (eq_attr "type" "insert") + (eq_attr "size" "64"))) + (eq_attr "cpu" "power4")) + "iq_power4") + +(define_insn_reservation "power4-two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "power4")) + "((du1_power4+du2_power4)\ + |(du2_power4+du3_power4)\ + |(du3_power4+du4_power4)\ + |(du4_power4+du1_power4)),\ + ((iu1_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu1_power4)\ + |(iu1_power4,nothing,iu1_power4))") + +(define_insn_reservation "power4-three" 2 + (and (eq_attr "type" "three") + (eq_attr "cpu" "power4")) + "(du1_power4+du2_power4+du3_power4|du2_power4+du3_power4+du4_power4\ + |du3_power4+du4_power4+du1_power4|du4_power4+du1_power4+du2_power4),\ + ((iu1_power4,nothing,iu2_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu2_power4,nothing,iu1_power4)\ + |(iu2_power4,nothing,iu1_power4,nothing,iu1_power4)\ + |(iu1_power4,nothing,iu1_power4,nothing,iu2_power4))") + +(define_insn_reservation "power4-insert" 4 + (and (eq_attr "type" "insert") + (eq_attr "size" "32") + (eq_attr "cpu" "power4")) + "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ + ((iu1_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu2_power4)\ + |(iu2_power4,nothing,iu1_power4))") + +(define_insn_reservation "power4-cmp" 3 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "power4")) + "iq_power4") + +(define_insn_reservation "power4-compare" 2 + (and (eq_attr "type" "shift,exts") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power4")) + "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ + ((iu1_power4,iu2_power4)\ + |(iu2_power4,iu2_power4)\ + |(iu2_power4,iu1_power4))") + +(define_bypass 4 "power4-compare" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") + +(define_insn_reservation "power4-lmul-cmp" 7 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "size" "64") + (eq_attr "cpu" "power4")) + "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ + ((iu1_power4*6,iu2_power4)\ + |(iu2_power4*6,iu2_power4)\ + |(iu2_power4*6,iu1_power4))") + +(define_bypass 10 "power4-lmul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") + +(define_insn_reservation "power4-imul-cmp" 5 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "size" "32") + (eq_attr "cpu" "power4")) + "(du1_power4+du2_power4|du2_power4+du3_power4|du3_power4+du4_power4),\ + ((iu1_power4*4,iu2_power4)\ + |(iu2_power4*4,iu2_power4)\ + |(iu2_power4*4,iu1_power4))") + +(define_bypass 8 "power4-imul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") + +(define_insn_reservation "power4-lmul" 7 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "64") + (eq_attr "cpu" "power4")) + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (iu1_power4*6|iu2_power4*6)") + +(define_insn_reservation "power4-imul" 5 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "32") + (eq_attr "cpu" "power4")) + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (iu1_power4*4|iu2_power4*4)") + +(define_insn_reservation "power4-imul3" 4 + (and (eq_attr "type" "mul") + (eq_attr "size" "8,16") + (eq_attr "cpu" "power4")) + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (iu1_power4*3|iu2_power4*3)") + + +; SPR move only executes in first IU. +; Integer division only executes in second IU. +(define_insn_reservation "power4-idiv" 36 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4,iu2_power4*35") + +(define_insn_reservation "power4-ldiv" 68 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4,iu2_power4*67") + + +(define_insn_reservation "power4-mtjmpr" 3 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "power4")) + "du1_power4,bpu_power4") + + +; Branches take dispatch Slot 4. The presence_sets prevent other insn from +; grabbing previous dispatch slots once this is assigned. +(define_insn_reservation "power4-branch" 2 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "power4")) + "(du5_power4\ + |du4_power4+du5_power4\ + |du3_power4+du4_power4+du5_power4\ + |du2_power4+du3_power4+du4_power4+du5_power4\ + |du1_power4+du2_power4+du3_power4+du4_power4+du5_power4),bpu_power4") + + +; Condition Register logical ops are split if non-destructive (RT != RB) +(define_insn_reservation "power4-crlogical" 2 + (and (eq_attr "type" "cr_logical") + (eq_attr "cpu" "power4")) + "du1_power4,cru_power4") + +(define_insn_reservation "power4-delayedcr" 4 + (and (eq_attr "type" "delayed_cr") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4,cru_power4,cru_power4") + +; 4 mfcrf (each 3 cyc, 1/cyc) + 3 fxu +(define_insn_reservation "power4-mfcr" 6 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4+du3_power4+du4_power4,\ + du1_power4+du2_power4+du3_power4+du4_power4+cru_power4,\ + cru_power4,cru_power4,cru_power4") + +; mfcrf (1 field) +(define_insn_reservation "power4-mfcrf" 3 + (and (eq_attr "type" "mfcrf") + (eq_attr "cpu" "power4")) + "du1_power4,cru_power4") + +; mtcrf (1 field) +(define_insn_reservation "power4-mtcr" 4 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "power4")) + "du1_power4,iu1_power4") + +; Basic FP latency is 6 cycles +(define_insn_reservation "power4-fp" 6 + (and (eq_attr "type" "fp,fpsimple,dmul") + (eq_attr "cpu" "power4")) + "fpq_power4") + +(define_insn_reservation "power4-fpcompare" 5 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "power4")) + "fpq_power4") + +(define_insn_reservation "power4-sdiv" 33 + (and (eq_attr "type" "sdiv,ddiv") + (eq_attr "cpu" "power4")) + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (fpu1_power4*28|fpu2_power4*28)") + +(define_insn_reservation "power4-sqrt" 40 + (and (eq_attr "type" "ssqrt,dsqrt") + (eq_attr "cpu" "power4")) + "(du1_power4|du2_power4|du3_power4|du4_power4),\ + (fpu1_power4*35|fpu2_power4*35)") + +(define_insn_reservation "power4-isync" 2 + (and (eq_attr "type" "isync") + (eq_attr "cpu" "power4")) + "du1_power4+du2_power4+du3_power4+du4_power4,lsu1_power4") + + +; VMX +(define_insn_reservation "power4-vecsimple" 2 + (and (eq_attr "type" "vecsimple,veclogical,vecmove") + (eq_attr "cpu" "power4")) + "vq_power4") + +(define_insn_reservation "power4-veccomplex" 5 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "power4")) + "vq_power4") + +; vecfp compare +(define_insn_reservation "power4-veccmp" 8 + (and (eq_attr "type" "veccmp,veccmpfx") + (eq_attr "cpu" "power4")) + "vq_power4") + +(define_insn_reservation "power4-vecfloat" 8 + (and (eq_attr "type" "vecfloat") + (eq_attr "cpu" "power4")) + "vq_power4") + +(define_insn_reservation "power4-vecperm" 2 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "power4")) + "vpq_power4") + +(define_bypass 4 "power4-vecload" "power4-vecperm") + +(define_bypass 3 "power4-vecsimple" "power4-vecperm") +(define_bypass 6 "power4-veccomplex" "power4-vecperm") +(define_bypass 3 "power4-vecperm" + "power4-vecsimple,power4-veccomplex,power4-vecfloat") +(define_bypass 9 "power4-vecfloat" "power4-vecperm") + +(define_bypass 5 "power4-vecsimple,power4-veccomplex" + "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf") + +(define_bypass 4 "power4-vecsimple,power4-vecperm" "power4-vecstore") +(define_bypass 7 "power4-veccomplex" "power4-vecstore") +(define_bypass 10 "power4-vecfloat" "power4-vecstore") diff --git a/gcc/config/powerpcspe/power5.md b/gcc/config/powerpcspe/power5.md new file mode 100644 index 00000000000..6c3ed7fe581 --- /dev/null +++ b/gcc/config/powerpcspe/power5.md @@ -0,0 +1,351 @@ +;; Scheduling description for IBM POWER5 processor. +;; Copyright (C) 2003-2017 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; Sources: IBM Red Book and White Paper on POWER5 + +;; The POWER5 has 2 iu, 2 fpu, 2 lsu per engine (2 engines per chip). +;; Instructions that update more than one register get broken into two +;; (split) or more internal ops. The chip can issue up to 5 +;; internal ops per cycle. + +(define_automaton "power5iu,power5fpu,power5misc") + +(define_cpu_unit "iu1_power5,iu2_power5" "power5iu") +(define_cpu_unit "lsu1_power5,lsu2_power5" "power5misc") +(define_cpu_unit "fpu1_power5,fpu2_power5" "power5fpu") +(define_cpu_unit "bpu_power5,cru_power5" "power5misc") +(define_cpu_unit "du1_power5,du2_power5,du3_power5,du4_power5,du5_power5" + "power5misc") + +(define_reservation "lsq_power5" + "(du1_power5,lsu1_power5)\ + |(du2_power5,lsu2_power5)\ + |(du3_power5,lsu2_power5)\ + |(du4_power5,lsu1_power5)") + +(define_reservation "iq_power5" + "(du1_power5|du2_power5|du3_power5|du4_power5),\ + (iu1_power5|iu2_power5)") + +(define_reservation "fpq_power5" + "(du1_power5|du2_power5|du3_power5|du4_power5),\ + (fpu1_power5|fpu2_power5)") + +; Dispatch slots are allocated in order conforming to program order. +(absence_set "du1_power5" "du2_power5,du3_power5,du4_power5,du5_power5") +(absence_set "du2_power5" "du3_power5,du4_power5,du5_power5") +(absence_set "du3_power5" "du4_power5,du5_power5") +(absence_set "du4_power5" "du5_power5") + + +; Load/store +(define_insn_reservation "power5-load" 4 ; 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "no") + (eq_attr "cpu" "power5")) + "lsq_power5") + +(define_insn_reservation "power5-load-ext" 5 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "no") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,lsu1_power5,nothing,nothing,iu2_power5") + +(define_insn_reservation "power5-load-ext-update" 5 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5+du3_power5+du4_power5,\ + lsu1_power5+iu2_power5,nothing,nothing,iu2_power5") + +(define_insn_reservation "power5-load-ext-update-indexed" 5 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5+du3_power5+du4_power5,\ + iu1_power5,lsu2_power5+iu1_power5,nothing,nothing,iu2_power5") + +(define_insn_reservation "power5-load-update-indexed" 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5+du3_power5+du4_power5,\ + iu1_power5,lsu2_power5+iu2_power5") + +(define_insn_reservation "power5-load-update" 4 ; 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,lsu1_power5+iu2_power5") + +(define_insn_reservation "power5-fpload" 6 ; 5 + (and (eq_attr "type" "fpload") + (eq_attr "update" "no") + (eq_attr "cpu" "power5")) + "lsq_power5") + +(define_insn_reservation "power5-fpload-update" 6 ; 5 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,lsu1_power5+iu2_power5") + +(define_insn_reservation "power5-store" 12 + (and (eq_attr "type" "store") + (eq_attr "update" "no") + (eq_attr "cpu" "power5")) + "((du1_power5,lsu1_power5)\ + |(du2_power5,lsu2_power5)\ + |(du3_power5,lsu2_power5)\ + |(du4_power5,lsu1_power5)),\ + (iu1_power5|iu2_power5)") + +(define_insn_reservation "power5-store-update" 12 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,lsu1_power5+iu2_power5,iu1_power5") + +(define_insn_reservation "power5-store-update-indexed" 12 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5+du3_power5+du4_power5,\ + iu1_power5,lsu2_power5+iu2_power5,iu2_power5") + +(define_insn_reservation "power5-fpstore" 12 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "no") + (eq_attr "cpu" "power5")) + "((du1_power5,lsu1_power5)\ + |(du2_power5,lsu2_power5)\ + |(du3_power5,lsu2_power5)\ + |(du4_power5,lsu1_power5)),\ + (fpu1_power5|fpu2_power5)") + +(define_insn_reservation "power5-fpstore-update" 12 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "yes") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,lsu1_power5+iu2_power5,fpu1_power5") + +(define_insn_reservation "power5-llsc" 11 + (and (eq_attr "type" "load_l,store_c,sync") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5+du3_power5+du4_power5,\ + lsu1_power5") + + +; Integer latency is 2 cycles +(define_insn_reservation "power5-integer" 2 + (and (ior (eq_attr "type" "integer,trap,cntlz,isel,popcnt") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no")) + (and (eq_attr "type" "insert") + (eq_attr "size" "64"))) + (eq_attr "cpu" "power5")) + "iq_power5") + +(define_insn_reservation "power5-two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "power5")) + "((du1_power5+du2_power5)\ + |(du2_power5+du3_power5)\ + |(du3_power5+du4_power5)\ + |(du4_power5+du1_power5)),\ + ((iu1_power5,nothing,iu2_power5)\ + |(iu2_power5,nothing,iu2_power5)\ + |(iu2_power5,nothing,iu1_power5)\ + |(iu1_power5,nothing,iu1_power5))") + +(define_insn_reservation "power5-three" 2 + (and (eq_attr "type" "three") + (eq_attr "cpu" "power5")) + "(du1_power5+du2_power5+du3_power5|du2_power5+du3_power5+du4_power5\ + |du3_power5+du4_power5+du1_power5|du4_power5+du1_power5+du2_power5),\ + ((iu1_power5,nothing,iu2_power5,nothing,iu2_power5)\ + |(iu2_power5,nothing,iu2_power5,nothing,iu1_power5)\ + |(iu2_power5,nothing,iu1_power5,nothing,iu1_power5)\ + |(iu1_power5,nothing,iu2_power5,nothing,iu2_power5))") + +(define_insn_reservation "power5-insert" 4 + (and (eq_attr "type" "insert") + (eq_attr "size" "32") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,iu1_power5,nothing,iu2_power5") + +(define_insn_reservation "power5-cmp" 3 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "power5")) + "iq_power5") + +(define_insn_reservation "power5-compare" 2 + (and (eq_attr "type" "shift,exts") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,iu1_power5,iu2_power5") + +(define_bypass 4 "power5-compare" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf") + +(define_insn_reservation "power5-lmul-cmp" 7 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "size" "64") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,iu1_power5*6,iu2_power5") + +(define_bypass 10 "power5-lmul-cmp" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf") + +(define_insn_reservation "power5-imul-cmp" 5 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "size" "32") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,iu1_power5*4,iu2_power5") + +(define_bypass 8 "power5-imul-cmp" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf") + +(define_insn_reservation "power5-lmul" 7 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "64") + (eq_attr "cpu" "power5")) + "(du1_power5|du2_power5|du3_power5|du4_power5),(iu1_power5*6|iu2_power5*6)") + +(define_insn_reservation "power5-imul" 5 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "32") + (eq_attr "cpu" "power5")) + "(du1_power5|du2_power5|du3_power5|du4_power5),(iu1_power5*4|iu2_power5*4)") + +(define_insn_reservation "power5-imul3" 4 + (and (eq_attr "type" "mul") + (eq_attr "size" "8,16") + (eq_attr "cpu" "power5")) + "(du1_power5|du2_power5|du3_power5|du4_power5),(iu1_power5*3|iu2_power5*3)") + + +; SPR move only executes in first IU. +; Integer division only executes in second IU. +(define_insn_reservation "power5-idiv" 36 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,iu2_power5*35") + +(define_insn_reservation "power5-ldiv" 68 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,iu2_power5*67") + + +(define_insn_reservation "power5-mtjmpr" 3 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "power5")) + "du1_power5,bpu_power5") + + +; Branches take dispatch Slot 4. The presence_sets prevent other insn from +; grabbing previous dispatch slots once this is assigned. +(define_insn_reservation "power5-branch" 2 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "power5")) + "(du5_power5\ + |du4_power5+du5_power5\ + |du3_power5+du4_power5+du5_power5\ + |du2_power5+du3_power5+du4_power5+du5_power5\ + |du1_power5+du2_power5+du3_power5+du4_power5+du5_power5),bpu_power5") + + +; Condition Register logical ops are split if non-destructive (RT != RB) +(define_insn_reservation "power5-crlogical" 2 + (and (eq_attr "type" "cr_logical") + (eq_attr "cpu" "power5")) + "du1_power5,cru_power5") + +(define_insn_reservation "power5-delayedcr" 4 + (and (eq_attr "type" "delayed_cr") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5,cru_power5,cru_power5") + +; 4 mfcrf (each 3 cyc, 1/cyc) + 3 fxu +(define_insn_reservation "power5-mfcr" 6 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5+du3_power5+du4_power5,\ + du1_power5+du2_power5+du3_power5+du4_power5+cru_power5,\ + cru_power5,cru_power5,cru_power5") + +; mfcrf (1 field) +(define_insn_reservation "power5-mfcrf" 3 + (and (eq_attr "type" "mfcrf") + (eq_attr "cpu" "power5")) + "du1_power5,cru_power5") + +; mtcrf (1 field) +(define_insn_reservation "power5-mtcr" 4 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "power5")) + "du1_power5,iu1_power5") + +; Basic FP latency is 6 cycles +(define_insn_reservation "power5-fp" 6 + (and (eq_attr "type" "fp,fpsimple,dmul") + (eq_attr "cpu" "power5")) + "fpq_power5") + +(define_insn_reservation "power5-fpcompare" 5 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "power5")) + "fpq_power5") + +(define_insn_reservation "power5-sdiv" 33 + (and (eq_attr "type" "sdiv,ddiv") + (eq_attr "cpu" "power5")) + "(du1_power5|du2_power5|du3_power5|du4_power5),\ + (fpu1_power5*28|fpu2_power5*28)") + +(define_insn_reservation "power5-sqrt" 40 + (and (eq_attr "type" "ssqrt,dsqrt") + (eq_attr "cpu" "power5")) + "(du1_power5|du2_power5|du3_power5|du4_power5),\ + (fpu1_power5*35|fpu2_power5*35)") + +(define_insn_reservation "power5-isync" 2 + (and (eq_attr "type" "isync") + (eq_attr "cpu" "power5")) + "du1_power5+du2_power5+du3_power5+du4_power5,\ + lsu1_power5") + diff --git a/gcc/config/powerpcspe/power6.md b/gcc/config/powerpcspe/power6.md new file mode 100644 index 00000000000..0d81cdebda5 --- /dev/null +++ b/gcc/config/powerpcspe/power6.md @@ -0,0 +1,629 @@ +;; Scheduling description for IBM POWER6 processor. +;; Copyright (C) 2006-2017 Free Software Foundation, Inc. +;; Contributed by Peter Steinmetz (steinmtz@us.ibm.com) +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +;; Sources: + +;; The POWER6 has 2 iu, 2 fpu, 2 lsu, and 1 bu/cru unit per engine +;; (2 engines per chip). The chip can issue up to 5 internal ops +;; per cycle. + +(define_automaton "power6iu,power6lsu,power6fpu,power6bu") + +(define_cpu_unit "iu1_power6,iu2_power6" "power6iu") +(define_cpu_unit "lsu1_power6,lsu2_power6" "power6lsu") +(define_cpu_unit "bpu_power6" "power6bu") +(define_cpu_unit "fpu1_power6,fpu2_power6" "power6fpu") + +(define_reservation "LS2_power6" + "lsu1_power6+lsu2_power6") + +(define_reservation "FPU_power6" + "fpu1_power6|fpu2_power6") + +(define_reservation "BRU_power6" + "bpu_power6") + +(define_reservation "LSU_power6" + "lsu1_power6|lsu2_power6") + +(define_reservation "LSF_power6" + "(lsu1_power6+fpu1_power6)\ + |(lsu1_power6+fpu2_power6)\ + |(lsu2_power6+fpu1_power6)\ + |(lsu2_power6+fpu2_power6)") + +(define_reservation "LX2_power6" + "(iu1_power6+iu2_power6+lsu1_power6)\ + |(iu1_power6+iu2_power6+lsu2_power6)") + +(define_reservation "FX2_power6" + "iu1_power6+iu2_power6") + +(define_reservation "X2F_power6" + "(iu1_power6+iu2_power6+fpu1_power6)\ + |(iu1_power6+iu2_power6+fpu2_power6)") + +(define_reservation "BX2_power6" + "iu1_power6+iu2_power6+bpu_power6") + +(define_reservation "LSX_power6" + "(iu1_power6+lsu1_power6)\ + |(iu1_power6+lsu2_power6)\ + |(iu2_power6+lsu1_power6)\ + |(iu2_power6+lsu2_power6)") + +(define_reservation "FXU_power6" + "iu1_power6|iu2_power6") + +(define_reservation "XLF_power6" + "(iu1_power6+lsu1_power6+fpu1_power6)\ + |(iu1_power6+lsu1_power6+fpu2_power6)\ + |(iu1_power6+lsu2_power6+fpu1_power6)\ + |(iu1_power6+lsu2_power6+fpu2_power6)\ + |(iu2_power6+lsu1_power6+fpu1_power6)\ + |(iu2_power6+lsu1_power6+fpu2_power6)\ + |(iu2_power6+lsu2_power6+fpu1_power6)\ + |(iu2_power6+lsu2_power6+fpu2_power6)") + +(define_reservation "BRX_power6" + "(bpu_power6+iu1_power6)\ + |(bpu_power6+iu2_power6)") + +; Load/store + +; The default for a value written by a fixed point load +; that is read/written by a subsequent fixed point op. +(define_insn_reservation "power6-load" 2 ; fx + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "no") + (eq_attr "cpu" "power6")) + "LSU_power6") + +; define the bypass for the case where the value written +; by a fixed point load is used as the source value on +; a store. +(define_bypass 1 "power6-load,\ + power6-load-update,\ + power6-load-update-indexed" + "power6-store,\ + power6-store-update,\ + power6-store-update-indexed,\ + power6-fpstore,\ + power6-fpstore-update" + "rs6000_store_data_bypass_p") + +(define_insn_reservation "power6-load-ext" 4 ; fx + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "no") + (eq_attr "cpu" "power6")) + "LSU_power6") + +; define the bypass for the case where the value written +; by a fixed point load ext is used as the source value on +; a store. +(define_bypass 1 "power6-load-ext,\ + power6-load-ext-update,\ + power6-load-ext-update-indexed" + "power6-store,\ + power6-store-update,\ + power6-store-update-indexed,\ + power6-fpstore,\ + power6-fpstore-update" + "rs6000_store_data_bypass_p") + +(define_insn_reservation "power6-load-update" 2 ; fx + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power6")) + "LSX_power6") + +(define_insn_reservation "power6-load-update-indexed" 2 ; fx + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power6")) + "LSX_power6") + +(define_insn_reservation "power6-load-ext-update" 4 ; fx + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power6")) + "LSX_power6") + +(define_insn_reservation "power6-load-ext-update-indexed" 4 ; fx + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power6")) + "LSX_power6") + +(define_insn_reservation "power6-fpload" 1 + (and (eq_attr "type" "fpload") + (eq_attr "update" "no") + (eq_attr "cpu" "power6")) + "LSU_power6") + +(define_insn_reservation "power6-fpload-update" 1 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (eq_attr "cpu" "power6")) + "LSX_power6") + +(define_insn_reservation "power6-store" 14 + (and (eq_attr "type" "store") + (eq_attr "update" "no") + (eq_attr "cpu" "power6")) + "LSU_power6") + +(define_insn_reservation "power6-store-update" 14 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power6")) + "LSX_power6") + +(define_insn_reservation "power6-store-update-indexed" 14 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power6")) + "LX2_power6") + +(define_insn_reservation "power6-fpstore" 14 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "no") + (eq_attr "cpu" "power6")) + "LSF_power6") + +(define_insn_reservation "power6-fpstore-update" 14 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "yes") + (eq_attr "cpu" "power6")) + "XLF_power6") + +(define_insn_reservation "power6-larx" 3 + (and (eq_attr "type" "load_l") + (eq_attr "cpu" "power6")) + "LS2_power6") + +(define_insn_reservation "power6-stcx" 10 ; best case + (and (eq_attr "type" "store_c") + (eq_attr "cpu" "power6")) + "LSX_power6") + +(define_insn_reservation "power6-sync" 11 ; N/A + (and (eq_attr "type" "sync") + (eq_attr "cpu" "power6")) + "LSU_power6") + +(define_insn_reservation "power6-integer" 1 + (and (ior (eq_attr "type" "integer") + (and (eq_attr "type" "add,logical") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-isel" 1 + (and (eq_attr "type" "isel") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-exts" 1 + (and (eq_attr "type" "exts") + (eq_attr "dot" "no") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-shift" 1 + (and (eq_attr "type" "shift") + (eq_attr "var_shift" "no") + (eq_attr "dot" "no") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-popcnt" 1 + (and (eq_attr "type" "popcnt") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-insert" 1 + (and (eq_attr "type" "insert") + (eq_attr "size" "32") + (eq_attr "cpu" "power6")) + "FX2_power6") + +(define_insn_reservation "power6-insert-dword" 1 + (and (eq_attr "type" "insert") + (eq_attr "size" "64") + (eq_attr "cpu" "power6")) + "FX2_power6") + +; define the bypass for the case where the value written +; by a fixed point op is used as the source value on a +; store. +(define_bypass 1 "power6-integer,\ + power6-exts,\ + power6-shift,\ + power6-insert,\ + power6-insert-dword" + "power6-store,\ + power6-store-update,\ + power6-store-update-indexed,\ + power6-fpstore,\ + power6-fpstore-update" + "rs6000_store_data_bypass_p") + +(define_insn_reservation "power6-cntlz" 2 + (and (eq_attr "type" "cntlz") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_bypass 1 "power6-cntlz" + "power6-store,\ + power6-store-update,\ + power6-store-update-indexed,\ + power6-fpstore,\ + power6-fpstore-update" + "rs6000_store_data_bypass_p") + +(define_insn_reservation "power6-var-rotate" 4 + (and (eq_attr "type" "shift") + (eq_attr "var_shift" "yes") + (eq_attr "dot" "no") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-trap" 1 ; N/A + (and (eq_attr "type" "trap") + (eq_attr "cpu" "power6")) + "BRX_power6") + +(define_insn_reservation "power6-two" 1 + (and (eq_attr "type" "two") + (eq_attr "cpu" "power6")) + "(iu1_power6,iu1_power6)\ + |(iu1_power6+iu2_power6,nothing)\ + |(iu1_power6,iu2_power6)\ + |(iu2_power6,iu1_power6)\ + |(iu2_power6,iu2_power6)") + +(define_insn_reservation "power6-three" 1 + (and (eq_attr "type" "three") + (eq_attr "cpu" "power6")) + "(iu1_power6,iu1_power6,iu1_power6)\ + |(iu1_power6,iu1_power6,iu2_power6)\ + |(iu1_power6,iu2_power6,iu1_power6)\ + |(iu1_power6,iu2_power6,iu2_power6)\ + |(iu2_power6,iu1_power6,iu1_power6)\ + |(iu2_power6,iu1_power6,iu2_power6)\ + |(iu2_power6,iu2_power6,iu1_power6)\ + |(iu2_power6,iu2_power6,iu2_power6)\ + |(iu1_power6+iu2_power6,iu1_power6)\ + |(iu1_power6+iu2_power6,iu2_power6)\ + |(iu1_power6,iu1_power6+iu2_power6)\ + |(iu2_power6,iu1_power6+iu2_power6)") + +(define_insn_reservation "power6-cmp" 1 + (and (eq_attr "type" "cmp") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-compare" 1 + (and (eq_attr "type" "exts") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-fast-compare" 1 + (and (eq_attr "type" "add,logical") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power6")) + "FXU_power6") + +; define the bypass for the case where the value written +; by a fixed point rec form op is used as the source value +; on a store. +(define_bypass 1 "power6-compare,\ + power6-fast-compare" + "power6-store,\ + power6-store-update,\ + power6-store-update-indexed,\ + power6-fpstore,\ + power6-fpstore-update" + "rs6000_store_data_bypass_p") + +(define_insn_reservation "power6-delayed-compare" 2 ; N/A + (and (eq_attr "type" "shift") + (eq_attr "var_shift" "no") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-var-delayed-compare" 4 + (and (eq_attr "type" "shift") + (eq_attr "var_shift" "yes") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-lmul-cmp" 16 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "size" "64") + (eq_attr "cpu" "power6")) + "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ + |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); + +(define_insn_reservation "power6-imul-cmp" 16 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "size" "32") + (eq_attr "cpu" "power6")) + "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ + |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); + +(define_insn_reservation "power6-lmul" 16 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "64") + (eq_attr "cpu" "power6")) + "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ + |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); + +(define_insn_reservation "power6-imul" 16 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "size" "32") + (eq_attr "cpu" "power6")) + "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ + |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); + +(define_insn_reservation "power6-imul3" 16 + (and (eq_attr "type" "mul") + (eq_attr "size" "8,16") + (eq_attr "cpu" "power6")) + "(iu1_power6*16+iu2_power6*16+fpu1_power6*16)\ + |(iu1_power6*16+iu2_power6*16+fpu2_power6*16)"); + +(define_bypass 9 "power6-imul,\ + power6-lmul,\ + power6-imul-cmp,\ + power6-lmul-cmp,\ + power6-imul3" + "power6-store,\ + power6-store-update,\ + power6-store-update-indexed,\ + power6-fpstore,\ + power6-fpstore-update" + "rs6000_store_data_bypass_p") + +(define_insn_reservation "power6-idiv" 44 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "power6")) + "(iu1_power6*44+iu2_power6*44+fpu1_power6*44)\ + |(iu1_power6*44+iu2_power6*44+fpu2_power6*44)"); + +; The latency for this bypass is yet to be defined +;(define_bypass ? "power6-idiv" +; "power6-store,\ +; power6-store-update,\ +; power6-store-update-indexed,\ +; power6-fpstore,\ +; power6-fpstore-update" +; "rs6000_store_data_bypass_p") + +(define_insn_reservation "power6-ldiv" 56 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "power6")) + "(iu1_power6*56+iu2_power6*56+fpu1_power6*56)\ + |(iu1_power6*56+iu2_power6*56+fpu2_power6*56)"); + +; The latency for this bypass is yet to be defined +;(define_bypass ? "power6-ldiv" +; "power6-store,\ +; power6-store-update,\ +; power6-store-update-indexed,\ +; power6-fpstore,\ +; power6-fpstore-update" +; "rs6000_store_data_bypass_p") + +(define_insn_reservation "power6-mtjmpr" 2 + (and (eq_attr "type" "mtjmpr,mfjmpr") + (eq_attr "cpu" "power6")) + "BX2_power6") + +(define_bypass 5 "power6-mtjmpr" "power6-branch") + +(define_insn_reservation "power6-branch" 2 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "power6")) + "BRU_power6") + +(define_bypass 5 "power6-branch" "power6-mtjmpr") + +(define_insn_reservation "power6-crlogical" 3 + (and (eq_attr "type" "cr_logical") + (eq_attr "cpu" "power6")) + "BRU_power6") + +(define_bypass 3 "power6-crlogical" "power6-branch") + +(define_insn_reservation "power6-delayedcr" 3 + (and (eq_attr "type" "delayed_cr") + (eq_attr "cpu" "power6")) + "BRU_power6") + +(define_insn_reservation "power6-mfcr" 6 ; N/A + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "power6")) + "BX2_power6") + +; mfcrf (1 field) +(define_insn_reservation "power6-mfcrf" 3 ; N/A + (and (eq_attr "type" "mfcrf") + (eq_attr "cpu" "power6")) + "BX2_power6") ; + +; mtcrf (1 field) +(define_insn_reservation "power6-mtcr" 4 ; N/A + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "power6")) + "BX2_power6") + +(define_bypass 9 "power6-mtcr" "power6-branch") + +(define_insn_reservation "power6-fp" 6 + (and (eq_attr "type" "fp,fpsimple,dmul,dfp") + (eq_attr "cpu" "power6")) + "FPU_power6") + +; Any fp instruction that updates a CR has a latency +; of 6 to a dependent branch +(define_bypass 6 "power6-fp" "power6-branch") + +(define_bypass 1 "power6-fp" + "power6-fpstore,power6-fpstore-update" + "rs6000_store_data_bypass_p") + +(define_insn_reservation "power6-fpcompare" 8 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_bypass 12 "power6-fpcompare" + "power6-branch,power6-crlogical") + +(define_insn_reservation "power6-sdiv" 26 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_insn_reservation "power6-ddiv" 32 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_insn_reservation "power6-sqrt" 30 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_insn_reservation "power6-dsqrt" 42 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_insn_reservation "power6-isync" 2 ; N/A + (and (eq_attr "type" "isync") + (eq_attr "cpu" "power6")) + "FXU_power6") + +(define_insn_reservation "power6-vecload" 1 + (and (eq_attr "type" "vecload") + (eq_attr "cpu" "power6")) + "LSU_power6") + +(define_insn_reservation "power6-vecstore" 1 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "power6")) + "LSF_power6") + +(define_insn_reservation "power6-vecsimple" 3 + (and (eq_attr "type" "vecsimple,veclogical,vecmove") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_bypass 6 "power6-vecsimple" "power6-veccomplex,\ + power6-vecperm") + +(define_bypass 5 "power6-vecsimple" "power6-vecfloat") + +(define_bypass 4 "power6-vecsimple" "power6-vecstore" ) + +(define_insn_reservation "power6-veccmp" 1 + (and (eq_attr "type" "veccmp,veccmpfx") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_bypass 10 "power6-veccmp" "power6-branch") + +(define_insn_reservation "power6-vecfloat" 7 + (and (eq_attr "type" "vecfloat") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_bypass 10 "power6-vecfloat" "power6-vecsimple") + +(define_bypass 11 "power6-vecfloat" "power6-veccomplex,\ + power6-vecperm") + +(define_bypass 9 "power6-vecfloat" "power6-vecstore" ) + +(define_insn_reservation "power6-veccomplex" 7 + (and (eq_attr "type" "vecsimple") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_bypass 10 "power6-veccomplex" "power6-vecsimple,\ + power6-vecfloat" ) + +(define_bypass 9 "power6-veccomplex" "power6-vecperm" ) + +(define_bypass 8 "power6-veccomplex" "power6-vecstore" ) + +(define_insn_reservation "power6-vecperm" 4 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "power6")) + "FPU_power6") + +(define_bypass 7 "power6-vecperm" "power6-vecsimple,\ + power6-vecfloat" ) + +(define_bypass 6 "power6-vecperm" "power6-veccomplex" ) + +(define_bypass 5 "power6-vecperm" "power6-vecstore" ) + +(define_insn_reservation "power6-mftgpr" 8 + (and (eq_attr "type" "mftgpr") + (eq_attr "cpu" "power6")) + "X2F_power6") + +(define_insn_reservation "power6-mffgpr" 14 + (and (eq_attr "type" "mffgpr") + (eq_attr "cpu" "power6")) + "LX2_power6") + +(define_bypass 4 "power6-mftgpr" "power6-imul,\ + power6-lmul,\ + power6-imul-cmp,\ + power6-lmul-cmp,\ + power6-imul3,\ + power6-idiv,\ + power6-ldiv" ) diff --git a/gcc/config/powerpcspe/power7.md b/gcc/config/powerpcspe/power7.md new file mode 100644 index 00000000000..723a7950bb3 --- /dev/null +++ b/gcc/config/powerpcspe/power7.md @@ -0,0 +1,366 @@ +;; Scheduling description for IBM POWER7 processor. +;; Copyright (C) 2009-2017 Free Software Foundation, Inc. +;; +;; Contributed by Pat Haugen (pthaugen@us.ibm.com). + +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "power7iu,power7lsu,power7vsu,power7misc") + +(define_cpu_unit "iu1_power7,iu2_power7" "power7iu") +(define_cpu_unit "lsu1_power7,lsu2_power7" "power7lsu") +(define_cpu_unit "vsu1_power7,vsu2_power7" "power7vsu") +(define_cpu_unit "bpu_power7,cru_power7" "power7misc") +(define_cpu_unit "du1_power7,du2_power7,du3_power7,du4_power7,du5_power7" + "power7misc") + + +(define_reservation "DU_power7" + "du1_power7|du2_power7|du3_power7|du4_power7") + +(define_reservation "DU2F_power7" + "du1_power7+du2_power7") + +(define_reservation "DU4_power7" + "du1_power7+du2_power7+du3_power7+du4_power7") + +(define_reservation "FXU_power7" + "iu1_power7|iu2_power7") + +(define_reservation "VSU_power7" + "vsu1_power7|vsu2_power7") + +(define_reservation "LSU_power7" + "lsu1_power7|lsu2_power7") + + +; Dispatch slots are allocated in order conforming to program order. +(absence_set "du1_power7" "du2_power7,du3_power7,du4_power7,du5_power7") +(absence_set "du2_power7" "du3_power7,du4_power7,du5_power7") +(absence_set "du3_power7" "du4_power7,du5_power7") +(absence_set "du4_power7" "du5_power7") + + +; LS Unit +(define_insn_reservation "power7-load" 2 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "no") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7") + +(define_insn_reservation "power7-load-ext" 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "no") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7,FXU_power7") + +(define_insn_reservation "power7-load-update" 2 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7+FXU_power7") + +(define_insn_reservation "power7-load-update-indexed" 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power7")) + "DU4_power7,FXU_power7,LSU_power7+FXU_power7") + +(define_insn_reservation "power7-load-ext-update" 4 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7+FXU_power7,FXU_power7") + +(define_insn_reservation "power7-load-ext-update-indexed" 4 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power7")) + "DU4_power7,FXU_power7,LSU_power7+FXU_power7,FXU_power7") + +(define_insn_reservation "power7-fpload" 3 + (and (eq_attr "type" "fpload") + (eq_attr "update" "no") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7") + +(define_insn_reservation "power7-fpload-update" 3 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7+FXU_power7") + +(define_insn_reservation "power7-store" 6 ; store-forwarding latency + (and (eq_attr "type" "store") + (eq_attr "update" "no") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7+FXU_power7") + +(define_insn_reservation "power7-store-update" 6 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power7")) + "DU2F_power7,LSU_power7+FXU_power7,FXU_power7") + +(define_insn_reservation "power7-store-update-indexed" 6 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power7")) + "DU4_power7,LSU_power7+FXU_power7,FXU_power7") + +(define_insn_reservation "power7-fpstore" 6 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "no") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7+VSU_power7") + +(define_insn_reservation "power7-fpstore-update" 6 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "yes") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7+VSU_power7+FXU_power7") + +(define_insn_reservation "power7-larx" 3 + (and (eq_attr "type" "load_l") + (eq_attr "cpu" "power7")) + "DU4_power7,LSU_power7") + +(define_insn_reservation "power7-stcx" 10 + (and (eq_attr "type" "store_c") + (eq_attr "cpu" "power7")) + "DU4_power7,LSU_power7") + +(define_insn_reservation "power7-vecload" 3 + (and (eq_attr "type" "vecload") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7") + +(define_insn_reservation "power7-vecstore" 6 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "power7")) + "DU_power7,LSU_power7+vsu2_power7") + +(define_insn_reservation "power7-sync" 11 + (and (eq_attr "type" "sync") + (eq_attr "cpu" "power7")) + "DU4_power7,LSU_power7") + + +; FX Unit +(define_insn_reservation "power7-integer" 1 + (and (ior (eq_attr "type" "integer,insert,trap,isel,popcnt") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "power7")) + "DU_power7,FXU_power7") + +(define_insn_reservation "power7-cntlz" 2 + (and (eq_attr "type" "cntlz") + (eq_attr "cpu" "power7")) + "DU_power7,FXU_power7") + +(define_insn_reservation "power7-two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "power7")) + "DU_power7+DU_power7,FXU_power7,FXU_power7") + +(define_insn_reservation "power7-three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "power7")) + "DU_power7+DU_power7+DU_power7,FXU_power7,FXU_power7,FXU_power7") + +(define_insn_reservation "power7-cmp" 1 + (and (ior (eq_attr "type" "cmp") + (and (eq_attr "type" "add,logical") + (eq_attr "dot" "yes"))) + (eq_attr "cpu" "power7")) + "DU_power7,FXU_power7") + +(define_insn_reservation "power7-compare" 2 + (and (eq_attr "type" "shift,exts") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power7")) + "DU2F_power7,FXU_power7,FXU_power7") + +(define_bypass 3 "power7-cmp,power7-compare" "power7-crlogical,power7-delayedcr") + +(define_insn_reservation "power7-mul" 4 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "cpu" "power7")) + "DU_power7,FXU_power7") + +(define_insn_reservation "power7-mul-compare" 5 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power7")) + "DU2F_power7,FXU_power7,nothing*3,FXU_power7") + +(define_insn_reservation "power7-idiv" 36 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "power7")) + "DU2F_power7,iu1_power7*36|iu2_power7*36") + +(define_insn_reservation "power7-ldiv" 68 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "power7")) + "DU2F_power7,iu1_power7*68|iu2_power7*68") + +(define_insn_reservation "power7-isync" 1 ; + (and (eq_attr "type" "isync") + (eq_attr "cpu" "power7")) + "DU4_power7,FXU_power7") + + +; CR Unit +(define_insn_reservation "power7-mtjmpr" 4 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "power7")) + "du1_power7,FXU_power7") + +(define_insn_reservation "power7-mfjmpr" 5 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7+FXU_power7") + +(define_insn_reservation "power7-crlogical" 3 + (and (eq_attr "type" "cr_logical") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7") + +(define_insn_reservation "power7-delayedcr" 3 + (and (eq_attr "type" "delayed_cr") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7") + +(define_insn_reservation "power7-mfcr" 6 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7") + +(define_insn_reservation "power7-mfcrf" 3 + (and (eq_attr "type" "mfcrf") + (eq_attr "cpu" "power7")) + "du1_power7,cru_power7") + +(define_insn_reservation "power7-mtcr" 3 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "power7")) + "DU4_power7,cru_power7+FXU_power7") + + +; BR Unit +; Branches take dispatch Slot 4. The presence_sets prevent other insn from +; grabbing previous dispatch slots once this is assigned. +(define_insn_reservation "power7-branch" 3 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "power7")) + "(du5_power7\ + |du4_power7+du5_power7\ + |du3_power7+du4_power7+du5_power7\ + |du2_power7+du3_power7+du4_power7+du5_power7\ + |du1_power7+du2_power7+du3_power7+du4_power7+du5_power7),bpu_power7") + + +; VS Unit (includes FP/VSX/VMX/DFP) +(define_insn_reservation "power7-fp" 6 + (and (eq_attr "type" "fp,fpsimple,dmul,dfp") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_bypass 8 "power7-fp" "power7-branch") + +(define_insn_reservation "power7-fpcompare" 8 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-sdiv" 27 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-ddiv" 33 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-sqrt" 32 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-dsqrt" 44 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-vecsimple" 2 + (and (eq_attr "type" "vecsimple,veclogical,vecmove,veccmp,veccmpfx") + (eq_attr "cpu" "power7")) + "DU_power7,vsu1_power7") + +(define_insn_reservation "power7-vecfloat" 6 + (and (eq_attr "type" "vecfloat") + (eq_attr "cpu" "power7")) + "DU_power7,vsu1_power7") + +(define_bypass 7 "power7-vecfloat" "power7-vecsimple,power7-veccomplex,\ + power7-vecperm") + +(define_insn_reservation "power7-veccomplex" 7 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "power7")) + "DU_power7,vsu1_power7") + +(define_insn_reservation "power7-vecperm" 3 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "power7")) + "DU_power7,vsu2_power7") + +(define_insn_reservation "power7-vecdouble" 6 + (and (eq_attr "type" "vecdouble") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_bypass 7 "power7-vecdouble" "power7-vecsimple,power7-veccomplex,\ + power7-vecperm") + +(define_insn_reservation "power7-vecfdiv" 26 + (and (eq_attr "type" "vecfdiv") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + +(define_insn_reservation "power7-vecdiv" 32 + (and (eq_attr "type" "vecdiv") + (eq_attr "cpu" "power7")) + "DU_power7,VSU_power7") + diff --git a/gcc/config/powerpcspe/power8.md b/gcc/config/powerpcspe/power8.md new file mode 100644 index 00000000000..21ebab45d74 --- /dev/null +++ b/gcc/config/powerpcspe/power8.md @@ -0,0 +1,396 @@ +;; Scheduling description for IBM POWER8 processor. +;; Copyright (C) 2013-2017 Free Software Foundation, Inc. +;; +;; Contributed by Pat Haugen (pthaugen@us.ibm.com). + +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "power8fxu,power8lsu,power8vsu,power8misc") + +(define_cpu_unit "fxu0_power8,fxu1_power8" "power8fxu") +(define_cpu_unit "lu0_power8,lu1_power8" "power8lsu") +(define_cpu_unit "lsu0_power8,lsu1_power8" "power8lsu") +(define_cpu_unit "vsu0_power8,vsu1_power8" "power8vsu") +(define_cpu_unit "bpu_power8,cru_power8" "power8misc") +(define_cpu_unit "du0_power8,du1_power8,du2_power8,du3_power8,du4_power8,\ + du5_power8,du6_power8" "power8misc") + + +; Dispatch group reservations +(define_reservation "DU_any_power8" + "du0_power8|du1_power8|du2_power8|du3_power8|du4_power8|\ + du5_power8") + +; 2-way Cracked instructions go in slots 0-1 +; (can also have a second in slots 3-4 if insns are adjacent) +(define_reservation "DU_cracked_power8" + "du0_power8+du1_power8") + +; Insns that are first in group +(define_reservation "DU_first_power8" + "du0_power8") + +; Insns that are first and last in group +(define_reservation "DU_both_power8" + "du0_power8+du1_power8+du2_power8+du3_power8+du4_power8+\ + du5_power8+du6_power8") + +; Dispatch slots are allocated in order conforming to program order. +(absence_set "du0_power8" "du1_power8,du2_power8,du3_power8,du4_power8,\ + du5_power8,du6_power8") +(absence_set "du1_power8" "du2_power8,du3_power8,du4_power8,du5_power8,\ + du6_power8") +(absence_set "du2_power8" "du3_power8,du4_power8,du5_power8,du6_power8") +(absence_set "du3_power8" "du4_power8,du5_power8,du6_power8") +(absence_set "du4_power8" "du5_power8,du6_power8") +(absence_set "du5_power8" "du6_power8") + + +; Execution unit reservations +(define_reservation "FXU_power8" + "fxu0_power8|fxu1_power8") + +(define_reservation "LU_power8" + "lu0_power8|lu1_power8") + +(define_reservation "LSU_power8" + "lsu0_power8|lsu1_power8") + +(define_reservation "LU_or_LSU_power8" + "lu0_power8|lu1_power8|lsu0_power8|lsu1_power8") + +(define_reservation "VSU_power8" + "vsu0_power8|vsu1_power8") + + +; LS Unit +(define_insn_reservation "power8-load" 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "no") + (eq_attr "cpu" "power8")) + "DU_any_power8,LU_or_LSU_power8") + +(define_insn_reservation "power8-load-update" 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "cpu" "power8")) + "DU_cracked_power8,LU_or_LSU_power8+FXU_power8") + +(define_insn_reservation "power8-load-ext" 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "no") + (eq_attr "cpu" "power8")) + "DU_cracked_power8,LU_or_LSU_power8,FXU_power8") + +(define_insn_reservation "power8-load-ext-update" 3 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "cpu" "power8")) + "DU_both_power8,LU_or_LSU_power8+FXU_power8,FXU_power8") + +(define_insn_reservation "power8-fpload" 5 + (and (ior (eq_attr "type" "vecload") + (and (eq_attr "type" "fpload") + (eq_attr "update" "no"))) + (eq_attr "cpu" "power8")) + "DU_any_power8,LU_power8") + +(define_insn_reservation "power8-fpload-update" 5 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (eq_attr "cpu" "power8")) + "DU_cracked_power8,LU_power8+FXU_power8") + +(define_insn_reservation "power8-store" 5 ; store-forwarding latency + (and (eq_attr "type" "store") + (not (and (eq_attr "update" "yes") + (eq_attr "indexed" "yes"))) + (eq_attr "cpu" "power8")) + "DU_any_power8,LSU_power8+LU_power8") + +(define_insn_reservation "power8-store-update-indexed" 5 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power8")) + "DU_cracked_power8,LSU_power8+LU_power8") + +(define_insn_reservation "power8-fpstore" 5 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "no") + (eq_attr "cpu" "power8")) + "DU_any_power8,LSU_power8+VSU_power8") + +(define_insn_reservation "power8-fpstore-update" 5 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "yes") + (eq_attr "cpu" "power8")) + "DU_any_power8,LSU_power8+VSU_power8") + +(define_insn_reservation "power8-vecstore" 5 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "power8")) + "DU_cracked_power8,LSU_power8+VSU_power8") + +(define_insn_reservation "power8-larx" 3 + (and (eq_attr "type" "load_l") + (eq_attr "cpu" "power8")) + "DU_both_power8,LU_or_LSU_power8") + +(define_insn_reservation "power8-stcx" 10 + (and (eq_attr "type" "store_c") + (eq_attr "cpu" "power8")) + "DU_both_power8,LSU_power8+LU_power8") + +(define_insn_reservation "power8-sync" 1 + (and (eq_attr "type" "sync,isync") + (eq_attr "cpu" "power8")) + "DU_both_power8,LSU_power8") + + +; FX Unit +(define_insn_reservation "power8-1cyc" 1 + (and (ior (eq_attr "type" "integer,insert,trap,isel") + (and (eq_attr "type" "add,logical,shift,exts") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "power8")) + "DU_any_power8,FXU_power8") + +; Extra cycle to LU/LSU +(define_bypass 2 "power8-1cyc" + "power8-load*,power8-fpload*,power8-store*,power8-fpstore*,\ + power8-vecstore,power8-larx,power8-stcx") +; "power8-load,power8-load-update,power8-load-ext,\ +; power8-load-ext-update,power8-fpload,power8-fpload-update,\ +; power8-store,power8-store-update,power8-store-update-indexed,\ +; power8-fpstore,power8-fpstore-update,power8-vecstore,\ +; power8-larx,power8-stcx") + +(define_insn_reservation "power8-2cyc" 2 + (and (eq_attr "type" "cntlz,popcnt") + (eq_attr "cpu" "power8")) + "DU_any_power8,FXU_power8") + +(define_insn_reservation "power8-two" 2 + (and (eq_attr "type" "two") + (eq_attr "cpu" "power8")) + "DU_any_power8+DU_any_power8,FXU_power8,FXU_power8") + +(define_insn_reservation "power8-three" 3 + (and (eq_attr "type" "three") + (eq_attr "cpu" "power8")) + "DU_any_power8+DU_any_power8+DU_any_power8,FXU_power8,FXU_power8,FXU_power8") + +; cmp - Normal compare insns +(define_insn_reservation "power8-cmp" 2 + (and (eq_attr "type" "cmp") + (eq_attr "cpu" "power8")) + "DU_any_power8,FXU_power8") + +; add/logical with dot : add./and./nor./etc +(define_insn_reservation "power8-fast-compare" 2 + (and (eq_attr "type" "add,logical") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power8")) + "DU_any_power8,FXU_power8") + +; exts/shift with dot : rldicl./exts./rlwinm./slwi./rlwnm./slw./etc +(define_insn_reservation "power8-compare" 2 + (and (eq_attr "type" "shift,exts") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power8")) + "DU_cracked_power8,FXU_power8,FXU_power8") + +; Extra cycle to LU/LSU +(define_bypass 3 "power8-fast-compare,power8-compare" + "power8-load*,power8-fpload*,power8-store*,power8-fpstore*,\ + power8-vecstore,power8-larx,power8-stcx") + +; 5 cycle CR latency +(define_bypass 5 "power8-fast-compare,power8-compare" + "power8-crlogical,power8-mfcr,power8-mfcrf,power8-branch") + +(define_insn_reservation "power8-mul" 4 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "cpu" "power8")) + "DU_any_power8,FXU_power8") + +(define_insn_reservation "power8-mul-compare" 4 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power8")) + "DU_cracked_power8,FXU_power8") + +; Extra cycle to LU/LSU +(define_bypass 5 "power8-mul,power8-mul-compare" + "power8-load*,power8-fpload*,power8-store*,power8-fpstore*,\ + power8-vecstore,power8-larx,power8-stcx") + +; 7 cycle CR latency +(define_bypass 7 "power8-mul,power8-mul-compare" + "power8-crlogical,power8-mfcr,power8-mfcrf,power8-branch") + +; FXU divides are not pipelined +(define_insn_reservation "power8-idiv" 37 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "power8")) + "DU_any_power8,fxu0_power8*37|fxu1_power8*37") + +(define_insn_reservation "power8-ldiv" 68 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "power8")) + "DU_any_power8,fxu0_power8*68|fxu1_power8*68") + +(define_insn_reservation "power8-mtjmpr" 5 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "power8")) + "DU_first_power8,FXU_power8") + +; Should differentiate between 1 cr field and > 1 since mtocrf is not microcode +(define_insn_reservation "power8-mtcr" 3 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "power8")) + "DU_both_power8,FXU_power8") + + +; CR Unit +(define_insn_reservation "power8-mfjmpr" 5 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "power8")) + "DU_first_power8,cru_power8+FXU_power8") + +(define_insn_reservation "power8-crlogical" 3 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "power8")) + "DU_first_power8,cru_power8") + +(define_insn_reservation "power8-mfcr" 5 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "power8")) + "DU_both_power8,cru_power8") + +(define_insn_reservation "power8-mfcrf" 3 + (and (eq_attr "type" "mfcrf") + (eq_attr "cpu" "power8")) + "DU_first_power8,cru_power8") + + +; BR Unit +; Branches take dispatch slot 7, but reserve any remaining prior slots to +; prevent other insns from grabbing them once this is assigned. +(define_insn_reservation "power8-branch" 3 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "power8")) + "(du6_power8\ + |du5_power8+du6_power8\ + |du4_power8+du5_power8+du6_power8\ + |du3_power8+du4_power8+du5_power8+du6_power8\ + |du2_power8+du3_power8+du4_power8+du5_power8+du6_power8\ + |du1_power8+du2_power8+du3_power8+du4_power8+du5_power8+du6_power8\ + |du0_power8+du1_power8+du2_power8+du3_power8+du4_power8+du5_power8+\ + du6_power8),bpu_power8") + +; Branch updating LR/CTR feeding mf[lr|ctr] +(define_bypass 4 "power8-branch" "power8-mfjmpr") + + +; VS Unit (includes FP/VSX/VMX/DFP/Crypto) +(define_insn_reservation "power8-fp" 6 + (and (eq_attr "type" "fp,fpsimple,dmul,dfp") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +; Additional 3 cycles for any CR result +(define_bypass 9 "power8-fp" "power8-crlogical,power8-mfcr*,power8-branch") + +(define_insn_reservation "power8-fpcompare" 8 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-sdiv" 27 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-ddiv" 33 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-sqrt" 32 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-dsqrt" 44 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-vecsimple" 2 + (and (eq_attr "type" "vecperm,vecsimple,veclogical,vecmove,veccmp, + veccmpfx") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-vecnormal" 6 + (and (eq_attr "type" "vecfloat,vecdouble") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_bypass 7 "power8-vecnormal" + "power8-vecsimple,power8-veccomplex,power8-fpstore*,\ + power8-vecstore") + +(define_insn_reservation "power8-veccomplex" 7 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-vecfdiv" 25 + (and (eq_attr "type" "vecfdiv") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-vecdiv" 31 + (and (eq_attr "type" "vecdiv") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-mffgpr" 5 + (and (eq_attr "type" "mffgpr") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-mftgpr" 6 + (and (eq_attr "type" "mftgpr") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + +(define_insn_reservation "power8-crypto" 7 + (and (eq_attr "type" "crypto") + (eq_attr "cpu" "power8")) + "DU_any_power8,VSU_power8") + diff --git a/gcc/config/powerpcspe/power9.md b/gcc/config/powerpcspe/power9.md new file mode 100644 index 00000000000..217864faaed --- /dev/null +++ b/gcc/config/powerpcspe/power9.md @@ -0,0 +1,489 @@ +;; Scheduling description for IBM POWER9 processor. +;; Copyright (C) 2016-2017 Free Software Foundation, Inc. +;; +;; Contributed by Pat Haugen (pthaugen@us.ibm.com). + +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "power9dsp,power9lsu,power9vsu,power9misc") + +(define_cpu_unit "lsu0_power9,lsu1_power9,lsu2_power9,lsu3_power9" "power9lsu") +(define_cpu_unit "vsu0_power9,vsu1_power9,vsu2_power9,vsu3_power9" "power9vsu") +; Two vector permute units, part of vsu +(define_cpu_unit "prm0_power9,prm1_power9" "power9vsu") +; Two fixed point divide units, not pipelined +(define_cpu_unit "fx_div0_power9,fx_div1_power9" "power9misc") +(define_cpu_unit "bru_power9,cryptu_power9,dfu_power9" "power9misc") + +(define_cpu_unit "x0_power9,x1_power9,xa0_power9,xa1_power9, + x2_power9,x3_power9,xb0_power9,xb1_power9, + br0_power9,br1_power9" "power9dsp") + + +; Dispatch port reservations +; +; Power9 can dispatch a maximum of 6 iops per cycle with the following +; general restrictions (other restrictions also apply): +; 1) At most 2 iops per execution slice +; 2) At most 2 iops to the branch unit +; Note that insn position in a dispatch group of 6 insns does not infer which +; execution slice the insn is routed to. The units are used to infer the +; conflicts that exist (i.e. an 'even' requirement will preclude dispatch +; with 2 insns with 'superslice' requirement). + +; The xa0/xa1 units really represent the 3rd dispatch port for a superslice but +; are listed as separate units to allow those insns that preclude its use to +; still be scheduled two to a superslice while reserving the 3rd slot. The +; same applies for xb0/xb1. +(define_reservation "DU_xa_power9" "xa0_power9+xa1_power9") +(define_reservation "DU_xb_power9" "xb0_power9+xb1_power9") + +; Any execution slice dispatch +(define_reservation "DU_any_power9" + "x0_power9|x1_power9|DU_xa_power9|x2_power9|x3_power9| + DU_xb_power9") + +; Even slice, actually takes even/odd slots +(define_reservation "DU_even_power9" "x0_power9+x1_power9|x2_power9+x3_power9") + +; Slice plus 3rd slot +(define_reservation "DU_slice_3_power9" + "x0_power9+xa0_power9|x1_power9+xa1_power9| + x2_power9+xb0_power9|x3_power9+xb1_power9") + +; Superslice +(define_reservation "DU_super_power9" + "x0_power9+x1_power9|x2_power9+x3_power9") + +; 2-way cracked +(define_reservation "DU_C2_power9" "x0_power9+x1_power9| + x1_power9+DU_xa_power9| + x1_power9+x2_power9| + DU_xa_power9+x2_power9| + x2_power9+x3_power9| + x3_power9+DU_xb_power9") + +; 2-way cracked plus 3rd slot +(define_reservation "DU_C2_3_power9" "x0_power9+x1_power9+xa0_power9| + x1_power9+x2_power9+xa0_power9| + x1_power9+x2_power9+xb0_power9| + x2_power9+x3_power9+xb0_power9") + +; 3-way cracked (consumes whole decode/dispatch cycle) +(define_reservation "DU_C3_power9" + "x0_power9+x1_power9+xa0_power9+xa1_power9+x2_power9+ + x3_power9+xb0_power9+xb1_power9+br0_power9+br1_power9") + +; Branch ports +(define_reservation "DU_branch_power9" "br0_power9|br1_power9") + + +; Execution unit reservations +(define_reservation "LSU_power9" + "lsu0_power9|lsu1_power9|lsu2_power9|lsu3_power9") + +(define_reservation "LSU_pair_power9" + "lsu0_power9+lsu1_power9|lsu1_power9+lsu2_power9| + lsu2_power9+lsu3_power9|lsu3_power9+lsu0_power9") + +(define_reservation "VSU_power9" + "vsu0_power9|vsu1_power9|vsu2_power9|vsu3_power9") + +(define_reservation "VSU_super_power9" + "vsu0_power9+vsu1_power9|vsu2_power9+vsu3_power9") + +(define_reservation "VSU_PRM_power9" "prm0_power9|prm1_power9") + + +; LS Unit +(define_insn_reservation "power9-load" 4 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "no") + (eq_attr "cpu" "power9")) + "DU_any_power9,LSU_power9") + +(define_insn_reservation "power9-load-update" 4 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-load-ext" 6 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "no") + (eq_attr "cpu" "power9")) + "DU_C2_power9,LSU_power9") + +(define_insn_reservation "power9-load-ext-update" 6 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "cpu" "power9")) + "DU_C3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-fpload-double" 4 + (and (eq_attr "type" "fpload") + (eq_attr "update" "no") + (eq_attr "size" "64") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,LSU_power9") + +(define_insn_reservation "power9-fpload-update-double" 4 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (eq_attr "size" "64") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +; SFmode loads are cracked and have additional 2 cycles over DFmode +(define_insn_reservation "power9-fpload-single" 6 + (and (eq_attr "type" "fpload") + (eq_attr "update" "no") + (eq_attr "size" "32") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9") + +(define_insn_reservation "power9-fpload-update-single" 6 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (eq_attr "size" "32") + (eq_attr "cpu" "power9")) + "DU_C3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-vecload" 5 + (and (eq_attr "type" "vecload") + (eq_attr "cpu" "power9")) + "DU_any_power9,LSU_pair_power9") + +; Store data can issue 2 cycles after AGEN issue, 3 cycles for vector store +(define_insn_reservation "power9-store" 0 + (and (eq_attr "type" "store") + (eq_attr "update" "no") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,LSU_power9") + +(define_insn_reservation "power9-store-indexed" 0 + (and (eq_attr "type" "store") + (eq_attr "update" "no") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,LSU_power9") + +; Update forms have 2 cycle latency for updated addr reg +(define_insn_reservation "power9-store-update" 2 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +; Update forms have 2 cycle latency for updated addr reg +(define_insn_reservation "power9-store-update-indexed" 2 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-fpstore" 0 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "no") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,LSU_power9") + +; Update forms have 2 cycle latency for updated addr reg +(define_insn_reservation "power9-fpstore-update" 2 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-vecstore" 0 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "power9")) + "DU_super_power9,LSU_pair_power9") + +(define_insn_reservation "power9-larx" 4 + (and (eq_attr "type" "load_l") + (eq_attr "cpu" "power9")) + "DU_any_power9,LSU_power9") + +(define_insn_reservation "power9-stcx" 2 + (and (eq_attr "type" "store_c") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-sync" 4 + (and (eq_attr "type" "sync,isync") + (eq_attr "cpu" "power9")) + "DU_any_power9,LSU_power9") + + +; VSU Execution Unit + +; Fixed point ops + +; Most ALU insns are simple 2 cycle, including record form +(define_insn_reservation "power9-alu" 2 + (and (ior (eq_attr "type" "add,exts,integer,logical,isel") + (and (eq_attr "type" "insert,shift") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") +; 5 cycle CR latency +(define_bypass 5 "power9-alu" + "power9-crlogical,power9-mfcr,power9-mfcrf") + +; Record form rotate/shift are cracked +(define_insn_reservation "power9-cracked-alu" 2 + (and (eq_attr "type" "insert,shift") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_power9,VSU_power9") +; 7 cycle CR latency +(define_bypass 7 "power9-cracked-alu" + "power9-crlogical,power9-mfcr,power9-mfcrf") + +(define_insn_reservation "power9-alu2" 3 + (and (eq_attr "type" "cntlz,popcnt,trap") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") +; 6 cycle CR latency +(define_bypass 6 "power9-alu2" + "power9-crlogical,power9-mfcr,power9-mfcrf") + +(define_insn_reservation "power9-cmp" 2 + (and (eq_attr "type" "cmp") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + + +; Treat 'two' and 'three' types as 2 or 3 way cracked +(define_insn_reservation "power9-two" 4 + (and (eq_attr "type" "two") + (eq_attr "cpu" "power9")) + "DU_C2_power9,VSU_power9") + +(define_insn_reservation "power9-three" 6 + (and (eq_attr "type" "three") + (eq_attr "cpu" "power9")) + "DU_C3_power9,VSU_power9") + +(define_insn_reservation "power9-mul" 5 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +(define_insn_reservation "power9-mul-compare" 5 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_power9,VSU_power9") +; 10 cycle CR latency +(define_bypass 10 "power9-mul-compare" + "power9-crlogical,power9-mfcr,power9-mfcrf") + +; Fixed point divides reserve the divide units for a minimum of 8 cycles +(define_insn_reservation "power9-idiv" 16 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "power9")) + "DU_even_power9,fx_div0_power9*8|fx_div1_power9*8") + +(define_insn_reservation "power9-ldiv" 24 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "power9")) + "DU_even_power9,fx_div0_power9*8|fx_div1_power9*8") + +(define_insn_reservation "power9-crlogical" 2 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +(define_insn_reservation "power9-mfcrf" 2 + (and (eq_attr "type" "mfcrf") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +(define_insn_reservation "power9-mfcr" 6 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "power9")) + "DU_C3_power9,VSU_power9") + +; Should differentiate between 1 cr field and > 1 since target of > 1 cr +; is cracked +(define_insn_reservation "power9-mtcr" 2 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +; Move to LR/CTR are executed in VSU +(define_insn_reservation "power9-mtjmpr" 5 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +; Floating point/Vector ops +(define_insn_reservation "power9-fpsimple" 2 + (and (eq_attr "type" "fpsimple") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-fp" 7 + (and (eq_attr "type" "fp,dmul") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-fpcompare" 3 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +; FP div/sqrt are executed in the VSU slices. They are not pipelined wrt other +; divide insns, but for the most part do not block pipelined ops. +(define_insn_reservation "power9-sdiv" 22 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-ddiv" 33 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-sqrt" 26 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-dsqrt" 36 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-vec-2cyc" 2 + (and (eq_attr "type" "vecmove,veclogical,vecexts,veccmpfx") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-veccmp" 3 + (and (eq_attr "type" "veccmp") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecsimple" 3 + (and (eq_attr "type" "vecsimple") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecnormal" 7 + (and (eq_attr "type" "vecfloat,vecdouble") + (eq_attr "size" "!128") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +; Quad-precision FP ops, execute in DFU +(define_insn_reservation "power9-qp" 12 + (and (eq_attr "type" "vecfloat,vecdouble") + (eq_attr "size" "128") + (eq_attr "cpu" "power9")) + "DU_super_power9,dfu_power9") + +(define_insn_reservation "power9-vecperm" 3 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_PRM_power9") + +(define_insn_reservation "power9-veccomplex" 7 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecfdiv" 28 + (and (eq_attr "type" "vecfdiv") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecdiv" 32 + (and (eq_attr "type" "vecdiv") + (eq_attr "size" "!128") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-qpdiv" 56 + (and (eq_attr "type" "vecdiv") + (eq_attr "size" "128") + (eq_attr "cpu" "power9")) + "DU_super_power9,dfu_power9") + +(define_insn_reservation "power9-mffgpr" 2 + (and (eq_attr "type" "mffgpr") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-mftgpr" 2 + (and (eq_attr "type" "mftgpr") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + + +; Branch Unit +; Move from LR/CTR are executed in BRU but consume a writeback port from an +; execution slice. +(define_insn_reservation "power9-mfjmpr" 6 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "power9")) + "DU_branch_power9,bru_power9+VSU_power9") + +; Branch is 2 cycles +(define_insn_reservation "power9-branch" 2 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "power9")) + "DU_branch_power9,bru_power9") + + +; Crypto Unit +(define_insn_reservation "power9-crypto" 6 + (and (eq_attr "type" "crypto") + (eq_attr "cpu" "power9")) + "DU_super_power9,cryptu_power9") + + +; HTM Unit +(define_insn_reservation "power9-htm" 4 + (and (eq_attr "type" "htm") + (eq_attr "cpu" "power9")) + "DU_C2_power9,LSU_power9") + +(define_insn_reservation "power9-htm-simple" 2 + (and (eq_attr "type" "htmsimple") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + + +; DFP Unit +(define_insn_reservation "power9-dfp" 12 + (and (eq_attr "type" "dfp") + (eq_attr "cpu" "power9")) + "DU_even_power9,dfu_power9") + diff --git a/gcc/config/powerpcspe/powerpcspe-builtin.def b/gcc/config/powerpcspe/powerpcspe-builtin.def new file mode 100644 index 00000000000..ebe005afb20 --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe-builtin.def @@ -0,0 +1,2674 @@ +/* Builtin functions for rs6000/powerpc. + Copyright (C) 2009-2017 Free Software Foundation, Inc. + Contributed by Michael Meissner (meissner@linux.vnet.ibm.com) + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* Before including this file, some macros must be defined: + RS6000_BUILTIN_0 -- 0 arg builtins + RS6000_BUILTIN_1 -- 1 arg builtins + RS6000_BUILTIN_2 -- 2 arg builtins + RS6000_BUILTIN_3 -- 3 arg builtins + RS6000_BUILTIN_A -- ABS builtins + RS6000_BUILTIN_D -- DST builtins + RS6000_BUILTIN_E -- SPE EVSEL builtins. + RS6000_BUILTIN_H -- HTM builtins + RS6000_BUILTIN_P -- Altivec, VSX, ISA 2.07 vector predicate builtins + RS6000_BUILTIN_Q -- Paired floating point VSX predicate builtins + RS6000_BUILTIN_S -- SPE predicate builtins + RS6000_BUILTIN_X -- special builtins + + Each of the above macros takes 4 arguments: + ENUM Enumeration name + NAME String literal for the name + MASK Mask of bits that indicate which options enables the builtin + ATTR builtin attribute information. + ICODE Insn code of the function that implements the builtin. */ + +#ifndef RS6000_BUILTIN_0 + #error "RS6000_BUILTIN_0 is not defined." +#endif + +#ifndef RS6000_BUILTIN_1 + #error "RS6000_BUILTIN_1 is not defined." +#endif + +#ifndef RS6000_BUILTIN_2 + #error "RS6000_BUILTIN_2 is not defined." +#endif + +#ifndef RS6000_BUILTIN_3 + #error "RS6000_BUILTIN_3 is not defined." +#endif + +#ifndef RS6000_BUILTIN_A + #error "RS6000_BUILTIN_A is not defined." +#endif + +#ifndef RS6000_BUILTIN_D + #error "RS6000_BUILTIN_D is not defined." +#endif + +#ifndef RS6000_BUILTIN_E + #error "RS6000_BUILTIN_E is not defined." +#endif + +#ifndef RS6000_BUILTIN_H + #error "RS6000_BUILTIN_H is not defined." +#endif + +#ifndef RS6000_BUILTIN_P + #error "RS6000_BUILTIN_P is not defined." +#endif + +#ifndef RS6000_BUILTIN_Q + #error "RS6000_BUILTIN_Q is not defined." +#endif + +#ifndef RS6000_BUILTIN_S + #error "RS6000_BUILTIN_S is not defined." +#endif + +#ifndef RS6000_BUILTIN_X + #error "RS6000_BUILTIN_X is not defined." +#endif + +#ifndef BU_AV_1 +/* Define convenience macros using token pasting to allow fitting everything in + one line. */ + +/* Altivec convenience macros. */ +#define BU_ALTIVEC_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_ALTIVEC_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_ALTIVEC_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_ALTIVEC_A(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_A (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_ABS), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_ALTIVEC_D(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_D (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_DST), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* All builtins defined with the RS6000_BUILTIN_P macro expect three + arguments, the first of which is an integer constant that clarifies + the implementation's use of CR6 flags. The integer constant + argument may have four values: __CR6_EQ (0) means the predicate is + considered true if the equality-test flag of the CR6 condition + register is true following execution of the code identified by the + ICODE pattern, __CR_EQ_REV (1) means the predicate is considered + true if the equality-test flag is false, __CR6_LT (2) means the + predicate is considered true if the less-than-test flag is true, and + __CR6_LT_REV (3) means the predicate is considered true if the + less-than-test flag is false. For all builtins defined by this + macro, the pattern selected by ICODE expects three operands, a + target and two inputs and is presumed to overwrite the flags of + condition register CR6 as a side effect of computing a result into + the target register. However, the built-in invocation provides + four operands, a target, an integer constant mode, and two inputs. + The second and third operands of the built-in function's invocation + are automatically mapped into operands 1 and 2 of the pattern + identifed by the ICODE argument and additional code is emitted, + depending on the value of the constant integer first argument. + This special processing happens within the implementation of + altivec_expand_predicate_builtin(), which is defined within + rs6000.c. The implementation of altivec_expand_predicate_builtin() + allocates a scratch register having the same mode as operand 0 to hold + the result produced by evaluating ICODE. */ + +#define BU_ALTIVEC_P(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_P (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_PREDICATE), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_ALTIVEC_X(ENUM, NAME, ATTR) \ + RS6000_BUILTIN_X (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_ALTIVEC_C(ENUM, NAME, ATTR) \ + RS6000_BUILTIN_X (ALTIVEC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + (RS6000_BTM_ALTIVEC /* MASK */ \ + | RS6000_BTM_CELL), \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_nothing) /* ICODE */ + +/* Altivec overloaded builtin function macros. */ +#define BU_ALTIVEC_OVERLOAD_1(ENUM, NAME) \ + RS6000_BUILTIN_1 (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_ALTIVEC_OVERLOAD_2(ENUM, NAME) \ + RS6000_BUILTIN_2 (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_ALTIVEC_OVERLOAD_3(ENUM, NAME) \ + RS6000_BUILTIN_3 (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_ALTIVEC_OVERLOAD_A(ENUM, NAME) \ + RS6000_BUILTIN_A (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_ABS), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_ALTIVEC_OVERLOAD_D(ENUM, NAME) \ + RS6000_BUILTIN_D (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_DST), \ + CODE_FOR_nothing) /* ICODE */ + +/* See the comment on BU_ALTIVEC_P. */ +#define BU_ALTIVEC_OVERLOAD_P(ENUM, NAME) \ + RS6000_BUILTIN_P (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_PREDICATE), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_ALTIVEC_OVERLOAD_X(ENUM, NAME) \ + RS6000_BUILTIN_X (ALTIVEC_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_nothing) /* ICODE */ + +/* VSX convenience macros. */ +#define BU_VSX_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_VSX_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_VSX_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_VSX_A(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_A (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_ABS), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* See the comment on BU_ALTIVEC_P. */ +#define BU_VSX_P(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_P (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_PREDICATE), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_VSX_X(ENUM, NAME, ATTR) \ + RS6000_BUILTIN_X (VSX_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_nothing) /* ICODE */ + +/* VSX overloaded builtin function macros. */ +#define BU_VSX_OVERLOAD_1(ENUM, NAME) \ + RS6000_BUILTIN_1 (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_VSX_OVERLOAD_2(ENUM, NAME) \ + RS6000_BUILTIN_2 (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_VSX_OVERLOAD_3(ENUM, NAME) \ + RS6000_BUILTIN_3 (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_nothing) /* ICODE */ + +/* xxpermdi and xxsldwi are overloaded functions, but had __builtin_vsx names + instead of __builtin_vec. */ +#define BU_VSX_OVERLOAD_3V(ENUM, NAME) \ + RS6000_BUILTIN_3 (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_VSX_OVERLOAD_X(ENUM, NAME) \ + RS6000_BUILTIN_X (VSX_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_VSX, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_nothing) /* ICODE */ + +/* ISA 2.05 (power6) convenience macros. */ +/* For functions that depend on the CMPB instruction */ +#define BU_P6_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (P6_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_p6_" NAME, /* NAME */ \ + RS6000_BTM_CMPB, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* For functions that depend on 64-BIT support and on the CMPB instruction */ +#define BU_P6_64BIT_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (P6_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_p6_" NAME, /* NAME */ \ + RS6000_BTM_CMPB \ + | RS6000_BTM_64BIT, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P6_OVERLOAD_2(ENUM, NAME) \ + RS6000_BUILTIN_2 (P6_OV_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_CMPB, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_nothing) /* ICODE */ + +/* ISA 2.07 (power8) vector convenience macros. */ +/* For the instructions that are encoded as altivec instructions use + __builtin_altivec_ as the builtin name. */ +#define BU_P8V_AV_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (P8V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P8V_AV_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (P8V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P8V_AV_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (P8V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* See the comment on BU_ALTIVEC_P. */ +#define BU_P8V_AV_P(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_P (P8V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_PREDICATE), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* For the instructions encoded as VSX instructions use __builtin_vsx as the + builtin name. */ +#define BU_P8V_VSX_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (P8V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P8V_OVERLOAD_1(ENUM, NAME) \ + RS6000_BUILTIN_1 (P8V_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_P8V_OVERLOAD_2(ENUM, NAME) \ + RS6000_BUILTIN_2 (P8V_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_P8V_OVERLOAD_3(ENUM, NAME) \ + RS6000_BUILTIN_3 (P8V_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_nothing) /* ICODE */ + +/* Crypto convenience macros. */ +#define BU_CRYPTO_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_CRYPTO, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_CRYPTO_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_CRYPTO, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_CRYPTO_2A(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_CRYPTO_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_CRYPTO, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_CRYPTO_3A(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_CRYPTO_OVERLOAD_1(ENUM, NAME) \ + RS6000_BUILTIN_1 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_CRYPTO, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_CRYPTO_OVERLOAD_2A(ENUM, NAME) \ + RS6000_BUILTIN_2 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_CRYPTO_OVERLOAD_3(ENUM, NAME) \ + RS6000_BUILTIN_3 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_CRYPTO, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_CRYPTO_OVERLOAD_3A(ENUM, NAME) \ + RS6000_BUILTIN_3 (CRYPTO_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_crypto_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_nothing) /* ICODE */ + +/* HTM convenience macros. */ +#define BU_HTM_0(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_HTM, /* MASK */ \ + RS6000_BTC_ ## ATTR, /* ATTR */ \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_HTM_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_HTM, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_HTM_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_HTM, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_HTM_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_HTM, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_HTM_V1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_HTM, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY \ + | RS6000_BTC_VOID), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* SPE convenience macros. */ +#define BU_SPE_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_spe_" NAME, /* NAME */ \ + RS6000_BTM_SPE, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_SPE_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_spe_" NAME, /* NAME */ \ + RS6000_BTM_SPE, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_SPE_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_spe_" NAME, /* NAME */ \ + RS6000_BTM_SPE, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_SPE_E(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_E (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_spe_" NAME, /* NAME */ \ + RS6000_BTM_SPE, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_EVSEL), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_SPE_P(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_S (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_spe_" NAME, /* NAME */ \ + RS6000_BTM_SPE, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_PREDICATE), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_SPE_X(ENUM, NAME, ATTR) \ + RS6000_BUILTIN_X (SPE_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_spe_" NAME, /* NAME */ \ + RS6000_BTM_SPE, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_nothing) /* ICODE */ + +/* Paired floating point convenience macros. */ +#define BU_PAIRED_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_paired_" NAME, /* NAME */ \ + RS6000_BTM_PAIRED, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_PAIRED_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_paired_" NAME, /* NAME */ \ + RS6000_BTM_PAIRED, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_PAIRED_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_paired_" NAME, /* NAME */ \ + RS6000_BTM_PAIRED, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_PAIRED_P(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_Q (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_paired_" NAME, /* NAME */ \ + RS6000_BTM_PAIRED, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_PREDICATE), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_PAIRED_X(ENUM, NAME, ATTR) \ + RS6000_BUILTIN_X (PAIRED_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_paired_" NAME, /* NAME */ \ + RS6000_BTM_PAIRED, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_SPECIAL_X(ENUM, NAME, MASK, ATTR) \ + RS6000_BUILTIN_X (ENUM, /* ENUM */ \ + NAME, /* NAME */ \ + MASK, /* MASK */ \ + (ATTR | RS6000_BTC_SPECIAL), /* ATTR */ \ + CODE_FOR_nothing) /* ICODE */ + + +/* Decimal floating point builtins for instructions. */ +#define BU_DFP_MISC_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_DFP, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_DFP_MISC_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_DFP, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + + +/* Miscellaneous builtins for instructions added in ISA 2.06. These + instructions don't require either the DFP or VSX options, just the basic ISA + 2.06 (popcntd) enablement since they operate on general purpose + registers. */ +#define BU_P7_MISC_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_POPCNTD, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P7_MISC_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_POPCNTD, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + + +/* Miscellaneous builtins for instructions added in ISA 2.07. These + instructions do require the ISA 2.07 vector support, but they aren't vector + instructions. */ +#define BU_P8V_MISC_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_P8_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* 128-bit long double floating point builtins. */ +#define BU_LDBL128_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + (RS6000_BTM_HARD_FLOAT /* MASK */ \ + | RS6000_BTM_LDBL128), \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* IEEE 128-bit floating-point builtins. */ +#define BU_FLOAT128_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_FLOAT128, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_FLOAT128_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_FLOAT128, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* Miscellaneous builtins for instructions added in ISA 3.0. These + instructions don't require either the DFP or VSX options, just the basic + ISA 3.0 enablement since they operate on general purpose registers. */ +#define BU_P9_MISC_0(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_P9_MISC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9_MISC_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_P9_MISC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* Miscellaneous builtins for instructions added in ISA 3.0. These + instructions don't require either the DFP or VSX options, just the basic + ISA 3.0 enablement since they operate on general purpose registers, + and they require 64-bit addressing. */ +#define BU_P9_64BIT_MISC_0(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_P9_MISC \ + | RS6000_BTM_64BIT, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* Miscellaneous builtins for decimal floating point instructions + added in ISA 3.0. These instructions don't require the VSX + options, just the basic ISA 3.0 enablement since they operate on + general purpose registers. */ +#define BU_P9_DFP_MISC_0(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_P9_MISC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9_DFP_MISC_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_P9_MISC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9_DFP_MISC_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_P9_MISC, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* Decimal floating point overloaded functions added in ISA 3.0 */ +#define BU_P9_DFP_OVERLOAD_1(ENUM, NAME) \ + RS6000_BUILTIN_1 (P9_BUILTIN_DFP_ ## ENUM, /* ENUM */ \ + "__builtin_dfp_" NAME, /* NAME */ \ + RS6000_BTM_P9_MISC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_P9_DFP_OVERLOAD_2(ENUM, NAME) \ + RS6000_BUILTIN_2 (P9_BUILTIN_DFP_ ## ENUM, /* ENUM */ \ + "__builtin_dfp_" NAME, /* NAME */ \ + RS6000_BTM_P9_MISC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_P9_DFP_OVERLOAD_3(ENUM, NAME) \ + RS6000_BUILTIN_3 (P9_BUILTIN_DFP_ ## ENUM, /* ENUM */ \ + "__builtin_dfp_" NAME, /* NAME */ \ + RS6000_BTM_P9_MISC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_nothing) /* ICODE */ + +/* ISA 3.0 (power9) vector convenience macros. */ +/* For the instructions that are encoded as altivec instructions use + __builtin_altivec_ as the builtin name. */ +#define BU_P9V_AV_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9V_AV_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9V_AV_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* See the comment on BU_ALTIVEC_P. */ +#define BU_P9V_AV_P(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_P (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_PREDICATE), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9V_AV_X(ENUM, NAME, ATTR) \ + RS6000_BUILTIN_X (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_P9V_64BIT_AV_X(ENUM, NAME, ATTR) \ + RS6000_BUILTIN_X (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_altivec_" NAME, /* NAME */ \ + (RS6000_BTM_P9_VECTOR \ + | RS6000_BTM_64BIT), /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_SPECIAL), \ + CODE_FOR_nothing) /* ICODE */ + +/* For the instructions encoded as VSX instructions use __builtin_vsx as the + builtin name. */ +#define BU_P9V_VSX_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9V_64BIT_VSX_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + (RS6000_BTM_64BIT \ + | RS6000_BTM_P9_VECTOR), /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9V_VSX_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9V_64BIT_VSX_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + (RS6000_BTM_64BIT \ + | RS6000_BTM_P9_VECTOR), /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9V_VSX_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_3 (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9V_64BIT_VSX_3(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (P9V_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_vsx_" NAME, /* NAME */ \ + (RS6000_BTM_64BIT \ + | RS6000_BTM_P9_VECTOR), /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +/* See the comment on BU_ALTIVEC_P. */ +#define BU_P9V_OVERLOAD_P(ENUM, NAME) \ + RS6000_BUILTIN_P (P9V_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_ALTIVEC, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_PREDICATE), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_P9_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (P9_BUILTIN_SCALAR_ ## ENUM, /* ENUM */ \ + "__builtin_scalar_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9_64BIT_2(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (P9_BUILTIN_SCALAR_ ## ENUM, /* ENUM */ \ + "__builtin_scalar_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR \ + | RS6000_BTM_64BIT, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +#define BU_P9V_OVERLOAD_1(ENUM, NAME) \ + RS6000_BUILTIN_1 (P9V_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_P9V_OVERLOAD_2(ENUM, NAME) \ + RS6000_BUILTIN_2 (P9V_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_P9V_OVERLOAD_3(ENUM, NAME) \ + RS6000_BUILTIN_3 (P9V_BUILTIN_VEC_ ## ENUM, /* ENUM */ \ + "__builtin_vec_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_TERNARY), \ + CODE_FOR_nothing) /* ICODE */ + +#define BU_P9_OVERLOAD_2(ENUM, NAME) \ + RS6000_BUILTIN_2 (P9_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_P9_VECTOR, /* MASK */ \ + (RS6000_BTC_OVERLOADED /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_nothing) /* ICODE */ + +#endif + + +/* Insure 0 is not a legitimate index. */ +BU_SPECIAL_X (RS6000_BUILTIN_NONE, NULL, 0, RS6000_BTC_MISC) + +/* 3 argument Altivec builtins. */ +BU_ALTIVEC_3 (VMADDFP, "vmaddfp", FP, fmav4sf4) +BU_ALTIVEC_3 (VMHADDSHS, "vmhaddshs", SAT, altivec_vmhaddshs) +BU_ALTIVEC_3 (VMHRADDSHS, "vmhraddshs", SAT, altivec_vmhraddshs) +BU_ALTIVEC_3 (VMLADDUHM, "vmladduhm", CONST, altivec_vmladduhm) +BU_ALTIVEC_3 (VMSUMUBM, "vmsumubm", CONST, altivec_vmsumubm) +BU_ALTIVEC_3 (VMSUMMBM, "vmsummbm", CONST, altivec_vmsummbm) +BU_ALTIVEC_3 (VMSUMUHM, "vmsumuhm", CONST, altivec_vmsumuhm) +BU_ALTIVEC_3 (VMSUMSHM, "vmsumshm", CONST, altivec_vmsumshm) +BU_ALTIVEC_3 (VMSUMUHS, "vmsumuhs", SAT, altivec_vmsumuhs) +BU_ALTIVEC_3 (VMSUMSHS, "vmsumshs", SAT, altivec_vmsumshs) +BU_ALTIVEC_3 (VNMSUBFP, "vnmsubfp", FP, nfmsv4sf4) +BU_ALTIVEC_3 (VPERM_1TI, "vperm_1ti", CONST, altivec_vperm_v1ti) +BU_ALTIVEC_3 (VPERM_2DF, "vperm_2df", CONST, altivec_vperm_v2df) +BU_ALTIVEC_3 (VPERM_2DI, "vperm_2di", CONST, altivec_vperm_v2di) +BU_ALTIVEC_3 (VPERM_4SF, "vperm_4sf", CONST, altivec_vperm_v4sf) +BU_ALTIVEC_3 (VPERM_4SI, "vperm_4si", CONST, altivec_vperm_v4si) +BU_ALTIVEC_3 (VPERM_8HI, "vperm_8hi", CONST, altivec_vperm_v8hi) +BU_ALTIVEC_3 (VPERM_16QI, "vperm_16qi", CONST, altivec_vperm_v16qi_uns) +BU_ALTIVEC_3 (VPERM_1TI_UNS, "vperm_1ti_uns", CONST, altivec_vperm_v1ti_uns) +BU_ALTIVEC_3 (VPERM_2DI_UNS, "vperm_2di_uns", CONST, altivec_vperm_v2di_uns) +BU_ALTIVEC_3 (VPERM_4SI_UNS, "vperm_4si_uns", CONST, altivec_vperm_v4si_uns) +BU_ALTIVEC_3 (VPERM_8HI_UNS, "vperm_8hi_uns", CONST, altivec_vperm_v8hi_uns) +BU_ALTIVEC_3 (VPERM_16QI_UNS, "vperm_16qi_uns", CONST, altivec_vperm_v16qi_uns) +BU_ALTIVEC_3 (VSEL_4SF, "vsel_4sf", CONST, vector_select_v4sf) +BU_ALTIVEC_3 (VSEL_4SI, "vsel_4si", CONST, vector_select_v4si) +BU_ALTIVEC_3 (VSEL_8HI, "vsel_8hi", CONST, vector_select_v8hi) +BU_ALTIVEC_3 (VSEL_16QI, "vsel_16qi", CONST, vector_select_v16qi) +BU_ALTIVEC_3 (VSEL_2DF, "vsel_2df", CONST, vector_select_v2df) +BU_ALTIVEC_3 (VSEL_2DI, "vsel_2di", CONST, vector_select_v2di) +BU_ALTIVEC_3 (VSEL_1TI, "vsel_1ti", CONST, vector_select_v1ti) +BU_ALTIVEC_3 (VSEL_4SI_UNS, "vsel_4si_uns", CONST, vector_select_v4si_uns) +BU_ALTIVEC_3 (VSEL_8HI_UNS, "vsel_8hi_uns", CONST, vector_select_v8hi_uns) +BU_ALTIVEC_3 (VSEL_16QI_UNS, "vsel_16qi_uns", CONST, vector_select_v16qi_uns) +BU_ALTIVEC_3 (VSEL_2DI_UNS, "vsel_2di_uns", CONST, vector_select_v2di_uns) +BU_ALTIVEC_3 (VSEL_1TI_UNS, "vsel_1ti_uns", CONST, vector_select_v1ti_uns) +BU_ALTIVEC_3 (VSLDOI_16QI, "vsldoi_16qi", CONST, altivec_vsldoi_v16qi) +BU_ALTIVEC_3 (VSLDOI_8HI, "vsldoi_8hi", CONST, altivec_vsldoi_v8hi) +BU_ALTIVEC_3 (VSLDOI_4SI, "vsldoi_4si", CONST, altivec_vsldoi_v4si) +BU_ALTIVEC_3 (VSLDOI_4SF, "vsldoi_4sf", CONST, altivec_vsldoi_v4sf) +BU_ALTIVEC_3 (VSLDOI_2DF, "vsldoi_2df", CONST, altivec_vsldoi_v2df) + +/* Altivec DST builtins. */ +BU_ALTIVEC_D (DST, "dst", MISC, altivec_dst) +BU_ALTIVEC_D (DSTT, "dstt", MISC, altivec_dstt) +BU_ALTIVEC_D (DSTST, "dstst", MISC, altivec_dstst) +BU_ALTIVEC_D (DSTSTT, "dststt", MISC, altivec_dststt) + +/* Altivec 2 argument builtin functions. */ +BU_ALTIVEC_2 (VADDUBM, "vaddubm", CONST, addv16qi3) +BU_ALTIVEC_2 (VADDUHM, "vadduhm", CONST, addv8hi3) +BU_ALTIVEC_2 (VADDUWM, "vadduwm", CONST, addv4si3) +BU_ALTIVEC_2 (VADDFP, "vaddfp", CONST, addv4sf3) +BU_ALTIVEC_2 (VADDCUW, "vaddcuw", CONST, altivec_vaddcuw) +BU_ALTIVEC_2 (VADDUBS, "vaddubs", CONST, altivec_vaddubs) +BU_ALTIVEC_2 (VADDSBS, "vaddsbs", CONST, altivec_vaddsbs) +BU_ALTIVEC_2 (VADDUHS, "vadduhs", CONST, altivec_vadduhs) +BU_ALTIVEC_2 (VADDSHS, "vaddshs", CONST, altivec_vaddshs) +BU_ALTIVEC_2 (VADDUWS, "vadduws", CONST, altivec_vadduws) +BU_ALTIVEC_2 (VADDSWS, "vaddsws", CONST, altivec_vaddsws) +BU_ALTIVEC_2 (VAND, "vand", CONST, andv4si3) +BU_ALTIVEC_2 (VANDC, "vandc", CONST, andcv4si3) +BU_ALTIVEC_2 (VAVGUB, "vavgub", CONST, altivec_vavgub) +BU_ALTIVEC_2 (VAVGSB, "vavgsb", CONST, altivec_vavgsb) +BU_ALTIVEC_2 (VAVGUH, "vavguh", CONST, altivec_vavguh) +BU_ALTIVEC_2 (VAVGSH, "vavgsh", CONST, altivec_vavgsh) +BU_ALTIVEC_2 (VAVGUW, "vavguw", CONST, altivec_vavguw) +BU_ALTIVEC_2 (VAVGSW, "vavgsw", CONST, altivec_vavgsw) +BU_ALTIVEC_2 (VCFUX, "vcfux", CONST, altivec_vcfux) +BU_ALTIVEC_2 (VCFSX, "vcfsx", CONST, altivec_vcfsx) +BU_ALTIVEC_2 (VCMPBFP, "vcmpbfp", CONST, altivec_vcmpbfp) +BU_ALTIVEC_2 (VCMPEQUB, "vcmpequb", CONST, vector_eqv16qi) +BU_ALTIVEC_2 (VCMPEQUH, "vcmpequh", CONST, vector_eqv8hi) +BU_ALTIVEC_2 (VCMPEQUW, "vcmpequw", CONST, vector_eqv4si) +BU_ALTIVEC_2 (VCMPEQFP, "vcmpeqfp", CONST, vector_eqv4sf) +BU_ALTIVEC_2 (VCMPGEFP, "vcmpgefp", CONST, vector_gev4sf) +BU_ALTIVEC_2 (VCMPGTUB, "vcmpgtub", CONST, vector_gtuv16qi) +BU_ALTIVEC_2 (VCMPGTSB, "vcmpgtsb", CONST, vector_gtv16qi) +BU_ALTIVEC_2 (VCMPGTUH, "vcmpgtuh", CONST, vector_gtuv8hi) +BU_ALTIVEC_2 (VCMPGTSH, "vcmpgtsh", CONST, vector_gtv8hi) +BU_ALTIVEC_2 (VCMPGTUW, "vcmpgtuw", CONST, vector_gtuv4si) +BU_ALTIVEC_2 (VCMPGTSW, "vcmpgtsw", CONST, vector_gtv4si) +BU_ALTIVEC_2 (VCMPGTFP, "vcmpgtfp", CONST, vector_gtv4sf) +BU_ALTIVEC_2 (VCTSXS, "vctsxs", CONST, altivec_vctsxs) +BU_ALTIVEC_2 (VCTUXS, "vctuxs", CONST, altivec_vctuxs) +BU_ALTIVEC_2 (VMAXUB, "vmaxub", CONST, umaxv16qi3) +BU_ALTIVEC_2 (VMAXSB, "vmaxsb", CONST, smaxv16qi3) +BU_ALTIVEC_2 (VMAXUH, "vmaxuh", CONST, umaxv8hi3) +BU_ALTIVEC_2 (VMAXSH, "vmaxsh", CONST, smaxv8hi3) +BU_ALTIVEC_2 (VMAXUW, "vmaxuw", CONST, umaxv4si3) +BU_ALTIVEC_2 (VMAXSW, "vmaxsw", CONST, smaxv4si3) +BU_ALTIVEC_2 (VMAXFP, "vmaxfp", CONST, smaxv4sf3) +BU_ALTIVEC_2 (VMRGHB, "vmrghb", CONST, altivec_vmrghb) +BU_ALTIVEC_2 (VMRGHH, "vmrghh", CONST, altivec_vmrghh) +BU_ALTIVEC_2 (VMRGHW, "vmrghw", CONST, altivec_vmrghw) +BU_ALTIVEC_2 (VMRGLB, "vmrglb", CONST, altivec_vmrglb) +BU_ALTIVEC_2 (VMRGLH, "vmrglh", CONST, altivec_vmrglh) +BU_ALTIVEC_2 (VMRGLW, "vmrglw", CONST, altivec_vmrglw) +BU_ALTIVEC_2 (VMINUB, "vminub", CONST, uminv16qi3) +BU_ALTIVEC_2 (VMINSB, "vminsb", CONST, sminv16qi3) +BU_ALTIVEC_2 (VMINUH, "vminuh", CONST, uminv8hi3) +BU_ALTIVEC_2 (VMINSH, "vminsh", CONST, sminv8hi3) +BU_ALTIVEC_2 (VMINUW, "vminuw", CONST, uminv4si3) +BU_ALTIVEC_2 (VMINSW, "vminsw", CONST, sminv4si3) +BU_ALTIVEC_2 (VMINFP, "vminfp", CONST, sminv4sf3) +BU_ALTIVEC_2 (VMULEUB, "vmuleub", CONST, vec_widen_umult_even_v16qi) +BU_ALTIVEC_2 (VMULESB, "vmulesb", CONST, vec_widen_smult_even_v16qi) +BU_ALTIVEC_2 (VMULEUH, "vmuleuh", CONST, vec_widen_umult_even_v8hi) +BU_ALTIVEC_2 (VMULESH, "vmulesh", CONST, vec_widen_smult_even_v8hi) +BU_ALTIVEC_2 (VMULOUB, "vmuloub", CONST, vec_widen_umult_odd_v16qi) +BU_ALTIVEC_2 (VMULOSB, "vmulosb", CONST, vec_widen_smult_odd_v16qi) +BU_ALTIVEC_2 (VMULOUH, "vmulouh", CONST, vec_widen_umult_odd_v8hi) +BU_ALTIVEC_2 (VMULOSH, "vmulosh", CONST, vec_widen_smult_odd_v8hi) +BU_ALTIVEC_2 (VNOR, "vnor", CONST, norv4si3) +BU_ALTIVEC_2 (VOR, "vor", CONST, iorv4si3) +BU_ALTIVEC_2 (VPKUHUM, "vpkuhum", CONST, altivec_vpkuhum) +BU_ALTIVEC_2 (VPKUWUM, "vpkuwum", CONST, altivec_vpkuwum) +BU_ALTIVEC_2 (VPKPX, "vpkpx", CONST, altivec_vpkpx) +BU_ALTIVEC_2 (VPKSHSS, "vpkshss", CONST, altivec_vpkshss) +BU_ALTIVEC_2 (VPKSWSS, "vpkswss", CONST, altivec_vpkswss) +BU_ALTIVEC_2 (VPKUHUS, "vpkuhus", CONST, altivec_vpkuhus) +BU_ALTIVEC_2 (VPKSHUS, "vpkshus", CONST, altivec_vpkshus) +BU_ALTIVEC_2 (VPKUWUS, "vpkuwus", CONST, altivec_vpkuwus) +BU_ALTIVEC_2 (VPKSWUS, "vpkswus", CONST, altivec_vpkswus) +BU_ALTIVEC_2 (VRECIPFP, "vrecipdivfp", CONST, recipv4sf3) +BU_ALTIVEC_2 (VRLB, "vrlb", CONST, vrotlv16qi3) +BU_ALTIVEC_2 (VRLH, "vrlh", CONST, vrotlv8hi3) +BU_ALTIVEC_2 (VRLW, "vrlw", CONST, vrotlv4si3) +BU_ALTIVEC_2 (VSLB, "vslb", CONST, vashlv16qi3) +BU_ALTIVEC_2 (VSLH, "vslh", CONST, vashlv8hi3) +BU_ALTIVEC_2 (VSLW, "vslw", CONST, vashlv4si3) +BU_ALTIVEC_2 (VSL, "vsl", CONST, altivec_vsl) +BU_ALTIVEC_2 (VSLO, "vslo", CONST, altivec_vslo) +BU_ALTIVEC_2 (VSPLTB, "vspltb", CONST, altivec_vspltb) +BU_ALTIVEC_2 (VSPLTH, "vsplth", CONST, altivec_vsplth) +BU_ALTIVEC_2 (VSPLTW, "vspltw", CONST, altivec_vspltw) +BU_ALTIVEC_2 (VSRB, "vsrb", CONST, vlshrv16qi3) +BU_ALTIVEC_2 (VSRH, "vsrh", CONST, vlshrv8hi3) +BU_ALTIVEC_2 (VSRW, "vsrw", CONST, vlshrv4si3) +BU_ALTIVEC_2 (VSRAB, "vsrab", CONST, vashrv16qi3) +BU_ALTIVEC_2 (VSRAH, "vsrah", CONST, vashrv8hi3) +BU_ALTIVEC_2 (VSRAW, "vsraw", CONST, vashrv4si3) +BU_ALTIVEC_2 (VSR, "vsr", CONST, altivec_vsr) +BU_ALTIVEC_2 (VSRO, "vsro", CONST, altivec_vsro) +BU_ALTIVEC_2 (VSUBUBM, "vsububm", CONST, subv16qi3) +BU_ALTIVEC_2 (VSUBUHM, "vsubuhm", CONST, subv8hi3) +BU_ALTIVEC_2 (VSUBUWM, "vsubuwm", CONST, subv4si3) +BU_ALTIVEC_2 (VSUBFP, "vsubfp", CONST, subv4sf3) +BU_ALTIVEC_2 (VSUBCUW, "vsubcuw", CONST, altivec_vsubcuw) +BU_ALTIVEC_2 (VSUBUBS, "vsububs", CONST, altivec_vsububs) +BU_ALTIVEC_2 (VSUBSBS, "vsubsbs", CONST, altivec_vsubsbs) +BU_ALTIVEC_2 (VSUBUHS, "vsubuhs", CONST, altivec_vsubuhs) +BU_ALTIVEC_2 (VSUBSHS, "vsubshs", CONST, altivec_vsubshs) +BU_ALTIVEC_2 (VSUBUWS, "vsubuws", CONST, altivec_vsubuws) +BU_ALTIVEC_2 (VSUBSWS, "vsubsws", CONST, altivec_vsubsws) +BU_ALTIVEC_2 (VSUM4UBS, "vsum4ubs", CONST, altivec_vsum4ubs) +BU_ALTIVEC_2 (VSUM4SBS, "vsum4sbs", CONST, altivec_vsum4sbs) +BU_ALTIVEC_2 (VSUM4SHS, "vsum4shs", CONST, altivec_vsum4shs) +BU_ALTIVEC_2 (VSUM2SWS, "vsum2sws", CONST, altivec_vsum2sws) +BU_ALTIVEC_2 (VSUMSWS, "vsumsws", CONST, altivec_vsumsws) +BU_ALTIVEC_2 (VXOR, "vxor", CONST, xorv4si3) +BU_ALTIVEC_2 (COPYSIGN_V4SF, "copysignfp", CONST, vector_copysignv4sf3) + +/* Altivec ABS functions. */ +BU_ALTIVEC_A (ABS_V4SI, "abs_v4si", CONST, absv4si2) +BU_ALTIVEC_A (ABS_V8HI, "abs_v8hi", CONST, absv8hi2) +BU_ALTIVEC_A (ABS_V4SF, "abs_v4sf", CONST, absv4sf2) +BU_ALTIVEC_A (ABS_V16QI, "abs_v16qi", CONST, absv16qi2) +BU_ALTIVEC_A (ABSS_V4SI, "abss_v4si", SAT, altivec_abss_v4si) +BU_ALTIVEC_A (ABSS_V8HI, "abss_v8hi", SAT, altivec_abss_v8hi) +BU_ALTIVEC_A (ABSS_V16QI, "abss_v16qi", SAT, altivec_abss_v16qi) + +/* Altivec NABS functions. */ +BU_ALTIVEC_A (NABS_V2DI, "nabs_v2di", CONST, nabsv2di2) +BU_ALTIVEC_A (NABS_V4SI, "nabs_v4si", CONST, nabsv4si2) +BU_ALTIVEC_A (NABS_V8HI, "nabs_v8hi", CONST, nabsv8hi2) +BU_ALTIVEC_A (NABS_V16QI, "nabs_v16qi", CONST, nabsv16qi2) +BU_ALTIVEC_A (NABS_V4SF, "nabs_v4sf", CONST, vsx_nabsv4sf2) +BU_ALTIVEC_A (NABS_V2DF, "nabs_v2df", CONST, vsx_nabsv2df2) + +/* Altivec NEG functions. */ +BU_ALTIVEC_A (NEG_V2DI, "neg_v2di", CONST, negv2di2) +BU_ALTIVEC_A (NEG_V4SI, "neg_v4si", CONST, negv4si2) +BU_ALTIVEC_A (NEG_V8HI, "neg_v8hi", CONST, negv8hi2) +BU_ALTIVEC_A (NEG_V16QI, "neg_v16qi", CONST, negv16qi2) +BU_ALTIVEC_A (NEG_V4SF, "neg_v4sf", CONST, negv4sf2) +BU_ALTIVEC_A (NEG_V2DF, "neg_v2df", CONST, negv2df2) + +/* 1 argument Altivec builtin functions. */ +BU_ALTIVEC_1 (VEXPTEFP, "vexptefp", FP, altivec_vexptefp) +BU_ALTIVEC_1 (VLOGEFP, "vlogefp", FP, altivec_vlogefp) +BU_ALTIVEC_1 (VREFP, "vrefp", FP, rev4sf2) +BU_ALTIVEC_1 (VRFIM, "vrfim", FP, vector_floorv4sf2) +BU_ALTIVEC_1 (VRFIN, "vrfin", FP, altivec_vrfin) +BU_ALTIVEC_1 (VRFIP, "vrfip", FP, vector_ceilv4sf2) +BU_ALTIVEC_1 (VRFIZ, "vrfiz", FP, vector_btruncv4sf2) +BU_ALTIVEC_1 (VRSQRTFP, "vrsqrtfp", FP, rsqrtv4sf2) +BU_ALTIVEC_1 (VRSQRTEFP, "vrsqrtefp", FP, rsqrtev4sf2) +BU_ALTIVEC_1 (VSPLTISB, "vspltisb", CONST, altivec_vspltisb) +BU_ALTIVEC_1 (VSPLTISH, "vspltish", CONST, altivec_vspltish) +BU_ALTIVEC_1 (VSPLTISW, "vspltisw", CONST, altivec_vspltisw) +BU_ALTIVEC_1 (VUPKHSB, "vupkhsb", CONST, altivec_vupkhsb) +BU_ALTIVEC_1 (VUPKHPX, "vupkhpx", CONST, altivec_vupkhpx) +BU_ALTIVEC_1 (VUPKHSH, "vupkhsh", CONST, altivec_vupkhsh) +BU_ALTIVEC_1 (VUPKLSB, "vupklsb", CONST, altivec_vupklsb) +BU_ALTIVEC_1 (VUPKLPX, "vupklpx", CONST, altivec_vupklpx) +BU_ALTIVEC_1 (VUPKLSH, "vupklsh", CONST, altivec_vupklsh) + +BU_ALTIVEC_1 (FLOAT_V4SI_V4SF, "float_sisf", FP, floatv4siv4sf2) +BU_ALTIVEC_1 (UNSFLOAT_V4SI_V4SF, "uns_float_sisf", FP, floatunsv4siv4sf2) +BU_ALTIVEC_1 (FIX_V4SF_V4SI, "fix_sfsi", FP, fix_truncv4sfv4si2) +BU_ALTIVEC_1 (FIXUNS_V4SF_V4SI, "fixuns_sfsi", FP, fixuns_truncv4sfv4si2) + +/* Altivec predicate functions. */ +BU_ALTIVEC_P (VCMPBFP_P, "vcmpbfp_p", CONST, altivec_vcmpbfp_p) +BU_ALTIVEC_P (VCMPEQFP_P, "vcmpeqfp_p", CONST, vector_eq_v4sf_p) +BU_ALTIVEC_P (VCMPGEFP_P, "vcmpgefp_p", CONST, vector_ge_v4sf_p) +BU_ALTIVEC_P (VCMPGTFP_P, "vcmpgtfp_p", CONST, vector_gt_v4sf_p) +BU_ALTIVEC_P (VCMPEQUW_P, "vcmpequw_p", CONST, vector_eq_v4si_p) +BU_ALTIVEC_P (VCMPGTSW_P, "vcmpgtsw_p", CONST, vector_gt_v4si_p) +BU_ALTIVEC_P (VCMPGTUW_P, "vcmpgtuw_p", CONST, vector_gtu_v4si_p) +BU_ALTIVEC_P (VCMPEQUH_P, "vcmpequh_p", CONST, vector_eq_v8hi_p) +BU_ALTIVEC_P (VCMPGTSH_P, "vcmpgtsh_p", CONST, vector_gt_v8hi_p) +BU_ALTIVEC_P (VCMPGTUH_P, "vcmpgtuh_p", CONST, vector_gtu_v8hi_p) +BU_ALTIVEC_P (VCMPEQUB_P, "vcmpequb_p", CONST, vector_eq_v16qi_p) +BU_ALTIVEC_P (VCMPGTSB_P, "vcmpgtsb_p", CONST, vector_gt_v16qi_p) +BU_ALTIVEC_P (VCMPGTUB_P, "vcmpgtub_p", CONST, vector_gtu_v16qi_p) + +/* AltiVec builtins that are handled as special cases. */ +BU_ALTIVEC_X (ST_INTERNAL_4si, "st_internal_4si", MEM) +BU_ALTIVEC_X (LD_INTERNAL_4si, "ld_internal_4si", MEM) +BU_ALTIVEC_X (ST_INTERNAL_8hi, "st_internal_8hi", MEM) +BU_ALTIVEC_X (LD_INTERNAL_8hi, "ld_internal_8hi", MEM) +BU_ALTIVEC_X (ST_INTERNAL_16qi, "st_internal_16qi", MEM) +BU_ALTIVEC_X (LD_INTERNAL_16qi, "ld_internal_16qi", MEM) +BU_ALTIVEC_X (ST_INTERNAL_4sf, "st_internal_16qi", MEM) +BU_ALTIVEC_X (LD_INTERNAL_4sf, "ld_internal_4sf", MEM) +BU_ALTIVEC_X (ST_INTERNAL_2df, "st_internal_4sf", MEM) +BU_ALTIVEC_X (LD_INTERNAL_2df, "ld_internal_2df", MEM) +BU_ALTIVEC_X (ST_INTERNAL_2di, "st_internal_2di", MEM) +BU_ALTIVEC_X (LD_INTERNAL_2di, "ld_internal_2di", MEM) +BU_ALTIVEC_X (ST_INTERNAL_1ti, "st_internal_1ti", MEM) +BU_ALTIVEC_X (LD_INTERNAL_1ti, "ld_internal_1ti", MEM) +BU_ALTIVEC_X (MTVSCR, "mtvscr", MISC) +BU_ALTIVEC_X (MFVSCR, "mfvscr", MISC) +BU_ALTIVEC_X (DSSALL, "dssall", MISC) +BU_ALTIVEC_X (DSS, "dss", MISC) +BU_ALTIVEC_X (LVSL, "lvsl", MEM) +BU_ALTIVEC_X (LVSR, "lvsr", MEM) +BU_ALTIVEC_X (LVEBX, "lvebx", MEM) +BU_ALTIVEC_X (LVEHX, "lvehx", MEM) +BU_ALTIVEC_X (LVEWX, "lvewx", MEM) +BU_ALTIVEC_X (LVXL, "lvxl", MEM) +BU_ALTIVEC_X (LVXL_V2DF, "lvxl_v2df", MEM) +BU_ALTIVEC_X (LVXL_V2DI, "lvxl_v2di", MEM) +BU_ALTIVEC_X (LVXL_V4SF, "lvxl_v4sf", MEM) +BU_ALTIVEC_X (LVXL_V4SI, "lvxl_v4si", MEM) +BU_ALTIVEC_X (LVXL_V8HI, "lvxl_v8hi", MEM) +BU_ALTIVEC_X (LVXL_V16QI, "lvxl_v16qi", MEM) +BU_ALTIVEC_X (LVX, "lvx", MEM) +BU_ALTIVEC_X (LVX_V2DF, "lvx_v2df", MEM) +BU_ALTIVEC_X (LVX_V2DI, "lvx_v2di", MEM) +BU_ALTIVEC_X (LVX_V4SF, "lvx_v4sf", MEM) +BU_ALTIVEC_X (LVX_V4SI, "lvx_v4si", MEM) +BU_ALTIVEC_X (LVX_V8HI, "lvx_v8hi", MEM) +BU_ALTIVEC_X (LVX_V16QI, "lvx_v16qi", MEM) +BU_ALTIVEC_X (STVX, "stvx", MEM) +BU_ALTIVEC_X (STVX_V2DF, "stvx_v2df", MEM) +BU_ALTIVEC_X (STVX_V2DI, "stvx_v2di", MEM) +BU_ALTIVEC_X (STVX_V4SF, "stvx_v4sf", MEM) +BU_ALTIVEC_X (STVX_V4SI, "stvx_v4si", MEM) +BU_ALTIVEC_X (STVX_V8HI, "stvx_v8hi", MEM) +BU_ALTIVEC_X (STVX_V16QI, "stvx_v16qi", MEM) +BU_ALTIVEC_C (LVLX, "lvlx", MEM) +BU_ALTIVEC_C (LVLXL, "lvlxl", MEM) +BU_ALTIVEC_C (LVRX, "lvrx", MEM) +BU_ALTIVEC_C (LVRXL, "lvrxl", MEM) +BU_ALTIVEC_X (STVEBX, "stvebx", MEM) +BU_ALTIVEC_X (STVEHX, "stvehx", MEM) +BU_ALTIVEC_X (STVEWX, "stvewx", MEM) +BU_ALTIVEC_X (STVXL, "stvxl", MEM) +BU_ALTIVEC_X (STVXL_V2DF, "stvxl_v2df", MEM) +BU_ALTIVEC_X (STVXL_V2DI, "stvxl_v2di", MEM) +BU_ALTIVEC_X (STVXL_V4SF, "stvxl_v4sf", MEM) +BU_ALTIVEC_X (STVXL_V4SI, "stvxl_v4si", MEM) +BU_ALTIVEC_X (STVXL_V8HI, "stvxl_v8hi", MEM) +BU_ALTIVEC_X (STVXL_V16QI, "stvxl_v16qi", MEM) +BU_ALTIVEC_C (STVLX, "stvlx", MEM) +BU_ALTIVEC_C (STVLXL, "stvlxl", MEM) +BU_ALTIVEC_C (STVRX, "stvrx", MEM) +BU_ALTIVEC_C (STVRXL, "stvrxl", MEM) +BU_ALTIVEC_X (MASK_FOR_LOAD, "mask_for_load", MISC) +BU_ALTIVEC_X (MASK_FOR_STORE, "mask_for_store", MISC) +BU_ALTIVEC_X (VEC_INIT_V4SI, "vec_init_v4si", CONST) +BU_ALTIVEC_X (VEC_INIT_V8HI, "vec_init_v8hi", CONST) +BU_ALTIVEC_X (VEC_INIT_V16QI, "vec_init_v16qi", CONST) +BU_ALTIVEC_X (VEC_INIT_V4SF, "vec_init_v4sf", CONST) +BU_ALTIVEC_X (VEC_SET_V4SI, "vec_set_v4si", CONST) +BU_ALTIVEC_X (VEC_SET_V8HI, "vec_set_v8hi", CONST) +BU_ALTIVEC_X (VEC_SET_V16QI, "vec_set_v16qi", CONST) +BU_ALTIVEC_X (VEC_SET_V4SF, "vec_set_v4sf", CONST) +BU_ALTIVEC_X (VEC_EXT_V4SI, "vec_ext_v4si", CONST) +BU_ALTIVEC_X (VEC_EXT_V8HI, "vec_ext_v8hi", CONST) +BU_ALTIVEC_X (VEC_EXT_V16QI, "vec_ext_v16qi", CONST) +BU_ALTIVEC_X (VEC_EXT_V4SF, "vec_ext_v4sf", CONST) + +/* Altivec overloaded builtins. */ +/* For now, don't set the classification for overloaded functions. + The function should be converted to the type specific instruction + before we get to the point about classifying the builtin type. */ + +/* 3 argument Altivec overloaded builtins. */ +BU_ALTIVEC_OVERLOAD_3 (MADD, "madd") +BU_ALTIVEC_OVERLOAD_3 (MADDS, "madds") +BU_ALTIVEC_OVERLOAD_3 (MLADD, "mladd") +BU_ALTIVEC_OVERLOAD_3 (MRADDS, "mradds") +BU_ALTIVEC_OVERLOAD_3 (MSUM, "msum") +BU_ALTIVEC_OVERLOAD_3 (MSUMS, "msums") +BU_ALTIVEC_OVERLOAD_3 (NMSUB, "nmsub") +BU_ALTIVEC_OVERLOAD_3 (PERM, "perm") +BU_ALTIVEC_OVERLOAD_3 (SEL, "sel") +BU_ALTIVEC_OVERLOAD_3 (VMSUMMBM, "vmsummbm") +BU_ALTIVEC_OVERLOAD_3 (VMSUMSHM, "vmsumshm") +BU_ALTIVEC_OVERLOAD_3 (VMSUMSHS, "vmsumshs") +BU_ALTIVEC_OVERLOAD_3 (VMSUMUBM, "vmsumubm") +BU_ALTIVEC_OVERLOAD_3 (VMSUMUHM, "vmsumuhm") +BU_ALTIVEC_OVERLOAD_3 (VMSUMUHS, "vmsumuhs") + +/* Altivec DST overloaded builtins. */ +BU_ALTIVEC_OVERLOAD_D (DST, "dst") +BU_ALTIVEC_OVERLOAD_D (DSTT, "dstt") +BU_ALTIVEC_OVERLOAD_D (DSTST, "dstst") +BU_ALTIVEC_OVERLOAD_D (DSTSTT, "dststt") + +/* 2 argument Altivec overloaded builtins. */ +BU_ALTIVEC_OVERLOAD_2 (ADD, "add") +BU_ALTIVEC_OVERLOAD_2 (ADDC, "addc") +BU_ALTIVEC_OVERLOAD_2 (ADDS, "adds") +BU_ALTIVEC_OVERLOAD_2 (AND, "and") +BU_ALTIVEC_OVERLOAD_2 (ANDC, "andc") +BU_ALTIVEC_OVERLOAD_2 (AVG, "avg") +BU_ALTIVEC_OVERLOAD_2 (CMPB, "cmpb") +BU_ALTIVEC_OVERLOAD_2 (CMPEQ, "cmpeq") +BU_ALTIVEC_OVERLOAD_2 (CMPGE, "cmpge") +BU_ALTIVEC_OVERLOAD_2 (CMPGT, "cmpgt") +BU_ALTIVEC_OVERLOAD_2 (CMPLE, "cmple") +BU_ALTIVEC_OVERLOAD_2 (CMPLT, "cmplt") +BU_ALTIVEC_OVERLOAD_2 (COPYSIGN, "copysign") +BU_ALTIVEC_OVERLOAD_2 (MAX, "max") +BU_ALTIVEC_OVERLOAD_2 (MERGEH, "mergeh") +BU_ALTIVEC_OVERLOAD_2 (MERGEL, "mergel") +BU_ALTIVEC_OVERLOAD_2 (MIN, "min") +BU_ALTIVEC_OVERLOAD_2 (MULE, "mule") +BU_ALTIVEC_OVERLOAD_2 (MULO, "mulo") +BU_ALTIVEC_OVERLOAD_2 (NOR, "nor") +BU_ALTIVEC_OVERLOAD_2 (OR, "or") +BU_ALTIVEC_OVERLOAD_2 (PACK, "pack") +BU_ALTIVEC_OVERLOAD_2 (PACKPX, "packpx") +BU_ALTIVEC_OVERLOAD_2 (PACKS, "packs") +BU_ALTIVEC_OVERLOAD_2 (PACKSU, "packsu") +BU_ALTIVEC_OVERLOAD_2 (RECIP, "recipdiv") +BU_ALTIVEC_OVERLOAD_2 (RL, "rl") +BU_ALTIVEC_OVERLOAD_2 (SL, "sl") +BU_ALTIVEC_OVERLOAD_2 (SLL, "sll") +BU_ALTIVEC_OVERLOAD_2 (SLO, "slo") +BU_ALTIVEC_OVERLOAD_2 (SR, "sr") +BU_ALTIVEC_OVERLOAD_2 (SRA, "sra") +BU_ALTIVEC_OVERLOAD_2 (SRL, "srl") +BU_ALTIVEC_OVERLOAD_2 (SRO, "sro") +BU_ALTIVEC_OVERLOAD_2 (SUB, "sub") +BU_ALTIVEC_OVERLOAD_2 (SUBC, "subc") +BU_ALTIVEC_OVERLOAD_2 (SUBS, "subs") +BU_ALTIVEC_OVERLOAD_2 (SUM2S, "sum2s") +BU_ALTIVEC_OVERLOAD_2 (SUM4S, "sum4s") +BU_ALTIVEC_OVERLOAD_2 (SUMS, "sums") +BU_ALTIVEC_OVERLOAD_2 (VADDFP, "vaddfp") +BU_ALTIVEC_OVERLOAD_2 (VADDSBS, "vaddsbs") +BU_ALTIVEC_OVERLOAD_2 (VADDSHS, "vaddshs") +BU_ALTIVEC_OVERLOAD_2 (VADDSWS, "vaddsws") +BU_ALTIVEC_OVERLOAD_2 (VADDUBM, "vaddubm") +BU_ALTIVEC_OVERLOAD_2 (VADDUBS, "vaddubs") +BU_ALTIVEC_OVERLOAD_2 (VADDUHM, "vadduhm") +BU_ALTIVEC_OVERLOAD_2 (VADDUHS, "vadduhs") +BU_ALTIVEC_OVERLOAD_2 (VADDUWM, "vadduwm") +BU_ALTIVEC_OVERLOAD_2 (VADDUWS, "vadduws") +BU_ALTIVEC_OVERLOAD_2 (VAVGSB, "vavgsb") +BU_ALTIVEC_OVERLOAD_2 (VAVGSH, "vavgsh") +BU_ALTIVEC_OVERLOAD_2 (VAVGSW, "vavgsw") +BU_ALTIVEC_OVERLOAD_2 (VAVGUB, "vavgub") +BU_ALTIVEC_OVERLOAD_2 (VAVGUH, "vavguh") +BU_ALTIVEC_OVERLOAD_2 (VAVGUW, "vavguw") +BU_ALTIVEC_OVERLOAD_2 (VCMPEQFP, "vcmpeqfp") +BU_ALTIVEC_OVERLOAD_2 (VCMPEQUB, "vcmpequb") +BU_ALTIVEC_OVERLOAD_2 (VCMPEQUH, "vcmpequh") +BU_ALTIVEC_OVERLOAD_2 (VCMPEQUW, "vcmpequw") +BU_ALTIVEC_OVERLOAD_2 (VCMPGTFP, "vcmpgtfp") +BU_ALTIVEC_OVERLOAD_2 (VCMPGTSB, "vcmpgtsb") +BU_ALTIVEC_OVERLOAD_2 (VCMPGTSH, "vcmpgtsh") +BU_ALTIVEC_OVERLOAD_2 (VCMPGTSW, "vcmpgtsw") +BU_ALTIVEC_OVERLOAD_2 (VCMPGTUB, "vcmpgtub") +BU_ALTIVEC_OVERLOAD_2 (VCMPGTUH, "vcmpgtuh") +BU_ALTIVEC_OVERLOAD_2 (VCMPGTUW, "vcmpgtuw") +BU_ALTIVEC_OVERLOAD_2 (VMAXFP, "vmaxfp") +BU_ALTIVEC_OVERLOAD_2 (VMAXSB, "vmaxsb") +BU_ALTIVEC_OVERLOAD_2 (VMAXSH, "vmaxsh") +BU_ALTIVEC_OVERLOAD_2 (VMAXSW, "vmaxsw") +BU_ALTIVEC_OVERLOAD_2 (VMAXUB, "vmaxub") +BU_ALTIVEC_OVERLOAD_2 (VMAXUH, "vmaxuh") +BU_ALTIVEC_OVERLOAD_2 (VMAXUW, "vmaxuw") +BU_ALTIVEC_OVERLOAD_2 (VMINFP, "vminfp") +BU_ALTIVEC_OVERLOAD_2 (VMINSB, "vminsb") +BU_ALTIVEC_OVERLOAD_2 (VMINSH, "vminsh") +BU_ALTIVEC_OVERLOAD_2 (VMINSW, "vminsw") +BU_ALTIVEC_OVERLOAD_2 (VMINUB, "vminub") +BU_ALTIVEC_OVERLOAD_2 (VMINUH, "vminuh") +BU_ALTIVEC_OVERLOAD_2 (VMINUW, "vminuw") +BU_ALTIVEC_OVERLOAD_2 (VMRGHB, "vmrghb") +BU_ALTIVEC_OVERLOAD_2 (VMRGHH, "vmrghh") +BU_ALTIVEC_OVERLOAD_2 (VMRGHW, "vmrghw") +BU_ALTIVEC_OVERLOAD_2 (VMRGLB, "vmrglb") +BU_ALTIVEC_OVERLOAD_2 (VMRGLH, "vmrglh") +BU_ALTIVEC_OVERLOAD_2 (VMRGLW, "vmrglw") +BU_ALTIVEC_OVERLOAD_2 (VMULESB, "vmulesb") +BU_ALTIVEC_OVERLOAD_2 (VMULESH, "vmulesh") +BU_ALTIVEC_OVERLOAD_2 (VMULEUB, "vmuleub") +BU_ALTIVEC_OVERLOAD_2 (VMULEUH, "vmuleuh") +BU_ALTIVEC_OVERLOAD_2 (VMULOSB, "vmulosb") +BU_ALTIVEC_OVERLOAD_2 (VMULOSH, "vmulosh") +BU_ALTIVEC_OVERLOAD_2 (VMULOUB, "vmuloub") +BU_ALTIVEC_OVERLOAD_2 (VMULOUH, "vmulouh") +BU_ALTIVEC_OVERLOAD_2 (VPKSHSS, "vpkshss") +BU_ALTIVEC_OVERLOAD_2 (VPKSHUS, "vpkshus") +BU_ALTIVEC_OVERLOAD_2 (VPKSWSS, "vpkswss") +BU_ALTIVEC_OVERLOAD_2 (VPKSWUS, "vpkswus") +BU_ALTIVEC_OVERLOAD_2 (VPKUHUM, "vpkuhum") +BU_ALTIVEC_OVERLOAD_2 (VPKUHUS, "vpkuhus") +BU_ALTIVEC_OVERLOAD_2 (VPKUWUM, "vpkuwum") +BU_ALTIVEC_OVERLOAD_2 (VPKUWUS, "vpkuwus") +BU_ALTIVEC_OVERLOAD_2 (VRLB, "vrlb") +BU_ALTIVEC_OVERLOAD_2 (VRLH, "vrlh") +BU_ALTIVEC_OVERLOAD_2 (VRLW, "vrlw") +BU_ALTIVEC_OVERLOAD_2 (VSLB, "vslb") +BU_ALTIVEC_OVERLOAD_2 (VSLH, "vslh") +BU_ALTIVEC_OVERLOAD_2 (VSLW, "vslw") +BU_ALTIVEC_OVERLOAD_2 (VSRAB, "vsrab") +BU_ALTIVEC_OVERLOAD_2 (VSRAH, "vsrah") +BU_ALTIVEC_OVERLOAD_2 (VSRAW, "vsraw") +BU_ALTIVEC_OVERLOAD_2 (VSRB, "vsrb") +BU_ALTIVEC_OVERLOAD_2 (VSRH, "vsrh") +BU_ALTIVEC_OVERLOAD_2 (VSRW, "vsrw") +BU_ALTIVEC_OVERLOAD_2 (VSUBFP, "vsubfp") +BU_ALTIVEC_OVERLOAD_2 (VSUBSBS, "vsubsbs") +BU_ALTIVEC_OVERLOAD_2 (VSUBSHS, "vsubshs") +BU_ALTIVEC_OVERLOAD_2 (VSUBSWS, "vsubsws") +BU_ALTIVEC_OVERLOAD_2 (VSUBUBM, "vsububm") +BU_ALTIVEC_OVERLOAD_2 (VSUBUBS, "vsububs") +BU_ALTIVEC_OVERLOAD_2 (VSUBUHM, "vsubuhm") +BU_ALTIVEC_OVERLOAD_2 (VSUBUHS, "vsubuhs") +BU_ALTIVEC_OVERLOAD_2 (VSUBUWM, "vsubuwm") +BU_ALTIVEC_OVERLOAD_2 (VSUBUWS, "vsubuws") +BU_ALTIVEC_OVERLOAD_2 (VSUM4SBS, "vsum4sbs") +BU_ALTIVEC_OVERLOAD_2 (VSUM4SHS, "vsum4shs") +BU_ALTIVEC_OVERLOAD_2 (VSUM4UBS, "vsum4ubs") +BU_ALTIVEC_OVERLOAD_2 (XOR, "xor") + +/* 1 argument Altivec overloaded functions. */ +BU_ALTIVEC_OVERLOAD_1 (ABS, "abs") +BU_ALTIVEC_OVERLOAD_1 (NABS, "nabs") +BU_ALTIVEC_OVERLOAD_1 (ABSS, "abss") +BU_ALTIVEC_OVERLOAD_1 (CEIL, "ceil") +BU_ALTIVEC_OVERLOAD_1 (EXPTE, "expte") +BU_ALTIVEC_OVERLOAD_1 (FLOOR, "floor") +BU_ALTIVEC_OVERLOAD_1 (LOGE, "loge") +BU_ALTIVEC_OVERLOAD_1 (MTVSCR, "mtvscr") +BU_ALTIVEC_OVERLOAD_1 (NEARBYINT, "nearbyint") +BU_ALTIVEC_OVERLOAD_1 (NEG, "neg") +BU_ALTIVEC_OVERLOAD_1 (RE, "re") +BU_ALTIVEC_OVERLOAD_1 (RINT, "rint") +BU_ALTIVEC_OVERLOAD_1 (ROUND, "round") +BU_ALTIVEC_OVERLOAD_1 (RSQRT, "rsqrt") +BU_ALTIVEC_OVERLOAD_1 (RSQRTE, "rsqrte") +BU_ALTIVEC_OVERLOAD_1 (SQRT, "sqrt") +BU_ALTIVEC_OVERLOAD_1 (TRUNC, "trunc") +BU_ALTIVEC_OVERLOAD_1 (UNPACKH, "unpackh") +BU_ALTIVEC_OVERLOAD_1 (UNPACKL, "unpackl") +BU_ALTIVEC_OVERLOAD_1 (VUPKHPX, "vupkhpx") +BU_ALTIVEC_OVERLOAD_1 (VUPKHSB, "vupkhsb") +BU_ALTIVEC_OVERLOAD_1 (VUPKHSH, "vupkhsh") +BU_ALTIVEC_OVERLOAD_1 (VUPKLPX, "vupklpx") +BU_ALTIVEC_OVERLOAD_1 (VUPKLSB, "vupklsb") +BU_ALTIVEC_OVERLOAD_1 (VUPKLSH, "vupklsh") + +/* Overloaded altivec predicates. */ +BU_ALTIVEC_OVERLOAD_P (VCMPEQ_P, "vcmpeq_p") +BU_ALTIVEC_OVERLOAD_P (VCMPGT_P, "vcmpgt_p") +BU_ALTIVEC_OVERLOAD_P (VCMPGE_P, "vcmpge_p") + +/* Overloaded Altivec builtins that are handled as special cases. */ +BU_ALTIVEC_OVERLOAD_X (ADDE, "adde") +BU_ALTIVEC_OVERLOAD_X (ADDEC, "addec") +BU_ALTIVEC_OVERLOAD_X (CMPNE, "cmpne") +BU_ALTIVEC_OVERLOAD_X (CTF, "ctf") +BU_ALTIVEC_OVERLOAD_X (CTS, "cts") +BU_ALTIVEC_OVERLOAD_X (CTU, "ctu") +BU_ALTIVEC_OVERLOAD_X (EXTRACT, "extract") +BU_ALTIVEC_OVERLOAD_X (INSERT, "insert") +BU_ALTIVEC_OVERLOAD_X (LD, "ld") +BU_ALTIVEC_OVERLOAD_X (LDE, "lde") +BU_ALTIVEC_OVERLOAD_X (LDL, "ldl") +BU_ALTIVEC_OVERLOAD_X (LVEBX, "lvebx") +BU_ALTIVEC_OVERLOAD_X (LVEHX, "lvehx") +BU_ALTIVEC_OVERLOAD_X (LVEWX, "lvewx") +BU_ALTIVEC_OVERLOAD_X (LVLX, "lvlx") +BU_ALTIVEC_OVERLOAD_X (LVLXL, "lvlxl") +BU_ALTIVEC_OVERLOAD_X (LVRX, "lvrx") +BU_ALTIVEC_OVERLOAD_X (LVRXL, "lvrxl") +BU_ALTIVEC_OVERLOAD_X (LVSL, "lvsl") +BU_ALTIVEC_OVERLOAD_X (LVSR, "lvsr") +BU_ALTIVEC_OVERLOAD_X (MUL, "mul") +BU_ALTIVEC_OVERLOAD_X (PROMOTE, "promote") +BU_ALTIVEC_OVERLOAD_X (SLD, "sld") +BU_ALTIVEC_OVERLOAD_X (SLDW, "sldw") +BU_ALTIVEC_OVERLOAD_X (SPLAT, "splat") +BU_ALTIVEC_OVERLOAD_X (SPLATS, "splats") +BU_ALTIVEC_OVERLOAD_X (ST, "st") +BU_ALTIVEC_OVERLOAD_X (STE, "ste") +BU_ALTIVEC_OVERLOAD_X (STEP, "step") +BU_ALTIVEC_OVERLOAD_X (STL, "stl") +BU_ALTIVEC_OVERLOAD_X (STVEBX, "stvebx") +BU_ALTIVEC_OVERLOAD_X (STVEHX, "stvehx") +BU_ALTIVEC_OVERLOAD_X (STVEWX, "stvewx") +BU_ALTIVEC_OVERLOAD_X (STVLX, "stvlx") +BU_ALTIVEC_OVERLOAD_X (STVLXL, "stvlxl") +BU_ALTIVEC_OVERLOAD_X (STVRX, "stvrx") +BU_ALTIVEC_OVERLOAD_X (STVRXL, "stvrxl") +BU_ALTIVEC_OVERLOAD_X (VCFSX, "vcfsx") +BU_ALTIVEC_OVERLOAD_X (VCFUX, "vcfux") +BU_ALTIVEC_OVERLOAD_X (VSPLTB, "vspltb") +BU_ALTIVEC_OVERLOAD_X (VSPLTH, "vsplth") +BU_ALTIVEC_OVERLOAD_X (VSPLTW, "vspltw") + +/* 3 argument VSX builtins. */ +BU_VSX_3 (XVMADDSP, "xvmaddsp", CONST, fmav4sf4) +BU_VSX_3 (XVMSUBSP, "xvmsubsp", CONST, fmsv4sf4) +BU_VSX_3 (XVNMADDSP, "xvnmaddsp", CONST, nfmav4sf4) +BU_VSX_3 (XVNMSUBSP, "xvnmsubsp", CONST, nfmsv4sf4) + +BU_VSX_3 (XVMADDDP, "xvmadddp", CONST, fmav2df4) +BU_VSX_3 (XVMSUBDP, "xvmsubdp", CONST, fmsv2df4) +BU_VSX_3 (XVNMADDDP, "xvnmadddp", CONST, nfmav2df4) +BU_VSX_3 (XVNMSUBDP, "xvnmsubdp", CONST, nfmsv2df4) + +BU_VSX_3 (XXSEL_1TI, "xxsel_1ti", CONST, vector_select_v1ti) +BU_VSX_3 (XXSEL_2DI, "xxsel_2di", CONST, vector_select_v2di) +BU_VSX_3 (XXSEL_2DF, "xxsel_2df", CONST, vector_select_v2df) +BU_VSX_3 (XXSEL_4SF, "xxsel_4sf", CONST, vector_select_v4sf) +BU_VSX_3 (XXSEL_4SI, "xxsel_4si", CONST, vector_select_v4si) +BU_VSX_3 (XXSEL_8HI, "xxsel_8hi", CONST, vector_select_v8hi) +BU_VSX_3 (XXSEL_16QI, "xxsel_16qi", CONST, vector_select_v16qi) +BU_VSX_3 (XXSEL_1TI_UNS, "xxsel_1ti_uns", CONST, vector_select_v1ti_uns) +BU_VSX_3 (XXSEL_2DI_UNS, "xxsel_2di_uns", CONST, vector_select_v2di_uns) +BU_VSX_3 (XXSEL_4SI_UNS, "xxsel_4si_uns", CONST, vector_select_v4si_uns) +BU_VSX_3 (XXSEL_8HI_UNS, "xxsel_8hi_uns", CONST, vector_select_v8hi_uns) +BU_VSX_3 (XXSEL_16QI_UNS, "xxsel_16qi_uns", CONST, vector_select_v16qi_uns) + +BU_VSX_3 (VPERM_1TI, "vperm_1ti", CONST, altivec_vperm_v1ti) +BU_VSX_3 (VPERM_2DI, "vperm_2di", CONST, altivec_vperm_v2di) +BU_VSX_3 (VPERM_2DF, "vperm_2df", CONST, altivec_vperm_v2df) +BU_VSX_3 (VPERM_4SF, "vperm_4sf", CONST, altivec_vperm_v4sf) +BU_VSX_3 (VPERM_4SI, "vperm_4si", CONST, altivec_vperm_v4si) +BU_VSX_3 (VPERM_8HI, "vperm_8hi", CONST, altivec_vperm_v8hi) +BU_VSX_3 (VPERM_16QI, "vperm_16qi", CONST, altivec_vperm_v16qi) +BU_VSX_3 (VPERM_1TI_UNS, "vperm_1ti_uns", CONST, altivec_vperm_v1ti_uns) +BU_VSX_3 (VPERM_2DI_UNS, "vperm_2di_uns", CONST, altivec_vperm_v2di_uns) +BU_VSX_3 (VPERM_4SI_UNS, "vperm_4si_uns", CONST, altivec_vperm_v4si_uns) +BU_VSX_3 (VPERM_8HI_UNS, "vperm_8hi_uns", CONST, altivec_vperm_v8hi_uns) +BU_VSX_3 (VPERM_16QI_UNS, "vperm_16qi_uns", CONST, altivec_vperm_v16qi_uns) + +BU_VSX_3 (XXPERMDI_1TI, "xxpermdi_1ti", CONST, vsx_xxpermdi_v1ti) +BU_VSX_3 (XXPERMDI_2DF, "xxpermdi_2df", CONST, vsx_xxpermdi_v2df) +BU_VSX_3 (XXPERMDI_2DI, "xxpermdi_2di", CONST, vsx_xxpermdi_v2di) +BU_VSX_3 (XXPERMDI_4SF, "xxpermdi_4sf", CONST, vsx_xxpermdi_v4sf) +BU_VSX_3 (XXPERMDI_4SI, "xxpermdi_4si", CONST, vsx_xxpermdi_v4si) +BU_VSX_3 (XXPERMDI_8HI, "xxpermdi_8hi", CONST, vsx_xxpermdi_v8hi) +BU_VSX_3 (XXPERMDI_16QI, "xxpermdi_16qi", CONST, vsx_xxpermdi_v16qi) +BU_VSX_3 (SET_1TI, "set_1ti", CONST, vsx_set_v1ti) +BU_VSX_3 (SET_2DF, "set_2df", CONST, vsx_set_v2df) +BU_VSX_3 (SET_2DI, "set_2di", CONST, vsx_set_v2di) +BU_VSX_3 (XXSLDWI_2DI, "xxsldwi_2di", CONST, vsx_xxsldwi_v2di) +BU_VSX_3 (XXSLDWI_2DF, "xxsldwi_2df", CONST, vsx_xxsldwi_v2df) +BU_VSX_3 (XXSLDWI_4SF, "xxsldwi_4sf", CONST, vsx_xxsldwi_v4sf) +BU_VSX_3 (XXSLDWI_4SI, "xxsldwi_4si", CONST, vsx_xxsldwi_v4si) +BU_VSX_3 (XXSLDWI_8HI, "xxsldwi_8hi", CONST, vsx_xxsldwi_v8hi) +BU_VSX_3 (XXSLDWI_16QI, "xxsldwi_16qi", CONST, vsx_xxsldwi_v16qi) + +/* 2 argument VSX builtins. */ +BU_VSX_2 (XVADDDP, "xvadddp", FP, addv2df3) +BU_VSX_2 (XVSUBDP, "xvsubdp", FP, subv2df3) +BU_VSX_2 (XVMULDP, "xvmuldp", FP, mulv2df3) +BU_VSX_2 (XVDIVDP, "xvdivdp", FP, divv2df3) +BU_VSX_2 (RECIP_V2DF, "xvrecipdivdp", FP, recipv2df3) +BU_VSX_2 (XVMINDP, "xvmindp", CONST, sminv2df3) +BU_VSX_2 (XVMAXDP, "xvmaxdp", CONST, smaxv2df3) +BU_VSX_2 (XVTDIVDP_FE, "xvtdivdp_fe", CONST, vsx_tdivv2df3_fe) +BU_VSX_2 (XVTDIVDP_FG, "xvtdivdp_fg", CONST, vsx_tdivv2df3_fg) +BU_VSX_2 (XVCMPEQDP, "xvcmpeqdp", CONST, vector_eqv2df) +BU_VSX_2 (XVCMPGTDP, "xvcmpgtdp", CONST, vector_gtv2df) +BU_VSX_2 (XVCMPGEDP, "xvcmpgedp", CONST, vector_gev2df) + +BU_VSX_2 (XVADDSP, "xvaddsp", FP, addv4sf3) +BU_VSX_2 (XVSUBSP, "xvsubsp", FP, subv4sf3) +BU_VSX_2 (XVMULSP, "xvmulsp", FP, mulv4sf3) +BU_VSX_2 (XVDIVSP, "xvdivsp", FP, divv4sf3) +BU_VSX_2 (RECIP_V4SF, "xvrecipdivsp", FP, recipv4sf3) +BU_VSX_2 (XVMINSP, "xvminsp", CONST, sminv4sf3) +BU_VSX_2 (XVMAXSP, "xvmaxsp", CONST, smaxv4sf3) +BU_VSX_2 (XVTDIVSP_FE, "xvtdivsp_fe", CONST, vsx_tdivv4sf3_fe) +BU_VSX_2 (XVTDIVSP_FG, "xvtdivsp_fg", CONST, vsx_tdivv4sf3_fg) +BU_VSX_2 (XVCMPEQSP, "xvcmpeqsp", CONST, vector_eqv4sf) +BU_VSX_2 (XVCMPGTSP, "xvcmpgtsp", CONST, vector_gtv4sf) +BU_VSX_2 (XVCMPGESP, "xvcmpgesp", CONST, vector_gev4sf) + +BU_VSX_2 (XSMINDP, "xsmindp", CONST, smindf3) +BU_VSX_2 (XSMAXDP, "xsmaxdp", CONST, smaxdf3) +BU_VSX_2 (XSTDIVDP_FE, "xstdivdp_fe", CONST, vsx_tdivdf3_fe) +BU_VSX_2 (XSTDIVDP_FG, "xstdivdp_fg", CONST, vsx_tdivdf3_fg) +BU_VSX_2 (CPSGNDP, "cpsgndp", CONST, vector_copysignv2df3) +BU_VSX_2 (CPSGNSP, "cpsgnsp", CONST, vector_copysignv4sf3) + +BU_VSX_2 (CONCAT_2DF, "concat_2df", CONST, vsx_concat_v2df) +BU_VSX_2 (CONCAT_2DI, "concat_2di", CONST, vsx_concat_v2di) +BU_VSX_2 (SPLAT_2DF, "splat_2df", CONST, vsx_splat_v2df) +BU_VSX_2 (SPLAT_2DI, "splat_2di", CONST, vsx_splat_v2di) +BU_VSX_2 (XXMRGHW_4SF, "xxmrghw", CONST, vsx_xxmrghw_v4sf) +BU_VSX_2 (XXMRGHW_4SI, "xxmrghw_4si", CONST, vsx_xxmrghw_v4si) +BU_VSX_2 (XXMRGLW_4SF, "xxmrglw", CONST, vsx_xxmrglw_v4sf) +BU_VSX_2 (XXMRGLW_4SI, "xxmrglw_4si", CONST, vsx_xxmrglw_v4si) +BU_VSX_2 (VEC_MERGEL_V2DF, "mergel_2df", CONST, vsx_mergel_v2df) +BU_VSX_2 (VEC_MERGEL_V2DI, "mergel_2di", CONST, vsx_mergel_v2di) +BU_VSX_2 (VEC_MERGEH_V2DF, "mergeh_2df", CONST, vsx_mergeh_v2df) +BU_VSX_2 (VEC_MERGEH_V2DI, "mergeh_2di", CONST, vsx_mergeh_v2di) +BU_VSX_2 (XXSPLTD_V2DF, "xxspltd_2df", CONST, vsx_xxspltd_v2df) +BU_VSX_2 (XXSPLTD_V2DI, "xxspltd_2di", CONST, vsx_xxspltd_v2di) +BU_VSX_2 (DIV_V2DI, "div_2di", CONST, vsx_div_v2di) +BU_VSX_2 (UDIV_V2DI, "udiv_2di", CONST, vsx_udiv_v2di) +BU_VSX_2 (MUL_V2DI, "mul_2di", CONST, vsx_mul_v2di) + +BU_VSX_2 (XVCVSXDDP_SCALE, "xvcvsxddp_scale", CONST, vsx_xvcvsxddp_scale) +BU_VSX_2 (XVCVUXDDP_SCALE, "xvcvuxddp_scale", CONST, vsx_xvcvuxddp_scale) +BU_VSX_2 (XVCVDPSXDS_SCALE, "xvcvdpsxds_scale", CONST, vsx_xvcvdpsxds_scale) +BU_VSX_2 (XVCVDPUXDS_SCALE, "xvcvdpuxds_scale", CONST, vsx_xvcvdpuxds_scale) + +BU_VSX_2 (CMPGE_16QI, "cmpge_16qi", CONST, vector_nltv16qi) +BU_VSX_2 (CMPGE_8HI, "cmpge_8hi", CONST, vector_nltv8hi) +BU_VSX_2 (CMPGE_4SI, "cmpge_4si", CONST, vector_nltv4si) +BU_VSX_2 (CMPGE_2DI, "cmpge_2di", CONST, vector_nltv2di) +BU_VSX_2 (CMPGE_U16QI, "cmpge_u16qi", CONST, vector_nltuv16qi) +BU_VSX_2 (CMPGE_U8HI, "cmpge_u8hi", CONST, vector_nltuv8hi) +BU_VSX_2 (CMPGE_U4SI, "cmpge_u4si", CONST, vector_nltuv4si) +BU_VSX_2 (CMPGE_U2DI, "cmpge_u2di", CONST, vector_nltuv2di) + +BU_VSX_2 (CMPLE_16QI, "cmple_16qi", CONST, vector_ngtv16qi) +BU_VSX_2 (CMPLE_8HI, "cmple_8hi", CONST, vector_ngtv8hi) +BU_VSX_2 (CMPLE_4SI, "cmple_4si", CONST, vector_ngtv4si) +BU_VSX_2 (CMPLE_2DI, "cmple_2di", CONST, vector_ngtv2di) +BU_VSX_2 (CMPLE_U16QI, "cmple_u16qi", CONST, vector_ngtuv16qi) +BU_VSX_2 (CMPLE_U8HI, "cmple_u8hi", CONST, vector_ngtuv8hi) +BU_VSX_2 (CMPLE_U4SI, "cmple_u4si", CONST, vector_ngtuv4si) +BU_VSX_2 (CMPLE_U2DI, "cmple_u2di", CONST, vector_ngtuv2di) + +/* VSX abs builtin functions. */ +BU_VSX_A (XVABSDP, "xvabsdp", CONST, absv2df2) +BU_VSX_A (XVNABSDP, "xvnabsdp", CONST, vsx_nabsv2df2) +BU_VSX_A (XVABSSP, "xvabssp", CONST, absv4sf2) +BU_VSX_A (XVNABSSP, "xvnabssp", CONST, vsx_nabsv4sf2) + +/* 1 argument VSX builtin functions. */ +BU_VSX_1 (XVNEGDP, "xvnegdp", CONST, negv2df2) +BU_VSX_1 (XVSQRTDP, "xvsqrtdp", CONST, sqrtv2df2) +BU_VSX_1 (RSQRT_2DF, "xvrsqrtdp", CONST, rsqrtv2df2) +BU_VSX_1 (XVRSQRTEDP, "xvrsqrtedp", CONST, rsqrtev2df2) +BU_VSX_1 (XVTSQRTDP_FE, "xvtsqrtdp_fe", CONST, vsx_tsqrtv2df2_fe) +BU_VSX_1 (XVTSQRTDP_FG, "xvtsqrtdp_fg", CONST, vsx_tsqrtv2df2_fg) +BU_VSX_1 (XVREDP, "xvredp", CONST, vsx_frev2df2) + +BU_VSX_1 (XVNEGSP, "xvnegsp", CONST, negv4sf2) +BU_VSX_1 (XVSQRTSP, "xvsqrtsp", CONST, sqrtv4sf2) +BU_VSX_1 (RSQRT_4SF, "xvrsqrtsp", CONST, rsqrtv4sf2) +BU_VSX_1 (XVRSQRTESP, "xvrsqrtesp", CONST, rsqrtev4sf2) +BU_VSX_1 (XVTSQRTSP_FE, "xvtsqrtsp_fe", CONST, vsx_tsqrtv4sf2_fe) +BU_VSX_1 (XVTSQRTSP_FG, "xvtsqrtsp_fg", CONST, vsx_tsqrtv4sf2_fg) +BU_VSX_1 (XVRESP, "xvresp", CONST, vsx_frev4sf2) + +BU_VSX_1 (XSCVDPSP, "xscvdpsp", CONST, vsx_xscvdpsp) +BU_VSX_1 (XSCVSPDP, "xscvspdp", CONST, vsx_xscvspdp) +BU_VSX_1 (XVCVDPSP, "xvcvdpsp", CONST, vsx_xvcvdpsp) +BU_VSX_1 (XVCVSPDP, "xvcvspdp", CONST, vsx_xvcvspdp) +BU_VSX_1 (XSTSQRTDP_FE, "xstsqrtdp_fe", CONST, vsx_tsqrtdf2_fe) +BU_VSX_1 (XSTSQRTDP_FG, "xstsqrtdp_fg", CONST, vsx_tsqrtdf2_fg) + +BU_VSX_1 (XVCVDPSXDS, "xvcvdpsxds", CONST, vsx_fix_truncv2dfv2di2) +BU_VSX_1 (XVCVDPUXDS, "xvcvdpuxds", CONST, vsx_fixuns_truncv2dfv2di2) +BU_VSX_1 (XVCVDPUXDS_UNS, "xvcvdpuxds_uns", CONST, vsx_fixuns_truncv2dfv2di2) +BU_VSX_1 (XVCVSXDDP, "xvcvsxddp", CONST, vsx_floatv2div2df2) +BU_VSX_1 (XVCVUXDDP, "xvcvuxddp", CONST, vsx_floatunsv2div2df2) +BU_VSX_1 (XVCVUXDDP_UNS, "xvcvuxddp_uns", CONST, vsx_floatunsv2div2df2) + +BU_VSX_1 (XVCVSPSXWS, "xvcvspsxws", CONST, vsx_fix_truncv4sfv4si2) +BU_VSX_1 (XVCVSPUXWS, "xvcvspuxws", CONST, vsx_fixuns_truncv4sfv4si2) +BU_VSX_1 (XVCVSXWSP, "xvcvsxwsp", CONST, vsx_floatv4siv4sf2) +BU_VSX_1 (XVCVUXWSP, "xvcvuxwsp", CONST, vsx_floatunsv4siv4sf2) + +BU_VSX_1 (XVCVDPSXWS, "xvcvdpsxws", CONST, vsx_xvcvdpsxws) +BU_VSX_1 (XVCVDPUXWS, "xvcvdpuxws", CONST, vsx_xvcvdpuxws) +BU_VSX_1 (XVCVSXWDP, "xvcvsxwdp", CONST, vsx_xvcvsxwdp) +BU_VSX_1 (XVCVUXWDP, "xvcvuxwdp", CONST, vsx_xvcvuxwdp) +BU_VSX_1 (XVRDPI, "xvrdpi", CONST, vsx_xvrdpi) +BU_VSX_1 (XVRDPIC, "xvrdpic", CONST, vsx_xvrdpic) +BU_VSX_1 (XVRDPIM, "xvrdpim", CONST, vsx_floorv2df2) +BU_VSX_1 (XVRDPIP, "xvrdpip", CONST, vsx_ceilv2df2) +BU_VSX_1 (XVRDPIZ, "xvrdpiz", CONST, vsx_btruncv2df2) + +BU_VSX_1 (XVCVSPSXDS, "xvcvspsxds", CONST, vsx_xvcvspsxds) +BU_VSX_1 (XVCVSPUXDS, "xvcvspuxds", CONST, vsx_xvcvspuxds) +BU_VSX_1 (XVCVSXDSP, "xvcvsxdsp", CONST, vsx_xvcvsxdsp) +BU_VSX_1 (XVCVUXDSP, "xvcvuxdsp", CONST, vsx_xvcvuxdsp) +BU_VSX_1 (XVRSPI, "xvrspi", CONST, vsx_xvrspi) +BU_VSX_1 (XVRSPIC, "xvrspic", CONST, vsx_xvrspic) +BU_VSX_1 (XVRSPIM, "xvrspim", CONST, vsx_floorv4sf2) +BU_VSX_1 (XVRSPIP, "xvrspip", CONST, vsx_ceilv4sf2) +BU_VSX_1 (XVRSPIZ, "xvrspiz", CONST, vsx_btruncv4sf2) + +BU_VSX_1 (XSRDPI, "xsrdpi", CONST, vsx_xsrdpi) +BU_VSX_1 (XSRDPIC, "xsrdpic", CONST, vsx_xsrdpic) +BU_VSX_1 (XSRDPIM, "xsrdpim", CONST, floordf2) +BU_VSX_1 (XSRDPIP, "xsrdpip", CONST, ceildf2) +BU_VSX_1 (XSRDPIZ, "xsrdpiz", CONST, btruncdf2) + +/* VSX predicate functions. */ +BU_VSX_P (XVCMPEQSP_P, "xvcmpeqsp_p", CONST, vector_eq_v4sf_p) +BU_VSX_P (XVCMPGESP_P, "xvcmpgesp_p", CONST, vector_ge_v4sf_p) +BU_VSX_P (XVCMPGTSP_P, "xvcmpgtsp_p", CONST, vector_gt_v4sf_p) +BU_VSX_P (XVCMPEQDP_P, "xvcmpeqdp_p", CONST, vector_eq_v2df_p) +BU_VSX_P (XVCMPGEDP_P, "xvcmpgedp_p", CONST, vector_ge_v2df_p) +BU_VSX_P (XVCMPGTDP_P, "xvcmpgtdp_p", CONST, vector_gt_v2df_p) + +/* VSX builtins that are handled as special cases. */ +BU_VSX_X (LXSDX, "lxsdx", MEM) +BU_VSX_X (LXVD2X_V1TI, "lxvd2x_v1ti", MEM) +BU_VSX_X (LXVD2X_V2DF, "lxvd2x_v2df", MEM) +BU_VSX_X (LXVD2X_V2DI, "lxvd2x_v2di", MEM) +BU_VSX_X (LXVDSX, "lxvdsx", MEM) +BU_VSX_X (LXVW4X_V4SF, "lxvw4x_v4sf", MEM) +BU_VSX_X (LXVW4X_V4SI, "lxvw4x_v4si", MEM) +BU_VSX_X (LXVW4X_V8HI, "lxvw4x_v8hi", MEM) +BU_VSX_X (LXVW4X_V16QI, "lxvw4x_v16qi", MEM) +BU_VSX_X (STXSDX, "stxsdx", MEM) +BU_VSX_X (STXVD2X_V1TI, "stxvd2x_v1ti", MEM) +BU_VSX_X (STXVD2X_V2DF, "stxvd2x_v2df", MEM) +BU_VSX_X (STXVD2X_V2DI, "stxvd2x_v2di", MEM) +BU_VSX_X (STXVW4X_V4SF, "stxvw4x_v4sf", MEM) +BU_VSX_X (STXVW4X_V4SI, "stxvw4x_v4si", MEM) +BU_VSX_X (STXVW4X_V8HI, "stxvw4x_v8hi", MEM) +BU_VSX_X (STXVW4X_V16QI, "stxvw4x_v16qi", MEM) +BU_VSX_X (LD_ELEMREV_V2DF, "ld_elemrev_v2df", MEM) +BU_VSX_X (LD_ELEMREV_V2DI, "ld_elemrev_v2di", MEM) +BU_VSX_X (LD_ELEMREV_V4SF, "ld_elemrev_v4sf", MEM) +BU_VSX_X (LD_ELEMREV_V4SI, "ld_elemrev_v4si", MEM) +BU_VSX_X (LD_ELEMREV_V8HI, "ld_elemrev_v8hi", MEM) +BU_VSX_X (LD_ELEMREV_V16QI, "ld_elemrev_v16qi", MEM) +BU_VSX_X (ST_ELEMREV_V2DF, "st_elemrev_v2df", MEM) +BU_VSX_X (ST_ELEMREV_V2DI, "st_elemrev_v2di", MEM) +BU_VSX_X (ST_ELEMREV_V4SF, "st_elemrev_v4sf", MEM) +BU_VSX_X (ST_ELEMREV_V4SI, "st_elemrev_v4si", MEM) +BU_VSX_X (ST_ELEMREV_V8HI, "st_elemrev_v8hi", MEM) +BU_VSX_X (ST_ELEMREV_V16QI, "st_elemrev_v16qi", MEM) +BU_VSX_X (XSABSDP, "xsabsdp", CONST) +BU_VSX_X (XSADDDP, "xsadddp", FP) +BU_VSX_X (XSCMPODP, "xscmpodp", FP) +BU_VSX_X (XSCMPUDP, "xscmpudp", FP) +BU_VSX_X (XSCVDPSXDS, "xscvdpsxds", FP) +BU_VSX_X (XSCVDPSXWS, "xscvdpsxws", FP) +BU_VSX_X (XSCVDPUXDS, "xscvdpuxds", FP) +BU_VSX_X (XSCVDPUXWS, "xscvdpuxws", FP) +BU_VSX_X (XSCVSXDDP, "xscvsxddp", FP) +BU_VSX_X (XSCVUXDDP, "xscvuxddp", FP) +BU_VSX_X (XSDIVDP, "xsdivdp", FP) +BU_VSX_X (XSMADDADP, "xsmaddadp", FP) +BU_VSX_X (XSMADDMDP, "xsmaddmdp", FP) +BU_VSX_X (XSMOVDP, "xsmovdp", FP) +BU_VSX_X (XSMSUBADP, "xsmsubadp", FP) +BU_VSX_X (XSMSUBMDP, "xsmsubmdp", FP) +BU_VSX_X (XSMULDP, "xsmuldp", FP) +BU_VSX_X (XSNABSDP, "xsnabsdp", FP) +BU_VSX_X (XSNEGDP, "xsnegdp", FP) +BU_VSX_X (XSNMADDADP, "xsnmaddadp", FP) +BU_VSX_X (XSNMADDMDP, "xsnmaddmdp", FP) +BU_VSX_X (XSNMSUBADP, "xsnmsubadp", FP) +BU_VSX_X (XSNMSUBMDP, "xsnmsubmdp", FP) +BU_VSX_X (XSSUBDP, "xssubdp", FP) +BU_VSX_X (VEC_INIT_V1TI, "vec_init_v1ti", CONST) +BU_VSX_X (VEC_INIT_V2DF, "vec_init_v2df", CONST) +BU_VSX_X (VEC_INIT_V2DI, "vec_init_v2di", CONST) +BU_VSX_X (VEC_SET_V1TI, "vec_set_v1ti", CONST) +BU_VSX_X (VEC_SET_V2DF, "vec_set_v2df", CONST) +BU_VSX_X (VEC_SET_V2DI, "vec_set_v2di", CONST) +BU_VSX_X (VEC_EXT_V1TI, "vec_ext_v1ti", CONST) +BU_VSX_X (VEC_EXT_V2DF, "vec_ext_v2df", CONST) +BU_VSX_X (VEC_EXT_V2DI, "vec_ext_v2di", CONST) + +/* VSX overloaded builtins, add the overloaded functions not present in + Altivec. */ + +/* 3 argument VSX overloaded builtins. */ +BU_VSX_OVERLOAD_3 (MSUB, "msub") +BU_VSX_OVERLOAD_3 (NMADD, "nmadd") +BU_VSX_OVERLOAD_3V (XXPERMDI, "xxpermdi") +BU_VSX_OVERLOAD_3V (XXSLDWI, "xxsldwi") + +/* 2 argument VSX overloaded builtin functions. */ +BU_VSX_OVERLOAD_2 (DIV, "div") +BU_VSX_OVERLOAD_2 (XXMRGHW, "xxmrghw") +BU_VSX_OVERLOAD_2 (XXMRGLW, "xxmrglw") +BU_VSX_OVERLOAD_2 (XXSPLTD, "xxspltd") +BU_VSX_OVERLOAD_2 (XXSPLTW, "xxspltw") + +/* 1 argument VSX overloaded builtin functions. */ +BU_VSX_OVERLOAD_1 (DOUBLE, "double") + +/* VSX builtins that are handled as special cases. */ +BU_VSX_OVERLOAD_X (LD, "ld") +BU_VSX_OVERLOAD_X (ST, "st") +BU_VSX_OVERLOAD_X (XL, "xl") +BU_VSX_OVERLOAD_X (XST, "xst") + +/* 2 argument CMPB instructions added in ISA 2.05. */ +BU_P6_2 (CMPB_32, "cmpb_32", CONST, cmpbsi3) +BU_P6_64BIT_2 (CMPB, "cmpb", CONST, cmpbdi3) + +/* 1 argument VSX instructions added in ISA 2.07. */ +BU_P8V_VSX_1 (XSCVSPDPN, "xscvspdpn", CONST, vsx_xscvspdpn) +BU_P8V_VSX_1 (XSCVDPSPN, "xscvdpspn", CONST, vsx_xscvdpspn) + +/* 1 argument altivec instructions added in ISA 2.07. */ +BU_P8V_AV_1 (ABS_V2DI, "abs_v2di", CONST, absv2di2) +BU_P8V_AV_1 (VUPKHSW, "vupkhsw", CONST, altivec_vupkhsw) +BU_P8V_AV_1 (VUPKLSW, "vupklsw", CONST, altivec_vupklsw) +BU_P8V_AV_1 (VCLZB, "vclzb", CONST, clzv16qi2) +BU_P8V_AV_1 (VCLZH, "vclzh", CONST, clzv8hi2) +BU_P8V_AV_1 (VCLZW, "vclzw", CONST, clzv4si2) +BU_P8V_AV_1 (VCLZD, "vclzd", CONST, clzv2di2) +BU_P8V_AV_1 (VPOPCNTB, "vpopcntb", CONST, popcountv16qi2) +BU_P8V_AV_1 (VPOPCNTH, "vpopcnth", CONST, popcountv8hi2) +BU_P8V_AV_1 (VPOPCNTW, "vpopcntw", CONST, popcountv4si2) +BU_P8V_AV_1 (VPOPCNTD, "vpopcntd", CONST, popcountv2di2) +BU_P8V_AV_1 (VPOPCNTUB, "vpopcntub", CONST, popcountv16qi2) +BU_P8V_AV_1 (VPOPCNTUH, "vpopcntuh", CONST, popcountv8hi2) +BU_P8V_AV_1 (VPOPCNTUW, "vpopcntuw", CONST, popcountv4si2) +BU_P8V_AV_1 (VPOPCNTUD, "vpopcntud", CONST, popcountv2di2) +BU_P8V_AV_1 (VGBBD, "vgbbd", CONST, p8v_vgbbd) + +/* 2 argument altivec instructions added in ISA 2.07. */ +BU_P8V_AV_2 (VADDCUQ, "vaddcuq", CONST, altivec_vaddcuq) +BU_P8V_AV_2 (VADDUDM, "vaddudm", CONST, addv2di3) +BU_P8V_AV_2 (VADDUQM, "vadduqm", CONST, altivec_vadduqm) +BU_P8V_AV_2 (VMINSD, "vminsd", CONST, sminv2di3) +BU_P8V_AV_2 (VMAXSD, "vmaxsd", CONST, smaxv2di3) +BU_P8V_AV_2 (VMINUD, "vminud", CONST, uminv2di3) +BU_P8V_AV_2 (VMAXUD, "vmaxud", CONST, umaxv2di3) +BU_P8V_AV_2 (VMRGEW, "vmrgew", CONST, p8_vmrgew) +BU_P8V_AV_2 (VMRGOW, "vmrgow", CONST, p8_vmrgow) +BU_P8V_AV_2 (VBPERMQ, "vbpermq", CONST, altivec_vbpermq) +BU_P8V_AV_2 (VBPERMQ2, "vbpermq2", CONST, altivec_vbpermq2) +BU_P8V_AV_2 (VPKUDUM, "vpkudum", CONST, altivec_vpkudum) +BU_P8V_AV_2 (VPKSDSS, "vpksdss", CONST, altivec_vpksdss) +BU_P8V_AV_2 (VPKUDUS, "vpkudus", CONST, altivec_vpkudus) +BU_P8V_AV_2 (VPKSDUS, "vpksdus", CONST, altivec_vpksdus) +BU_P8V_AV_2 (VPMSUMB, "vpmsumb", CONST, crypto_vpmsumb) +BU_P8V_AV_2 (VPMSUMH, "vpmsumh", CONST, crypto_vpmsumh) +BU_P8V_AV_2 (VPMSUMW, "vpmsumw", CONST, crypto_vpmsumw) +BU_P8V_AV_2 (VPMSUMD, "vpmsumd", CONST, crypto_vpmsumd) +BU_P8V_AV_2 (VRLD, "vrld", CONST, vrotlv2di3) +BU_P8V_AV_2 (VSLD, "vsld", CONST, vashlv2di3) +BU_P8V_AV_2 (VSRD, "vsrd", CONST, vlshrv2di3) +BU_P8V_AV_2 (VSRAD, "vsrad", CONST, vashrv2di3) +BU_P8V_AV_2 (VSUBCUQ, "vsubcuq", CONST, altivec_vsubcuq) +BU_P8V_AV_2 (VSUBUDM, "vsubudm", CONST, subv2di3) +BU_P8V_AV_2 (VSUBUQM, "vsubuqm", CONST, altivec_vsubuqm) + +BU_P8V_AV_2 (EQV_V16QI, "eqv_v16qi", CONST, eqvv16qi3) +BU_P8V_AV_2 (EQV_V8HI, "eqv_v8hi", CONST, eqvv8hi3) +BU_P8V_AV_2 (EQV_V4SI, "eqv_v4si", CONST, eqvv4si3) +BU_P8V_AV_2 (EQV_V2DI, "eqv_v2di", CONST, eqvv2di3) +BU_P8V_AV_2 (EQV_V1TI, "eqv_v1ti", CONST, eqvv1ti3) +BU_P8V_AV_2 (EQV_V4SF, "eqv_v4sf", CONST, eqvv4sf3) +BU_P8V_AV_2 (EQV_V2DF, "eqv_v2df", CONST, eqvv2df3) + +BU_P8V_AV_2 (NAND_V16QI, "nand_v16qi", CONST, nandv16qi3) +BU_P8V_AV_2 (NAND_V8HI, "nand_v8hi", CONST, nandv8hi3) +BU_P8V_AV_2 (NAND_V4SI, "nand_v4si", CONST, nandv4si3) +BU_P8V_AV_2 (NAND_V2DI, "nand_v2di", CONST, nandv2di3) +BU_P8V_AV_2 (NAND_V1TI, "nand_v1ti", CONST, nandv1ti3) +BU_P8V_AV_2 (NAND_V4SF, "nand_v4sf", CONST, nandv4sf3) +BU_P8V_AV_2 (NAND_V2DF, "nand_v2df", CONST, nandv2df3) + +BU_P8V_AV_2 (ORC_V16QI, "orc_v16qi", CONST, orcv16qi3) +BU_P8V_AV_2 (ORC_V8HI, "orc_v8hi", CONST, orcv8hi3) +BU_P8V_AV_2 (ORC_V4SI, "orc_v4si", CONST, orcv4si3) +BU_P8V_AV_2 (ORC_V2DI, "orc_v2di", CONST, orcv2di3) +BU_P8V_AV_2 (ORC_V1TI, "orc_v1ti", CONST, orcv1ti3) +BU_P8V_AV_2 (ORC_V4SF, "orc_v4sf", CONST, orcv4sf3) +BU_P8V_AV_2 (ORC_V2DF, "orc_v2df", CONST, orcv2df3) + +/* 3 argument altivec instructions added in ISA 2.07. */ +BU_P8V_AV_3 (VADDEUQM, "vaddeuqm", CONST, altivec_vaddeuqm) +BU_P8V_AV_3 (VADDECUQ, "vaddecuq", CONST, altivec_vaddecuq) +BU_P8V_AV_3 (VSUBEUQM, "vsubeuqm", CONST, altivec_vsubeuqm) +BU_P8V_AV_3 (VSUBECUQ, "vsubecuq", CONST, altivec_vsubecuq) + +/* Vector comparison instructions added in ISA 2.07. */ +BU_P8V_AV_2 (VCMPEQUD, "vcmpequd", CONST, vector_eqv2di) +BU_P8V_AV_2 (VCMPGTSD, "vcmpgtsd", CONST, vector_gtv2di) +BU_P8V_AV_2 (VCMPGTUD, "vcmpgtud", CONST, vector_gtuv2di) + +/* Vector comparison predicate instructions added in ISA 2.07. */ +BU_P8V_AV_P (VCMPEQUD_P, "vcmpequd_p", CONST, vector_eq_v2di_p) +BU_P8V_AV_P (VCMPGTSD_P, "vcmpgtsd_p", CONST, vector_gt_v2di_p) +BU_P8V_AV_P (VCMPGTUD_P, "vcmpgtud_p", CONST, vector_gtu_v2di_p) + +/* ISA 2.05 overloaded 2 argument functions. */ +BU_P6_OVERLOAD_2 (CMPB, "cmpb") + +/* ISA 2.07 vector overloaded 1 argument functions. */ +BU_P8V_OVERLOAD_1 (VUPKHSW, "vupkhsw") +BU_P8V_OVERLOAD_1 (VUPKLSW, "vupklsw") +BU_P8V_OVERLOAD_1 (VCLZ, "vclz") +BU_P8V_OVERLOAD_1 (VCLZB, "vclzb") +BU_P8V_OVERLOAD_1 (VCLZH, "vclzh") +BU_P8V_OVERLOAD_1 (VCLZW, "vclzw") +BU_P8V_OVERLOAD_1 (VCLZD, "vclzd") +BU_P8V_OVERLOAD_1 (VPOPCNT, "vpopcnt") +BU_P8V_OVERLOAD_1 (VPOPCNTB, "vpopcntb") +BU_P8V_OVERLOAD_1 (VPOPCNTH, "vpopcnth") +BU_P8V_OVERLOAD_1 (VPOPCNTW, "vpopcntw") +BU_P8V_OVERLOAD_1 (VPOPCNTD, "vpopcntd") +BU_P8V_OVERLOAD_1 (VPOPCNTU, "vpopcntu") +BU_P8V_OVERLOAD_1 (VPOPCNTUB, "vpopcntub") +BU_P8V_OVERLOAD_1 (VPOPCNTUH, "vpopcntuh") +BU_P8V_OVERLOAD_1 (VPOPCNTUW, "vpopcntuw") +BU_P8V_OVERLOAD_1 (VPOPCNTUD, "vpopcntud") +BU_P8V_OVERLOAD_1 (VGBBD, "vgbbd") + +/* ISA 2.07 vector overloaded 2 argument functions. */ +BU_P8V_OVERLOAD_2 (EQV, "eqv") +BU_P8V_OVERLOAD_2 (NAND, "nand") +BU_P8V_OVERLOAD_2 (ORC, "orc") +BU_P8V_OVERLOAD_2 (VADDCUQ, "vaddcuq") +BU_P8V_OVERLOAD_2 (VADDUDM, "vaddudm") +BU_P8V_OVERLOAD_2 (VADDUQM, "vadduqm") +BU_P8V_OVERLOAD_2 (VBPERMQ, "vbpermq") +BU_P8V_OVERLOAD_2 (VMAXSD, "vmaxsd") +BU_P8V_OVERLOAD_2 (VMAXUD, "vmaxud") +BU_P8V_OVERLOAD_2 (VMINSD, "vminsd") +BU_P8V_OVERLOAD_2 (VMINUD, "vminud") +BU_P8V_OVERLOAD_2 (VMRGEW, "vmrgew") +BU_P8V_OVERLOAD_2 (VMRGOW, "vmrgow") +BU_P8V_OVERLOAD_2 (VPKSDSS, "vpksdss") +BU_P8V_OVERLOAD_2 (VPKSDUS, "vpksdus") +BU_P8V_OVERLOAD_2 (VPKUDUM, "vpkudum") +BU_P8V_OVERLOAD_2 (VPKUDUS, "vpkudus") +BU_P8V_OVERLOAD_2 (VPMSUM, "vpmsum") +BU_P8V_OVERLOAD_2 (VRLD, "vrld") +BU_P8V_OVERLOAD_2 (VSLD, "vsld") +BU_P8V_OVERLOAD_2 (VSRAD, "vsrad") +BU_P8V_OVERLOAD_2 (VSRD, "vsrd") +BU_P8V_OVERLOAD_2 (VSUBCUQ, "vsubcuq") +BU_P8V_OVERLOAD_2 (VSUBUDM, "vsubudm") +BU_P8V_OVERLOAD_2 (VSUBUQM, "vsubuqm") + +/* ISA 2.07 vector overloaded 3 argument functions. */ +BU_P8V_OVERLOAD_3 (VADDECUQ, "vaddecuq") +BU_P8V_OVERLOAD_3 (VADDEUQM, "vaddeuqm") +BU_P8V_OVERLOAD_3 (VSUBECUQ, "vsubecuq") +BU_P8V_OVERLOAD_3 (VSUBEUQM, "vsubeuqm") + +/* ISA 3.0 vector overloaded 2-argument functions. */ +BU_P9V_AV_2 (VSLV, "vslv", CONST, vslv) +BU_P9V_AV_2 (VSRV, "vsrv", CONST, vsrv) + +/* ISA 3.0 vector overloaded 2-argument functions. */ +BU_P9V_OVERLOAD_2 (VSLV, "vslv") +BU_P9V_OVERLOAD_2 (VSRV, "vsrv") + +/* 2 argument vector functions added in ISA 3.0 (power9). */ +BU_P9V_AV_2 (VADUB, "vadub", CONST, vaduv16qi3) +BU_P9V_AV_2 (VADUH, "vaduh", CONST, vaduv8hi3) +BU_P9V_AV_2 (VADUW, "vaduw", CONST, vaduv4si3) +BU_P9V_AV_2 (VRLWNM, "vrlwnm", CONST, altivec_vrlwnm) +BU_P9V_AV_2 (VRLDNM, "vrldnm", CONST, altivec_vrldnm) +BU_P9V_AV_2 (VBPERMD, "vbpermd", CONST, altivec_vbpermd) + +/* ISA 3.0 vector overloaded 2 argument functions. */ +BU_P9V_OVERLOAD_2 (VADU, "vadu") +BU_P9V_OVERLOAD_2 (VADUB, "vadub") +BU_P9V_OVERLOAD_2 (VADUH, "vaduh") +BU_P9V_OVERLOAD_2 (VADUW, "vaduw") +BU_P9V_OVERLOAD_2 (RLNM, "rlnm") +BU_P9V_OVERLOAD_2 (VBPERM, "vbperm_api") + +/* ISA 3.0 3-argument vector functions. */ +BU_P9V_AV_3 (VRLWMI, "vrlwmi", CONST, altivec_vrlwmi) +BU_P9V_AV_3 (VRLDMI, "vrldmi", CONST, altivec_vrldmi) + +/* ISA 3.0 vector overloaded 3-argument functions. */ +BU_P9V_OVERLOAD_3 (RLMI, "rlmi") + +/* 1 argument vsx scalar functions added in ISA 3.0 (power9). */ +BU_P9V_64BIT_VSX_1 (VSEEDP, "scalar_extract_exp", CONST, xsxexpdp) +BU_P9V_64BIT_VSX_1 (VSESDP, "scalar_extract_sig", CONST, xsxsigdp) + +BU_P9V_VSX_1 (VSTDCNDP, "scalar_test_neg_dp", CONST, xststdcnegdp) +BU_P9V_VSX_1 (VSTDCNSP, "scalar_test_neg_sp", CONST, xststdcnegsp) + +BU_P9V_VSX_1 (XXBRQ_V16QI, "xxbrq_v16qi", CONST, p9_xxbrq_v16qi) +BU_P9V_VSX_1 (XXBRQ_V1TI, "xxbrq_v1ti", CONST, p9_xxbrq_v1ti) +BU_P9V_VSX_1 (XXBRD_V2DI, "xxbrd_v2di", CONST, p9_xxbrd_v2di) +BU_P9V_VSX_1 (XXBRD_V2DF, "xxbrd_v2df", CONST, p9_xxbrd_v2df) +BU_P9V_VSX_1 (XXBRW_V4SI, "xxbrw_v4si", CONST, p9_xxbrw_v4si) +BU_P9V_VSX_1 (XXBRW_V4SF, "xxbrw_v4sf", CONST, p9_xxbrw_v4sf) +BU_P9V_VSX_1 (XXBRH_V8HI, "xxbrh_v8hi", CONST, p9_xxbrh_v8hi) + +/* 2 argument vsx scalar functions added in ISA 3.0 (power9). */ +BU_P9V_64BIT_VSX_2 (VSIEDP, "scalar_insert_exp", CONST, xsiexpdp) +BU_P9V_64BIT_VSX_2 (VSIEDPF, "scalar_insert_exp_dp", CONST, xsiexpdpf) + +BU_P9V_VSX_2 (VSCEDPGT, "scalar_cmp_exp_dp_gt", CONST, xscmpexpdp_gt) +BU_P9V_VSX_2 (VSCEDPLT, "scalar_cmp_exp_dp_lt", CONST, xscmpexpdp_lt) +BU_P9V_VSX_2 (VSCEDPEQ, "scalar_cmp_exp_dp_eq", CONST, xscmpexpdp_eq) +BU_P9V_VSX_2 (VSCEDPUO, "scalar_cmp_exp_dp_unordered", CONST, xscmpexpdp_unordered) + +BU_P9V_VSX_2 (VSTDCDP, "scalar_test_data_class_dp", CONST, xststdcdp) +BU_P9V_VSX_2 (VSTDCSP, "scalar_test_data_class_sp", CONST, xststdcsp) + +/* ISA 3.0 vector scalar overloaded 1 argument functions. */ +BU_P9V_OVERLOAD_1 (VSEEDP, "scalar_extract_exp") +BU_P9V_OVERLOAD_1 (VSESDP, "scalar_extract_sig") + +BU_P9V_OVERLOAD_1 (VSTDCN, "scalar_test_neg") +BU_P9V_OVERLOAD_1 (VSTDCNDP, "scalar_test_neg_dp") +BU_P9V_OVERLOAD_1 (VSTDCNSP, "scalar_test_neg_sp") + +BU_P9V_OVERLOAD_1 (REVB, "revb") + +/* ISA 3.0 vector scalar overloaded 2 argument functions. */ +BU_P9V_OVERLOAD_2 (VSIEDP, "scalar_insert_exp") + +BU_P9V_OVERLOAD_2 (VSTDC, "scalar_test_data_class") +BU_P9V_OVERLOAD_2 (VSTDCDP, "scalar_test_data_class_dp") +BU_P9V_OVERLOAD_2 (VSTDCSP, "scalar_test_data_class_sp") + +BU_P9V_OVERLOAD_2 (VSCEDPGT, "scalar_cmp_exp_gt") +BU_P9V_OVERLOAD_2 (VSCEDPLT, "scalar_cmp_exp_lt") +BU_P9V_OVERLOAD_2 (VSCEDPEQ, "scalar_cmp_exp_eq") +BU_P9V_OVERLOAD_2 (VSCEDPUO, "scalar_cmp_exp_unordered") + +/* 1 argument vsx vector functions added in ISA 3.0 (power9). */ +BU_P9V_VSX_1 (VEEDP, "extract_exp_dp", CONST, xvxexpdp) +BU_P9V_VSX_1 (VEESP, "extract_exp_sp", CONST, xvxexpsp) +BU_P9V_VSX_1 (VESDP, "extract_sig_dp", CONST, xvxsigdp) +BU_P9V_VSX_1 (VESSP, "extract_sig_sp", CONST, xvxsigsp) + +/* 2 argument vsx vector functions added in ISA 3.0 (power9). */ +BU_P9V_VSX_2 (VIEDP, "insert_exp_dp", CONST, xviexpdp) +BU_P9V_VSX_2 (VIESP, "insert_exp_sp", CONST, xviexpsp) +BU_P9V_VSX_2 (VTDCDP, "test_data_class_dp", CONST, xvtstdcdp) +BU_P9V_VSX_2 (VTDCSP, "test_data_class_sp", CONST, xvtstdcsp) + +/* ISA 3.0 vector overloaded 1 argument functions. */ +BU_P9V_OVERLOAD_1 (VES, "extract_sig") +BU_P9V_OVERLOAD_1 (VESDP, "extract_sig_dp") +BU_P9V_OVERLOAD_1 (VESSP, "extract_sig_sp") + +BU_P9V_OVERLOAD_1 (VEE, "extract_exp") +BU_P9V_OVERLOAD_1 (VEEDP, "extract_exp_dp") +BU_P9V_OVERLOAD_1 (VEESP, "extract_exp_sp") + +/* ISA 3.0 vector overloaded 2 argument functions. */ +BU_P9V_OVERLOAD_2 (VTDC, "test_data_class") +BU_P9V_OVERLOAD_2 (VTDCDP, "test_data_class_dp") +BU_P9V_OVERLOAD_2 (VTDCSP, "test_data_class_sp") + +BU_P9V_OVERLOAD_2 (VIE, "insert_exp") +BU_P9V_OVERLOAD_2 (VIEDP, "insert_exp_dp") +BU_P9V_OVERLOAD_2 (VIESP, "insert_exp_sp") + +/* 2 argument vector functions added in ISA 3.0 (power9). */ +BU_P9V_64BIT_VSX_2 (LXVL, "lxvl", CONST, lxvl) + +BU_P9V_AV_2 (VEXTUBLX, "vextublx", CONST, vextublx) +BU_P9V_AV_2 (VEXTUBRX, "vextubrx", CONST, vextubrx) +BU_P9V_AV_2 (VEXTUHLX, "vextuhlx", CONST, vextuhlx) +BU_P9V_AV_2 (VEXTUHRX, "vextuhrx", CONST, vextuhrx) +BU_P9V_AV_2 (VEXTUWLX, "vextuwlx", CONST, vextuwlx) +BU_P9V_AV_2 (VEXTUWRX, "vextuwrx", CONST, vextuwrx) + +/* Insert/extract 4 byte word into a vector. */ +BU_P9V_VSX_2 (VEXTRACT4B, "vextract4b", CONST, vextract4b) +BU_P9V_VSX_3 (VINSERT4B, "vinsert4b", CONST, vinsert4b) +BU_P9V_VSX_3 (VINSERT4B_DI, "vinsert4b_di", CONST, vinsert4b_di) + +/* 3 argument vector functions returning void, treated as SPECIAL, + added in ISA 3.0 (power9). */ +BU_P9V_64BIT_AV_X (STXVL, "stxvl", MISC) + +/* 1 argument vector functions added in ISA 3.0 (power9). */ +BU_P9V_AV_1 (VCLZLSBB, "vclzlsbb", CONST, vclzlsbb) +BU_P9V_AV_1 (VCTZLSBB, "vctzlsbb", CONST, vctzlsbb) + +/* Built-in support for Power9 "VSU option" string operations includes + new awareness of the "vector compare not equal" (vcmpneb, vcmpneb., + vcmpneh, vcmpneh., vcmpnew, vcmpnew.) and "vector compare + not equal or zero" (vcmpnezb, vcmpnezb., vcmpnezh, vcmpnezh., + vcmpnezw, vcmpnezw.) instructions. */ + +BU_P9V_AV_2 (CMPNEB, "vcmpneb", CONST, vcmpneb) +BU_P9V_AV_2 (CMPNEH, "vcmpneh", CONST, vcmpneh) +BU_P9V_AV_2 (CMPNEW, "vcmpnew", CONST, vcmpnew) + +BU_P9V_AV_2 (VCMPNEB_P, "vcmpneb_p", CONST, vector_ne_v16qi_p) +BU_P9V_AV_2 (VCMPNEH_P, "vcmpneh_p", CONST, vector_ne_v8hi_p) +BU_P9V_AV_2 (VCMPNEW_P, "vcmpnew_p", CONST, vector_ne_v4si_p) +BU_P9V_AV_2 (VCMPNED_P, "vcmpned_p", CONST, vector_ne_v2di_p) + +BU_P9V_AV_2 (VCMPNEFP_P, "vcmpnefp_p", CONST, vector_ne_v4sf_p) +BU_P9V_AV_2 (VCMPNEDP_P, "vcmpnedp_p", CONST, vector_ne_v2df_p) + +BU_P9V_AV_2 (VCMPAEB_P, "vcmpaeb_p", CONST, vector_ae_v16qi_p) +BU_P9V_AV_2 (VCMPAEH_P, "vcmpaeh_p", CONST, vector_ae_v8hi_p) +BU_P9V_AV_2 (VCMPAEW_P, "vcmpaew_p", CONST, vector_ae_v4si_p) +BU_P9V_AV_2 (VCMPAED_P, "vcmpaed_p", CONST, vector_ae_v2di_p) + +BU_P9V_AV_2 (VCMPAEFP_P, "vcmpaefp_p", CONST, vector_ae_v4sf_p) +BU_P9V_AV_2 (VCMPAEDP_P, "vcmpaedp_p", CONST, vector_ae_v2df_p) + +BU_P9V_AV_2 (CMPNEZB, "vcmpnezb", CONST, vcmpnezb) +BU_P9V_AV_2 (CMPNEZH, "vcmpnezh", CONST, vcmpnezh) +BU_P9V_AV_2 (CMPNEZW, "vcmpnezw", CONST, vcmpnezw) + +BU_P9V_AV_P (VCMPNEZB_P, "vcmpnezb_p", CONST, vector_nez_v16qi_p) +BU_P9V_AV_P (VCMPNEZH_P, "vcmpnezh_p", CONST, vector_nez_v8hi_p) +BU_P9V_AV_P (VCMPNEZW_P, "vcmpnezw_p", CONST, vector_nez_v4si_p) + +/* ISA 3.0 Vector scalar overloaded 2 argument functions */ +BU_P9V_OVERLOAD_2 (LXVL, "lxvl") +BU_P9V_OVERLOAD_2 (VEXTULX, "vextulx") +BU_P9V_OVERLOAD_2 (VEXTURX, "vexturx") +BU_P9V_OVERLOAD_2 (VEXTRACT4B, "vextract4b") + +/* ISA 3.0 Vector scalar overloaded 3 argument functions */ +BU_P9V_OVERLOAD_3 (STXVL, "stxvl") +BU_P9V_OVERLOAD_3 (VINSERT4B, "vinsert4b") + +/* Overloaded CMPNE support was implemented prior to Power 9, + so is not mentioned here. */ +BU_P9V_OVERLOAD_2 (CMPNEZ, "vcmpnez") + +BU_P9V_OVERLOAD_P (VCMPNEZ_P, "vcmpnez_p") +BU_P9V_OVERLOAD_2 (VCMPNE_P, "vcmpne_p") +BU_P9V_OVERLOAD_2 (VCMPAE_P, "vcmpae_p") + +/* ISA 3.0 Vector scalar overloaded 1 argument functions */ +BU_P9V_OVERLOAD_1 (VCLZLSBB, "vclzlsbb") +BU_P9V_OVERLOAD_1 (VCTZLSBB, "vctzlsbb") + +/* 2 argument extended divide functions added in ISA 2.06. */ +BU_P7_MISC_2 (DIVWE, "divwe", CONST, dive_si) +BU_P7_MISC_2 (DIVWEO, "divweo", CONST, diveo_si) +BU_P7_MISC_2 (DIVWEU, "divweu", CONST, diveu_si) +BU_P7_MISC_2 (DIVWEUO, "divweuo", CONST, diveuo_si) +BU_P7_MISC_2 (DIVDE, "divde", CONST, dive_di) +BU_P7_MISC_2 (DIVDEO, "divdeo", CONST, diveo_di) +BU_P7_MISC_2 (DIVDEU, "divdeu", CONST, diveu_di) +BU_P7_MISC_2 (DIVDEUO, "divdeuo", CONST, diveuo_di) + +/* 1 argument DFP (decimal floating point) functions added in ISA 2.05. */ +BU_DFP_MISC_1 (DXEX, "dxex", CONST, dfp_dxex_dd) +BU_DFP_MISC_1 (DXEXQ, "dxexq", CONST, dfp_dxex_td) + +/* 2 argument DFP (decimal floating point) functions added in ISA 2.05. */ +BU_DFP_MISC_2 (DDEDPD, "ddedpd", CONST, dfp_ddedpd_dd) +BU_DFP_MISC_2 (DDEDPDQ, "ddedpdq", CONST, dfp_ddedpd_td) +BU_DFP_MISC_2 (DENBCD, "denbcd", CONST, dfp_denbcd_dd) +BU_DFP_MISC_2 (DENBCDQ, "denbcdq", CONST, dfp_denbcd_td) +BU_DFP_MISC_2 (DIEX, "diex", CONST, dfp_diex_dd) +BU_DFP_MISC_2 (DIEXQ, "diexq", CONST, dfp_diex_td) +BU_DFP_MISC_2 (DSCLI, "dscli", CONST, dfp_dscli_dd) +BU_DFP_MISC_2 (DSCLIQ, "dscliq", CONST, dfp_dscli_td) +BU_DFP_MISC_2 (DSCRI, "dscri", CONST, dfp_dscri_dd) +BU_DFP_MISC_2 (DSCRIQ, "dscriq", CONST, dfp_dscri_td) + +/* 1 argument BCD functions added in ISA 2.06. */ +BU_P7_MISC_1 (CDTBCD, "cdtbcd", CONST, cdtbcd) +BU_P7_MISC_1 (CBCDTD, "cbcdtd", CONST, cbcdtd) + +/* 2 argument BCD functions added in ISA 2.06. */ +BU_P7_MISC_2 (ADDG6S, "addg6s", CONST, addg6s) + +/* 3 argument BCD functions added in ISA 2.07. */ +BU_P8V_MISC_3 (BCDADD, "bcdadd", CONST, bcdadd) +BU_P8V_MISC_3 (BCDADD_LT, "bcdadd_lt", CONST, bcdadd_lt) +BU_P8V_MISC_3 (BCDADD_EQ, "bcdadd_eq", CONST, bcdadd_eq) +BU_P8V_MISC_3 (BCDADD_GT, "bcdadd_gt", CONST, bcdadd_gt) +BU_P8V_MISC_3 (BCDADD_OV, "bcdadd_ov", CONST, bcdadd_unordered) +BU_P8V_MISC_3 (BCDSUB, "bcdsub", CONST, bcdsub) +BU_P8V_MISC_3 (BCDSUB_LT, "bcdsub_lt", CONST, bcdsub_lt) +BU_P8V_MISC_3 (BCDSUB_EQ, "bcdsub_eq", CONST, bcdsub_eq) +BU_P8V_MISC_3 (BCDSUB_GT, "bcdsub_gt", CONST, bcdsub_gt) +BU_P8V_MISC_3 (BCDSUB_OV, "bcdsub_ov", CONST, bcdsub_unordered) + +/* 2 argument pack/unpack 128-bit floating point types. */ +BU_DFP_MISC_2 (PACK_TD, "pack_dec128", CONST, packtd) +BU_DFP_MISC_2 (UNPACK_TD, "unpack_dec128", CONST, unpacktd) + +/* 0 argument general-purpose register functions added in ISA 3.0 (power9). */ +BU_P9_MISC_0 (DARN_32, "darn_32", MISC, darn_32) +BU_P9_64BIT_MISC_0 (DARN_RAW, "darn_raw", MISC, darn_raw) +BU_P9_64BIT_MISC_0 (DARN, "darn", MISC, darn) + +BU_LDBL128_2 (PACK_TF, "pack_longdouble", CONST, packtf) +BU_LDBL128_2 (UNPACK_TF, "unpack_longdouble", CONST, unpacktf) + +BU_P7_MISC_2 (PACK_V1TI, "pack_vector_int128", CONST, packv1ti) +BU_P7_MISC_2 (UNPACK_V1TI, "unpack_vector_int128", CONST, unpackv1ti) + +/* 2 argument DFP (Decimal Floating Point) functions added in ISA 3.0. */ +BU_P9_DFP_MISC_2 (TSTSFI_LT_DD, "dtstsfi_lt_dd", CONST, dfptstsfi_lt_dd) +BU_P9_DFP_MISC_2 (TSTSFI_LT_TD, "dtstsfi_lt_td", CONST, dfptstsfi_lt_td) + +BU_P9_DFP_MISC_2 (TSTSFI_EQ_DD, "dtstsfi_eq_dd", CONST, dfptstsfi_eq_dd) +BU_P9_DFP_MISC_2 (TSTSFI_EQ_TD, "dtstsfi_eq_td", CONST, dfptstsfi_eq_td) + +BU_P9_DFP_MISC_2 (TSTSFI_GT_DD, "dtstsfi_gt_dd", CONST, dfptstsfi_gt_dd) +BU_P9_DFP_MISC_2 (TSTSFI_GT_TD, "dtstsfi_gt_td", CONST, dfptstsfi_gt_td) + +BU_P9_DFP_MISC_2 (TSTSFI_OV_DD, "dtstsfi_ov_dd", CONST, dfptstsfi_unordered_dd) +BU_P9_DFP_MISC_2 (TSTSFI_OV_TD, "dtstsfi_ov_td", CONST, dfptstsfi_unordered_td) + +/* 2 argument overloaded DFP functions added in ISA 3.0. */ +BU_P9_DFP_OVERLOAD_2 (TSTSFI_LT, "dtstsfi_lt") +BU_P9_DFP_OVERLOAD_2 (TSTSFI_LT_DD, "dtstsfi_lt_dd") +BU_P9_DFP_OVERLOAD_2 (TSTSFI_LT_TD, "dtstsfi_lt_td") + +BU_P9_DFP_OVERLOAD_2 (TSTSFI_EQ, "dtstsfi_eq") +BU_P9_DFP_OVERLOAD_2 (TSTSFI_EQ_DD, "dtstsfi_eq_dd") +BU_P9_DFP_OVERLOAD_2 (TSTSFI_EQ_TD, "dtstsfi_eq_td") + +BU_P9_DFP_OVERLOAD_2 (TSTSFI_GT, "dtstsfi_gt") +BU_P9_DFP_OVERLOAD_2 (TSTSFI_GT_DD, "dtstsfi_gt_dd") +BU_P9_DFP_OVERLOAD_2 (TSTSFI_GT_TD, "dtstsfi_gt_td") + +BU_P9_DFP_OVERLOAD_2 (TSTSFI_OV, "dtstsfi_ov") +BU_P9_DFP_OVERLOAD_2 (TSTSFI_OV_DD, "dtstsfi_ov_dd") +BU_P9_DFP_OVERLOAD_2 (TSTSFI_OV_TD, "dtstsfi_ov_td") + +/* 1 argument vector functions added in ISA 3.0 (power9). */ +BU_P9V_AV_1 (VCTZB, "vctzb", CONST, ctzv16qi2) +BU_P9V_AV_1 (VCTZH, "vctzh", CONST, ctzv8hi2) +BU_P9V_AV_1 (VCTZW, "vctzw", CONST, ctzv4si2) +BU_P9V_AV_1 (VCTZD, "vctzd", CONST, ctzv2di2) +BU_P9V_AV_1 (VPRTYBD, "vprtybd", CONST, parityv2di2) +BU_P9V_AV_1 (VPRTYBQ, "vprtybq", CONST, parityv1ti2) +BU_P9V_AV_1 (VPRTYBW, "vprtybw", CONST, parityv4si2) + +/* ISA 3.0 vector overloaded 1 argument functions. */ +BU_P9V_OVERLOAD_1 (VCTZ, "vctz") +BU_P9V_OVERLOAD_1 (VCTZB, "vctzb") +BU_P9V_OVERLOAD_1 (VCTZH, "vctzh") +BU_P9V_OVERLOAD_1 (VCTZW, "vctzw") +BU_P9V_OVERLOAD_1 (VCTZD, "vctzd") +BU_P9V_OVERLOAD_1 (VPRTYB, "vprtyb") +BU_P9V_OVERLOAD_1 (VPRTYBD, "vprtybd") +BU_P9V_OVERLOAD_1 (VPRTYBQ, "vprtybq") +BU_P9V_OVERLOAD_1 (VPRTYBW, "vprtybw") + +/* 2 argument functions added in ISA 3.0 (power9). */ +BU_P9_2 (CMPRB, "byte_in_range", CONST, cmprb) +BU_P9_2 (CMPRB2, "byte_in_either_range", CONST, cmprb2) +BU_P9_64BIT_2 (CMPEQB, "byte_in_set", CONST, cmpeqb) + +/* 2 argument overloaded functions added in ISA 3.0 (power9). */ +BU_P9_OVERLOAD_2 (CMPRB, "byte_in_range") +BU_P9_OVERLOAD_2 (CMPRB2, "byte_in_either_range") +BU_P9_OVERLOAD_2 (CMPEQB, "byte_in_set") + +/* 1 argument IEEE 128-bit floating-point functions. */ +BU_FLOAT128_1 (FABSQ, "fabsq", CONST, abskf2) + +/* 2 argument IEEE 128-bit floating-point functions. */ +BU_FLOAT128_2 (COPYSIGNQ, "copysignq", CONST, copysignkf3) + +/* 1 argument crypto functions. */ +BU_CRYPTO_1 (VSBOX, "vsbox", CONST, crypto_vsbox) + +/* 2 argument crypto functions. */ +BU_CRYPTO_2 (VCIPHER, "vcipher", CONST, crypto_vcipher) +BU_CRYPTO_2 (VCIPHERLAST, "vcipherlast", CONST, crypto_vcipherlast) +BU_CRYPTO_2 (VNCIPHER, "vncipher", CONST, crypto_vncipher) +BU_CRYPTO_2 (VNCIPHERLAST, "vncipherlast", CONST, crypto_vncipherlast) +BU_CRYPTO_2A (VPMSUMB, "vpmsumb", CONST, crypto_vpmsumb) +BU_CRYPTO_2A (VPMSUMH, "vpmsumh", CONST, crypto_vpmsumh) +BU_CRYPTO_2A (VPMSUMW, "vpmsumw", CONST, crypto_vpmsumw) +BU_CRYPTO_2A (VPMSUMD, "vpmsumd", CONST, crypto_vpmsumd) + +/* 3 argument crypto functions. */ +BU_CRYPTO_3A (VPERMXOR_V2DI, "vpermxor_v2di", CONST, crypto_vpermxor_v2di) +BU_CRYPTO_3A (VPERMXOR_V4SI, "vpermxor_v4si", CONST, crypto_vpermxor_v4si) +BU_CRYPTO_3A (VPERMXOR_V8HI, "vpermxor_v8hi", CONST, crypto_vpermxor_v8hi) +BU_CRYPTO_3A (VPERMXOR_V16QI, "vpermxor_v16qi", CONST, crypto_vpermxor_v16qi) +BU_CRYPTO_3 (VSHASIGMAW, "vshasigmaw", CONST, crypto_vshasigmaw) +BU_CRYPTO_3 (VSHASIGMAD, "vshasigmad", CONST, crypto_vshasigmad) + +/* 2 argument crypto overloaded functions. */ +BU_CRYPTO_OVERLOAD_2A (VPMSUM, "vpmsum") + +/* 3 argument crypto overloaded functions. */ +BU_CRYPTO_OVERLOAD_3A (VPERMXOR, "vpermxor") +BU_CRYPTO_OVERLOAD_3 (VSHASIGMA, "vshasigma") + + +/* HTM functions. */ +BU_HTM_1 (TABORT, "tabort", CR, tabort) +BU_HTM_3 (TABORTDC, "tabortdc", CR, tabortdc) +BU_HTM_3 (TABORTDCI, "tabortdci", CR, tabortdci) +BU_HTM_3 (TABORTWC, "tabortwc", CR, tabortwc) +BU_HTM_3 (TABORTWCI, "tabortwci", CR, tabortwci) +BU_HTM_1 (TBEGIN, "tbegin", CR, tbegin) +BU_HTM_0 (TCHECK, "tcheck", CR, tcheck) +BU_HTM_1 (TEND, "tend", CR, tend) +BU_HTM_0 (TENDALL, "tendall", CR, tend) +BU_HTM_0 (TRECHKPT, "trechkpt", CR, trechkpt) +BU_HTM_1 (TRECLAIM, "treclaim", CR, treclaim) +BU_HTM_0 (TRESUME, "tresume", CR, tsr) +BU_HTM_0 (TSUSPEND, "tsuspend", CR, tsr) +BU_HTM_1 (TSR, "tsr", CR, tsr) +BU_HTM_0 (TTEST, "ttest", CR, ttest) + +BU_HTM_0 (GET_TFHAR, "get_tfhar", SPR, nothing) +BU_HTM_V1 (SET_TFHAR, "set_tfhar", SPR, nothing) +BU_HTM_0 (GET_TFIAR, "get_tfiar", SPR, nothing) +BU_HTM_V1 (SET_TFIAR, "set_tfiar", SPR, nothing) +BU_HTM_0 (GET_TEXASR, "get_texasr", SPR, nothing) +BU_HTM_V1 (SET_TEXASR, "set_texasr", SPR, nothing) +BU_HTM_0 (GET_TEXASRU, "get_texasru", SPR, nothing) +BU_HTM_V1 (SET_TEXASRU, "set_texasru", SPR, nothing) + + +/* 3 argument paired floating point builtins. */ +BU_PAIRED_3 (MSUB, "msub", FP, fmsv2sf4) +BU_PAIRED_3 (MADD, "madd", FP, fmav2sf4) +BU_PAIRED_3 (MADDS0, "madds0", FP, paired_madds0) +BU_PAIRED_3 (MADDS1, "madds1", FP, paired_madds1) +BU_PAIRED_3 (NMSUB, "nmsub", FP, nfmsv2sf4) +BU_PAIRED_3 (NMADD, "nmadd", FP, nfmav2sf4) +BU_PAIRED_3 (SUM0, "sum0", FP, paired_sum0) +BU_PAIRED_3 (SUM1, "sum1", FP, paired_sum1) +BU_PAIRED_3 (SELV2SF4, "selv2sf4", CONST, selv2sf4) + +/* 2 argument paired floating point builtins. */ +BU_PAIRED_2 (DIVV2SF3, "divv2sf3", FP, paired_divv2sf3) +BU_PAIRED_2 (ADDV2SF3, "addv2sf3", FP, paired_addv2sf3) +BU_PAIRED_2 (SUBV2SF3, "subv2sf3", FP, paired_subv2sf3) +BU_PAIRED_2 (MULV2SF3, "mulv2sf3", FP, paired_mulv2sf3) +BU_PAIRED_2 (MULS0, "muls0", FP, paired_muls0) +BU_PAIRED_2 (MULS1, "muls1", FP, paired_muls1) +BU_PAIRED_2 (MERGE00, "merge00", CONST, paired_merge00) +BU_PAIRED_2 (MERGE01, "merge01", CONST, paired_merge01) +BU_PAIRED_2 (MERGE10, "merge10", CONST, paired_merge10) +BU_PAIRED_2 (MERGE11, "merge11", CONST, paired_merge11) + +/* 1 argument paired floating point builtin functions. */ +BU_PAIRED_1 (ABSV2SF2, "absv2sf2", CONST, paired_absv2sf2) +BU_PAIRED_1 (NABSV2SF2, "nabsv2sf2", CONST, nabsv2sf2) +BU_PAIRED_1 (NEGV2SF2, "negv2sf2", CONST, paired_negv2sf2) +BU_PAIRED_1 (SQRTV2SF2, "sqrtv2sf2", FP, sqrtv2sf2) +BU_PAIRED_1 (RESV2SF, "resv2sf2", FP, resv2sf2) + +/* PAIRED builtins that are handled as special cases. */ +BU_PAIRED_X (STX, "stx", MISC) +BU_PAIRED_X (LX, "lx", MISC) + +/* Paired predicates. */ +BU_PAIRED_P (CMPU0, "cmpu0", CONST, paired_cmpu0) +BU_PAIRED_P (CMPU1, "cmpu1", CONST, paired_cmpu1) + +/* PowerPC E500 builtins (SPE). */ + +BU_SPE_2 (EVADDW, "evaddw", MISC, addv2si3) +BU_SPE_2 (EVAND, "evand", MISC, andv2si3) +BU_SPE_2 (EVANDC, "evandc", MISC, spe_evandc) +BU_SPE_2 (EVDIVWS, "evdivws", MISC, divv2si3) +BU_SPE_2 (EVDIVWU, "evdivwu", MISC, spe_evdivwu) +BU_SPE_2 (EVEQV, "eveqv", MISC, spe_eveqv) +BU_SPE_2 (EVFSADD, "evfsadd", MISC, spe_evfsadd) +BU_SPE_2 (EVFSDIV, "evfsdiv", MISC, spe_evfsdiv) +BU_SPE_2 (EVFSMUL, "evfsmul", MISC, spe_evfsmul) +BU_SPE_2 (EVFSSUB, "evfssub", MISC, spe_evfssub) +BU_SPE_2 (EVMERGEHI, "evmergehi", MISC, spe_evmergehi) +BU_SPE_2 (EVMERGEHILO, "evmergehilo", MISC, spe_evmergehilo) +BU_SPE_2 (EVMERGELO, "evmergelo", MISC, spe_evmergelo) +BU_SPE_2 (EVMERGELOHI, "evmergelohi", MISC, spe_evmergelohi) +BU_SPE_2 (EVMHEGSMFAA, "evmhegsmfaa", MISC, spe_evmhegsmfaa) +BU_SPE_2 (EVMHEGSMFAN, "evmhegsmfan", MISC, spe_evmhegsmfan) +BU_SPE_2 (EVMHEGSMIAA, "evmhegsmiaa", MISC, spe_evmhegsmiaa) +BU_SPE_2 (EVMHEGSMIAN, "evmhegsmian", MISC, spe_evmhegsmian) +BU_SPE_2 (EVMHEGUMIAA, "evmhegumiaa", MISC, spe_evmhegumiaa) +BU_SPE_2 (EVMHEGUMIAN, "evmhegumian", MISC, spe_evmhegumian) +BU_SPE_2 (EVMHESMF, "evmhesmf", MISC, spe_evmhesmf) +BU_SPE_2 (EVMHESMFA, "evmhesmfa", MISC, spe_evmhesmfa) +BU_SPE_2 (EVMHESMFAAW, "evmhesmfaaw", MISC, spe_evmhesmfaaw) +BU_SPE_2 (EVMHESMFANW, "evmhesmfanw", MISC, spe_evmhesmfanw) +BU_SPE_2 (EVMHESMI, "evmhesmi", MISC, spe_evmhesmi) +BU_SPE_2 (EVMHESMIA, "evmhesmia", MISC, spe_evmhesmia) +BU_SPE_2 (EVMHESMIAAW, "evmhesmiaaw", MISC, spe_evmhesmiaaw) +BU_SPE_2 (EVMHESMIANW, "evmhesmianw", MISC, spe_evmhesmianw) +BU_SPE_2 (EVMHESSF, "evmhessf", MISC, spe_evmhessf) +BU_SPE_2 (EVMHESSFA, "evmhessfa", MISC, spe_evmhessfa) +BU_SPE_2 (EVMHESSFAAW, "evmhessfaaw", MISC, spe_evmhessfaaw) +BU_SPE_2 (EVMHESSFANW, "evmhessfanw", MISC, spe_evmhessfanw) +BU_SPE_2 (EVMHESSIAAW, "evmhessiaaw", MISC, spe_evmhessiaaw) +BU_SPE_2 (EVMHESSIANW, "evmhessianw", MISC, spe_evmhessianw) +BU_SPE_2 (EVMHEUMI, "evmheumi", MISC, spe_evmheumi) +BU_SPE_2 (EVMHEUMIA, "evmheumia", MISC, spe_evmheumia) +BU_SPE_2 (EVMHEUMIAAW, "evmheumiaaw", MISC, spe_evmheumiaaw) +BU_SPE_2 (EVMHEUMIANW, "evmheumianw", MISC, spe_evmheumianw) +BU_SPE_2 (EVMHEUSIAAW, "evmheusiaaw", MISC, spe_evmheusiaaw) +BU_SPE_2 (EVMHEUSIANW, "evmheusianw", MISC, spe_evmheusianw) +BU_SPE_2 (EVMHOGSMFAA, "evmhogsmfaa", MISC, spe_evmhogsmfaa) +BU_SPE_2 (EVMHOGSMFAN, "evmhogsmfan", MISC, spe_evmhogsmfan) +BU_SPE_2 (EVMHOGSMIAA, "evmhogsmiaa", MISC, spe_evmhogsmiaa) +BU_SPE_2 (EVMHOGSMIAN, "evmhogsmian", MISC, spe_evmhogsmian) +BU_SPE_2 (EVMHOGUMIAA, "evmhogumiaa", MISC, spe_evmhogumiaa) +BU_SPE_2 (EVMHOGUMIAN, "evmhogumian", MISC, spe_evmhogumian) +BU_SPE_2 (EVMHOSMF, "evmhosmf", MISC, spe_evmhosmf) +BU_SPE_2 (EVMHOSMFA, "evmhosmfa", MISC, spe_evmhosmfa) +BU_SPE_2 (EVMHOSMFAAW, "evmhosmfaaw", MISC, spe_evmhosmfaaw) +BU_SPE_2 (EVMHOSMFANW, "evmhosmfanw", MISC, spe_evmhosmfanw) +BU_SPE_2 (EVMHOSMI, "evmhosmi", MISC, spe_evmhosmi) +BU_SPE_2 (EVMHOSMIA, "evmhosmia", MISC, spe_evmhosmia) +BU_SPE_2 (EVMHOSMIAAW, "evmhosmiaaw", MISC, spe_evmhosmiaaw) +BU_SPE_2 (EVMHOSMIANW, "evmhosmianw", MISC, spe_evmhosmianw) +BU_SPE_2 (EVMHOSSF, "evmhossf", MISC, spe_evmhossf) +BU_SPE_2 (EVMHOSSFA, "evmhossfa", MISC, spe_evmhossfa) +BU_SPE_2 (EVMHOSSFAAW, "evmhossfaaw", MISC, spe_evmhossfaaw) +BU_SPE_2 (EVMHOSSFANW, "evmhossfanw", MISC, spe_evmhossfanw) +BU_SPE_2 (EVMHOSSIAAW, "evmhossiaaw", MISC, spe_evmhossiaaw) +BU_SPE_2 (EVMHOSSIANW, "evmhossianw", MISC, spe_evmhossianw) +BU_SPE_2 (EVMHOUMI, "evmhoumi", MISC, spe_evmhoumi) +BU_SPE_2 (EVMHOUMIA, "evmhoumia", MISC, spe_evmhoumia) +BU_SPE_2 (EVMHOUMIAAW, "evmhoumiaaw", MISC, spe_evmhoumiaaw) +BU_SPE_2 (EVMHOUMIANW, "evmhoumianw", MISC, spe_evmhoumianw) +BU_SPE_2 (EVMHOUSIAAW, "evmhousiaaw", MISC, spe_evmhousiaaw) +BU_SPE_2 (EVMHOUSIANW, "evmhousianw", MISC, spe_evmhousianw) +BU_SPE_2 (EVMWHSMF, "evmwhsmf", MISC, spe_evmwhsmf) +BU_SPE_2 (EVMWHSMFA, "evmwhsmfa", MISC, spe_evmwhsmfa) +BU_SPE_2 (EVMWHSMI, "evmwhsmi", MISC, spe_evmwhsmi) +BU_SPE_2 (EVMWHSMIA, "evmwhsmia", MISC, spe_evmwhsmia) +BU_SPE_2 (EVMWHSSF, "evmwhssf", MISC, spe_evmwhssf) +BU_SPE_2 (EVMWHSSFA, "evmwhssfa", MISC, spe_evmwhssfa) +BU_SPE_2 (EVMWHUMI, "evmwhumi", MISC, spe_evmwhumi) +BU_SPE_2 (EVMWHUMIA, "evmwhumia", MISC, spe_evmwhumia) +BU_SPE_2 (EVMWLSMIAAW, "evmwlsmiaaw", MISC, spe_evmwlsmiaaw) +BU_SPE_2 (EVMWLSMIANW, "evmwlsmianw", MISC, spe_evmwlsmianw) +BU_SPE_2 (EVMWLSSIAAW, "evmwlssiaaw", MISC, spe_evmwlssiaaw) +BU_SPE_2 (EVMWLSSIANW, "evmwlssianw", MISC, spe_evmwlssianw) +BU_SPE_2 (EVMWLUMI, "evmwlumi", MISC, spe_evmwlumi) +BU_SPE_2 (EVMWLUMIA, "evmwlumia", MISC, spe_evmwlumia) +BU_SPE_2 (EVMWLUMIAAW, "evmwlumiaaw", MISC, spe_evmwlumiaaw) +BU_SPE_2 (EVMWLUMIANW, "evmwlumianw", MISC, spe_evmwlumianw) +BU_SPE_2 (EVMWLUSIAAW, "evmwlusiaaw", MISC, spe_evmwlusiaaw) +BU_SPE_2 (EVMWLUSIANW, "evmwlusianw", MISC, spe_evmwlusianw) +BU_SPE_2 (EVMWSMF, "evmwsmf", MISC, spe_evmwsmf) +BU_SPE_2 (EVMWSMFA, "evmwsmfa", MISC, spe_evmwsmfa) +BU_SPE_2 (EVMWSMFAA, "evmwsmfaa", MISC, spe_evmwsmfaa) +BU_SPE_2 (EVMWSMFAN, "evmwsmfan", MISC, spe_evmwsmfan) +BU_SPE_2 (EVMWSMI, "evmwsmi", MISC, spe_evmwsmi) +BU_SPE_2 (EVMWSMIA, "evmwsmia", MISC, spe_evmwsmia) +BU_SPE_2 (EVMWSMIAA, "evmwsmiaa", MISC, spe_evmwsmiaa) +BU_SPE_2 (EVMWSMIAN, "evmwsmian", MISC, spe_evmwsmian) +BU_SPE_2 (EVMWSSF, "evmwssf", MISC, spe_evmwssf) +BU_SPE_2 (EVMWSSFA, "evmwssfa", MISC, spe_evmwssfa) +BU_SPE_2 (EVMWSSFAA, "evmwssfaa", MISC, spe_evmwssfaa) +BU_SPE_2 (EVMWSSFAN, "evmwssfan", MISC, spe_evmwssfan) +BU_SPE_2 (EVMWUMI, "evmwumi", MISC, spe_evmwumi) +BU_SPE_2 (EVMWUMIA, "evmwumia", MISC, spe_evmwumia) +BU_SPE_2 (EVMWUMIAA, "evmwumiaa", MISC, spe_evmwumiaa) +BU_SPE_2 (EVMWUMIAN, "evmwumian", MISC, spe_evmwumian) +BU_SPE_2 (EVNAND, "evnand", MISC, spe_evnand) +BU_SPE_2 (EVNOR, "evnor", MISC, spe_evnor) +BU_SPE_2 (EVOR, "evor", MISC, spe_evor) +BU_SPE_2 (EVORC, "evorc", MISC, spe_evorc) +BU_SPE_2 (EVRLW, "evrlw", MISC, spe_evrlw) +BU_SPE_2 (EVSLW, "evslw", MISC, spe_evslw) +BU_SPE_2 (EVSRWS, "evsrws", MISC, spe_evsrws) +BU_SPE_2 (EVSRWU, "evsrwu", MISC, spe_evsrwu) +BU_SPE_2 (EVSUBFW, "evsubfw", MISC, subv2si3) + +/* SPE binary operations expecting a 5-bit unsigned literal. */ +BU_SPE_2 (EVADDIW, "evaddiw", MISC, spe_evaddiw) + +BU_SPE_2 (EVRLWI, "evrlwi", MISC, spe_evrlwi) +BU_SPE_2 (EVSLWI, "evslwi", MISC, spe_evslwi) +BU_SPE_2 (EVSRWIS, "evsrwis", MISC, spe_evsrwis) +BU_SPE_2 (EVSRWIU, "evsrwiu", MISC, spe_evsrwiu) +BU_SPE_2 (EVSUBIFW, "evsubifw", MISC, spe_evsubifw) +BU_SPE_2 (EVMWHSSFAA, "evmwhssfaa", MISC, spe_evmwhssfaa) +BU_SPE_2 (EVMWHSSMAA, "evmwhssmaa", MISC, spe_evmwhssmaa) +BU_SPE_2 (EVMWHSMFAA, "evmwhsmfaa", MISC, spe_evmwhsmfaa) +BU_SPE_2 (EVMWHSMIAA, "evmwhsmiaa", MISC, spe_evmwhsmiaa) +BU_SPE_2 (EVMWHUSIAA, "evmwhusiaa", MISC, spe_evmwhusiaa) +BU_SPE_2 (EVMWHUMIAA, "evmwhumiaa", MISC, spe_evmwhumiaa) +BU_SPE_2 (EVMWHSSFAN, "evmwhssfan", MISC, spe_evmwhssfan) +BU_SPE_2 (EVMWHSSIAN, "evmwhssian", MISC, spe_evmwhssian) +BU_SPE_2 (EVMWHSMFAN, "evmwhsmfan", MISC, spe_evmwhsmfan) +BU_SPE_2 (EVMWHSMIAN, "evmwhsmian", MISC, spe_evmwhsmian) +BU_SPE_2 (EVMWHUSIAN, "evmwhusian", MISC, spe_evmwhusian) +BU_SPE_2 (EVMWHUMIAN, "evmwhumian", MISC, spe_evmwhumian) +BU_SPE_2 (EVMWHGSSFAA, "evmwhgssfaa", MISC, spe_evmwhgssfaa) +BU_SPE_2 (EVMWHGSMFAA, "evmwhgsmfaa", MISC, spe_evmwhgsmfaa) +BU_SPE_2 (EVMWHGSMIAA, "evmwhgsmiaa", MISC, spe_evmwhgsmiaa) +BU_SPE_2 (EVMWHGUMIAA, "evmwhgumiaa", MISC, spe_evmwhgumiaa) +BU_SPE_2 (EVMWHGSSFAN, "evmwhgssfan", MISC, spe_evmwhgssfan) +BU_SPE_2 (EVMWHGSMFAN, "evmwhgsmfan", MISC, spe_evmwhgsmfan) +BU_SPE_2 (EVMWHGSMIAN, "evmwhgsmian", MISC, spe_evmwhgsmian) +BU_SPE_2 (EVMWHGUMIAN, "evmwhgumian", MISC, spe_evmwhgumian) +BU_SPE_2 (BRINC, "brinc", MISC, spe_brinc) +BU_SPE_2 (EVXOR, "evxor", MISC, xorv2si3) + +/* SPE predicate builtins. */ +BU_SPE_P (EVCMPEQ, "evcmpeq", MISC, spe_evcmpeq) +BU_SPE_P (EVCMPGTS, "evcmpgts", MISC, spe_evcmpgts) +BU_SPE_P (EVCMPGTU, "evcmpgtu", MISC, spe_evcmpgtu) +BU_SPE_P (EVCMPLTS, "evcmplts", MISC, spe_evcmplts) +BU_SPE_P (EVCMPLTU, "evcmpltu", MISC, spe_evcmpltu) +BU_SPE_P (EVFSCMPEQ, "evfscmpeq", MISC, spe_evfscmpeq) +BU_SPE_P (EVFSCMPGT, "evfscmpgt", MISC, spe_evfscmpgt) +BU_SPE_P (EVFSCMPLT, "evfscmplt", MISC, spe_evfscmplt) +BU_SPE_P (EVFSTSTEQ, "evfststeq", MISC, spe_evfststeq) +BU_SPE_P (EVFSTSTGT, "evfststgt", MISC, spe_evfststgt) +BU_SPE_P (EVFSTSTLT, "evfststlt", MISC, spe_evfststlt) + +/* SPE evsel builtins. */ +BU_SPE_E (EVSEL_CMPGTS, "evsel_gts", MISC, spe_evcmpgts) +BU_SPE_E (EVSEL_CMPGTU, "evsel_gtu", MISC, spe_evcmpgtu) +BU_SPE_E (EVSEL_CMPLTS, "evsel_lts", MISC, spe_evcmplts) +BU_SPE_E (EVSEL_CMPLTU, "evsel_ltu", MISC, spe_evcmpltu) +BU_SPE_E (EVSEL_CMPEQ, "evsel_eq", MISC, spe_evcmpeq) +BU_SPE_E (EVSEL_FSCMPGT, "evsel_fsgt", MISC, spe_evfscmpgt) +BU_SPE_E (EVSEL_FSCMPLT, "evsel_fslt", MISC, spe_evfscmplt) +BU_SPE_E (EVSEL_FSCMPEQ, "evsel_fseq", MISC, spe_evfscmpeq) +BU_SPE_E (EVSEL_FSTSTGT, "evsel_fststgt", MISC, spe_evfststgt) +BU_SPE_E (EVSEL_FSTSTLT, "evsel_fststlt", MISC, spe_evfststlt) +BU_SPE_E (EVSEL_FSTSTEQ, "evsel_fststeq", MISC, spe_evfststeq) + +BU_SPE_1 (EVABS, "evabs", CONST, absv2si2) +BU_SPE_1 (EVADDSMIAAW, "evaddsmiaaw", CONST, spe_evaddsmiaaw) +BU_SPE_1 (EVADDSSIAAW, "evaddssiaaw", CONST, spe_evaddssiaaw) +BU_SPE_1 (EVADDUMIAAW, "evaddumiaaw", CONST, spe_evaddumiaaw) +BU_SPE_1 (EVADDUSIAAW, "evaddusiaaw", CONST, spe_evaddusiaaw) +BU_SPE_1 (EVCNTLSW, "evcntlsw", CONST, spe_evcntlsw) +BU_SPE_1 (EVCNTLZW, "evcntlzw", CONST, spe_evcntlzw) +BU_SPE_1 (EVEXTSB, "evextsb", CONST, spe_evextsb) +BU_SPE_1 (EVEXTSH, "evextsh", CONST, spe_evextsh) +BU_SPE_1 (EVFSABS, "evfsabs", CONST, spe_evfsabs) +BU_SPE_1 (EVFSCFSF, "evfscfsf", CONST, spe_evfscfsf) +BU_SPE_1 (EVFSCFSI, "evfscfsi", CONST, spe_evfscfsi) +BU_SPE_1 (EVFSCFUF, "evfscfuf", CONST, spe_evfscfuf) +BU_SPE_1 (EVFSCFUI, "evfscfui", CONST, spe_evfscfui) +BU_SPE_1 (EVFSCTSF, "evfsctsf", CONST, spe_evfsctsf) +BU_SPE_1 (EVFSCTSI, "evfsctsi", CONST, spe_evfsctsi) +BU_SPE_1 (EVFSCTSIZ, "evfsctsiz", CONST, spe_evfsctsiz) +BU_SPE_1 (EVFSCTUF, "evfsctuf", CONST, spe_evfsctuf) +BU_SPE_1 (EVFSCTUI, "evfsctui", CONST, spe_evfsctui) +BU_SPE_1 (EVFSCTUIZ, "evfsctuiz", CONST, spe_evfsctuiz) +BU_SPE_1 (EVFSNABS, "evfsnabs", CONST, spe_evfsnabs) +BU_SPE_1 (EVFSNEG, "evfsneg", CONST, spe_evfsneg) +BU_SPE_1 (EVMRA, "evmra", CONST, spe_evmra) +BU_SPE_1 (EVNEG, "evneg", CONST, negv2si2) +BU_SPE_1 (EVRNDW, "evrndw", CONST, spe_evrndw) +BU_SPE_1 (EVSUBFSMIAAW, "evsubfsmiaaw", CONST, spe_evsubfsmiaaw) +BU_SPE_1 (EVSUBFSSIAAW, "evsubfssiaaw", CONST, spe_evsubfssiaaw) +BU_SPE_1 (EVSUBFUMIAAW, "evsubfumiaaw", CONST, spe_evsubfumiaaw) +BU_SPE_1 (EVSUBFUSIAAW, "evsubfusiaaw", CONST, spe_evsubfusiaaw) + +/* SPE builtins that are handled as special cases. */ +BU_SPE_X (EVLDD, "evldd", MISC) +BU_SPE_X (EVLDDX, "evlddx", MISC) +BU_SPE_X (EVLDH, "evldh", MISC) +BU_SPE_X (EVLDHX, "evldhx", MISC) +BU_SPE_X (EVLDW, "evldw", MISC) +BU_SPE_X (EVLDWX, "evldwx", MISC) +BU_SPE_X (EVLHHESPLAT, "evlhhesplat", MISC) +BU_SPE_X (EVLHHESPLATX, "evlhhesplatx", MISC) +BU_SPE_X (EVLHHOSSPLAT, "evlhhossplat", MISC) +BU_SPE_X (EVLHHOSSPLATX, "evlhhossplatx", MISC) +BU_SPE_X (EVLHHOUSPLAT, "evlhhousplat", MISC) +BU_SPE_X (EVLHHOUSPLATX, "evlhhousplatx", MISC) +BU_SPE_X (EVLWHE, "evlwhe", MISC) +BU_SPE_X (EVLWHEX, "evlwhex", MISC) +BU_SPE_X (EVLWHOS, "evlwhos", MISC) +BU_SPE_X (EVLWHOSX, "evlwhosx", MISC) +BU_SPE_X (EVLWHOU, "evlwhou", MISC) +BU_SPE_X (EVLWHOUX, "evlwhoux", MISC) +BU_SPE_X (EVLWHSPLAT, "evlwhsplat", MISC) +BU_SPE_X (EVLWHSPLATX, "evlwhsplatx", MISC) +BU_SPE_X (EVLWWSPLAT, "evlwwsplat", MISC) +BU_SPE_X (EVLWWSPLATX, "evlwwsplatx", MISC) +BU_SPE_X (EVSPLATFI, "evsplatfi", MISC) +BU_SPE_X (EVSPLATI, "evsplati", MISC) +BU_SPE_X (EVSTDD, "evstdd", MISC) +BU_SPE_X (EVSTDDX, "evstddx", MISC) +BU_SPE_X (EVSTDH, "evstdh", MISC) +BU_SPE_X (EVSTDHX, "evstdhx", MISC) +BU_SPE_X (EVSTDW, "evstdw", MISC) +BU_SPE_X (EVSTDWX, "evstdwx", MISC) +BU_SPE_X (EVSTWHE, "evstwhe", MISC) +BU_SPE_X (EVSTWHEX, "evstwhex", MISC) +BU_SPE_X (EVSTWHO, "evstwho", MISC) +BU_SPE_X (EVSTWHOX, "evstwhox", MISC) +BU_SPE_X (EVSTWWE, "evstwwe", MISC) +BU_SPE_X (EVSTWWEX, "evstwwex", MISC) +BU_SPE_X (EVSTWWO, "evstwwo", MISC) +BU_SPE_X (EVSTWWOX, "evstwwox", MISC) +BU_SPE_X (MFSPEFSCR, "mfspefscr", MISC) +BU_SPE_X (MTSPEFSCR, "mtspefscr", MISC) + + +/* Power7 builtins, that aren't VSX instructions. */ +BU_SPECIAL_X (POWER7_BUILTIN_BPERMD, "__builtin_bpermd", RS6000_BTM_POPCNTD, + RS6000_BTC_CONST) + +/* Miscellaneous builtins. */ +BU_SPECIAL_X (RS6000_BUILTIN_RECIP, "__builtin_recipdiv", RS6000_BTM_FRE, + RS6000_BTC_FP) + +BU_SPECIAL_X (RS6000_BUILTIN_RECIPF, "__builtin_recipdivf", RS6000_BTM_FRES, + RS6000_BTC_FP) + +BU_SPECIAL_X (RS6000_BUILTIN_RSQRT, "__builtin_rsqrt", RS6000_BTM_FRSQRTE, + RS6000_BTC_FP) + +BU_SPECIAL_X (RS6000_BUILTIN_RSQRTF, "__builtin_rsqrtf", RS6000_BTM_FRSQRTES, + RS6000_BTC_FP) + +BU_SPECIAL_X (RS6000_BUILTIN_GET_TB, "__builtin_ppc_get_timebase", + RS6000_BTM_ALWAYS, RS6000_BTC_MISC) + +BU_SPECIAL_X (RS6000_BUILTIN_MFTB, "__builtin_ppc_mftb", + RS6000_BTM_ALWAYS, RS6000_BTC_MISC) + +BU_SPECIAL_X (RS6000_BUILTIN_MFFS, "__builtin_mffs", + RS6000_BTM_ALWAYS, RS6000_BTC_MISC) + +RS6000_BUILTIN_X (RS6000_BUILTIN_MTFSF, "__builtin_mtfsf", + RS6000_BTM_ALWAYS, + RS6000_BTC_MISC | RS6000_BTC_UNARY | RS6000_BTC_VOID, + CODE_FOR_rs6000_mtfsf) + +BU_SPECIAL_X (RS6000_BUILTIN_CPU_INIT, "__builtin_cpu_init", + RS6000_BTM_ALWAYS, RS6000_BTC_MISC) + +BU_SPECIAL_X (RS6000_BUILTIN_CPU_IS, "__builtin_cpu_is", + RS6000_BTM_ALWAYS, RS6000_BTC_MISC) + +BU_SPECIAL_X (RS6000_BUILTIN_CPU_SUPPORTS, "__builtin_cpu_supports", + RS6000_BTM_ALWAYS, RS6000_BTC_MISC) + +BU_SPECIAL_X (RS6000_BUILTIN_NANQ, "__builtin_nanq", + RS6000_BTM_FLOAT128, RS6000_BTC_CONST) + +BU_SPECIAL_X (RS6000_BUILTIN_NANSQ, "__builtin_nansq", + RS6000_BTM_FLOAT128, RS6000_BTC_CONST) + +BU_SPECIAL_X (RS6000_BUILTIN_INFQ, "__builtin_infq", + RS6000_BTM_FLOAT128, RS6000_BTC_CONST) + +BU_SPECIAL_X (RS6000_BUILTIN_HUGE_VALQ, "__builtin_huge_valq", + RS6000_BTM_FLOAT128, RS6000_BTC_CONST) + +/* Darwin CfString builtin. */ +BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS, + RS6000_BTC_MISC) diff --git a/gcc/config/powerpcspe/powerpcspe-c.c b/gcc/config/powerpcspe/powerpcspe-c.c new file mode 100644 index 00000000000..8039814b48e --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe-c.c @@ -0,0 +1,6581 @@ +/* Subroutines for the C front end on the PowerPC architecture. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + + Contributed by Zack Weinberg + and Paolo Bonzini + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "target.h" +#include "c-family/c-common.h" +#include "memmodel.h" +#include "tm_p.h" +#include "stringpool.h" +#include "stor-layout.h" +#include "c-family/c-pragma.h" +#include "langhooks.h" +#include "c/c-tree.h" + + + +/* Handle the machine specific pragma longcall. Its syntax is + + # pragma longcall ( TOGGLE ) + + where TOGGLE is either 0 or 1. + + rs6000_default_long_calls is set to the value of TOGGLE, changing + whether or not new function declarations receive a longcall + attribute by default. */ + +#define SYNTAX_ERROR(gmsgid) do { \ + warning (OPT_Wpragmas, gmsgid); \ + warning (OPT_Wpragmas, "ignoring malformed #pragma longcall"); \ + return; \ +} while (0) + +void +rs6000_pragma_longcall (cpp_reader *pfile ATTRIBUTE_UNUSED) +{ + tree x, n; + + /* If we get here, generic code has already scanned the directive + leader and the word "longcall". */ + + if (pragma_lex (&x) != CPP_OPEN_PAREN) + SYNTAX_ERROR ("missing open paren"); + if (pragma_lex (&n) != CPP_NUMBER) + SYNTAX_ERROR ("missing number"); + if (pragma_lex (&x) != CPP_CLOSE_PAREN) + SYNTAX_ERROR ("missing close paren"); + + if (n != integer_zero_node && n != integer_one_node) + SYNTAX_ERROR ("number must be 0 or 1"); + + if (pragma_lex (&x) != CPP_EOF) + warning (OPT_Wpragmas, "junk at end of #pragma longcall"); + + rs6000_default_long_calls = (n == integer_one_node); +} + +/* Handle defining many CPP flags based on TARGET_xxx. As a general + policy, rather than trying to guess what flags a user might want a + #define for, it's better to define a flag for everything. */ + +#define builtin_define(TXT) cpp_define (pfile, TXT) +#define builtin_assert(TXT) cpp_assert (pfile, TXT) + +/* Keep the AltiVec keywords handy for fast comparisons. */ +static GTY(()) tree __vector_keyword; +static GTY(()) tree vector_keyword; +static GTY(()) tree __pixel_keyword; +static GTY(()) tree pixel_keyword; +static GTY(()) tree __bool_keyword; +static GTY(()) tree bool_keyword; +static GTY(()) tree _Bool_keyword; +static GTY(()) tree __int128_type; +static GTY(()) tree __uint128_type; + +/* Preserved across calls. */ +static tree expand_bool_pixel; + +static cpp_hashnode * +altivec_categorize_keyword (const cpp_token *tok) +{ + if (tok->type == CPP_NAME) + { + cpp_hashnode *ident = tok->val.node.node; + + if (ident == C_CPP_HASHNODE (vector_keyword)) + return C_CPP_HASHNODE (__vector_keyword); + + if (ident == C_CPP_HASHNODE (pixel_keyword)) + return C_CPP_HASHNODE (__pixel_keyword); + + if (ident == C_CPP_HASHNODE (bool_keyword)) + return C_CPP_HASHNODE (__bool_keyword); + + if (ident == C_CPP_HASHNODE (_Bool_keyword)) + return C_CPP_HASHNODE (__bool_keyword); + + return ident; + } + + return 0; +} + +static void +init_vector_keywords (void) +{ + /* Keywords without two leading underscores are context-sensitive, and hence + implemented as conditional macros, controlled by the + rs6000_macro_to_expand() function below. If we have ISA 2.07 64-bit + support, record the __int128_t and __uint128_t types. */ + + __vector_keyword = get_identifier ("__vector"); + C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL; + + __pixel_keyword = get_identifier ("__pixel"); + C_CPP_HASHNODE (__pixel_keyword)->flags |= NODE_CONDITIONAL; + + __bool_keyword = get_identifier ("__bool"); + C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL; + + vector_keyword = get_identifier ("vector"); + C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL; + + pixel_keyword = get_identifier ("pixel"); + C_CPP_HASHNODE (pixel_keyword)->flags |= NODE_CONDITIONAL; + + bool_keyword = get_identifier ("bool"); + C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL; + + _Bool_keyword = get_identifier ("_Bool"); + C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL; + + if (TARGET_VADDUQM) + { + __int128_type = get_identifier ("__int128_t"); + __uint128_type = get_identifier ("__uint128_t"); + } +} + +/* Helper function to find out which RID_INT_N_* code is the one for + __int128, if any. Returns RID_MAX+1 if none apply, which is safe + (for our purposes, since we always expect to have __int128) to + compare against. */ +static int +rid_int128(void) +{ + int i; + + for (i = 0; i < NUM_INT_N_ENTS; i ++) + if (int_n_enabled_p[i] + && int_n_data[i].bitsize == 128) + return RID_INT_N_0 + i; + + return RID_MAX + 1; +} + +/* Called to decide whether a conditional macro should be expanded. + Since we have exactly one such macro (i.e, 'vector'), we do not + need to examine the 'tok' parameter. */ + +static cpp_hashnode * +rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok) +{ + cpp_hashnode *expand_this = tok->val.node.node; + cpp_hashnode *ident; + + /* If the current machine does not have altivec, don't look for the + keywords. */ + if (!TARGET_ALTIVEC) + return NULL; + + ident = altivec_categorize_keyword (tok); + + if (ident != expand_this) + expand_this = NULL; + + if (ident == C_CPP_HASHNODE (__vector_keyword)) + { + int idx = 0; + do + tok = cpp_peek_token (pfile, idx++); + while (tok->type == CPP_PADDING); + ident = altivec_categorize_keyword (tok); + + if (ident == C_CPP_HASHNODE (__pixel_keyword)) + { + expand_this = C_CPP_HASHNODE (__vector_keyword); + expand_bool_pixel = __pixel_keyword; + } + else if (ident == C_CPP_HASHNODE (__bool_keyword)) + { + expand_this = C_CPP_HASHNODE (__vector_keyword); + expand_bool_pixel = __bool_keyword; + } + /* The boost libraries have code with Iterator::vector vector in it. If + we allow the normal handling, this module will be called recursively, + and the vector will be skipped.; */ + else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword))) + { + enum rid rid_code = (enum rid)(ident->rid_code); + enum node_type itype = ident->type; + /* If there is a function-like macro, check if it is going to be + invoked with or without arguments. Without following ( treat + it like non-macro, otherwise the following cpp_get_token eats + what should be preserved. */ + if (itype == NT_MACRO && cpp_fun_like_macro_p (ident)) + { + int idx2 = idx; + do + tok = cpp_peek_token (pfile, idx2++); + while (tok->type == CPP_PADDING); + if (tok->type != CPP_OPEN_PAREN) + itype = NT_VOID; + } + if (itype == NT_MACRO) + { + do + (void) cpp_get_token (pfile); + while (--idx > 0); + do + tok = cpp_peek_token (pfile, idx++); + while (tok->type == CPP_PADDING); + ident = altivec_categorize_keyword (tok); + if (ident == C_CPP_HASHNODE (__pixel_keyword)) + { + expand_this = C_CPP_HASHNODE (__vector_keyword); + expand_bool_pixel = __pixel_keyword; + rid_code = RID_MAX; + } + else if (ident == C_CPP_HASHNODE (__bool_keyword)) + { + expand_this = C_CPP_HASHNODE (__vector_keyword); + expand_bool_pixel = __bool_keyword; + rid_code = RID_MAX; + } + else if (ident) + rid_code = (enum rid)(ident->rid_code); + } + + if (rid_code == RID_UNSIGNED || rid_code == RID_LONG + || rid_code == RID_SHORT || rid_code == RID_SIGNED + || rid_code == RID_INT || rid_code == RID_CHAR + || rid_code == RID_FLOAT + || (rid_code == RID_DOUBLE && TARGET_VSX) + || (rid_code == rid_int128 () && TARGET_VADDUQM)) + { + expand_this = C_CPP_HASHNODE (__vector_keyword); + /* If the next keyword is bool or pixel, it + will need to be expanded as well. */ + do + tok = cpp_peek_token (pfile, idx++); + while (tok->type == CPP_PADDING); + ident = altivec_categorize_keyword (tok); + + if (ident == C_CPP_HASHNODE (__pixel_keyword)) + expand_bool_pixel = __pixel_keyword; + else if (ident == C_CPP_HASHNODE (__bool_keyword)) + expand_bool_pixel = __bool_keyword; + else + { + /* Try two tokens down, too. */ + do + tok = cpp_peek_token (pfile, idx++); + while (tok->type == CPP_PADDING); + ident = altivec_categorize_keyword (tok); + if (ident == C_CPP_HASHNODE (__pixel_keyword)) + expand_bool_pixel = __pixel_keyword; + else if (ident == C_CPP_HASHNODE (__bool_keyword)) + expand_bool_pixel = __bool_keyword; + } + } + + /* Support vector __int128_t, but we don't need to worry about bool + or pixel on this type. */ + else if (TARGET_VADDUQM + && (ident == C_CPP_HASHNODE (__int128_type) + || ident == C_CPP_HASHNODE (__uint128_type))) + expand_this = C_CPP_HASHNODE (__vector_keyword); + } + } + else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__pixel_keyword)) + { + expand_this = C_CPP_HASHNODE (__pixel_keyword); + expand_bool_pixel = 0; + } + else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__bool_keyword)) + { + expand_this = C_CPP_HASHNODE (__bool_keyword); + expand_bool_pixel = 0; + } + + return expand_this; +} + + +/* Define or undefine a single macro. */ + +static void +rs6000_define_or_undefine_macro (bool define_p, const char *name) +{ + if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET) + fprintf (stderr, "#%s %s\n", (define_p) ? "define" : "undef", name); + + if (define_p) + cpp_define (parse_in, name); + else + cpp_undef (parse_in, name); +} + +/* Define or undefine macros based on the current target. If the user does + #pragma GCC target, we need to adjust the macros dynamically. Note, some of + the options needed for builtins have been moved to separate variables, so + have both the target flags and the builtin flags as arguments. */ + +void +rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags, + HOST_WIDE_INT bu_mask) +{ + if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET) + fprintf (stderr, + "rs6000_target_modify_macros (%s, " HOST_WIDE_INT_PRINT_HEX + ", " HOST_WIDE_INT_PRINT_HEX ")\n", + (define_p) ? "define" : "undef", + flags, bu_mask); + + /* Each of the flags mentioned below controls whether certain + preprocessor macros will be automatically defined when + preprocessing source files for compilation by this compiler. + While most of these flags can be enabled or disabled + explicitly by specifying certain command-line options when + invoking the compiler, there are also many ways in which these + flags are enabled or disabled implicitly, based on compiler + defaults, configuration choices, and on the presence of certain + related command-line options. Many, but not all, of these + implicit behaviors can be found in file "rs6000.c", the + rs6000_option_override_internal() function. + + In general, each of the flags may be automatically enabled in + any of the following conditions: + + 1. If no -mcpu target is specified on the command line and no + --with-cpu target is specified to the configure command line + and the TARGET_DEFAULT macro for this default cpu host + includes the flag, and the flag has not been explicitly disabled + by command-line options. + + 2. If the target specified with -mcpu=target on the command line, or + in the absence of a -mcpu=target command-line option, if the + target specified using --with-cpu=target on the configure + command line, is disqualified because the associated binary + tools (e.g. the assembler) lack support for the requested cpu, + and the TARGET_DEFAULT macro for this default cpu host + includes the flag, and the flag has not been explicitly disabled + by command-line options. + + 3. If either of the above two conditions apply except that the + TARGET_DEFAULT macro is defined to equal zero, and + TARGET_POWERPC64 and + a) BYTES_BIG_ENDIAN and the flag to be enabled is either + MASK_PPC_GFXOPT or MASK_POWERPC64 (flags for "powerpc64" + target), or + b) !BYTES_BIG_ENDIAN and the flag to be enabled is either + MASK_POWERPC64 or it is one of the flags included in + ISA_2_7_MASKS_SERVER (flags for "powerpc64le" target). + + 4. If a cpu has been requested with a -mcpu=target command-line option + and this cpu has not been disqualified due to shortcomings of the + binary tools, and the set of flags associated with the requested cpu + include the flag to be enabled. See rs6000-cpus.def for macro + definitions that represent various ABI standards + (e.g. ISA_2_1_MASKS, ISA_3_0_MASKS_SERVER) and for a list of + the specific flags that are associated with each of the cpu + choices that can be specified as the target of a -mcpu=target + compile option, or as the the target of a --with-cpu=target + configure option. Target flags that are specified in either + of these two ways are considered "implicit" since the flags + are not mentioned specifically by name. + + Additional documentation describing behavior specific to + particular flags is provided below, immediately preceding the + use of each relevant flag. + + 5. If there is no -mcpu=target command-line option, and the cpu + requested by a --with-cpu=target command-line option has not + been disqualified due to shortcomings of the binary tools, and + the set of flags associated with the specified target include + the flag to be enabled. See the notes immediately above for a + summary of the flags associated with particular cpu + definitions. */ + + /* rs6000_isa_flags based options. */ + rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC"); + if ((flags & OPTION_MASK_PPC_GPOPT) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCSQ"); + if ((flags & OPTION_MASK_PPC_GFXOPT) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCGR"); + if ((flags & OPTION_MASK_POWERPC64) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC64"); + if ((flags & OPTION_MASK_MFCRF) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR4"); + if ((flags & OPTION_MASK_POPCNTB) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5"); + if ((flags & OPTION_MASK_FPRND) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5X"); + if ((flags & OPTION_MASK_CMPB) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6"); + if ((flags & OPTION_MASK_MFPGPR) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6X"); + if ((flags & OPTION_MASK_POPCNTD) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR7"); + /* Note that the OPTION_MASK_DIRECT_MOVE flag is automatically + turned on in the following condition: + 1. TARGET_P9_DFORM_SCALAR or TARGET_P9_DFORM_VECTOR are enabled + and OPTION_MASK_DIRECT_MOVE is not explicitly disabled. + Hereafter, the OPTION_MASK_DIRECT_MOVE flag is considered to + have been turned on explicitly. + Note that the OPTION_MASK_DIRECT_MOVE flag is automatically + turned off in any of the following conditions: + 1. TARGET_HARD_FLOAT, TARGET_ALTIVEC, or TARGET_VSX is explicitly + disabled and OPTION_MASK_DIRECT_MOVE was not explicitly + enabled. + 2. TARGET_VSX is off. */ + if ((flags & OPTION_MASK_DIRECT_MOVE) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR8"); + if ((flags & OPTION_MASK_MODULO) != 0) + rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR9"); + if ((flags & OPTION_MASK_SOFT_FLOAT) != 0) + rs6000_define_or_undefine_macro (define_p, "_SOFT_FLOAT"); + if ((flags & OPTION_MASK_RECIP_PRECISION) != 0) + rs6000_define_or_undefine_macro (define_p, "__RECIP_PRECISION__"); + /* Note that the OPTION_MASK_ALTIVEC flag is automatically turned on + in any of the following conditions: + 1. The command line specifies either -maltivec=le or -maltivec=be. + 2. The operating system is Darwin and it is configured for 64 + bit. (See darwin_rs6000_override_options.) + 3. The operating system is Darwin and the operating system + version is 10.5 or higher and the user has not explicitly + disabled ALTIVEC by specifying -mcpu=G3 or -mno-altivec and + the compiler is not producing code for integration within the + kernel. (See darwin_rs6000_override_options.) + Note that the OPTION_MASK_ALTIVEC flag is automatically turned + off in any of the following conditions: + 1. The operating system does not support saving of AltiVec + registers (OS_MISSING_ALTIVEC). + 2. If an inner context (as introduced by + __attribute__((__target__())) or #pragma GCC target() + requests a target that normally enables the + OPTION_MASK_ALTIVEC flag but the outer-most "main target" + does not support the rs6000_altivec_abi, this flag is + turned off for the inner context unless OPTION_MASK_ALTIVEC + was explicitly enabled for the inner context. */ + if ((flags & OPTION_MASK_ALTIVEC) != 0) + { + const char *vec_str = (define_p) ? "__VEC__=10206" : "__VEC__"; + rs6000_define_or_undefine_macro (define_p, "__ALTIVEC__"); + rs6000_define_or_undefine_macro (define_p, vec_str); + + /* Define this when supporting context-sensitive keywords. */ + if (!flag_iso) + rs6000_define_or_undefine_macro (define_p, "__APPLE_ALTIVEC__"); + } + /* Note that the OPTION_MASK_VSX flag is automatically turned on in + the following conditions: + 1. TARGET_P8_VECTOR is explicitly turned on and the OPTION_MASK_VSX + was not explicitly turned off. Hereafter, the OPTION_MASK_VSX + flag is considered to have been explicitly turned on. + Note that the OPTION_MASK_VSX flag is automatically turned off in + the following conditions: + 1. The operating system does not support saving of AltiVec + registers (OS_MISSING_ALTIVEC). + 2. If any of the options TARGET_HARD_FLOAT, TARGET_FPRS, + TARGET_SINGLE_FLOAT, or TARGET_DOUBLE_FLOAT are turned off. + Hereafter, the OPTION_MASK_VSX flag is considered to have been + turned off explicitly. + 3. If TARGET_PAIRED_FLOAT was enabled. Hereafter, the + OPTION_MASK_VSX flag is considered to have been turned off + explicitly. + 4. If TARGET_AVOID_XFORM is turned on explicitly at the outermost + compilation context, or if it is turned on by any means in an + inner compilation context. Hereafter, the OPTION_MASK_VSX + flag is considered to have been turned off explicitly. + 5. If TARGET_ALTIVEC was explicitly disabled. Hereafter, the + OPTION_MASK_VSX flag is considered to have been turned off + explicitly. + 6. If an inner context (as introduced by + __attribute__((__target__())) or #pragma GCC target() + requests a target that normally enables the + OPTION_MASK_VSX flag but the outer-most "main target" + does not support the rs6000_altivec_abi, this flag is + turned off for the inner context unless OPTION_MASK_VSX + was explicitly enabled for the inner context. */ + if ((flags & OPTION_MASK_VSX) != 0) + rs6000_define_or_undefine_macro (define_p, "__VSX__"); + if ((flags & OPTION_MASK_HTM) != 0) + { + rs6000_define_or_undefine_macro (define_p, "__HTM__"); + /* Tell the user that our HTM insn patterns act as memory barriers. */ + rs6000_define_or_undefine_macro (define_p, "__TM_FENCE__"); + } + /* Note that the OPTION_MASK_P8_VECTOR flag is automatically turned + on in the following conditions: + 1. TARGET_P9_VECTOR is explicitly turned on and + OPTION_MASK_P8_VECTOR is not explicitly turned off. + Hereafter, the OPTION_MASK_P8_VECTOR flag is considered to + have been turned off explicitly. + Note that the OPTION_MASK_P8_VECTOR flag is automatically turned + off in the following conditions: + 1. If any of TARGET_HARD_FLOAT, TARGET_ALTIVEC, or TARGET_VSX + were turned off explicitly and OPTION_MASK_P8_VECTOR flag was + not turned on explicitly. + 2. If TARGET_ALTIVEC is turned off. Hereafter, the + OPTION_MASK_P8_VECTOR flag is considered to have been turned off + explicitly. + 3. If TARGET_VSX is turned off and OPTION_MASK_P8_VECTOR was not + explicitly enabled. If TARGET_VSX is explicitly enabled, the + OPTION_MASK_P8_VECTOR flag is hereafter also considered to + have been turned off explicitly. */ + if ((flags & OPTION_MASK_P8_VECTOR) != 0) + rs6000_define_or_undefine_macro (define_p, "__POWER8_VECTOR__"); + /* Note that the OPTION_MASK_P9_VECTOR flag is automatically turned + off in the following conditions: + 1. If TARGET_P8_VECTOR is turned off and OPTION_MASK_P9_VECTOR is + not turned on explicitly. Hereafter, if OPTION_MASK_P8_VECTOR + was turned on explicitly, the OPTION_MASK_P9_VECTOR flag is + also considered to have been turned off explicitly. + Note that the OPTION_MASK_P9_VECTOR is automatically turned on + in the following conditions: + 1. If TARGET_P9_DFORM_SCALAR or TARGET_P9_DFORM_VECTOR and + OPTION_MASK_P9_VECTOR was not turned off explicitly. + Hereafter, THE OPTION_MASK_P9_VECTOR flag is considered to + have been turned on explicitly. */ + if ((flags & OPTION_MASK_P9_VECTOR) != 0) + rs6000_define_or_undefine_macro (define_p, "__POWER9_VECTOR__"); + /* Note that the OPTION_MASK_QUAD_MEMORY flag is automatically + turned off in the following conditions: + 1. If TARGET_POWERPC64 is turned off. + 2. If WORDS_BIG_ENDIAN is false (non-atomic quad memory + load/store are disabled on little endian). */ + if ((flags & OPTION_MASK_QUAD_MEMORY) != 0) + rs6000_define_or_undefine_macro (define_p, "__QUAD_MEMORY__"); + /* Note that the OPTION_MASK_QUAD_MEMORY_ATOMIC flag is automatically + turned off in the following conditions: + 1. If TARGET_POWERPC64 is turned off. + Note that the OPTION_MASK_QUAD_MEMORY_ATOMIC flag is + automatically turned on in the following conditions: + 1. If TARGET_QUAD_MEMORY and this flag was not explicitly + disabled. */ + if ((flags & OPTION_MASK_QUAD_MEMORY_ATOMIC) != 0) + rs6000_define_or_undefine_macro (define_p, "__QUAD_MEMORY_ATOMIC__"); + /* Note that the OPTION_MASK_CRYPTO flag is automatically turned off + in the following conditions: + 1. If any of TARGET_HARD_FLOAT or TARGET_ALTIVEC or TARGET_VSX + are turned off explicitly and OPTION_MASK_CRYPTO is not turned + on explicitly. + 2. If TARGET_ALTIVEC is turned off. */ + if ((flags & OPTION_MASK_CRYPTO) != 0) + rs6000_define_or_undefine_macro (define_p, "__CRYPTO__"); + /* Note that the OPTION_MASK_UPPER_REGS_DF flag is automatically + turned on in the following conditions: + 1. If TARGET_UPPER_REGS is explicitly turned on and + TARGET_VSX is turned on and OPTION_MASK_UPPER_REGS_DF is not + explicitly turned off. Hereafter, the + OPTION_MASK_UPPER_REGS_DF flag is considered to have been + explicitly set. + Note that the OPTION_MASK_UPPER_REGS_DF flag is automatically + turned off in the following conditions: + 1. If TARGET_UPPER_REGS is explicitly turned off and TARGET_VSX + is turned on and OPTION_MASK_UPPER_REGS_DF is not explicitly + turned on. Hereafter, the OPTION_MASK_UPPER_REGS_DF flag is + considered to have been explicitly cleared. + 2. If TARGET_UPPER_REGS_DF is turned on but TARGET_VSX is turned + off. */ + if ((flags & OPTION_MASK_UPPER_REGS_DF) != 0) + rs6000_define_or_undefine_macro (define_p, "__UPPER_REGS_DF__"); + /* Note that the OPTION_MASK_UPPER_REGS_SF flag is automatically + turned on in the following conditions: + 1. If TARGET_UPPER_REGS is explicitly turned on and + TARGET_P8_VECTOR is on and OPTION_MASK_UPPER_REGS_SF is not + turned off explicitly. Hereafter, the + OPTION_MASK_UPPER_REGS_SF flag is considered to have been + explicitly set. + Note that the OPTION_MASK_UPPER_REGS_SF flag is automatically + turned off in the following conditions: + 1. If TARGET_UPPER_REGS is explicitly turned off and + TARGET_P8_VECTOR is on and OPTION_MASK_UPPER_REGS_SF is not + turned off explicitly. Hereafter, the + OPTION_MASK_UPPER_REGS_SF flag is considered to have been + explicitly cleared. + 2. If TARGET_P8_VECTOR is off. */ + if ((flags & OPTION_MASK_UPPER_REGS_SF) != 0) + rs6000_define_or_undefine_macro (define_p, "__UPPER_REGS_SF__"); + + /* options from the builtin masks. */ + /* Note that RS6000_BTM_SPE is enabled only if TARGET_SPE + (e.g. -mspe). */ + if ((bu_mask & RS6000_BTM_SPE) != 0) + rs6000_define_or_undefine_macro (define_p, "__SPE__"); + /* Note that RS6000_BTM_PAIRED is enabled only if + TARGET_PAIRED_FLOAT is enabled (e.g. -mpaired). */ + if ((bu_mask & RS6000_BTM_PAIRED) != 0) + rs6000_define_or_undefine_macro (define_p, "__PAIRED__"); + /* Note that RS6000_BTM_CELL is enabled only if (rs6000_cpu == + PROCESSOR_CELL) (e.g. -mcpu=cell). */ + if ((bu_mask & RS6000_BTM_CELL) != 0) + rs6000_define_or_undefine_macro (define_p, "__PPU__"); +} + +void +rs6000_cpu_cpp_builtins (cpp_reader *pfile) +{ + /* Define all of the common macros. */ + rs6000_target_modify_macros (true, rs6000_isa_flags, + rs6000_builtin_mask_calculate ()); + + if (TARGET_FRE) + builtin_define ("__RECIP__"); + if (TARGET_FRES) + builtin_define ("__RECIPF__"); + if (TARGET_FRSQRTE) + builtin_define ("__RSQRTE__"); + if (TARGET_FRSQRTES) + builtin_define ("__RSQRTEF__"); + if (TARGET_FLOAT128_KEYWORD) + builtin_define ("__FLOAT128__"); + if (TARGET_FLOAT128_TYPE) + builtin_define ("__FLOAT128_TYPE__"); + if (TARGET_FLOAT128_HW) + builtin_define ("__FLOAT128_HARDWARE__"); + if (TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (TFmode)) + builtin_define ("__ibm128=long double"); + + /* We needed to create a keyword if -mfloat128-type was used but not -mfloat, + so we used __ieee128. If -mfloat128 was used, create a #define back to + the real keyword in case somebody used it. */ + if (TARGET_FLOAT128_KEYWORD) + builtin_define ("__ieee128=__float128"); + + if (TARGET_EXTRA_BUILTINS && cpp_get_options (pfile)->lang != CLK_ASM) + { + /* Define the AltiVec syntactic elements. */ + builtin_define ("__vector=__attribute__((altivec(vector__)))"); + builtin_define ("__pixel=__attribute__((altivec(pixel__))) unsigned short"); + builtin_define ("__bool=__attribute__((altivec(bool__))) unsigned"); + + if (!flag_iso) + { + builtin_define ("vector=vector"); + builtin_define ("pixel=pixel"); + builtin_define ("bool=bool"); + builtin_define ("_Bool=_Bool"); + init_vector_keywords (); + + /* Enable context-sensitive macros. */ + cpp_get_callbacks (pfile)->macro_to_expand = rs6000_macro_to_expand; + } + } + if ((!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE))) + ||(TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_DOUBLE_FLOAT)) + builtin_define ("_SOFT_DOUBLE"); + /* Used by lwarx/stwcx. errata work-around. */ + if (rs6000_cpu == PROCESSOR_PPC405) + builtin_define ("__PPC405__"); + /* Used by libstdc++. */ + if (TARGET_NO_LWSYNC) + builtin_define ("__NO_LWSYNC__"); + + if (TARGET_EXTRA_BUILTINS) + { + /* For the VSX builtin functions identical to Altivec functions, just map + the altivec builtin into the vsx version (the altivec functions + generate VSX code if -mvsx). */ + builtin_define ("__builtin_vsx_xxland=__builtin_vec_and"); + builtin_define ("__builtin_vsx_xxlandc=__builtin_vec_andc"); + builtin_define ("__builtin_vsx_xxlnor=__builtin_vec_nor"); + builtin_define ("__builtin_vsx_xxlor=__builtin_vec_or"); + builtin_define ("__builtin_vsx_xxlxor=__builtin_vec_xor"); + builtin_define ("__builtin_vsx_xxsel=__builtin_vec_sel"); + builtin_define ("__builtin_vsx_vperm=__builtin_vec_perm"); + + /* Also map the a and m versions of the multiply/add instructions to the + builtin for people blindly going off the instruction manual. */ + builtin_define ("__builtin_vsx_xvmaddadp=__builtin_vsx_xvmadddp"); + builtin_define ("__builtin_vsx_xvmaddmdp=__builtin_vsx_xvmadddp"); + builtin_define ("__builtin_vsx_xvmaddasp=__builtin_vsx_xvmaddsp"); + builtin_define ("__builtin_vsx_xvmaddmsp=__builtin_vsx_xvmaddsp"); + builtin_define ("__builtin_vsx_xvmsubadp=__builtin_vsx_xvmsubdp"); + builtin_define ("__builtin_vsx_xvmsubmdp=__builtin_vsx_xvmsubdp"); + builtin_define ("__builtin_vsx_xvmsubasp=__builtin_vsx_xvmsubsp"); + builtin_define ("__builtin_vsx_xvmsubmsp=__builtin_vsx_xvmsubsp"); + builtin_define ("__builtin_vsx_xvnmaddadp=__builtin_vsx_xvnmadddp"); + builtin_define ("__builtin_vsx_xvnmaddmdp=__builtin_vsx_xvnmadddp"); + builtin_define ("__builtin_vsx_xvnmaddasp=__builtin_vsx_xvnmaddsp"); + builtin_define ("__builtin_vsx_xvnmaddmsp=__builtin_vsx_xvnmaddsp"); + builtin_define ("__builtin_vsx_xvnmsubadp=__builtin_vsx_xvnmsubdp"); + builtin_define ("__builtin_vsx_xvnmsubmdp=__builtin_vsx_xvnmsubdp"); + builtin_define ("__builtin_vsx_xvnmsubasp=__builtin_vsx_xvnmsubsp"); + builtin_define ("__builtin_vsx_xvnmsubmsp=__builtin_vsx_xvnmsubsp"); + } + + /* Tell users they can use __builtin_bswap{16,64}. */ + builtin_define ("__HAVE_BSWAP__"); + + /* May be overridden by target configuration. */ + RS6000_CPU_CPP_ENDIAN_BUILTINS(); + + if (TARGET_LONG_DOUBLE_128) + { + builtin_define ("__LONG_DOUBLE_128__"); + builtin_define ("__LONGDOUBLE128"); + + if (TARGET_IEEEQUAD) + builtin_define ("__LONG_DOUBLE_IEEE128__"); + else + builtin_define ("__LONG_DOUBLE_IBM128__"); + } + + switch (TARGET_CMODEL) + { + /* Deliberately omit __CMODEL_SMALL__ since that was the default + before --mcmodel support was added. */ + case CMODEL_MEDIUM: + builtin_define ("__CMODEL_MEDIUM__"); + break; + case CMODEL_LARGE: + builtin_define ("__CMODEL_LARGE__"); + break; + default: + break; + } + + switch (rs6000_current_abi) + { + case ABI_V4: + builtin_define ("_CALL_SYSV"); + break; + case ABI_AIX: + builtin_define ("_CALL_AIXDESC"); + builtin_define ("_CALL_AIX"); + builtin_define ("_CALL_ELF=1"); + break; + case ABI_ELFv2: + builtin_define ("_CALL_ELF=2"); + break; + case ABI_DARWIN: + builtin_define ("_CALL_DARWIN"); + break; + default: + break; + } + + /* Vector element order. */ + if (BYTES_BIG_ENDIAN || (rs6000_altivec_element_order == 2)) + builtin_define ("__VEC_ELEMENT_REG_ORDER__=__ORDER_BIG_ENDIAN__"); + else + builtin_define ("__VEC_ELEMENT_REG_ORDER__=__ORDER_LITTLE_ENDIAN__"); + + /* Let the compiled code know if 'f' class registers will not be available. */ + if (TARGET_SOFT_FLOAT || !TARGET_FPRS) + builtin_define ("__NO_FPRS__"); + + /* Whether aggregates passed by value are aligned to a 16 byte boundary + if their alignment is 16 bytes or larger. */ + if ((TARGET_MACHO && rs6000_darwin64_abi) + || DEFAULT_ABI == ABI_ELFv2 + || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm)) + builtin_define ("__STRUCT_PARM_ALIGN__=16"); + + /* Generate defines for Xilinx FPU. */ + if (rs6000_xilinx_fpu) + { + builtin_define ("_XFPU"); + if (rs6000_single_float && ! rs6000_double_float) + { + if (rs6000_simple_fpu) + builtin_define ("_XFPU_SP_LITE"); + else + builtin_define ("_XFPU_SP_FULL"); + } + if (rs6000_double_float) + { + if (rs6000_simple_fpu) + builtin_define ("_XFPU_DP_LITE"); + else + builtin_define ("_XFPU_DP_FULL"); + } + } +} + + +struct altivec_builtin_types +{ + enum rs6000_builtins code; + enum rs6000_builtins overloaded_code; + signed char ret_type; + signed char op1; + signed char op2; + signed char op3; +}; + +const struct altivec_builtin_types altivec_overloaded_builtins[] = { + /* Unary AltiVec/VSX builtins. */ + { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ABS, P8V_BUILTIN_ABS_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ABS, ALTIVEC_BUILTIN_ABS_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ABS, VSX_BUILTIN_XVABSDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ABSS, ALTIVEC_BUILTIN_ABSS_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_CEIL, ALTIVEC_BUILTIN_VRFIP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_CEIL, VSX_BUILTIN_XVRDPIP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_EXPTE, ALTIVEC_BUILTIN_VEXPTEFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_FLOOR, VSX_BUILTIN_XVRDPIM, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_FLOOR, ALTIVEC_BUILTIN_VRFIM, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_LOGE, ALTIVEC_BUILTIN_VLOGEFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_MTVSCR, ALTIVEC_BUILTIN_MTVSCR, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_RE, ALTIVEC_BUILTIN_VREFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_RE, VSX_BUILTIN_XVREDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ROUND, ALTIVEC_BUILTIN_VRFIN, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_ROUND, VSX_BUILTIN_XVRDPI, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_RECIP, ALTIVEC_BUILTIN_VRECIPFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_RECIP, VSX_BUILTIN_RECIP_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_RSQRT, ALTIVEC_BUILTIN_VRSQRTFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_RSQRT, VSX_BUILTIN_RSQRT_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_RSQRTE, ALTIVEC_BUILTIN_VRSQRTEFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_RSQRTE, VSX_BUILTIN_XVRSQRTEDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_TRUNC, ALTIVEC_BUILTIN_VRFIZ, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_TRUNC, VSX_BUILTIN_XVRDPIZ, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB, + RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSB, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSH, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHSH, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKH, P8V_BUILTIN_VUPKHSW, + RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKH, P8V_BUILTIN_VUPKHSW, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKH, ALTIVEC_BUILTIN_VUPKHPX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_pixel_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKHSH, ALTIVEC_BUILTIN_VUPKHSH, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKHSH, ALTIVEC_BUILTIN_VUPKHSH, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKHSH, P8V_BUILTIN_VUPKHSW, + RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKHSH, P8V_BUILTIN_VUPKHSW, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKHPX, ALTIVEC_BUILTIN_VUPKHPX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKHPX, ALTIVEC_BUILTIN_VUPKHPX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_pixel_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKHSB, ALTIVEC_BUILTIN_VUPKHSB, + RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKHSB, ALTIVEC_BUILTIN_VUPKHSB, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLSB, + RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLSB, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLPX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_pixel_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLSH, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKL, ALTIVEC_BUILTIN_VUPKLSH, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKL, P8V_BUILTIN_VUPKLSW, + RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_UNPACKL, P8V_BUILTIN_VUPKLSW, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKLPX, ALTIVEC_BUILTIN_VUPKLPX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKLPX, ALTIVEC_BUILTIN_VUPKLPX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_pixel_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKLSH, ALTIVEC_BUILTIN_VUPKLSH, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKLSH, ALTIVEC_BUILTIN_VUPKLSH, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKLSB, ALTIVEC_BUILTIN_VUPKLSB, + RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VUPKLSB, ALTIVEC_BUILTIN_VUPKLSB, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 }, + + /* Binary AltiVec/VSX builtins. */ + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, VSX_BUILTIN_XVADDDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUQM, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADD, P8V_BUILTIN_VADDUQM, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDFP, ALTIVEC_BUILTIN_VADDFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWM, ALTIVEC_BUILTIN_VADDUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHM, ALTIVEC_BUILTIN_VADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBM, ALTIVEC_BUILTIN_VADDUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDC, ALTIVEC_BUILTIN_VADDCUW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDC, ALTIVEC_BUILTIN_VADDCUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDC, P8V_BUILTIN_VADDCUQ, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDC, P8V_BUILTIN_VADDCUQ, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDEC, P8V_BUILTIN_VADDECUQ, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI }, + { ALTIVEC_BUILTIN_VEC_ADDEC, P8V_BUILTIN_VADDECUQ, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSBS, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSBS, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSBS, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSHS, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSWS, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ADDS, ALTIVEC_BUILTIN_VADDSWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDSWS, ALTIVEC_BUILTIN_VADDSWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDSWS, ALTIVEC_BUILTIN_VADDSWS, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDSWS, ALTIVEC_BUILTIN_VADDSWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUWS, ALTIVEC_BUILTIN_VADDUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDSHS, ALTIVEC_BUILTIN_VADDSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDSHS, ALTIVEC_BUILTIN_VADDSHS, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDSHS, ALTIVEC_BUILTIN_VADDSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUHS, ALTIVEC_BUILTIN_VADDUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDSBS, ALTIVEC_BUILTIN_VADDSBS, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDSBS, ALTIVEC_BUILTIN_VADDSBS, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDSBS, ALTIVEC_BUILTIN_VADDSBS, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VADDUBS, ALTIVEC_BUILTIN_VADDUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AND, ALTIVEC_BUILTIN_VAND, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_ANDC, ALTIVEC_BUILTIN_VANDC, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_AVG, ALTIVEC_BUILTIN_VAVGSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VAVGSW, ALTIVEC_BUILTIN_VAVGSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VAVGUW, ALTIVEC_BUILTIN_VAVGUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VAVGSH, ALTIVEC_BUILTIN_VAVGSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VAVGUH, ALTIVEC_BUILTIN_VAVGUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VAVGSB, ALTIVEC_BUILTIN_VAVGSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VAVGUB, ALTIVEC_BUILTIN_VAVGUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPB, ALTIVEC_BUILTIN_VCMPBFP, + RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUB, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUB, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUB, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUH, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUH, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUH, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUW, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQUW, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, P8V_BUILTIN_VCMPEQUD, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, P8V_BUILTIN_VCMPEQUD, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, P8V_BUILTIN_VCMPEQUD, + RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, ALTIVEC_BUILTIN_VCMPEQFP, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPEQ, VSX_BUILTIN_XVCMPEQDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPEQFP, ALTIVEC_BUILTIN_VCMPEQFP, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + + { ALTIVEC_BUILTIN_VEC_VCMPEQUW, ALTIVEC_BUILTIN_VCMPEQUW, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPEQUW, ALTIVEC_BUILTIN_VCMPEQUW, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + + { ALTIVEC_BUILTIN_VEC_VCMPEQUH, ALTIVEC_BUILTIN_VCMPEQUH, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPEQUH, ALTIVEC_BUILTIN_VCMPEQUH, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + + { ALTIVEC_BUILTIN_VEC_VCMPEQUB, ALTIVEC_BUILTIN_VCMPEQUB, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPEQUB, ALTIVEC_BUILTIN_VCMPEQUB, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + + { ALTIVEC_BUILTIN_VEC_CMPGE, ALTIVEC_BUILTIN_VCMPGEFP, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_XVCMPGEDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_CMPGE_16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_CMPGE_U16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_CMPGE_8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_CMPGE_U8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_CMPGE_4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_CMPGE_U4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_CMPGE_2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPGE, VSX_BUILTIN_CMPGE_U2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTUB, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSB, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTUH, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSH, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTUW, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTSW, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, P8V_BUILTIN_VCMPGTUD, + RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, P8V_BUILTIN_VCMPGTSD, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, ALTIVEC_BUILTIN_VCMPGTFP, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPGT, VSX_BUILTIN_XVCMPGTDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTFP, ALTIVEC_BUILTIN_VCMPGTFP, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTSW, ALTIVEC_BUILTIN_VCMPGTSW, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTSW, ALTIVEC_BUILTIN_VCMPGTSW, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTUW, ALTIVEC_BUILTIN_VCMPGTUW, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTUW, ALTIVEC_BUILTIN_VCMPGTUW, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTSH, ALTIVEC_BUILTIN_VCMPGTSH, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTSH, ALTIVEC_BUILTIN_VCMPGTSH, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTUH, ALTIVEC_BUILTIN_VCMPGTUH, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTUH, ALTIVEC_BUILTIN_VCMPGTUH, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTSB, ALTIVEC_BUILTIN_VCMPGTSB, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTSB, ALTIVEC_BUILTIN_VCMPGTSB, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTUB, ALTIVEC_BUILTIN_VCMPGTUB, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCMPGTUB, ALTIVEC_BUILTIN_VCMPGTUB, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLE, ALTIVEC_BUILTIN_VCMPGEFP, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_XVCMPGEDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_CMPLE_16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_CMPLE_U16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_CMPLE_8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_CMPLE_U8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_CMPLE_4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_CMPLE_U4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_CMPLE_2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPLE, VSX_BUILTIN_CMPLE_U2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0}, + { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTUB, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSB, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTUH, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSH, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTUW, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTSW, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, P8V_BUILTIN_VCMPGTUD, + RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, P8V_BUILTIN_VCMPGTSD, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, ALTIVEC_BUILTIN_VCMPGTFP, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPLT, VSX_BUILTIN_XVCMPGTDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_COPYSIGN, VSX_BUILTIN_CPSGNDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_COPYSIGN, ALTIVEC_BUILTIN_COPYSIGN_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFUX, + RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_CTF, ALTIVEC_BUILTIN_VCFSX, + RS6000_BTI_V4SF, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_CTF, VSX_BUILTIN_XVCVSXDDP_SCALE, + RS6000_BTI_V2DF, RS6000_BTI_V2DI, RS6000_BTI_INTSI, 0}, + { ALTIVEC_BUILTIN_VEC_CTF, VSX_BUILTIN_XVCVUXDDP_SCALE, + RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, 0}, + { ALTIVEC_BUILTIN_VEC_VCFSX, ALTIVEC_BUILTIN_VCFSX, + RS6000_BTI_V4SF, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VCFUX, ALTIVEC_BUILTIN_VCFUX, + RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_CTS, ALTIVEC_BUILTIN_VCTSXS, + RS6000_BTI_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_CTS, VSX_BUILTIN_XVCVDPSXDS_SCALE, + RS6000_BTI_V2DI, RS6000_BTI_V2DF, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_CTU, ALTIVEC_BUILTIN_VCTUXS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_CTU, VSX_BUILTIN_XVCVDPUXDS_SCALE, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_V2DF, RS6000_BTI_INTSI, 0 }, + { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVSP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_DIV_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_UDIV_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { VSX_BUILTIN_VEC_DOUBLE, VSX_BUILTIN_XVCVSXDDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DI, 0, 0 }, + { VSX_BUILTIN_VEC_DOUBLE, VSX_BUILTIN_XVCVUXDDP, + RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V8HI, + RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LD, ALTIVEC_BUILTIN_LVX_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEBX, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEBX, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEHX, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEHX, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LDE, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVEWX, ALTIVEC_BUILTIN_LVEWX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVEHX, ALTIVEC_BUILTIN_LVEHX, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVEHX, ALTIVEC_BUILTIN_LVEHX, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVEBX, ALTIVEC_BUILTIN_LVEBX, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVEBX, ALTIVEC_BUILTIN_LVEBX, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V8HI, + RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_LDL, ALTIVEC_BUILTIN_LVXL_V2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_double, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTDI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTDI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_long_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSL, ALTIVEC_BUILTIN_LVSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_long_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_double, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTDI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTDI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_long_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVSR, ALTIVEC_BUILTIN_LVSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_long_long, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLX, ALTIVEC_BUILTIN_LVLX, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVLXL, ALTIVEC_BUILTIN_LVLXL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRX, ALTIVEC_BUILTIN_LVRX, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_LVRXL, ALTIVEC_BUILTIN_LVRXL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSB, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSH, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSW, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXSD, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXSD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, P8V_BUILTIN_VMAXSD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, ALTIVEC_BUILTIN_VMAXFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_MAX, VSX_BUILTIN_XVMAXDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXFP, ALTIVEC_BUILTIN_VMAXFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSW, ALTIVEC_BUILTIN_VMAXSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUW, ALTIVEC_BUILTIN_VMAXUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSH, ALTIVEC_BUILTIN_VMAXSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSH, ALTIVEC_BUILTIN_VMAXSH, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSH, ALTIVEC_BUILTIN_VMAXSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUH, ALTIVEC_BUILTIN_VMAXUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSB, ALTIVEC_BUILTIN_VMAXSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSB, ALTIVEC_BUILTIN_VMAXSB, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXSB, ALTIVEC_BUILTIN_VMAXSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMAXUB, ALTIVEC_BUILTIN_VMAXUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHB, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHH, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHH, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHW, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, ALTIVEC_BUILTIN_VMRGHW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEH, VSX_BUILTIN_VEC_MERGEH_V2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHW, ALTIVEC_BUILTIN_VMRGHW, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHW, ALTIVEC_BUILTIN_VMRGHW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHW, ALTIVEC_BUILTIN_VMRGHW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHW, ALTIVEC_BUILTIN_VMRGHW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHH, ALTIVEC_BUILTIN_VMRGHH, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHH, ALTIVEC_BUILTIN_VMRGHH, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHH, ALTIVEC_BUILTIN_VMRGHH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHH, ALTIVEC_BUILTIN_VMRGHH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHB, ALTIVEC_BUILTIN_VMRGHB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHB, ALTIVEC_BUILTIN_VMRGHB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGHB, ALTIVEC_BUILTIN_VMRGHB, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLB, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLH, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLH, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLW, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, ALTIVEC_BUILTIN_VMRGLW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MERGEL, VSX_BUILTIN_VEC_MERGEL_V2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLW, ALTIVEC_BUILTIN_VMRGLW, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLW, ALTIVEC_BUILTIN_VMRGLW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLW, ALTIVEC_BUILTIN_VMRGLW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLW, ALTIVEC_BUILTIN_VMRGLW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLH, ALTIVEC_BUILTIN_VMRGLH, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLH, ALTIVEC_BUILTIN_VMRGLH, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLH, ALTIVEC_BUILTIN_VMRGLH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLH, ALTIVEC_BUILTIN_VMRGLH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLB, ALTIVEC_BUILTIN_VMRGLB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLB, ALTIVEC_BUILTIN_VMRGLB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMRGLB, ALTIVEC_BUILTIN_VMRGLB, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSB, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSH, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSW, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINSD, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINSD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, P8V_BUILTIN_VMINSD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, ALTIVEC_BUILTIN_VMINFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_MIN, VSX_BUILTIN_XVMINDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINFP, ALTIVEC_BUILTIN_VMINFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSW, ALTIVEC_BUILTIN_VMINSW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUW, ALTIVEC_BUILTIN_VMINUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSH, ALTIVEC_BUILTIN_VMINSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSH, ALTIVEC_BUILTIN_VMINSH, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSH, ALTIVEC_BUILTIN_VMINSH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSB, ALTIVEC_BUILTIN_VMINSB, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSB, ALTIVEC_BUILTIN_VMINSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINSB, ALTIVEC_BUILTIN_VMINSB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUH, ALTIVEC_BUILTIN_VMINUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMINUB, ALTIVEC_BUILTIN_VMINUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULEUB, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESB, + RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULEUH, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESH, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESH, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULE, ALTIVEC_BUILTIN_VMULESH, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMULEUB, ALTIVEC_BUILTIN_VMULEUB, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMULESB, ALTIVEC_BUILTIN_VMULESB, + RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMULEUH, ALTIVEC_BUILTIN_VMULEUH, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMULESH, ALTIVEC_BUILTIN_VMULESH, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOUB, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOSB, + RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOUH, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOSH, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOSH, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_MULO, ALTIVEC_BUILTIN_VMULOSH, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMULOSH, ALTIVEC_BUILTIN_VMULOSH, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMULOUH, ALTIVEC_BUILTIN_VMULOUH, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMULOSB, ALTIVEC_BUILTIN_VMULOSB, + RS6000_BTI_V8HI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VMULOUB, ALTIVEC_BUILTIN_VMULOUB, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_NABS, ALTIVEC_BUILTIN_NABS_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NABS, ALTIVEC_BUILTIN_NABS_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NABS, ALTIVEC_BUILTIN_NABS_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NABS, ALTIVEC_BUILTIN_NABS_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NABS, ALTIVEC_BUILTIN_NABS_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NABS, VSX_BUILTIN_XVNABSDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NEARBYINT, VSX_BUILTIN_XVRDPI, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NEARBYINT, VSX_BUILTIN_XVRSPI, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + + { ALTIVEC_BUILTIN_VEC_NEG, ALTIVEC_BUILTIN_NEG_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NEG, ALTIVEC_BUILTIN_NEG_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NEG, ALTIVEC_BUILTIN_NEG_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NEG, ALTIVEC_BUILTIN_NEG_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NEG, ALTIVEC_BUILTIN_NEG_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_NEG, ALTIVEC_BUILTIN_NEG_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_NOR, ALTIVEC_BUILTIN_VNOR, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_OR, ALTIVEC_BUILTIN_VOR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUHUM, + RS6000_BTI_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUHUM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUHUM, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUWUM, + RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUWUM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, ALTIVEC_BUILTIN_VPKUWUM, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, P8V_BUILTIN_VPKUDUM, + RS6000_BTI_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, P8V_BUILTIN_VPKUDUM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, P8V_BUILTIN_VPKUDUM, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACK, P8V_BUILTIN_VPKUDUM, + RS6000_BTI_V4SF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM, + RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKUHUM, ALTIVEC_BUILTIN_VPKUHUM, + RS6000_BTI_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKUHUM, ALTIVEC_BUILTIN_VPKUHUM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKUHUM, ALTIVEC_BUILTIN_VPKUHUM, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKPX, ALTIVEC_BUILTIN_VPKPX, + RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKS, ALTIVEC_BUILTIN_VPKUHUS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKS, ALTIVEC_BUILTIN_VPKSHSS, + RS6000_BTI_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKS, ALTIVEC_BUILTIN_VPKUWUS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKS, ALTIVEC_BUILTIN_VPKSWSS, + RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKS, P8V_BUILTIN_VPKUDUS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKS, P8V_BUILTIN_VPKSDSS, + RS6000_BTI_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKSWSS, ALTIVEC_BUILTIN_VPKSWSS, + RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKUWUS, ALTIVEC_BUILTIN_VPKUWUS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKSHSS, ALTIVEC_BUILTIN_VPKSHSS, + RS6000_BTI_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKUHUS, ALTIVEC_BUILTIN_VPKUHUS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKSU, ALTIVEC_BUILTIN_VPKUHUS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKSU, ALTIVEC_BUILTIN_VPKSHUS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKSU, ALTIVEC_BUILTIN_VPKUWUS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKSU, ALTIVEC_BUILTIN_VPKSWUS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKSU, P8V_BUILTIN_VPKSDUS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_PACKSU, P8V_BUILTIN_VPKSDUS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKSWUS, ALTIVEC_BUILTIN_VPKSWUS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VPKSHUS, ALTIVEC_BUILTIN_VPKSHUS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_RINT, VSX_BUILTIN_XVRDPIC, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_RINT, VSX_BUILTIN_XVRSPIC, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_RL, ALTIVEC_BUILTIN_VRLW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_RL, P8V_BUILTIN_VRLD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_RL, P8V_BUILTIN_VRLD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_VRLW, ALTIVEC_BUILTIN_VRLW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VRLW, ALTIVEC_BUILTIN_VRLW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VRLH, ALTIVEC_BUILTIN_VRLH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VRLH, ALTIVEC_BUILTIN_VRLH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VRLB, ALTIVEC_BUILTIN_VRLB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VRLB, ALTIVEC_BUILTIN_VRLB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { P9V_BUILTIN_VEC_RLMI, P9V_BUILTIN_VRLWMI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, + { P9V_BUILTIN_VEC_RLMI, P9V_BUILTIN_VRLDMI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI }, + { P9V_BUILTIN_VEC_RLNM, P9V_BUILTIN_VRLWNM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P9V_BUILTIN_VEC_RLNM, P9V_BUILTIN_VRLDNM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SL, ALTIVEC_BUILTIN_VSLW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SL, P8V_BUILTIN_VSLD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SL, P8V_BUILTIN_VSLD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_SQRT, VSX_BUILTIN_XVSQRTSP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSLW, ALTIVEC_BUILTIN_VSLW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSLH, ALTIVEC_BUILTIN_VSLH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSLH, ALTIVEC_BUILTIN_VSLH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSLB, ALTIVEC_BUILTIN_VSLB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSLB, ALTIVEC_BUILTIN_VSLB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLL, ALTIVEC_BUILTIN_VSL, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SLO, ALTIVEC_BUILTIN_VSLO, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTB, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTH, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTH, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTW, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, ALTIVEC_BUILTIN_VSPLTW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, VSX_BUILTIN_XXSPLTD_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, VSX_BUILTIN_XXSPLTD_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, VSX_BUILTIN_XXSPLTD_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SPLAT, VSX_BUILTIN_XXSPLTD_V2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTW, ALTIVEC_BUILTIN_VSPLTW, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTW, ALTIVEC_BUILTIN_VSPLTW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTW, ALTIVEC_BUILTIN_VSPLTW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTW, ALTIVEC_BUILTIN_VSPLTW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTH, ALTIVEC_BUILTIN_VSPLTH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTH, ALTIVEC_BUILTIN_VSPLTH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTH, ALTIVEC_BUILTIN_VSPLTH, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTH, ALTIVEC_BUILTIN_VSPLTH, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTB, ALTIVEC_BUILTIN_VSPLTB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTB, ALTIVEC_BUILTIN_VSPLTB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSPLTB, ALTIVEC_BUILTIN_VSPLTB, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, 0 }, + { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SR, ALTIVEC_BUILTIN_VSRW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SR, P8V_BUILTIN_VSRD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SR, P8V_BUILTIN_VSRD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRW, ALTIVEC_BUILTIN_VSRW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRW, ALTIVEC_BUILTIN_VSRW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRH, ALTIVEC_BUILTIN_VSRH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRH, ALTIVEC_BUILTIN_VSRH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRB, ALTIVEC_BUILTIN_VSRB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRB, ALTIVEC_BUILTIN_VSRB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRA, ALTIVEC_BUILTIN_VSRAW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRA, P8V_BUILTIN_VSRAD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRA, P8V_BUILTIN_VSRAD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRAW, ALTIVEC_BUILTIN_VSRAW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRAW, ALTIVEC_BUILTIN_VSRAW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRAH, ALTIVEC_BUILTIN_VSRAH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRAH, ALTIVEC_BUILTIN_VSRAH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRAB, ALTIVEC_BUILTIN_VSRAB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSRAB, ALTIVEC_BUILTIN_VSRAB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRL, ALTIVEC_BUILTIN_VSR, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SRO, ALTIVEC_BUILTIN_VSRO, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, ALTIVEC_BUILTIN_VSUBFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, VSX_BUILTIN_XVSUBDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUQM, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUB, P8V_BUILTIN_VSUBUQM, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBFP, ALTIVEC_BUILTIN_VSUBFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWM, ALTIVEC_BUILTIN_VSUBUWM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHM, ALTIVEC_BUILTIN_VSUBUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBM, ALTIVEC_BUILTIN_VSUBUBM, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBC, ALTIVEC_BUILTIN_VSUBCUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSBS, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSBS, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSBS, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSHS, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSWS, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUBS, ALTIVEC_BUILTIN_VSUBSWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBSWS, ALTIVEC_BUILTIN_VSUBSWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBSWS, ALTIVEC_BUILTIN_VSUBSWS, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBSWS, ALTIVEC_BUILTIN_VSUBSWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUWS, ALTIVEC_BUILTIN_VSUBUWS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBSHS, ALTIVEC_BUILTIN_VSUBSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBSHS, ALTIVEC_BUILTIN_VSUBSHS, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBSHS, ALTIVEC_BUILTIN_VSUBSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUHS, ALTIVEC_BUILTIN_VSUBUHS, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBSBS, ALTIVEC_BUILTIN_VSUBSBS, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBSBS, ALTIVEC_BUILTIN_VSUBSBS, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBSBS, ALTIVEC_BUILTIN_VSUBSBS, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUBUBS, ALTIVEC_BUILTIN_VSUBUBS, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUM4S, ALTIVEC_BUILTIN_VSUM4UBS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUM4S, ALTIVEC_BUILTIN_VSUM4SBS, + RS6000_BTI_V4SI, RS6000_BTI_V16QI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUM4S, ALTIVEC_BUILTIN_VSUM4SHS, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUM4SHS, ALTIVEC_BUILTIN_VSUM4SHS, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUM4SBS, ALTIVEC_BUILTIN_VSUM4SBS, + RS6000_BTI_V4SI, RS6000_BTI_V16QI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_VSUM4UBS, ALTIVEC_BUILTIN_VSUM4UBS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUM2S, ALTIVEC_BUILTIN_VSUM2SWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_SUMS, ALTIVEC_BUILTIN_VSUMSWS, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_double, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_long_long, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V2DI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_long_long, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V16QI, 0 }, + { VSX_BUILTIN_VEC_XL, VSX_BUILTIN_LD_ELEMREV_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_XOR, ALTIVEC_BUILTIN_VXOR, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 }, + + /* Ternary AltiVec/VSX builtins. */ + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_V4SF, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_UINTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_INTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_UINTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_INTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_UINTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_unsigned_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DST, ALTIVEC_BUILTIN_DST, + RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_V4SF, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_UINTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_INTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_UINTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_INTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_UINTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_unsigned_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTST, ALTIVEC_BUILTIN_DSTST, + RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_V4SF, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_UINTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_INTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_UINTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_INTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_UINTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_unsigned_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTSTT, ALTIVEC_BUILTIN_DSTSTT, + RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_V4SF, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_UINTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_INTQI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_UINTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_INTHI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_UINTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_unsigned_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_long, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_DSTT, ALTIVEC_BUILTIN_DSTT, + RS6000_BTI_void, ~RS6000_BTI_float, RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_MADD, ALTIVEC_BUILTIN_VMADDFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_MADD, VSX_BUILTIN_XVMADDDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, + { ALTIVEC_BUILTIN_VEC_MADD, ALTIVEC_BUILTIN_VMLADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_MADD, ALTIVEC_BUILTIN_VMLADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_MADD, ALTIVEC_BUILTIN_VMLADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_MADD, ALTIVEC_BUILTIN_VMLADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_MADDS, ALTIVEC_BUILTIN_VMHADDSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, + RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_MLADD, ALTIVEC_BUILTIN_VMLADDUHM, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_MRADDS, ALTIVEC_BUILTIN_VMHRADDSHS, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { VSX_BUILTIN_VEC_MSUB, VSX_BUILTIN_XVMSUBSP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { VSX_BUILTIN_VEC_MSUB, VSX_BUILTIN_XVMSUBDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, + { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMUBM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMMBM, + RS6000_BTI_V4SI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMUHM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMSHM, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VMSUMSHM, ALTIVEC_BUILTIN_VMSUMSHM, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VMSUMUHM, ALTIVEC_BUILTIN_VMSUMUHM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_VMSUMMBM, ALTIVEC_BUILTIN_VMSUMMBM, + RS6000_BTI_V4SI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VMSUMUBM, ALTIVEC_BUILTIN_VMSUMUBM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_MSUMS, ALTIVEC_BUILTIN_VMSUMUHS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_MSUMS, ALTIVEC_BUILTIN_VMSUMSHS, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VMSUMSHS, ALTIVEC_BUILTIN_VMSUMSHS, + RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VMSUMUHS, ALTIVEC_BUILTIN_VMSUMUHS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI }, + { VSX_BUILTIN_VEC_NMADD, VSX_BUILTIN_XVNMADDSP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { VSX_BUILTIN_VEC_NMADD, VSX_BUILTIN_XVNMADDDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, + { ALTIVEC_BUILTIN_VEC_NMSUB, ALTIVEC_BUILTIN_VNMSUBFP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_NMSUB, VSX_BUILTIN_XVNMSUBDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, + RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_8HI, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_PERM, ALTIVEC_BUILTIN_VPERM_16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, + RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, + RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_8HI, + RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLD, ALTIVEC_BUILTIN_VSLDOI_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLDW, VSX_BUILTIN_XXSLDWI_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, + RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLDW, VSX_BUILTIN_XXSLDWI_16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLDW, VSX_BUILTIN_XXSLDWI_8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, + RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLDW, VSX_BUILTIN_XXSLDWI_8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLDW, VSX_BUILTIN_XXSLDWI_4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, + RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLDW, VSX_BUILTIN_XXSLDWI_4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLDW, VSX_BUILTIN_XXSLDWI_2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, + RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_SLDW, VSX_BUILTIN_XXSLDWI_2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_NOT_OPAQUE }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V2DF, + RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V2DI, + RS6000_BTI_void, RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V2DI, + RS6000_BTI_void, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V2DI, + RS6000_BTI_void, RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V4SF, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V4SF, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V4SI, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V4SI, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V4SI, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V4SI, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V4SI, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V4SI, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V4SI, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V8HI, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V8HI, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V8HI, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V8HI, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V8HI, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V8HI, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V8HI, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V16QI, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V16QI, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V16QI, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V16QI, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V16QI, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V16QI, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V16QI, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_ST, ALTIVEC_BUILTIN_STVX_V8HI, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STE, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_void }, + { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, + { ALTIVEC_BUILTIN_VEC_STVEWX, ALTIVEC_BUILTIN_STVEWX, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, + { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, + { ALTIVEC_BUILTIN_VEC_STVEHX, ALTIVEC_BUILTIN_STVEHX, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, + { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, + { ALTIVEC_BUILTIN_VEC_STVEBX, ALTIVEC_BUILTIN_STVEBX, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_void }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SF, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SF, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SI, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SI, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SI, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SI, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SI, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SI, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V4SI, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V8HI, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V8HI, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V8HI, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V8HI, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V8HI, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V8HI, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V8HI, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V16QI, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V16QI, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V16QI, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V16QI, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V16QI, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V16QI, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V16QI, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V8HI, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V2DF, + RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V2DF, + RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_double }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V2DI, + RS6000_BTI_void, RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V2DI, + RS6000_BTI_void, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_STL, ALTIVEC_BUILTIN_STVXL_V2DI, + RS6000_BTI_void, RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVLX, ALTIVEC_BUILTIN_STVLX, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVLXL, ALTIVEC_BUILTIN_STVLXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVRX, ALTIVEC_BUILTIN_STVRX, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_STVRXL, ALTIVEC_BUILTIN_STVRXL, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V2DF, + RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V2DF, + RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_double }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V2DI, + RS6000_BTI_void, RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V2DI, + RS6000_BTI_void, RS6000_BTI_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_long_long }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V2DI, + RS6000_BTI_void, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V2DI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V2DI, + RS6000_BTI_void, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_long_long }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V4SF, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V4SF, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V4SI, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V4SI, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V4SI, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V4SI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V4SI, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, + ~RS6000_BTI_UINTSI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V8HI, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V8HI, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V8HI, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V8HI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V8HI, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, + ~RS6000_BTI_UINTHI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V16QI, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V16QI, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V16QI, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V16QI }, + { VSX_BUILTIN_VEC_XST, VSX_BUILTIN_ST_ELEMREV_V16QI, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_UINTQI }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXSLDWI, VSX_BUILTIN_XXSLDWI_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_NOT_OPAQUE }, + { VSX_BUILTIN_VEC_XXPERMDI, VSX_BUILTIN_XXPERMDI_16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_NOT_OPAQUE }, + + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVD2X_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVD2X_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_double, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVD2X_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVD2X_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V2DI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVD2X_V2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V2DI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V4SI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_long, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V4SI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTSI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_long, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V8HI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, + RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_pixel_V8HI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V8HI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTHI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_bool_V16QI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V16QI, 0 }, + { VSX_BUILTIN_VEC_LD, VSX_BUILTIN_LXVW4X_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_UINTQI, 0 }, + + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVD2X_V2DF, + RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_V2DF }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVD2X_V2DF, + RS6000_BTI_void, RS6000_BTI_V2DF, RS6000_BTI_INTSI, ~RS6000_BTI_double }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVD2X_V2DI, + RS6000_BTI_void, RS6000_BTI_V2DI, RS6000_BTI_INTSI, ~RS6000_BTI_V2DI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVD2X_V2DI, + RS6000_BTI_void, RS6000_BTI_unsigned_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V2DI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVD2X_V2DI, + RS6000_BTI_void, RS6000_BTI_bool_V2DI, RS6000_BTI_INTSI, + ~RS6000_BTI_bool_V2DI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SF, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_V4SF }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SF, + RS6000_BTI_void, RS6000_BTI_V4SF, RS6000_BTI_INTSI, ~RS6000_BTI_float }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_V4SI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, + RS6000_BTI_void, RS6000_BTI_V4SI, RS6000_BTI_INTSI, ~RS6000_BTI_INTSI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V4SI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, RS6000_BTI_INTSI, + ~RS6000_BTI_UINTSI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, + ~RS6000_BTI_bool_V4SI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, + ~RS6000_BTI_UINTSI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V4SI, + RS6000_BTI_void, RS6000_BTI_bool_V4SI, RS6000_BTI_INTSI, + ~RS6000_BTI_INTSI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_V8HI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, + RS6000_BTI_void, RS6000_BTI_V8HI, RS6000_BTI_INTSI, ~RS6000_BTI_INTHI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V8HI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, RS6000_BTI_INTSI, + ~RS6000_BTI_UINTHI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, + ~RS6000_BTI_bool_V8HI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, + ~RS6000_BTI_UINTHI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V8HI, + RS6000_BTI_void, RS6000_BTI_bool_V8HI, RS6000_BTI_INTSI, + ~RS6000_BTI_INTHI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_V16QI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, + RS6000_BTI_void, RS6000_BTI_V16QI, RS6000_BTI_INTSI, ~RS6000_BTI_INTQI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_unsigned_V16QI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_UINTQI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_bool_V16QI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_UINTQI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, + RS6000_BTI_void, RS6000_BTI_bool_V16QI, RS6000_BTI_INTSI, + ~RS6000_BTI_INTQI }, + { VSX_BUILTIN_VEC_ST, VSX_BUILTIN_STXVW4X_V16QI, + RS6000_BTI_void, RS6000_BTI_pixel_V8HI, RS6000_BTI_INTSI, + ~RS6000_BTI_pixel_V8HI }, + + /* Predicates. */ + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTSW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, P8V_BUILTIN_VCMPGTUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, P8V_BUILTIN_VCMPGTUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, P8V_BUILTIN_VCMPGTUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, P8V_BUILTIN_VCMPGTSD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, P8V_BUILTIN_VCMPGTSD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, P8V_BUILTIN_VCMPGTSD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, ALTIVEC_BUILTIN_VCMPGTFP_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_VCMPGT_P, VSX_BUILTIN_XVCMPGTDP_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, + + + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_pixel_V8HI, RS6000_BTI_pixel_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, P8V_BUILTIN_VCMPEQUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, ALTIVEC_BUILTIN_VCMPEQFP_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_VCMPEQ_P, VSX_BUILTIN_XVCMPEQDP_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, + + + /* cmpge is the same as cmpgt for all cases except floating point. + There is further code to deal with this special case in + altivec_build_resolved_builtin. */ + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTUW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGTSW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTUD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTSD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTSD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, P8V_BUILTIN_VCMPGTSD_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_V2DI }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, ALTIVEC_BUILTIN_VCMPGEFP_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF }, + { ALTIVEC_BUILTIN_VEC_VCMPGE_P, VSX_BUILTIN_XVCMPGEDP_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF }, + + /* Power8 vector overloaded functions. */ + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { P8V_BUILTIN_VEC_EQV, P8V_BUILTIN_EQV_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { P8V_BUILTIN_VEC_NAND, P8V_BUILTIN_NAND_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_bool_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V16QI, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_bool_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V8HI, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_bool_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V4SI, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V2DI, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { P8V_BUILTIN_VEC_ORC, P8V_BUILTIN_ORC_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + + { P8V_BUILTIN_VEC_VADDCUQ, P8V_BUILTIN_VADDCUQ, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0 }, + { P8V_BUILTIN_VEC_VADDCUQ, P8V_BUILTIN_VADDCUQ, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, 0 }, + + { P8V_BUILTIN_VEC_VADDUDM, P8V_BUILTIN_VADDUDM, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_VADDUDM, P8V_BUILTIN_VADDUDM, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_VADDUDM, P8V_BUILTIN_VADDUDM, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_VADDUDM, P8V_BUILTIN_VADDUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_VADDUDM, P8V_BUILTIN_VADDUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_VADDUDM, P8V_BUILTIN_VADDUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VADDUQM, P8V_BUILTIN_VADDUQM, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0 }, + { P8V_BUILTIN_VEC_VADDUQM, P8V_BUILTIN_VADDUQM, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, 0 }, + + { P9V_BUILTIN_VEC_VBPERM, P9V_BUILTIN_VBPERMD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P9V_BUILTIN_VEC_VBPERM, P8V_BUILTIN_VBPERMQ, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P9V_BUILTIN_VEC_VBPERM, P8V_BUILTIN_VBPERMQ2, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + + { P8V_BUILTIN_VEC_VBPERMQ, P8V_BUILTIN_VBPERMQ, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P8V_BUILTIN_VEC_VBPERMQ, P8V_BUILTIN_VBPERMQ, + RS6000_BTI_V2DI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { P8V_BUILTIN_VEC_VBPERMQ, P8V_BUILTIN_VBPERMQ, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P8V_BUILTIN_VEC_VBPERMQ, P8V_BUILTIN_VBPERMQ, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V16QI, 0 }, + + { P8V_BUILTIN_VEC_VCLZ, P8V_BUILTIN_VCLZB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZ, P8V_BUILTIN_VCLZB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZ, P8V_BUILTIN_VCLZH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZ, P8V_BUILTIN_VCLZH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZ, P8V_BUILTIN_VCLZW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZ, P8V_BUILTIN_VCLZW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZ, P8V_BUILTIN_VCLZD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZ, P8V_BUILTIN_VCLZD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + + { P8V_BUILTIN_VEC_VCLZB, P8V_BUILTIN_VCLZB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZB, P8V_BUILTIN_VCLZB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + + { P8V_BUILTIN_VEC_VCLZH, P8V_BUILTIN_VCLZH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZH, P8V_BUILTIN_VCLZH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + + { P8V_BUILTIN_VEC_VCLZW, P8V_BUILTIN_VCLZW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZW, P8V_BUILTIN_VCLZW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + + { P8V_BUILTIN_VEC_VCLZD, P8V_BUILTIN_VCLZD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P8V_BUILTIN_VEC_VCLZD, P8V_BUILTIN_VCLZD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + + { P9_BUILTIN_DFP_TSTSFI_LT, MISC_BUILTIN_TSTSFI_LT_TD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 }, + { P9_BUILTIN_DFP_TSTSFI_LT, MISC_BUILTIN_TSTSFI_LT_DD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 }, + + { P9_BUILTIN_DFP_TSTSFI_LT_TD, MISC_BUILTIN_TSTSFI_LT_TD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 }, + { P9_BUILTIN_DFP_TSTSFI_LT_DD, MISC_BUILTIN_TSTSFI_LT_DD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 }, + + { P9_BUILTIN_DFP_TSTSFI_EQ, MISC_BUILTIN_TSTSFI_EQ_TD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 }, + { P9_BUILTIN_DFP_TSTSFI_EQ, MISC_BUILTIN_TSTSFI_EQ_DD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 }, + + { P9_BUILTIN_DFP_TSTSFI_EQ_TD, MISC_BUILTIN_TSTSFI_EQ_TD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 }, + { P9_BUILTIN_DFP_TSTSFI_EQ_DD, MISC_BUILTIN_TSTSFI_EQ_DD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 }, + + { P9_BUILTIN_DFP_TSTSFI_GT, MISC_BUILTIN_TSTSFI_GT_TD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 }, + { P9_BUILTIN_DFP_TSTSFI_GT, MISC_BUILTIN_TSTSFI_GT_DD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 }, + + { P9_BUILTIN_DFP_TSTSFI_GT_TD, MISC_BUILTIN_TSTSFI_GT_TD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 }, + { P9_BUILTIN_DFP_TSTSFI_GT_DD, MISC_BUILTIN_TSTSFI_GT_DD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 }, + + { P9_BUILTIN_DFP_TSTSFI_OV, MISC_BUILTIN_TSTSFI_OV_TD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 }, + { P9_BUILTIN_DFP_TSTSFI_OV, MISC_BUILTIN_TSTSFI_OV_DD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 }, + + { P9_BUILTIN_DFP_TSTSFI_OV_TD, MISC_BUILTIN_TSTSFI_OV_TD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat128, 0 }, + { P9_BUILTIN_DFP_TSTSFI_OV_DD, MISC_BUILTIN_TSTSFI_OV_DD, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, RS6000_BTI_dfloat64, 0 }, + + { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZ, P9V_BUILTIN_VCTZD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + + { P9V_BUILTIN_VEC_VCTZB, P9V_BUILTIN_VCTZB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZB, P9V_BUILTIN_VCTZB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + + { P9V_BUILTIN_VEC_VCTZH, P9V_BUILTIN_VCTZH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZH, P9V_BUILTIN_VCTZH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + + { P9V_BUILTIN_VEC_VCTZW, P9V_BUILTIN_VCTZW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZW, P9V_BUILTIN_VCTZW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + + { P9V_BUILTIN_VEC_VCTZD, P9V_BUILTIN_VCTZD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZD, P9V_BUILTIN_VCTZD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + + { P9V_BUILTIN_VEC_VADU, P9V_BUILTIN_VADUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P9V_BUILTIN_VEC_VADU, P9V_BUILTIN_VADUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P9V_BUILTIN_VEC_VADU, P9V_BUILTIN_VADUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + + { P9V_BUILTIN_VEC_VADUB, P9V_BUILTIN_VADUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + + { P9V_BUILTIN_VEC_VADUH, P9V_BUILTIN_VADUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + + { P9V_BUILTIN_VEC_VADUW, P9V_BUILTIN_VADUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + + { P9V_BUILTIN_VEC_VES, P9V_BUILTIN_VESSP, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, 0, 0 }, + { P9V_BUILTIN_VEC_VES, P9V_BUILTIN_VESDP, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_V2DF, 0, 0 }, + + { P9V_BUILTIN_VEC_VESSP, P9V_BUILTIN_VESSP, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, 0, 0 }, + { P9V_BUILTIN_VEC_VESDP, P9V_BUILTIN_VESDP, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_V2DF, 0, 0 }, + + { P9V_BUILTIN_VEC_VEE, P9V_BUILTIN_VEESP, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, 0, 0 }, + { P9V_BUILTIN_VEC_VEE, P9V_BUILTIN_VEEDP, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_V2DF, 0, 0 }, + + { P9V_BUILTIN_VEC_VEESP, P9V_BUILTIN_VEESP, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SF, 0, 0 }, + { P9V_BUILTIN_VEC_VEEDP, P9V_BUILTIN_VEEDP, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_V2DF, 0, 0 }, + + { P9V_BUILTIN_VEC_VTDC, P9V_BUILTIN_VTDCSP, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, + { P9V_BUILTIN_VEC_VTDC, P9V_BUILTIN_VTDCDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_INTSI, 0 }, + + { P9V_BUILTIN_VEC_VTDCSP, P9V_BUILTIN_VTDCSP, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SF, RS6000_BTI_INTSI, 0 }, + { P9V_BUILTIN_VEC_VTDCDP, P9V_BUILTIN_VTDCDP, + RS6000_BTI_bool_V2DI, RS6000_BTI_V2DF, RS6000_BTI_INTSI, 0 }, + + { P9V_BUILTIN_VEC_VIE, P9V_BUILTIN_VIESP, + RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { P9V_BUILTIN_VEC_VIE, P9V_BUILTIN_VIESP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, 0 }, + + { P9V_BUILTIN_VEC_VIE, P9V_BUILTIN_VIEDP, + RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { P9V_BUILTIN_VEC_VIE, P9V_BUILTIN_VIEDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI, 0 }, + + { P9V_BUILTIN_VEC_VIESP, P9V_BUILTIN_VIESP, + RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 }, + { P9V_BUILTIN_VEC_VIESP, P9V_BUILTIN_VIESP, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_unsigned_V4SI, 0 }, + + { P9V_BUILTIN_VEC_VIEDP, P9V_BUILTIN_VIEDP, + RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { P9V_BUILTIN_VEC_VIEDP, P9V_BUILTIN_VIEDP, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_unsigned_V2DI, 0 }, + + { P9V_BUILTIN_VEC_VSTDC, P9V_BUILTIN_VSTDCSP, + RS6000_BTI_bool_int, RS6000_BTI_float, RS6000_BTI_INTSI, 0 }, + { P9V_BUILTIN_VEC_VSTDC, P9V_BUILTIN_VSTDCDP, + RS6000_BTI_bool_int, RS6000_BTI_double, RS6000_BTI_INTSI, 0 }, + + { P9V_BUILTIN_VEC_VSTDCSP, P9V_BUILTIN_VSTDCSP, + RS6000_BTI_bool_int, RS6000_BTI_float, RS6000_BTI_INTSI, 0 }, + { P9V_BUILTIN_VEC_VSTDCDP, P9V_BUILTIN_VSTDCDP, + RS6000_BTI_bool_int, RS6000_BTI_double, RS6000_BTI_INTSI, 0 }, + + { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNSP, + RS6000_BTI_bool_int, RS6000_BTI_float, 0, 0 }, + { P9V_BUILTIN_VEC_VSTDCN, P9V_BUILTIN_VSTDCNDP, + RS6000_BTI_bool_int, RS6000_BTI_double, 0, 0 }, + + { P9V_BUILTIN_VEC_VSTDCNSP, P9V_BUILTIN_VSTDCNSP, + RS6000_BTI_bool_int, RS6000_BTI_float, 0, 0 }, + { P9V_BUILTIN_VEC_VSTDCNDP, P9V_BUILTIN_VSTDCNDP, + RS6000_BTI_bool_int, RS6000_BTI_double, 0, 0 }, + + { P9V_BUILTIN_VEC_VSEEDP, P9V_BUILTIN_VSEEDP, + RS6000_BTI_UINTSI, RS6000_BTI_double, 0, 0 }, + + { P9V_BUILTIN_VEC_VSESDP, P9V_BUILTIN_VSESDP, + RS6000_BTI_UINTDI, RS6000_BTI_double, 0, 0 }, + + { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEDP, + RS6000_BTI_double, RS6000_BTI_UINTDI, RS6000_BTI_UINTDI, 0 }, + { P9V_BUILTIN_VEC_VSIEDP, P9V_BUILTIN_VSIEDPF, + RS6000_BTI_double, RS6000_BTI_double, RS6000_BTI_UINTDI, 0 }, + + { P9V_BUILTIN_VEC_VSCEDPGT, P9V_BUILTIN_VSCEDPGT, + RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 }, + { P9V_BUILTIN_VEC_VSCEDPLT, P9V_BUILTIN_VSCEDPLT, + RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 }, + { P9V_BUILTIN_VEC_VSCEDPEQ, P9V_BUILTIN_VSCEDPEQ, + RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 }, + { P9V_BUILTIN_VEC_VSCEDPUO, P9V_BUILTIN_VSCEDPUO, + RS6000_BTI_INTSI, RS6000_BTI_double, RS6000_BTI_double, 0 }, + + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_V16QI, ~RS6000_BTI_INTQI, + RS6000_BTI_unsigned_long_long, 0 }, + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_unsigned_V16QI, ~RS6000_BTI_UINTQI, + RS6000_BTI_unsigned_long_long, 0 }, + + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_V4SI, ~RS6000_BTI_INTSI, + RS6000_BTI_unsigned_long_long, 0 }, + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_unsigned_V4SI, ~RS6000_BTI_UINTSI, + RS6000_BTI_unsigned_long_long, 0 }, + + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_V1TI, ~RS6000_BTI_INTTI, + RS6000_BTI_unsigned_long_long, 0 }, + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_unsigned_V1TI, ~RS6000_BTI_UINTTI, + RS6000_BTI_unsigned_long_long, 0 }, + + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_V2DI, ~RS6000_BTI_long_long, + RS6000_BTI_unsigned_long_long, 0 }, + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_unsigned_V2DI, ~RS6000_BTI_unsigned_long_long, + RS6000_BTI_unsigned_long_long, 0 }, + + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_V8HI, ~RS6000_BTI_INTHI, + RS6000_BTI_unsigned_long_long, 0 }, + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_unsigned_V8HI, ~RS6000_BTI_UINTHI, + RS6000_BTI_unsigned_long_long, 0 }, + + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_V2DF, ~RS6000_BTI_double, + RS6000_BTI_unsigned_long_long, 0 }, + { P9V_BUILTIN_VEC_LXVL, P9V_BUILTIN_LXVL, + RS6000_BTI_V4SF, ~RS6000_BTI_float, + RS6000_BTI_unsigned_long_long, 0 }, + /* At an appropriate future time, add support for the + RS6000_BTI_Float16 (exact name to be determined) type here. */ + + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_V16QI, ~RS6000_BTI_INTQI, + RS6000_BTI_unsigned_long_long }, + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_unsigned_V16QI, ~RS6000_BTI_UINTQI, + RS6000_BTI_unsigned_long_long }, + + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_V4SI, ~RS6000_BTI_INTSI, + RS6000_BTI_unsigned_long_long }, + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_unsigned_V4SI, ~RS6000_BTI_UINTSI, + RS6000_BTI_unsigned_long_long }, + + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_V1TI, ~RS6000_BTI_INTTI, + RS6000_BTI_unsigned_long_long }, + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_unsigned_V1TI, ~RS6000_BTI_UINTTI, + RS6000_BTI_unsigned_long_long }, + + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_V2DI, ~RS6000_BTI_long_long, + RS6000_BTI_unsigned_long_long }, + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_unsigned_V2DI, ~RS6000_BTI_unsigned_long_long, + RS6000_BTI_unsigned_long_long }, + + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_V8HI, ~RS6000_BTI_INTHI, + RS6000_BTI_unsigned_long_long }, + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_unsigned_V8HI, ~RS6000_BTI_UINTHI, + RS6000_BTI_unsigned_long_long }, + + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_V2DF, ~RS6000_BTI_double, + RS6000_BTI_unsigned_long_long }, + { P9V_BUILTIN_VEC_STXVL, P9V_BUILTIN_STXVL, + RS6000_BTI_void, RS6000_BTI_V4SF, ~RS6000_BTI_float, + RS6000_BTI_unsigned_long_long }, + /* At an appropriate future time, add support for the + RS6000_BTI_Float16 (exact name to be determined) type here. */ + + { ALTIVEC_BUILTIN_VEC_CMPNE, P9V_BUILTIN_CMPNEB, + RS6000_BTI_bool_V16QI, RS6000_BTI_bool_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPNE, P9V_BUILTIN_CMPNEB, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, + RS6000_BTI_V16QI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPNE, P9V_BUILTIN_CMPNEB, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + + { ALTIVEC_BUILTIN_VEC_CMPNE, P9V_BUILTIN_CMPNEH, + RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPNE, P9V_BUILTIN_CMPNEH, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, + RS6000_BTI_V8HI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPNE, P9V_BUILTIN_CMPNEH, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + + { ALTIVEC_BUILTIN_VEC_CMPNE, P9V_BUILTIN_CMPNEW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPNE, P9V_BUILTIN_CMPNEW, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, + RS6000_BTI_V4SI, 0 }, + { ALTIVEC_BUILTIN_VEC_CMPNE, P9V_BUILTIN_CMPNEW, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEB_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEB_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEB_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEB_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, + RS6000_BTI_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEB_P, + RS6000_BTI_INTSI, RS6000_BTI_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEB_P, + RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEB_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEH_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEH_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEH_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEH_P, + RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEH_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, + RS6000_BTI_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEH_P, + RS6000_BTI_INTSI, RS6000_BTI_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEH_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEH_P, + RS6000_BTI_INTSI, RS6000_BTI_pixel_V8HI, + RS6000_BTI_pixel_V8HI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEW_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEW_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEW_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEW_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, + RS6000_BTI_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEW_P, + RS6000_BTI_INTSI, RS6000_BTI_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEW_P, + RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEW_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNED_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNED_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNED_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 + }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNED_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, + RS6000_BTI_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNED_P, + RS6000_BTI_INTSI, RS6000_BTI_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNED_P, + RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNED_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEFP_P, + RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { P9V_BUILTIN_VEC_VCMPNE_P, P9V_BUILTIN_VCMPNEDP_P, + RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEB_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEB_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEB_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEB_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, + RS6000_BTI_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEB_P, + RS6000_BTI_INTSI, RS6000_BTI_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEB_P, + RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEB_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V16QI, + RS6000_BTI_bool_V16QI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEH_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEH_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEH_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEH_P, + RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEH_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, + RS6000_BTI_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEH_P, + RS6000_BTI_INTSI, RS6000_BTI_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEH_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V8HI, + RS6000_BTI_bool_V8HI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEH_P, + RS6000_BTI_INTSI, RS6000_BTI_pixel_V8HI, + RS6000_BTI_pixel_V8HI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEW_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEW_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEW_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEW_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, + RS6000_BTI_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEW_P, + RS6000_BTI_INTSI, RS6000_BTI_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEW_P, + RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEW_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V4SI, + RS6000_BTI_bool_V4SI, 0 }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAED_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAED_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAED_P, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 + }, + + /* The following 2 entries have been deprecated. */ + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAED_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, + RS6000_BTI_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAED_P, + RS6000_BTI_INTSI, RS6000_BTI_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAED_P, + RS6000_BTI_INTSI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAED_P, + RS6000_BTI_INTSI, RS6000_BTI_bool_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEFP_P, + RS6000_BTI_INTSI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 }, + { P9V_BUILTIN_VEC_VCMPAE_P, P9V_BUILTIN_VCMPAEDP_P, + RS6000_BTI_INTSI, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 }, + + { P9V_BUILTIN_VEC_VCMPNEZ_P, P9V_BUILTIN_VCMPNEZB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI }, + { P9V_BUILTIN_VEC_VCMPNEZ_P, P9V_BUILTIN_VCMPNEZB_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI }, + + { P9V_BUILTIN_VEC_VCMPNEZ_P, P9V_BUILTIN_VCMPNEZH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI }, + { P9V_BUILTIN_VEC_VCMPNEZ_P, P9V_BUILTIN_VCMPNEZH_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI }, + + { P9V_BUILTIN_VEC_VCMPNEZ_P, P9V_BUILTIN_VCMPNEZW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI }, + { P9V_BUILTIN_VEC_VCMPNEZ_P, P9V_BUILTIN_VCMPNEZW_P, + RS6000_BTI_INTSI, RS6000_BTI_INTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI }, + + { P9V_BUILTIN_VEC_CMPNEZ, P9V_BUILTIN_CMPNEZB, + RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, + RS6000_BTI_V16QI, 0 }, + { P9V_BUILTIN_VEC_CMPNEZ, P9V_BUILTIN_CMPNEZB, + RS6000_BTI_bool_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + + { P9V_BUILTIN_VEC_CMPNEZ, P9V_BUILTIN_CMPNEZH, + RS6000_BTI_bool_V8HI, RS6000_BTI_V8HI, + RS6000_BTI_V8HI, 0 }, + { P9V_BUILTIN_VEC_CMPNEZ, P9V_BUILTIN_CMPNEZH, + RS6000_BTI_bool_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + + { P9V_BUILTIN_VEC_CMPNEZ, P9V_BUILTIN_CMPNEZW, + RS6000_BTI_bool_V4SI, RS6000_BTI_V4SI, + RS6000_BTI_V4SI, 0 }, + { P9V_BUILTIN_VEC_CMPNEZ, P9V_BUILTIN_CMPNEZW, + RS6000_BTI_bool_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + + { P9V_BUILTIN_VEC_VCLZLSBB, P9V_BUILTIN_VCLZLSBB, + RS6000_BTI_INTSI, RS6000_BTI_V16QI, 0, 0 }, + { P9V_BUILTIN_VEC_VCLZLSBB, P9V_BUILTIN_VCLZLSBB, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + + { P9V_BUILTIN_VEC_VCTZLSBB, P9V_BUILTIN_VCTZLSBB, + RS6000_BTI_INTSI, RS6000_BTI_V16QI, 0, 0 }, + { P9V_BUILTIN_VEC_VCTZLSBB, P9V_BUILTIN_VCTZLSBB, + RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + + { P9V_BUILTIN_VEC_VEXTRACT4B, P9V_BUILTIN_VEXTRACT4B, + RS6000_BTI_INTDI, RS6000_BTI_V16QI, RS6000_BTI_UINTSI, 0 }, + { P9V_BUILTIN_VEC_VEXTRACT4B, P9V_BUILTIN_VEXTRACT4B, + RS6000_BTI_INTDI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTSI, 0 }, + + { P9V_BUILTIN_VEC_VEXTULX, P9V_BUILTIN_VEXTUBLX, + RS6000_BTI_INTQI, RS6000_BTI_UINTSI, + RS6000_BTI_V16QI, 0 }, + { P9V_BUILTIN_VEC_VEXTULX, P9V_BUILTIN_VEXTUBLX, + RS6000_BTI_UINTQI, RS6000_BTI_UINTSI, + RS6000_BTI_unsigned_V16QI, 0 }, + + { P9V_BUILTIN_VEC_VEXTULX, P9V_BUILTIN_VEXTUHLX, + RS6000_BTI_INTHI, RS6000_BTI_UINTSI, + RS6000_BTI_V8HI, 0 }, + { P9V_BUILTIN_VEC_VEXTULX, P9V_BUILTIN_VEXTUHLX, + RS6000_BTI_UINTHI, RS6000_BTI_UINTSI, + RS6000_BTI_unsigned_V8HI, 0 }, + + { P9V_BUILTIN_VEC_VEXTULX, P9V_BUILTIN_VEXTUWLX, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, + RS6000_BTI_V4SI, 0 }, + { P9V_BUILTIN_VEC_VEXTULX, P9V_BUILTIN_VEXTUWLX, + RS6000_BTI_UINTSI, RS6000_BTI_UINTSI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P9V_BUILTIN_VEC_VEXTULX, P9V_BUILTIN_VEXTUWLX, + RS6000_BTI_float, RS6000_BTI_UINTSI, + RS6000_BTI_V4SF, 0 }, + + { P9V_BUILTIN_VEC_VEXTURX, P9V_BUILTIN_VEXTUBRX, + RS6000_BTI_INTQI, RS6000_BTI_UINTSI, + RS6000_BTI_V16QI, 0 }, + { P9V_BUILTIN_VEC_VEXTURX, P9V_BUILTIN_VEXTUBRX, + RS6000_BTI_UINTQI, RS6000_BTI_UINTSI, + RS6000_BTI_unsigned_V16QI, 0 }, + + { P9V_BUILTIN_VEC_VEXTURX, P9V_BUILTIN_VEXTUHRX, + RS6000_BTI_INTHI, RS6000_BTI_UINTSI, + RS6000_BTI_V8HI, 0 }, + { P9V_BUILTIN_VEC_VEXTURX, P9V_BUILTIN_VEXTUHRX, + RS6000_BTI_UINTHI, RS6000_BTI_UINTSI, + RS6000_BTI_unsigned_V8HI, 0 }, + + { P9V_BUILTIN_VEC_VEXTURX, P9V_BUILTIN_VEXTUWRX, + RS6000_BTI_INTSI, RS6000_BTI_UINTSI, + RS6000_BTI_V4SI, 0 }, + { P9V_BUILTIN_VEC_VEXTURX, P9V_BUILTIN_VEXTUWRX, + RS6000_BTI_UINTSI, RS6000_BTI_UINTSI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P9V_BUILTIN_VEC_VEXTURX, P9V_BUILTIN_VEXTUWRX, + RS6000_BTI_float, RS6000_BTI_UINTSI, + RS6000_BTI_V4SF, 0 }, + + { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { P8V_BUILTIN_VEC_VGBBD, P8V_BUILTIN_VGBBD, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + + { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B, + RS6000_BTI_V16QI, RS6000_BTI_V4SI, + RS6000_BTI_V16QI, RS6000_BTI_UINTSI }, + { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B, + RS6000_BTI_V16QI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_V16QI, RS6000_BTI_UINTSI }, + { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTSI }, + { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, + RS6000_BTI_V16QI, RS6000_BTI_INTDI, + RS6000_BTI_V16QI, RS6000_BTI_UINTDI }, + { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, + RS6000_BTI_V16QI, RS6000_BTI_UINTDI, + RS6000_BTI_V16QI, RS6000_BTI_UINTDI }, + { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_INTDI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTDI }, + { P9V_BUILTIN_VEC_VINSERT4B, P9V_BUILTIN_VINSERT4B_DI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTDI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_UINTDI }, + + { P8V_BUILTIN_VEC_VADDECUQ, P8V_BUILTIN_VADDECUQ, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI }, + { P8V_BUILTIN_VEC_VADDECUQ, P8V_BUILTIN_VADDECUQ, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI }, + + { P8V_BUILTIN_VEC_VADDEUQM, P8V_BUILTIN_VADDEUQM, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI }, + { P8V_BUILTIN_VEC_VADDEUQM, P8V_BUILTIN_VADDEUQM, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI }, + + { P8V_BUILTIN_VEC_VSUBECUQ, P8V_BUILTIN_VSUBECUQ, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI }, + { P8V_BUILTIN_VEC_VSUBECUQ, P8V_BUILTIN_VSUBECUQ, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI }, + + { P8V_BUILTIN_VEC_VSUBEUQM, P8V_BUILTIN_VSUBEUQM, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI }, + { P8V_BUILTIN_VEC_VSUBEUQM, P8V_BUILTIN_VSUBEUQM, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI }, + + { P8V_BUILTIN_VEC_VMINSD, P8V_BUILTIN_VMINSD, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_VMINSD, P8V_BUILTIN_VMINSD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_VMINSD, P8V_BUILTIN_VMINSD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VMAXSD, P8V_BUILTIN_VMAXSD, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_VMAXSD, P8V_BUILTIN_VMAXSD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_VMAXSD, P8V_BUILTIN_VMAXSD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VMINUD, P8V_BUILTIN_VMINUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_VMINUD, P8V_BUILTIN_VMINUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_VMINUD, P8V_BUILTIN_VMINUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VMAXUD, P8V_BUILTIN_VMAXUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_VMAXUD, P8V_BUILTIN_VMAXUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_VMAXUD, P8V_BUILTIN_VMAXUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VMRGEW, P8V_BUILTIN_VMRGEW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { P8V_BUILTIN_VEC_VMRGEW, P8V_BUILTIN_VMRGEW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_VMRGEW, P8V_BUILTIN_VMRGEW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + + { P8V_BUILTIN_VEC_VMRGOW, P8V_BUILTIN_VMRGOW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 }, + { P8V_BUILTIN_VEC_VMRGOW, P8V_BUILTIN_VMRGOW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_VMRGOW, P8V_BUILTIN_VMRGOW, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V4SI, 0 }, + + { P8V_BUILTIN_VEC_VPMSUM, P8V_BUILTIN_VPMSUMB, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P8V_BUILTIN_VEC_VPMSUM, P8V_BUILTIN_VPMSUMH, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { P8V_BUILTIN_VEC_VPMSUM, P8V_BUILTIN_VPMSUMW, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { P8V_BUILTIN_VEC_VPMSUM, P8V_BUILTIN_VPMSUMD, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VPOPCNT, P8V_BUILTIN_VPOPCNTB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNT, P8V_BUILTIN_VPOPCNTB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNT, P8V_BUILTIN_VPOPCNTH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNT, P8V_BUILTIN_VPOPCNTH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNT, P8V_BUILTIN_VPOPCNTW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNT, P8V_BUILTIN_VPOPCNTW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNT, P8V_BUILTIN_VPOPCNTD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNT, P8V_BUILTIN_VPOPCNTD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + + { P8V_BUILTIN_VEC_VPOPCNTB, P8V_BUILTIN_VPOPCNTB, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNTB, P8V_BUILTIN_VPOPCNTB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + + { P8V_BUILTIN_VEC_VPOPCNTU, P8V_BUILTIN_VPOPCNTUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNTU, P8V_BUILTIN_VPOPCNTUB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + + { P8V_BUILTIN_VEC_VPOPCNTU, P8V_BUILTIN_VPOPCNTUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNTU, P8V_BUILTIN_VPOPCNTUH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + + { P8V_BUILTIN_VEC_VPOPCNTU, P8V_BUILTIN_VPOPCNTUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNTU, P8V_BUILTIN_VPOPCNTUW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + + { P8V_BUILTIN_VEC_VPOPCNTU, P8V_BUILTIN_VPOPCNTUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNTU, P8V_BUILTIN_VPOPCNTUD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + + { P8V_BUILTIN_VEC_VPOPCNTH, P8V_BUILTIN_VPOPCNTH, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNTH, P8V_BUILTIN_VPOPCNTH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + + { P8V_BUILTIN_VEC_VPOPCNTW, P8V_BUILTIN_VPOPCNTW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNTW, P8V_BUILTIN_VPOPCNTW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + + { P8V_BUILTIN_VEC_VPOPCNTD, P8V_BUILTIN_VPOPCNTD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P8V_BUILTIN_VEC_VPOPCNTD, P8V_BUILTIN_VPOPCNTD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + + { P9V_BUILTIN_VEC_VPRTYB, P9V_BUILTIN_VPRTYBW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYB, P9V_BUILTIN_VPRTYBW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYB, P9V_BUILTIN_VPRTYBD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYB, P9V_BUILTIN_VPRTYBD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYB, P9V_BUILTIN_VPRTYBQ, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYB, P9V_BUILTIN_VPRTYBQ, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYB, P9V_BUILTIN_VPRTYBQ, + RS6000_BTI_INTTI, RS6000_BTI_INTTI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYB, P9V_BUILTIN_VPRTYBQ, + RS6000_BTI_UINTTI, RS6000_BTI_UINTTI, 0, 0 }, + + { P9V_BUILTIN_VEC_VPRTYBW, P9V_BUILTIN_VPRTYBW, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYBW, P9V_BUILTIN_VPRTYBW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + + { P9V_BUILTIN_VEC_VPRTYBD, P9V_BUILTIN_VPRTYBD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYBD, P9V_BUILTIN_VPRTYBD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + + { P9V_BUILTIN_VEC_VPRTYBQ, P9V_BUILTIN_VPRTYBQ, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYBQ, P9V_BUILTIN_VPRTYBQ, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYBQ, P9V_BUILTIN_VPRTYBQ, + RS6000_BTI_INTTI, RS6000_BTI_INTTI, 0, 0 }, + { P9V_BUILTIN_VEC_VPRTYBQ, P9V_BUILTIN_VPRTYBQ, + RS6000_BTI_UINTTI, RS6000_BTI_UINTTI, 0, 0 }, + + { P9_BUILTIN_CMPRB, P9_BUILTIN_SCALAR_CMPRB, + RS6000_BTI_INTSI, RS6000_BTI_UINTQI, RS6000_BTI_UINTSI, 0 }, + { P9_BUILTIN_CMPRB2, P9_BUILTIN_SCALAR_CMPRB2, + RS6000_BTI_INTSI, RS6000_BTI_UINTQI, RS6000_BTI_UINTSI, 0 }, + { P9_BUILTIN_CMPEQB, P9_BUILTIN_SCALAR_CMPEQB, + RS6000_BTI_INTSI, RS6000_BTI_UINTQI, RS6000_BTI_UINTDI, 0 }, + + { P8V_BUILTIN_VEC_VPKUDUM, P8V_BUILTIN_VPKUDUM, + RS6000_BTI_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_VPKUDUM, P8V_BUILTIN_VPKUDUM, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_VPKUDUM, P8V_BUILTIN_VPKUDUM, + RS6000_BTI_bool_V4SI, RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VPKSDSS, P8V_BUILTIN_VPKSDSS, + RS6000_BTI_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VPKUDUS, P8V_BUILTIN_VPKUDUS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VPKSDUS, P8V_BUILTIN_VPKSDUS, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VRLD, P8V_BUILTIN_VRLD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_VRLD, P8V_BUILTIN_VRLD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VSLD, P8V_BUILTIN_VSLD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_VSLD, P8V_BUILTIN_VSLD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VSRD, P8V_BUILTIN_VSRD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_VSRD, P8V_BUILTIN_VSRD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VSRAD, P8V_BUILTIN_VSRAD, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_VSRAD, P8V_BUILTIN_VSRAD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VSUBCUQ, P8V_BUILTIN_VSUBCUQ, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0 }, + { P8V_BUILTIN_VEC_VSUBCUQ, P8V_BUILTIN_VSUBCUQ, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, 0 }, + + { P8V_BUILTIN_VEC_VSUBUDM, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_VSUBUDM, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_VSUBUDM, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 }, + { P8V_BUILTIN_VEC_VSUBUDM, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + { P8V_BUILTIN_VEC_VSUBUDM, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_bool_V2DI, 0 }, + { P8V_BUILTIN_VEC_VSUBUDM, P8V_BUILTIN_VSUBUDM, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 }, + + { P8V_BUILTIN_VEC_VSUBUQM, P8V_BUILTIN_VSUBUQM, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0 }, + { P8V_BUILTIN_VEC_VSUBUQM, P8V_BUILTIN_VSUBUQM, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, + RS6000_BTI_unsigned_V1TI, 0 }, + + { P6_OV_BUILTIN_CMPB, P6_BUILTIN_CMPB_32, + RS6000_BTI_UINTSI, RS6000_BTI_UINTSI, RS6000_BTI_UINTSI, 0 }, + { P6_OV_BUILTIN_CMPB, P6_BUILTIN_CMPB, + RS6000_BTI_UINTDI, RS6000_BTI_UINTDI, RS6000_BTI_UINTDI, 0 }, + + { P8V_BUILTIN_VEC_VUPKHSW, P8V_BUILTIN_VUPKHSW, + RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 }, + { P8V_BUILTIN_VEC_VUPKHSW, P8V_BUILTIN_VUPKHSW, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 }, + + { P8V_BUILTIN_VEC_VUPKLSW, P8V_BUILTIN_VUPKLSW, + RS6000_BTI_V2DI, RS6000_BTI_V4SI, 0, 0 }, + { P8V_BUILTIN_VEC_VUPKLSW, P8V_BUILTIN_VUPKLSW, + RS6000_BTI_bool_V2DI, RS6000_BTI_bool_V4SI, 0, 0 }, + + { P9V_BUILTIN_VEC_VSLV, P9V_BUILTIN_VSLV, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { P9V_BUILTIN_VEC_VSRV, P9V_BUILTIN_VSRV, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRQ_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRQ_V16QI, + RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRQ_V1TI, + RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRQ_V1TI, + RS6000_BTI_V1TI, RS6000_BTI_V1TI, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRD_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRD_V2DI, + RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRD_V2DF, + RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRW_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRW_V4SI, + RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRW_V4SF, + RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRH_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0, 0 }, + { P9V_BUILTIN_VEC_REVB, P9V_BUILTIN_XXBRH_V8HI, + RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0, 0 }, + + /* Crypto builtins. */ + { CRYPTO_BUILTIN_VPERMXOR, CRYPTO_BUILTIN_VPERMXOR_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI }, + { CRYPTO_BUILTIN_VPERMXOR, CRYPTO_BUILTIN_VPERMXOR_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI }, + { CRYPTO_BUILTIN_VPERMXOR, CRYPTO_BUILTIN_VPERMXOR_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI }, + { CRYPTO_BUILTIN_VPERMXOR, CRYPTO_BUILTIN_VPERMXOR_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI }, + + { CRYPTO_BUILTIN_VPMSUM, CRYPTO_BUILTIN_VPMSUMB, + RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, + RS6000_BTI_unsigned_V16QI, 0 }, + { CRYPTO_BUILTIN_VPMSUM, CRYPTO_BUILTIN_VPMSUMH, + RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, + RS6000_BTI_unsigned_V8HI, 0 }, + { CRYPTO_BUILTIN_VPMSUM, CRYPTO_BUILTIN_VPMSUMW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_unsigned_V4SI, 0 }, + { CRYPTO_BUILTIN_VPMSUM, CRYPTO_BUILTIN_VPMSUMD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_unsigned_V2DI, 0 }, + + { CRYPTO_BUILTIN_VSHASIGMA, CRYPTO_BUILTIN_VSHASIGMAW, + RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, + RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + { CRYPTO_BUILTIN_VSHASIGMA, CRYPTO_BUILTIN_VSHASIGMAD, + RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, + RS6000_BTI_INTSI, RS6000_BTI_INTSI }, + + { (enum rs6000_builtins) 0, (enum rs6000_builtins) 0, 0, 0, 0, 0 } +}; + + +/* Convert a type stored into a struct altivec_builtin_types as ID, + into a tree. The types are in rs6000_builtin_types: negative values + create a pointer type for the type associated to ~ID. Note it is + a logical NOT, rather than a negation, otherwise you cannot represent + a pointer type for ID 0. */ + +static inline tree +rs6000_builtin_type (int id) +{ + tree t; + t = rs6000_builtin_types[id < 0 ? ~id : id]; + return id < 0 ? build_pointer_type (t) : t; +} + +/* Check whether the type of an argument, T, is compatible with a + type ID stored into a struct altivec_builtin_types. Integer + types are considered compatible; otherwise, the language hook + lang_hooks.types_compatible_p makes the decision. */ + +static inline bool +rs6000_builtin_type_compatible (tree t, int id) +{ + tree builtin_type; + builtin_type = rs6000_builtin_type (id); + if (t == error_mark_node) + return false; + if (INTEGRAL_TYPE_P (t) && INTEGRAL_TYPE_P (builtin_type)) + return true; + else + return lang_hooks.types_compatible_p (t, builtin_type); +} + + +/* In addition to calling fold_convert for EXPR of type TYPE, also + call c_fully_fold to remove any C_MAYBE_CONST_EXPRs that could be + hiding there (PR47197). */ + +static tree +fully_fold_convert (tree type, tree expr) +{ + tree result = fold_convert (type, expr); + bool maybe_const = true; + + if (!c_dialect_cxx ()) + result = c_fully_fold (result, false, &maybe_const); + + return result; +} + +/* Build a tree for a function call to an Altivec non-overloaded builtin. + The overloaded builtin that matched the types and args is described + by DESC. The N arguments are given in ARGS, respectively. + + Actually the only thing it does is calling fold_convert on ARGS, with + a small exception for vec_{all,any}_{ge,le} predicates. */ + +static tree +altivec_build_resolved_builtin (tree *args, int n, + const struct altivec_builtin_types *desc) +{ + tree impl_fndecl = rs6000_builtin_decls[desc->overloaded_code]; + tree ret_type = rs6000_builtin_type (desc->ret_type); + tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (impl_fndecl)); + tree arg_type[3]; + tree call; + + int i; + for (i = 0; i < n; i++) + arg_type[i] = TREE_VALUE (argtypes), argtypes = TREE_CHAIN (argtypes); + + /* The AltiVec overloading implementation is overall gross, but this + is particularly disgusting. The vec_{all,any}_{ge,le} builtins + are completely different for floating-point vs. integer vector + types, because the former has vcmpgefp, but the latter should use + vcmpgtXX. + + In practice, the second and third arguments are swapped, and the + condition (LT vs. EQ, which is recognizable by bit 1 of the first + argument) is reversed. Patch the arguments here before building + the resolved CALL_EXPR. */ + if (desc->code == ALTIVEC_BUILTIN_VEC_VCMPGE_P + && desc->overloaded_code != ALTIVEC_BUILTIN_VCMPGEFP_P + && desc->overloaded_code != VSX_BUILTIN_XVCMPGEDP_P) + { + tree t; + t = args[2], args[2] = args[1], args[1] = t; + t = arg_type[2], arg_type[2] = arg_type[1], arg_type[1] = t; + + args[0] = fold_build2 (BIT_XOR_EXPR, TREE_TYPE (args[0]), args[0], + build_int_cst (NULL_TREE, 2)); + } + + switch (n) + { + case 0: + call = build_call_expr (impl_fndecl, 0); + break; + case 1: + call = build_call_expr (impl_fndecl, 1, + fully_fold_convert (arg_type[0], args[0])); + break; + case 2: + call = build_call_expr (impl_fndecl, 2, + fully_fold_convert (arg_type[0], args[0]), + fully_fold_convert (arg_type[1], args[1])); + break; + case 3: + call = build_call_expr (impl_fndecl, 3, + fully_fold_convert (arg_type[0], args[0]), + fully_fold_convert (arg_type[1], args[1]), + fully_fold_convert (arg_type[2], args[2])); + break; + default: + gcc_unreachable (); + } + return fold_convert (ret_type, call); +} + +/* Implementation of the resolve_overloaded_builtin target hook, to + support Altivec's overloaded builtins. */ + +tree +altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, + void *passed_arglist) +{ + vec *arglist = static_cast *> (passed_arglist); + unsigned int nargs = vec_safe_length (arglist); + enum rs6000_builtins fcode + = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl); + tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); + tree types[3], args[3]; + const struct altivec_builtin_types *desc; + unsigned int n; + + if (!rs6000_overloaded_builtin_p (fcode)) + return NULL_TREE; + + if (TARGET_DEBUG_BUILTIN) + fprintf (stderr, "altivec_resolve_overloaded_builtin, code = %4d, %s\n", + (int)fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl))); + + /* vec_lvsl and vec_lvsr are deprecated for use with LE element order. */ + if (fcode == ALTIVEC_BUILTIN_VEC_LVSL && !VECTOR_ELT_ORDER_BIG) + warning (OPT_Wdeprecated, + "vec_lvsl is deprecated for little endian; use " + "assignment for unaligned loads and stores"); + else if (fcode == ALTIVEC_BUILTIN_VEC_LVSR && !VECTOR_ELT_ORDER_BIG) + warning (OPT_Wdeprecated, + "vec_lvsr is deprecated for little endian; use " + "assignment for unaligned loads and stores"); + + if (fcode == ALTIVEC_BUILTIN_VEC_MUL) + { + /* vec_mul needs to be special cased because there are no instructions + for it for the {un}signed char, {un}signed short, and {un}signed int + types. */ + if (nargs != 2) + { + error ("vec_mul only accepts 2 arguments"); + return error_mark_node; + } + + tree arg0 = (*arglist)[0]; + tree arg0_type = TREE_TYPE (arg0); + tree arg1 = (*arglist)[1]; + tree arg1_type = TREE_TYPE (arg1); + + /* Both arguments must be vectors and the types must be compatible. */ + if (TREE_CODE (arg0_type) != VECTOR_TYPE) + goto bad; + if (!lang_hooks.types_compatible_p (arg0_type, arg1_type)) + goto bad; + + switch (TYPE_MODE (TREE_TYPE (arg0_type))) + { + case QImode: + case HImode: + case SImode: + case DImode: + case TImode: + { + /* For scalar types just use a multiply expression. */ + return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0), arg0, + fold_convert (TREE_TYPE (arg0), arg1)); + } + case SFmode: + { + /* For floats use the xvmulsp instruction directly. */ + tree call = rs6000_builtin_decls[VSX_BUILTIN_XVMULSP]; + return build_call_expr (call, 2, arg0, arg1); + } + case DFmode: + { + /* For doubles use the xvmuldp instruction directly. */ + tree call = rs6000_builtin_decls[VSX_BUILTIN_XVMULDP]; + return build_call_expr (call, 2, arg0, arg1); + } + /* Other types are errors. */ + default: + goto bad; + } + } + + if (fcode == ALTIVEC_BUILTIN_VEC_CMPNE) + { + /* vec_cmpne needs to be special cased because there are no instructions + for it (prior to power 9). */ + if (nargs != 2) + { + error ("vec_cmpne only accepts 2 arguments"); + return error_mark_node; + } + + tree arg0 = (*arglist)[0]; + tree arg0_type = TREE_TYPE (arg0); + tree arg1 = (*arglist)[1]; + tree arg1_type = TREE_TYPE (arg1); + + /* Power9 instructions provide the most efficient implementation of + ALTIVEC_BUILTIN_VEC_CMPNE if the mode is not DImode or TImode + or SFmode or DFmode. */ + if (!TARGET_P9_VECTOR + || (TYPE_MODE (TREE_TYPE (arg0_type)) == DImode) + || (TYPE_MODE (TREE_TYPE (arg0_type)) == TImode) + || (TYPE_MODE (TREE_TYPE (arg0_type)) == SFmode) + || (TYPE_MODE (TREE_TYPE (arg0_type)) == DFmode)) + { + /* Both arguments must be vectors and the types must be compatible. */ + if (TREE_CODE (arg0_type) != VECTOR_TYPE) + goto bad; + if (!lang_hooks.types_compatible_p (arg0_type, arg1_type)) + goto bad; + + switch (TYPE_MODE (TREE_TYPE (arg0_type))) + { + /* vec_cmpneq (va, vb) == vec_nor (vec_cmpeq (va, vb), + vec_cmpeq (va, vb)). */ + /* Note: vec_nand also works but opt changes vec_nand's + to vec_nor's anyway. */ + case QImode: + case HImode: + case SImode: + case DImode: + case TImode: + case SFmode: + case DFmode: + { + /* call = vec_cmpeq (va, vb) + result = vec_nor (call, call). */ + vec *params = make_tree_vector (); + vec_safe_push (params, arg0); + vec_safe_push (params, arg1); + tree call = altivec_resolve_overloaded_builtin + (loc, rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_CMPEQ], + params); + /* Use save_expr to ensure that operands used more than once + that may have side effects (like calls) are only evaluated + once. */ + call = save_expr (call); + params = make_tree_vector (); + vec_safe_push (params, call); + vec_safe_push (params, call); + return altivec_resolve_overloaded_builtin + (loc, rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_NOR], params); + } + /* Other types are errors. */ + default: + goto bad; + } + } + /* else, fall through and process the Power9 alternative below */ + } + + if (fcode == ALTIVEC_BUILTIN_VEC_ADDE) + { + /* vec_adde needs to be special cased because there is no instruction + for the {un}signed int version. */ + if (nargs != 3) + { + error ("vec_adde only accepts 3 arguments"); + return error_mark_node; + } + + tree arg0 = (*arglist)[0]; + tree arg0_type = TREE_TYPE (arg0); + tree arg1 = (*arglist)[1]; + tree arg1_type = TREE_TYPE (arg1); + tree arg2 = (*arglist)[2]; + tree arg2_type = TREE_TYPE (arg2); + + /* All 3 arguments must be vectors of (signed or unsigned) (int or + __int128) and the types must be compatible. */ + if (TREE_CODE (arg0_type) != VECTOR_TYPE) + goto bad; + if (!lang_hooks.types_compatible_p (arg0_type, arg1_type) || + !lang_hooks.types_compatible_p (arg1_type, arg2_type)) + goto bad; + + switch (TYPE_MODE (TREE_TYPE (arg0_type))) + { + /* For {un}signed ints, + vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb), + vec_and (carryv, 0x1)). */ + case SImode: + { + vec *params = make_tree_vector (); + vec_safe_push (params, arg0); + vec_safe_push (params, arg1); + tree add_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD]; + tree call = altivec_resolve_overloaded_builtin (loc, add_builtin, + params); + tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1); + tree ones_vector = build_vector_from_val (arg0_type, const1); + tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type, + arg2, ones_vector); + params = make_tree_vector (); + vec_safe_push (params, call); + vec_safe_push (params, and_expr); + return altivec_resolve_overloaded_builtin (loc, add_builtin, + params); + } + /* For {un}signed __int128s use the vaddeuqm instruction + directly. */ + case TImode: + { + tree adde_bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDEUQM]; + return altivec_resolve_overloaded_builtin (loc, adde_bii, + arglist); + } + + /* Types other than {un}signed int and {un}signed __int128 + are errors. */ + default: + goto bad; + } + } + + if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC) + { + /* vec_addec needs to be special cased because there is no instruction + for the {un}signed int version. */ + if (nargs != 3) + { + error ("vec_addec only accepts 3 arguments"); + return error_mark_node; + } + + tree arg0 = (*arglist)[0]; + tree arg0_type = TREE_TYPE (arg0); + tree arg1 = (*arglist)[1]; + tree arg1_type = TREE_TYPE (arg1); + tree arg2 = (*arglist)[2]; + tree arg2_type = TREE_TYPE (arg2); + + /* All 3 arguments must be vectors of (signed or unsigned) (int or + __int128) and the types must be compatible. */ + if (TREE_CODE (arg0_type) != VECTOR_TYPE) + goto bad; + if (!lang_hooks.types_compatible_p (arg0_type, arg1_type) || + !lang_hooks.types_compatible_p (arg1_type, arg2_type)) + goto bad; + + switch (TYPE_MODE (TREE_TYPE (arg0_type))) + { + /* For {un}signed ints, + vec_addec (va, vb, carryv) == + vec_or (vec_addc (va, vb), + vec_addc (vec_add (va, vb), + vec_and (carryv, 0x1))). */ + case SImode: + { + /* Use save_expr to ensure that operands used more than once + that may have side effects (like calls) are only evaluated + once. */ + arg0 = save_expr (arg0); + arg1 = save_expr (arg1); + vec *params = make_tree_vector (); + vec_safe_push (params, arg0); + vec_safe_push (params, arg1); + tree addc_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADDC]; + tree call1 = altivec_resolve_overloaded_builtin (loc, addc_builtin, + params); + params = make_tree_vector (); + vec_safe_push (params, arg0); + vec_safe_push (params, arg1); + tree add_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD]; + tree call2 = altivec_resolve_overloaded_builtin (loc, add_builtin, + params); + tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1); + tree ones_vector = build_vector_from_val (arg0_type, const1); + tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type, + arg2, ones_vector); + params = make_tree_vector (); + vec_safe_push (params, call2); + vec_safe_push (params, and_expr); + call2 = altivec_resolve_overloaded_builtin (loc, addc_builtin, + params); + params = make_tree_vector (); + vec_safe_push (params, call1); + vec_safe_push (params, call2); + tree or_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_OR]; + return altivec_resolve_overloaded_builtin (loc, or_builtin, + params); + } + /* For {un}signed __int128s use the vaddecuq instruction. */ + case TImode: + { + tree VADDECUQ_bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDECUQ]; + return altivec_resolve_overloaded_builtin (loc, VADDECUQ_bii, + arglist); + } + /* Types other than {un}signed int and {un}signed __int128 + are errors. */ + default: + goto bad; + } + } + + /* For now treat vec_splats and vec_promote as the same. */ + if (fcode == ALTIVEC_BUILTIN_VEC_SPLATS + || fcode == ALTIVEC_BUILTIN_VEC_PROMOTE) + { + tree type, arg; + int size; + int i; + bool unsigned_p; + vec *vec; + const char *name = fcode == ALTIVEC_BUILTIN_VEC_SPLATS ? "vec_splats": "vec_promote"; + + if (nargs == 0) + { + error ("%s only accepts %d arguments", name, (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE)+1 ); + return error_mark_node; + } + if (fcode == ALTIVEC_BUILTIN_VEC_SPLATS && nargs != 1) + { + error ("%s only accepts 1 argument", name); + return error_mark_node; + } + if (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE && nargs != 2) + { + error ("%s only accepts 2 arguments", name); + return error_mark_node; + } + /* Ignore promote's element argument. */ + if (fcode == ALTIVEC_BUILTIN_VEC_PROMOTE + && !INTEGRAL_TYPE_P (TREE_TYPE ((*arglist)[1]))) + goto bad; + + arg = (*arglist)[0]; + type = TREE_TYPE (arg); + if (!SCALAR_FLOAT_TYPE_P (type) + && !INTEGRAL_TYPE_P (type)) + goto bad; + unsigned_p = TYPE_UNSIGNED (type); + switch (TYPE_MODE (type)) + { + case TImode: + type = (unsigned_p ? unsigned_V1TI_type_node : V1TI_type_node); + size = 1; + break; + case DImode: + type = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node); + size = 2; + break; + case SImode: + type = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node); + size = 4; + break; + case HImode: + type = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node); + size = 8; + break; + case QImode: + type = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node); + size = 16; + break; + case SFmode: type = V4SF_type_node; size = 4; break; + case DFmode: type = V2DF_type_node; size = 2; break; + default: + goto bad; + } + arg = save_expr (fold_convert (TREE_TYPE (type), arg)); + vec_alloc (vec, size); + for(i = 0; i < size; i++) + { + constructor_elt elt = {NULL_TREE, arg}; + vec->quick_push (elt); + } + return build_constructor (type, vec); + } + + /* For now use pointer tricks to do the extraction, unless we are on VSX + extracting a double from a constant offset. */ + if (fcode == ALTIVEC_BUILTIN_VEC_EXTRACT) + { + tree arg1; + tree arg1_type; + tree arg2; + tree arg1_inner_type; + tree decl, stmt; + tree innerptrtype; + machine_mode mode; + + /* No second argument. */ + if (nargs != 2) + { + error ("vec_extract only accepts 2 arguments"); + return error_mark_node; + } + + arg2 = (*arglist)[1]; + arg1 = (*arglist)[0]; + arg1_type = TREE_TYPE (arg1); + + if (TREE_CODE (arg1_type) != VECTOR_TYPE) + goto bad; + if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) + goto bad; + + /* If we are targeting little-endian, but -maltivec=be has been + specified to override the element order, adjust the element + number accordingly. */ + if (!BYTES_BIG_ENDIAN && rs6000_altivec_element_order == 2) + { + unsigned int last_elem = TYPE_VECTOR_SUBPARTS (arg1_type) - 1; + arg2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (arg2), + build_int_cstu (TREE_TYPE (arg2), last_elem), + arg2); + } + + /* See if we can optimize vec_extracts with the current VSX instruction + set. */ + mode = TYPE_MODE (arg1_type); + if (VECTOR_MEM_VSX_P (mode)) + + { + tree call = NULL_TREE; + int nunits = GET_MODE_NUNITS (mode); + + /* If the second argument is an integer constant, if the value is in + the expected range, generate the built-in code if we can. We need + 64-bit and direct move to extract the small integer vectors. */ + if (TREE_CODE (arg2) == INTEGER_CST && wi::ltu_p (arg2, nunits)) + { + switch (mode) + { + default: + break; + + case V1TImode: + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V1TI]; + break; + + case V2DFmode: + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF]; + break; + + case V2DImode: + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI]; + break; + + case V4SFmode: + call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V4SF]; + break; + + case V4SImode: + if (TARGET_DIRECT_MOVE_64BIT) + call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V4SI]; + break; + + case V8HImode: + if (TARGET_DIRECT_MOVE_64BIT) + call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V8HI]; + break; + + case V16QImode: + if (TARGET_DIRECT_MOVE_64BIT) + call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V16QI]; + break; + } + } + + /* If the second argument is variable, we can optimize it if we are + generating 64-bit code on a machine with direct move. */ + else if (TREE_CODE (arg2) != INTEGER_CST && TARGET_DIRECT_MOVE_64BIT) + { + switch (mode) + { + default: + break; + + case V2DFmode: + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DF]; + break; + + case V2DImode: + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_EXT_V2DI]; + break; + + case V4SFmode: + call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V4SF]; + break; + + case V4SImode: + call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V4SI]; + break; + + case V8HImode: + call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V8HI]; + break; + + case V16QImode: + call = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_EXT_V16QI]; + break; + } + } + + if (call) + return build_call_expr (call, 2, arg1, arg2); + } + + /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2). */ + arg1_inner_type = TREE_TYPE (arg1_type); + arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, + build_int_cst (TREE_TYPE (arg2), + TYPE_VECTOR_SUBPARTS (arg1_type) + - 1), 0); + decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type); + DECL_EXTERNAL (decl) = 0; + TREE_PUBLIC (decl) = 0; + DECL_CONTEXT (decl) = current_function_decl; + TREE_USED (decl) = 1; + TREE_TYPE (decl) = arg1_type; + TREE_READONLY (decl) = TYPE_READONLY (arg1_type); + if (c_dialect_cxx ()) + { + stmt = build4 (TARGET_EXPR, arg1_type, decl, arg1, + NULL_TREE, NULL_TREE); + SET_EXPR_LOCATION (stmt, loc); + } + else + { + DECL_INITIAL (decl) = arg1; + stmt = build1 (DECL_EXPR, arg1_type, decl); + TREE_ADDRESSABLE (decl) = 1; + SET_EXPR_LOCATION (stmt, loc); + stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt); + } + + innerptrtype = build_pointer_type (arg1_inner_type); + + stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0); + stmt = convert (innerptrtype, stmt); + stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1); + stmt = build_indirect_ref (loc, stmt, RO_NULL); + + return stmt; + } + + /* For now use pointer tricks to do the insertion, unless we are on VSX + inserting a double to a constant offset.. */ + if (fcode == ALTIVEC_BUILTIN_VEC_INSERT) + { + tree arg0; + tree arg1; + tree arg2; + tree arg1_type; + tree arg1_inner_type; + tree decl, stmt; + tree innerptrtype; + machine_mode mode; + + /* No second or third arguments. */ + if (nargs != 3) + { + error ("vec_insert only accepts 3 arguments"); + return error_mark_node; + } + + arg0 = (*arglist)[0]; + arg1 = (*arglist)[1]; + arg1_type = TREE_TYPE (arg1); + arg2 = (*arglist)[2]; + + if (TREE_CODE (arg1_type) != VECTOR_TYPE) + goto bad; + if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2))) + goto bad; + + /* If we are targeting little-endian, but -maltivec=be has been + specified to override the element order, adjust the element + number accordingly. */ + if (!BYTES_BIG_ENDIAN && rs6000_altivec_element_order == 2) + { + unsigned int last_elem = TYPE_VECTOR_SUBPARTS (arg1_type) - 1; + arg2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (arg2), + build_int_cstu (TREE_TYPE (arg2), last_elem), + arg2); + } + + /* If we can use the VSX xxpermdi instruction, use that for insert. */ + mode = TYPE_MODE (arg1_type); + if ((mode == V2DFmode || mode == V2DImode) && VECTOR_UNIT_VSX_P (mode) + && TREE_CODE (arg2) == INTEGER_CST + && wi::ltu_p (arg2, 2)) + { + tree call = NULL_TREE; + + if (mode == V2DFmode) + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DF]; + else if (mode == V2DImode) + call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DI]; + + /* Note, __builtin_vec_insert_ has vector and scalar types + reversed. */ + if (call) + return build_call_expr (call, 3, arg1, arg0, arg2); + } + else if (mode == V1TImode && VECTOR_UNIT_VSX_P (mode) + && TREE_CODE (arg2) == INTEGER_CST + && wi::eq_p (arg2, 0)) + { + tree call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V1TI]; + + /* Note, __builtin_vec_insert_ has vector and scalar types + reversed. */ + return build_call_expr (call, 3, arg1, arg0, arg2); + } + + /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2) = arg0. */ + arg1_inner_type = TREE_TYPE (arg1_type); + arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, + build_int_cst (TREE_TYPE (arg2), + TYPE_VECTOR_SUBPARTS (arg1_type) + - 1), 0); + decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type); + DECL_EXTERNAL (decl) = 0; + TREE_PUBLIC (decl) = 0; + DECL_CONTEXT (decl) = current_function_decl; + TREE_USED (decl) = 1; + TREE_TYPE (decl) = arg1_type; + TREE_READONLY (decl) = TYPE_READONLY (arg1_type); + if (c_dialect_cxx ()) + { + stmt = build4 (TARGET_EXPR, arg1_type, decl, arg1, + NULL_TREE, NULL_TREE); + SET_EXPR_LOCATION (stmt, loc); + } + else + { + DECL_INITIAL (decl) = arg1; + stmt = build1 (DECL_EXPR, arg1_type, decl); + TREE_ADDRESSABLE (decl) = 1; + SET_EXPR_LOCATION (stmt, loc); + stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt); + } + + innerptrtype = build_pointer_type (arg1_inner_type); + + stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0); + stmt = convert (innerptrtype, stmt); + stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1); + stmt = build_indirect_ref (loc, stmt, RO_NULL); + stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt, + convert (TREE_TYPE (stmt), arg0)); + stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl); + return stmt; + } + + /* Expand vec_ld into an expression that masks the address and + performs the load. We need to expand this early to allow + the best aliasing, as by the time we get into RTL we no longer + are able to honor __restrict__, for example. We may want to + consider this for all memory access built-ins. + + When -maltivec=be is specified, or the wrong number of arguments + is provided, simply punt to existing built-in processing. */ + if (fcode == ALTIVEC_BUILTIN_VEC_LD + && (BYTES_BIG_ENDIAN || !VECTOR_ELT_ORDER_BIG) + && nargs == 2) + { + tree arg0 = (*arglist)[0]; + tree arg1 = (*arglist)[1]; + + /* Strip qualifiers like "const" from the pointer arg. */ + tree arg1_type = TREE_TYPE (arg1); + tree inner_type = TREE_TYPE (arg1_type); + if (TYPE_QUALS (TREE_TYPE (arg1_type)) != 0) + { + arg1_type = build_pointer_type (build_qualified_type (inner_type, + 0)); + arg1 = fold_convert (arg1_type, arg1); + } + + /* Construct the masked address. Let existing error handling take + over if we don't have a constant offset. */ + arg0 = fold (arg0); + + if (TREE_CODE (arg0) == INTEGER_CST) + { + if (!ptrofftype_p (TREE_TYPE (arg0))) + arg0 = build1 (NOP_EXPR, sizetype, arg0); + + tree arg1_type = TREE_TYPE (arg1); + if (TREE_CODE (arg1_type) == ARRAY_TYPE) + { + arg1_type = TYPE_POINTER_TO (TREE_TYPE (arg1_type)); + tree const0 = build_int_cstu (sizetype, 0); + tree arg1_elt0 = build_array_ref (loc, arg1, const0); + arg1 = build1 (ADDR_EXPR, arg1_type, arg1_elt0); + } + + tree addr = fold_build2_loc (loc, POINTER_PLUS_EXPR, arg1_type, + arg1, arg0); + tree aligned = fold_build2_loc (loc, BIT_AND_EXPR, arg1_type, addr, + build_int_cst (arg1_type, -16)); + + /* Find the built-in to get the return type so we can convert + the result properly (or fall back to default handling if the + arguments aren't compatible). */ + for (desc = altivec_overloaded_builtins; + desc->code && desc->code != fcode; desc++) + continue; + + for (; desc->code == fcode; desc++) + if (rs6000_builtin_type_compatible (TREE_TYPE (arg0), desc->op1) + && (rs6000_builtin_type_compatible (TREE_TYPE (arg1), + desc->op2))) + { + tree ret_type = rs6000_builtin_type (desc->ret_type); + if (TYPE_MODE (ret_type) == V2DImode) + /* Type-based aliasing analysis thinks vector long + and vector long long are different and will put them + in distinct alias classes. Force our return type + to be a may-alias type to avoid this. */ + ret_type + = build_pointer_type_for_mode (ret_type, Pmode, + true/*can_alias_all*/); + else + ret_type = build_pointer_type (ret_type); + aligned = build1 (NOP_EXPR, ret_type, aligned); + tree ret_val = build_indirect_ref (loc, aligned, RO_NULL); + return ret_val; + } + } + } + + /* Similarly for stvx. */ + if (fcode == ALTIVEC_BUILTIN_VEC_ST + && (BYTES_BIG_ENDIAN || !VECTOR_ELT_ORDER_BIG) + && nargs == 3) + { + tree arg0 = (*arglist)[0]; + tree arg1 = (*arglist)[1]; + tree arg2 = (*arglist)[2]; + + /* Construct the masked address. Let existing error handling take + over if we don't have a constant offset. */ + arg1 = fold (arg1); + + if (TREE_CODE (arg1) == INTEGER_CST) + { + if (!ptrofftype_p (TREE_TYPE (arg1))) + arg1 = build1 (NOP_EXPR, sizetype, arg1); + + tree arg2_type = TREE_TYPE (arg2); + if (TREE_CODE (arg2_type) == ARRAY_TYPE) + { + arg2_type = TYPE_POINTER_TO (TREE_TYPE (arg2_type)); + tree const0 = build_int_cstu (sizetype, 0); + tree arg2_elt0 = build_array_ref (loc, arg2, const0); + arg2 = build1 (ADDR_EXPR, arg2_type, arg2_elt0); + } + + tree addr = fold_build2_loc (loc, POINTER_PLUS_EXPR, arg2_type, + arg2, arg1); + tree aligned = fold_build2_loc (loc, BIT_AND_EXPR, arg2_type, addr, + build_int_cst (arg2_type, -16)); + + /* Find the built-in to make sure a compatible one exists; if not + we fall back to default handling to get the error message. */ + for (desc = altivec_overloaded_builtins; + desc->code && desc->code != fcode; desc++) + continue; + + for (; desc->code == fcode; desc++) + if (rs6000_builtin_type_compatible (TREE_TYPE (arg0), desc->op1) + && rs6000_builtin_type_compatible (TREE_TYPE (arg1), desc->op2) + && rs6000_builtin_type_compatible (TREE_TYPE (arg2), + desc->op3)) + { + tree arg0_type = TREE_TYPE (arg0); + if (TYPE_MODE (arg0_type) == V2DImode) + /* Type-based aliasing analysis thinks vector long + and vector long long are different and will put them + in distinct alias classes. Force our address type + to be a may-alias type to avoid this. */ + arg0_type + = build_pointer_type_for_mode (arg0_type, Pmode, + true/*can_alias_all*/); + else + arg0_type = build_pointer_type (arg0_type); + aligned = build1 (NOP_EXPR, arg0_type, aligned); + tree stg = build_indirect_ref (loc, aligned, RO_NULL); + tree retval = build2 (MODIFY_EXPR, TREE_TYPE (stg), stg, + convert (TREE_TYPE (stg), arg0)); + return retval; + } + } + } + + for (n = 0; + !VOID_TYPE_P (TREE_VALUE (fnargs)) && n < nargs; + fnargs = TREE_CHAIN (fnargs), n++) + { + tree decl_type = TREE_VALUE (fnargs); + tree arg = (*arglist)[n]; + tree type; + + if (arg == error_mark_node) + return error_mark_node; + + if (n >= 3) + abort (); + + arg = default_conversion (arg); + + /* The C++ front-end converts float * to const void * using + NOP_EXPR (NOP_EXPR (x)). */ + type = TREE_TYPE (arg); + if (POINTER_TYPE_P (type) + && TREE_CODE (arg) == NOP_EXPR + && lang_hooks.types_compatible_p (TREE_TYPE (arg), + const_ptr_type_node) + && lang_hooks.types_compatible_p (TREE_TYPE (TREE_OPERAND (arg, 0)), + ptr_type_node)) + { + arg = TREE_OPERAND (arg, 0); + type = TREE_TYPE (arg); + } + + /* Remove the const from the pointers to simplify the overload + matching further down. */ + if (POINTER_TYPE_P (decl_type) + && POINTER_TYPE_P (type) + && TYPE_QUALS (TREE_TYPE (type)) != 0) + { + if (TYPE_READONLY (TREE_TYPE (type)) + && !TYPE_READONLY (TREE_TYPE (decl_type))) + warning (0, "passing arg %d of %qE discards qualifiers from " + "pointer target type", n + 1, fndecl); + type = build_pointer_type (build_qualified_type (TREE_TYPE (type), + 0)); + arg = fold_convert (type, arg); + } + + args[n] = arg; + types[n] = type; + } + + /* If the number of arguments did not match the prototype, return NULL + and the generic code will issue the appropriate error message. */ + if (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs) + return NULL; + + if (n == 0) + abort (); + + if (fcode == ALTIVEC_BUILTIN_VEC_STEP) + { + if (TREE_CODE (types[0]) != VECTOR_TYPE) + goto bad; + + return build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (types[0])); + } + + { + bool unsupported_builtin = false; + for (desc = altivec_overloaded_builtins; + desc->code && desc->code != fcode; desc++) + continue; + + /* Need to special case __builtin_cmp because the overloaded forms + of this function take (unsigned int, unsigned int) or (unsigned + long long int, unsigned long long int). Since C conventions + allow the respective argument types to be implicitly coerced into + each other, the default handling does not provide adequate + discrimination between the desired forms of the function. */ + if (fcode == P6_OV_BUILTIN_CMPB) + { + int overloaded_code; + int arg1_mode = TYPE_MODE (types[0]); + int arg2_mode = TYPE_MODE (types[1]); + + if (nargs != 2) + { + error ("__builtin_cmpb only accepts 2 arguments"); + return error_mark_node; + } + + /* If any supplied arguments are wider than 32 bits, resolve to + 64-bit variant of built-in function. */ + if ((GET_MODE_PRECISION (arg1_mode) > 32) + || (GET_MODE_PRECISION (arg2_mode) > 32)) + { + /* Assure all argument and result types are compatible with + the built-in function represented by P6_BUILTIN_CMPB. */ + overloaded_code = P6_BUILTIN_CMPB; + } + else + { + /* Assure all argument and result types are compatible with + the built-in function represented by P6_BUILTIN_CMPB_32. */ + overloaded_code = P6_BUILTIN_CMPB_32; + } + + while (desc->code && desc->code == fcode && + desc->overloaded_code != overloaded_code) + desc++; + + if (desc->code && (desc->code == fcode) + && rs6000_builtin_type_compatible (types[0], desc->op1) + && rs6000_builtin_type_compatible (types[1], desc->op2)) + { + if (rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE) + return altivec_build_resolved_builtin (args, n, desc); + else + unsupported_builtin = true; + } + } + else + { + /* For arguments after the last, we have RS6000_BTI_NOT_OPAQUE in + the opX fields. */ + for (; desc->code == fcode; desc++) + { + if ((desc->op1 == RS6000_BTI_NOT_OPAQUE + || rs6000_builtin_type_compatible (types[0], desc->op1)) + && (desc->op2 == RS6000_BTI_NOT_OPAQUE + || rs6000_builtin_type_compatible (types[1], desc->op2)) + && (desc->op3 == RS6000_BTI_NOT_OPAQUE + || rs6000_builtin_type_compatible (types[2], desc->op3))) + { + if (rs6000_builtin_decls[desc->overloaded_code] != NULL_TREE) + return altivec_build_resolved_builtin (args, n, desc); + else + unsupported_builtin = true; + } + } + } + + if (unsupported_builtin) + { + const char *name = rs6000_overloaded_builtin_name (fcode); + error ("Builtin function %s not supported in this compiler configuration", + name); + return error_mark_node; + } + } + bad: + { + const char *name = rs6000_overloaded_builtin_name (fcode); + error ("invalid parameter combination for AltiVec intrinsic %s", name); + return error_mark_node; + } +} diff --git a/gcc/config/powerpcspe/powerpcspe-cpus.def b/gcc/config/powerpcspe/powerpcspe-cpus.def new file mode 100644 index 00000000000..cd5c70688d8 --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe-cpus.def @@ -0,0 +1,264 @@ +/* IBM RS/6000 CPU names.. + Copyright (C) 1991-2017 Free Software Foundation, Inc. + Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* ISA masks. */ +#ifndef ISA_2_1_MASKS +#define ISA_2_1_MASKS OPTION_MASK_MFCRF +#define ISA_2_2_MASKS (ISA_2_1_MASKS | OPTION_MASK_POPCNTB) +#define ISA_2_4_MASKS (ISA_2_2_MASKS | OPTION_MASK_FPRND) + + /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add + ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel, + fre, fsqrt, etc. were no longer documented as optional. Group masks by + server and embedded. */ +#define ISA_2_5_MASKS_EMBEDDED (ISA_2_4_MASKS \ + | OPTION_MASK_CMPB \ + | OPTION_MASK_RECIP_PRECISION \ + | OPTION_MASK_PPC_GFXOPT \ + | OPTION_MASK_PPC_GPOPT) + +#define ISA_2_5_MASKS_SERVER (ISA_2_5_MASKS_EMBEDDED | OPTION_MASK_DFP) + + /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but + altivec is a win so enable it. */ + /* OPTION_MASK_VSX_TIMODE should be set, but disable it for now until + PR 58587 is fixed. */ +#define ISA_2_6_MASKS_EMBEDDED (ISA_2_5_MASKS_EMBEDDED | OPTION_MASK_POPCNTD) +#define ISA_2_6_MASKS_SERVER (ISA_2_5_MASKS_SERVER \ + | OPTION_MASK_POPCNTD \ + | OPTION_MASK_ALTIVEC \ + | OPTION_MASK_VSX \ + | OPTION_MASK_UPPER_REGS_DI \ + | OPTION_MASK_UPPER_REGS_DF) + +/* For now, don't provide an embedded version of ISA 2.07. */ +#define ISA_2_7_MASKS_SERVER (ISA_2_6_MASKS_SERVER \ + | OPTION_MASK_P8_FUSION \ + | OPTION_MASK_P8_VECTOR \ + | OPTION_MASK_CRYPTO \ + | OPTION_MASK_DIRECT_MOVE \ + | OPTION_MASK_EFFICIENT_UNALIGNED_VSX \ + | OPTION_MASK_HTM \ + | OPTION_MASK_QUAD_MEMORY \ + | OPTION_MASK_QUAD_MEMORY_ATOMIC \ + | OPTION_MASK_UPPER_REGS_SF \ + | OPTION_MASK_VSX_SMALL_INTEGER) + +/* Add ISEL back into ISA 3.0, since it is supposed to be a win. Do not add + FLOAT128_HW here until we are ready to make -mfloat128 on by default. */ +#define ISA_3_0_MASKS_SERVER (ISA_2_7_MASKS_SERVER \ + | OPTION_MASK_ISEL \ + | OPTION_MASK_MODULO \ + | OPTION_MASK_P9_FUSION \ + | OPTION_MASK_P9_DFORM_SCALAR \ + | OPTION_MASK_P9_DFORM_VECTOR \ + | OPTION_MASK_P9_MINMAX \ + | OPTION_MASK_P9_MISC \ + | OPTION_MASK_P9_VECTOR) + +/* Support for the IEEE 128-bit floating point hardware requires a lot of the + VSX instructions that are part of ISA 3.0. */ +#define ISA_3_0_MASKS_IEEE (OPTION_MASK_VSX \ + | OPTION_MASK_P8_VECTOR \ + | OPTION_MASK_P9_VECTOR \ + | OPTION_MASK_DIRECT_MOVE \ + | OPTION_MASK_UPPER_REGS_DI \ + | OPTION_MASK_UPPER_REGS_DF \ + | OPTION_MASK_UPPER_REGS_SF \ + | OPTION_MASK_VSX_SMALL_INTEGER) + +/* Flags that need to be turned off if -mno-power9-vector. */ +#define OTHER_P9_VECTOR_MASKS (OPTION_MASK_FLOAT128_HW \ + | OPTION_MASK_P9_DFORM_SCALAR \ + | OPTION_MASK_P9_DFORM_VECTOR \ + | OPTION_MASK_P9_MINMAX) + +/* Flags that need to be turned off if -mno-power8-vector. */ +#define OTHER_P8_VECTOR_MASKS (OTHER_P9_VECTOR_MASKS \ + | OPTION_MASK_P9_VECTOR \ + | OPTION_MASK_DIRECT_MOVE \ + | OPTION_MASK_CRYPTO \ + | OPTION_MASK_UPPER_REGS_SF) \ + +/* Flags that need to be turned off if -mno-vsx. */ +#define OTHER_VSX_VECTOR_MASKS (OTHER_P8_VECTOR_MASKS \ + | OPTION_MASK_EFFICIENT_UNALIGNED_VSX \ + | OPTION_MASK_FLOAT128_KEYWORD \ + | OPTION_MASK_FLOAT128_TYPE \ + | OPTION_MASK_P8_VECTOR \ + | OPTION_MASK_UPPER_REGS_DI \ + | OPTION_MASK_UPPER_REGS_DF \ + | OPTION_MASK_VSX_SMALL_INTEGER \ + | OPTION_MASK_VSX_TIMODE) + +#define POWERPC_7400_MASK (OPTION_MASK_PPC_GFXOPT | OPTION_MASK_ALTIVEC) + +/* Deal with ports that do not have -mstrict-align. */ +#ifdef OPTION_MASK_STRICT_ALIGN +#define OPTION_MASK_STRICT_ALIGN_OPTIONAL OPTION_MASK_STRICT_ALIGN +#else +#define OPTION_MASK_STRICT_ALIGN 0 +#define OPTION_MASK_STRICT_ALIGN_OPTIONAL 0 +#ifndef MASK_STRICT_ALIGN +#define MASK_STRICT_ALIGN 0 +#endif +#endif + +/* Mask of all options to set the default isa flags based on -mcpu=. */ +#define POWERPC_MASKS (OPTION_MASK_ALTIVEC \ + | OPTION_MASK_CMPB \ + | OPTION_MASK_CRYPTO \ + | OPTION_MASK_DFP \ + | OPTION_MASK_DIRECT_MOVE \ + | OPTION_MASK_DLMZB \ + | OPTION_MASK_EFFICIENT_UNALIGNED_VSX \ + | OPTION_MASK_FLOAT128_HW \ + | OPTION_MASK_FLOAT128_KEYWORD \ + | OPTION_MASK_FLOAT128_TYPE \ + | OPTION_MASK_FPRND \ + | OPTION_MASK_HTM \ + | OPTION_MASK_ISEL \ + | OPTION_MASK_LRA \ + | OPTION_MASK_MFCRF \ + | OPTION_MASK_MFPGPR \ + | OPTION_MASK_MODULO \ + | OPTION_MASK_MULHW \ + | OPTION_MASK_NO_UPDATE \ + | OPTION_MASK_P8_FUSION \ + | OPTION_MASK_P8_VECTOR \ + | OPTION_MASK_P9_DFORM_SCALAR \ + | OPTION_MASK_P9_DFORM_VECTOR \ + | OPTION_MASK_P9_FUSION \ + | OPTION_MASK_P9_MINMAX \ + | OPTION_MASK_P9_MISC \ + | OPTION_MASK_P9_VECTOR \ + | OPTION_MASK_POPCNTB \ + | OPTION_MASK_POPCNTD \ + | OPTION_MASK_POWERPC64 \ + | OPTION_MASK_PPC_GFXOPT \ + | OPTION_MASK_PPC_GPOPT \ + | OPTION_MASK_QUAD_MEMORY \ + | OPTION_MASK_QUAD_MEMORY_ATOMIC \ + | OPTION_MASK_RECIP_PRECISION \ + | OPTION_MASK_SOFT_FLOAT \ + | OPTION_MASK_STRICT_ALIGN_OPTIONAL \ + | OPTION_MASK_TOC_FUSION \ + | OPTION_MASK_UPPER_REGS_DI \ + | OPTION_MASK_UPPER_REGS_DF \ + | OPTION_MASK_UPPER_REGS_SF \ + | OPTION_MASK_VSX \ + | OPTION_MASK_VSX_SMALL_INTEGER \ + | OPTION_MASK_VSX_TIMODE) + +#endif + +/* This table occasionally claims that a processor does not support a + particular feature even though it does, but the feature is slower than the + alternative. Thus, it shouldn't be relied on as a complete description of + the processor's support. + + Please keep this list in order, and don't forget to update the documentation + in invoke.texi when adding a new processor or flag. + + Before including this file, define a macro: + + RS6000_CPU (NAME, CPU, FLAGS) + + where the arguments are the fields of struct rs6000_ptt. */ + +RS6000_CPU ("401", PROCESSOR_PPC403, MASK_SOFT_FLOAT) +RS6000_CPU ("403", PROCESSOR_PPC403, MASK_SOFT_FLOAT | MASK_STRICT_ALIGN) +RS6000_CPU ("405", PROCESSOR_PPC405, MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB) +RS6000_CPU ("405fp", PROCESSOR_PPC405, MASK_MULHW | MASK_DLMZB) +RS6000_CPU ("440", PROCESSOR_PPC440, MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB) +RS6000_CPU ("440fp", PROCESSOR_PPC440, MASK_MULHW | MASK_DLMZB) +RS6000_CPU ("464", PROCESSOR_PPC440, MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB) +RS6000_CPU ("464fp", PROCESSOR_PPC440, MASK_MULHW | MASK_DLMZB) +RS6000_CPU ("476", PROCESSOR_PPC476, + MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB + | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB) +RS6000_CPU ("476fp", PROCESSOR_PPC476, + MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND + | MASK_CMPB | MASK_MULHW | MASK_DLMZB) +RS6000_CPU ("505", PROCESSOR_MPCCORE, 0) +RS6000_CPU ("601", PROCESSOR_PPC601, MASK_MULTIPLE | MASK_STRING) +RS6000_CPU ("602", PROCESSOR_PPC603, MASK_PPC_GFXOPT) +RS6000_CPU ("603", PROCESSOR_PPC603, MASK_PPC_GFXOPT) +RS6000_CPU ("603e", PROCESSOR_PPC603, MASK_PPC_GFXOPT) +RS6000_CPU ("604", PROCESSOR_PPC604, MASK_PPC_GFXOPT) +RS6000_CPU ("604e", PROCESSOR_PPC604e, MASK_PPC_GFXOPT) +RS6000_CPU ("620", PROCESSOR_PPC620, MASK_PPC_GFXOPT | MASK_POWERPC64) +RS6000_CPU ("630", PROCESSOR_PPC630, MASK_PPC_GFXOPT | MASK_POWERPC64) +RS6000_CPU ("740", PROCESSOR_PPC750, MASK_PPC_GFXOPT) +RS6000_CPU ("7400", PROCESSOR_PPC7400, POWERPC_7400_MASK) +RS6000_CPU ("7450", PROCESSOR_PPC7450, POWERPC_7400_MASK) +RS6000_CPU ("750", PROCESSOR_PPC750, MASK_PPC_GFXOPT) +RS6000_CPU ("801", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT) +RS6000_CPU ("821", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT) +RS6000_CPU ("823", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT) +RS6000_CPU ("8540", PROCESSOR_PPC8540, MASK_STRICT_ALIGN | MASK_ISEL) +RS6000_CPU ("8548", PROCESSOR_PPC8548, MASK_STRICT_ALIGN | MASK_ISEL) +RS6000_CPU ("a2", PROCESSOR_PPCA2, + MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB | MASK_CMPB + | MASK_NO_UPDATE) +RS6000_CPU ("e300c2", PROCESSOR_PPCE300C2, MASK_SOFT_FLOAT) +RS6000_CPU ("e300c3", PROCESSOR_PPCE300C3, 0) +RS6000_CPU ("e500mc", PROCESSOR_PPCE500MC, MASK_PPC_GFXOPT | MASK_ISEL) +RS6000_CPU ("e500mc64", PROCESSOR_PPCE500MC64, + MASK_POWERPC64 | MASK_PPC_GFXOPT | MASK_ISEL) +RS6000_CPU ("e5500", PROCESSOR_PPCE5500, + MASK_POWERPC64 | MASK_PPC_GFXOPT | MASK_ISEL) +RS6000_CPU ("e6500", PROCESSOR_PPCE6500, POWERPC_7400_MASK | MASK_POWERPC64 + | MASK_MFCRF | MASK_ISEL) +RS6000_CPU ("860", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT) +RS6000_CPU ("970", PROCESSOR_POWER4, + POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64) +RS6000_CPU ("cell", PROCESSOR_CELL, + POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64) +RS6000_CPU ("ec603e", PROCESSOR_PPC603, MASK_SOFT_FLOAT) +RS6000_CPU ("G3", PROCESSOR_PPC750, MASK_PPC_GFXOPT) +RS6000_CPU ("G4", PROCESSOR_PPC7450, POWERPC_7400_MASK) +RS6000_CPU ("G5", PROCESSOR_POWER4, + POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64) +RS6000_CPU ("titan", PROCESSOR_TITAN, MASK_MULHW | MASK_DLMZB) +RS6000_CPU ("power3", PROCESSOR_PPC630, MASK_PPC_GFXOPT | MASK_POWERPC64) +RS6000_CPU ("power4", PROCESSOR_POWER4, MASK_POWERPC64 | MASK_PPC_GPOPT + | MASK_PPC_GFXOPT | MASK_MFCRF) +RS6000_CPU ("power5", PROCESSOR_POWER5, MASK_POWERPC64 | MASK_PPC_GPOPT + | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB) +RS6000_CPU ("power5+", PROCESSOR_POWER5, MASK_POWERPC64 | MASK_PPC_GPOPT + | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND) +RS6000_CPU ("power6", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT + | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND + | MASK_CMPB | MASK_DFP | MASK_RECIP_PRECISION) +RS6000_CPU ("power6x", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT + | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND + | MASK_CMPB | MASK_DFP | MASK_MFPGPR | MASK_RECIP_PRECISION) +RS6000_CPU ("power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */ + POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF + | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD + | MASK_VSX | MASK_RECIP_PRECISION | OPTION_MASK_UPPER_REGS_DF + | OPTION_MASK_UPPER_REGS_DI) +RS6000_CPU ("power8", PROCESSOR_POWER8, MASK_POWERPC64 | ISA_2_7_MASKS_SERVER) +RS6000_CPU ("power9", PROCESSOR_POWER9, MASK_POWERPC64 | ISA_3_0_MASKS_SERVER) +RS6000_CPU ("powerpc", PROCESSOR_POWERPC, 0) +RS6000_CPU ("powerpc64", PROCESSOR_POWERPC64, MASK_PPC_GFXOPT | MASK_POWERPC64) +RS6000_CPU ("powerpc64le", PROCESSOR_POWER8, MASK_POWERPC64 | ISA_2_7_MASKS_SERVER) +RS6000_CPU ("rs64", PROCESSOR_RS64A, MASK_PPC_GFXOPT | MASK_POWERPC64) diff --git a/gcc/config/powerpcspe/powerpcspe-linux.c b/gcc/config/powerpcspe/powerpcspe-linux.c new file mode 100644 index 00000000000..4a8d9fad6ea --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe-linux.c @@ -0,0 +1,36 @@ +/* Functions for Linux on PowerPC. + Copyright (C) 2013-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" + +/* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P. */ + +bool +rs6000_linux_float_exceptions_rounding_supported_p (void) +{ + /* glibc has support for exceptions and rounding modes for software + floating point. */ + if (OPTION_GLIBC) + return true; + else + return TARGET_DF_INSN; +} diff --git a/gcc/config/powerpcspe/powerpcspe-modes.def b/gcc/config/powerpcspe/powerpcspe-modes.def new file mode 100644 index 00000000000..fc66fca7300 --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe-modes.def @@ -0,0 +1,56 @@ +/* Definitions of target machine for GNU compiler, for IBM RS/6000. + Copyright (C) 2002-2017 Free Software Foundation, Inc. + Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +/* IBM 128-bit floating point. IFmode and KFmode use the fractional float + support in order to declare 3 128-bit floating point types. */ +FRACTIONAL_FLOAT_MODE (IF, 106, 16, ibm_extended_format); + +/* Explicit IEEE 128-bit floating point. */ +FRACTIONAL_FLOAT_MODE (KF, 113, 16, ieee_quad_format); + +/* 128-bit floating point. ABI_V4 uses IEEE quad, AIX/Darwin + adjust this in rs6000_option_override_internal. */ +FLOAT_MODE (TF, 16, ieee_quad_format); + +/* 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. */ + +CC_MODE (CCUNS); +CC_MODE (CCFP); +CC_MODE (CCEQ); + +/* Vector modes. */ +VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */ +VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */ +VECTOR_MODES (INT, 32); /* V32QI V16HI V8SI V4DI */ +VECTOR_MODE (INT, DI, 1); +VECTOR_MODE (INT, TI, 1); +VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */ +VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */ +VECTOR_MODES (FLOAT, 32); /* V16HF V8SF V4DF */ + +/* Replacement for TImode that only is allowed in GPRs. We also use PTImode + for quad memory atomic operations to force getting an even/odd register + combination. */ +PARTIAL_INT_MODE (TI, 128, PTI); diff --git a/gcc/config/powerpcspe/powerpcspe-opts.h b/gcc/config/powerpcspe/powerpcspe-opts.h new file mode 100644 index 00000000000..086217a37f7 --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe-opts.h @@ -0,0 +1,168 @@ +/* Definitions of target machine needed for option handling for GNU compiler, + for IBM RS/6000. + Copyright (C) 2010-2017 Free Software Foundation, Inc. + Contributed by Michael Meissner (meissner@linux.vnet.ibm.com) + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +#ifndef RS6000_OPTS_H +#define RS6000_OPTS_H + +/* Processor type. Order must match cpu attribute in MD file. */ +enum processor_type + { + PROCESSOR_PPC601, + PROCESSOR_PPC603, + PROCESSOR_PPC604, + PROCESSOR_PPC604e, + PROCESSOR_PPC620, + PROCESSOR_PPC630, + + PROCESSOR_PPC750, + PROCESSOR_PPC7400, + PROCESSOR_PPC7450, + + PROCESSOR_PPC403, + PROCESSOR_PPC405, + PROCESSOR_PPC440, + PROCESSOR_PPC476, + + PROCESSOR_PPC8540, + PROCESSOR_PPC8548, + PROCESSOR_PPCE300C2, + PROCESSOR_PPCE300C3, + PROCESSOR_PPCE500MC, + PROCESSOR_PPCE500MC64, + PROCESSOR_PPCE5500, + PROCESSOR_PPCE6500, + + PROCESSOR_POWER4, + PROCESSOR_POWER5, + PROCESSOR_POWER6, + PROCESSOR_POWER7, + PROCESSOR_POWER8, + PROCESSOR_POWER9, + + PROCESSOR_RS64A, + PROCESSOR_MPCCORE, + PROCESSOR_CELL, + PROCESSOR_PPCA2, + PROCESSOR_TITAN +}; + + +/* FP processor type. */ +enum fpu_type_t +{ + FPU_NONE, /* No FPU */ + FPU_SF_LITE, /* Limited Single Precision FPU */ + FPU_DF_LITE, /* Limited Double Precision FPU */ + FPU_SF_FULL, /* Full Single Precision FPU */ + FPU_DF_FULL /* Full Double Single Precision FPU */ +}; + + +/* Types of costly dependences. */ +enum rs6000_dependence_cost +{ + max_dep_latency = 1000, + no_dep_costly, + all_deps_costly, + true_store_to_load_dep_costly, + store_to_load_dep_costly +}; + +/* Types of nop insertion schemes in sched target hook sched_finish. */ +enum rs6000_nop_insertion +{ + sched_finish_regroup_exact = 1000, + sched_finish_pad_groups, + sched_finish_none +}; + +/* Dispatch group termination caused by an insn. */ +enum group_termination +{ + current_group, + previous_group +}; + +/* Enumeration to give which calling sequence to use. */ +enum rs6000_abi { + ABI_NONE, + ABI_AIX, /* IBM's AIX, or Linux ELFv1 */ + ABI_ELFv2, /* Linux ELFv2 ABI */ + ABI_V4, /* System V.4/eabi */ + ABI_DARWIN /* Apple's Darwin (OS X kernel) */ +}; + +/* Small data support types. */ +enum rs6000_sdata_type { + SDATA_NONE, /* No small data support. */ + SDATA_DATA, /* Just put data in .sbss/.sdata, don't use relocs. */ + SDATA_SYSV, /* Use r13 to point to .sdata/.sbss. */ + SDATA_EABI /* Use r13 like above, r2 points to .sdata2/.sbss2. */ +}; + +/* Type of traceback to use. */ +enum rs6000_traceback_type { + traceback_default = 0, + traceback_none, + traceback_part, + traceback_full +}; + +/* Code model for 64-bit linux. + small: 16-bit toc offsets. + medium: 32-bit toc offsets, static data and code within 2G of TOC pointer. + large: 32-bit toc offsets, no limit on static data and code. */ +enum rs6000_cmodel { + CMODEL_SMALL, + CMODEL_MEDIUM, + CMODEL_LARGE +}; + +/* Describe which vector unit to use for a given machine mode. The + VECTOR_MEM_* and VECTOR_UNIT_* macros assume that Altivec, VSX, and + P8_VECTOR are contiguous. */ +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_P8_VECTOR, /* Use ISA 2.07 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 */ +}; + +/* Where to get the canary for the stack protector. */ +enum stack_protector_guard { + SSP_TLS, /* per-thread canary in TLS block */ + SSP_GLOBAL /* global canary */ +}; + +/* No enumeration is defined to index the -mcpu= values (entries in + processor_target_table), with the type int being used instead, but + we need to distinguish the special "native" value. */ +#define RS6000_CPU_OPTION_NATIVE -1 + +#endif diff --git a/gcc/config/powerpcspe/powerpcspe-passes.def b/gcc/config/powerpcspe/powerpcspe-passes.def new file mode 100644 index 00000000000..4383554d00e --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe-passes.def @@ -0,0 +1,27 @@ +/* Description of target passes for rs6000 + Copyright (C) 2016-2017 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* + Macros that can be used in this file: + INSERT_PASS_AFTER (PASS, INSTANCE, TGT_PASS) + INSERT_PASS_BEFORE (PASS, INSTANCE, TGT_PASS) + REPLACE_PASS (PASS, INSTANCE, TGT_PASS) + */ + + INSERT_PASS_BEFORE (pass_cse, 1, pass_analyze_swaps); diff --git a/gcc/config/powerpcspe/powerpcspe-protos.h b/gcc/config/powerpcspe/powerpcspe-protos.h new file mode 100644 index 00000000000..0344823db0a --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe-protos.h @@ -0,0 +1,269 @@ +/* Definitions of target machine for GNU compiler, for IBM RS/6000. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#ifndef GCC_RS6000_PROTOS_H +#define GCC_RS6000_PROTOS_H + +/* Declare functions in rs6000.c */ + +#ifdef RTX_CODE + +#ifdef TREE_CODE +extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, int, int, int, + tree, machine_mode); +#endif /* TREE_CODE */ + +extern bool easy_altivec_constant (rtx, machine_mode); +extern bool xxspltib_constant_p (rtx, machine_mode, int *, int *); +extern int vspltis_shifted (rtx); +extern HOST_WIDE_INT const_vector_elt_as_int (rtx, unsigned int); +extern bool macho_lo_sum_memory_operand (rtx, machine_mode); +extern int num_insns_constant (rtx, machine_mode); +extern int num_insns_constant_wide (HOST_WIDE_INT); +extern int small_data_operand (rtx, machine_mode); +extern bool mem_operand_gpr (rtx, machine_mode); +extern bool mem_operand_ds_form (rtx, machine_mode); +extern bool toc_relative_expr_p (const_rtx, bool); +extern bool invalid_e500_subreg (rtx, machine_mode); +extern void validate_condition_mode (enum rtx_code, machine_mode); +extern bool legitimate_constant_pool_address_p (const_rtx, machine_mode, + bool); +extern bool legitimate_indirect_address_p (rtx, int); +extern bool legitimate_indexed_address_p (rtx, int); +extern bool avoiding_indexed_address_p (machine_mode); + +extern rtx rs6000_got_register (rtx); +extern rtx find_addr_reg (rtx); +extern rtx gen_easy_altivec_constant (rtx); +extern const char *output_vec_const_move (rtx *); +extern const char *rs6000_output_move_128bit (rtx *); +extern bool rs6000_move_128bit_ok_p (rtx []); +extern bool rs6000_split_128bit_ok_p (rtx []); +extern void rs6000_expand_float128_convert (rtx, rtx, bool); +extern void rs6000_expand_vector_init (rtx, rtx); +extern void paired_expand_vector_init (rtx, rtx); +extern void rs6000_expand_vector_set (rtx, rtx, int); +extern void rs6000_expand_vector_extract (rtx, rtx, rtx); +extern void rs6000_split_vec_extract_var (rtx, rtx, rtx, rtx, rtx); +extern rtx rs6000_adjust_vec_address (rtx, rtx, rtx, rtx, machine_mode); +extern void rs6000_split_v4si_init (rtx []); +extern bool altivec_expand_vec_perm_const (rtx op[4]); +extern void altivec_expand_vec_perm_le (rtx op[4]); +extern bool rs6000_expand_vec_perm_const (rtx op[4]); +extern void altivec_expand_lvx_be (rtx, rtx, machine_mode, unsigned); +extern void altivec_expand_stvx_be (rtx, rtx, machine_mode, unsigned); +extern void altivec_expand_stvex_be (rtx, rtx, machine_mode, unsigned); +extern void rs6000_expand_extract_even (rtx, rtx, rtx); +extern void rs6000_expand_interleave (rtx, rtx, rtx, bool); +extern void rs6000_scale_v2df (rtx, rtx, int); +extern int expand_block_clear (rtx[]); +extern int expand_block_move (rtx[]); +extern bool expand_block_compare (rtx[]); +extern bool expand_strn_compare (rtx[], int); +extern const char * rs6000_output_load_multiple (rtx[]); +extern bool rs6000_is_valid_mask (rtx, int *, int *, machine_mode); +extern bool rs6000_is_valid_and_mask (rtx, machine_mode); +extern bool rs6000_is_valid_shift_mask (rtx, rtx, machine_mode); +extern bool rs6000_is_valid_insert_mask (rtx, rtx, machine_mode); +extern const char *rs6000_insn_for_and_mask (machine_mode, rtx *, bool); +extern const char *rs6000_insn_for_shift_mask (machine_mode, rtx *, bool); +extern const char *rs6000_insn_for_insert_mask (machine_mode, rtx *, bool); +extern bool rs6000_is_valid_2insn_and (rtx, machine_mode); +extern void rs6000_emit_2insn_and (machine_mode, rtx *, bool, int); +extern int registers_ok_for_quad_peep (rtx, rtx); +extern int mems_ok_for_quad_peep (rtx, rtx); +extern bool gpr_or_gpr_p (rtx, rtx); +extern bool direct_move_p (rtx, rtx); +extern bool quad_address_p (rtx, machine_mode, bool); +extern bool quad_load_store_p (rtx, rtx); +extern bool fusion_gpr_load_p (rtx, rtx, rtx, rtx); +extern void expand_fusion_gpr_load (rtx *); +extern void emit_fusion_addis (rtx, rtx, const char *, const char *); +extern void emit_fusion_load_store (rtx, rtx, rtx, const char *); +extern const char *emit_fusion_gpr_load (rtx, rtx); +extern bool fusion_p9_p (rtx, rtx, rtx, rtx); +extern void expand_fusion_p9_load (rtx *); +extern void expand_fusion_p9_store (rtx *); +extern const char *emit_fusion_p9_load (rtx, rtx, rtx); +extern const char *emit_fusion_p9_store (rtx, rtx, rtx); +extern rtx fusion_wrap_memory_address (rtx); +extern enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, + enum reg_class); +extern enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class, + machine_mode, + rtx); +extern bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, + enum reg_class, + machine_mode); +extern bool (*rs6000_cannot_change_mode_class_ptr) (machine_mode, + machine_mode, + enum reg_class); +extern void rs6000_secondary_reload_inner (rtx, rtx, rtx, bool); +extern void rs6000_secondary_reload_gpr (rtx, rtx, rtx, bool); +extern int paired_emit_vector_cond_expr (rtx, rtx, rtx, + rtx, rtx, rtx); +extern void paired_expand_vector_move (rtx operands[]); + + +extern int ccr_bit (rtx, int); +extern void rs6000_output_function_entry (FILE *, const char *); +extern void print_operand (FILE *, rtx, int); +extern void print_operand_address (FILE *, rtx); +extern enum rtx_code rs6000_reverse_condition (machine_mode, + enum rtx_code); +extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx); +extern void rs6000_emit_sISEL (machine_mode, rtx[]); +extern void rs6000_emit_sCOND (machine_mode, rtx[]); +extern void rs6000_emit_cbranch (machine_mode, rtx[]); +extern char * output_cbranch (rtx, const char *, int, rtx_insn *); +extern char * output_e500_flip_gt_bit (rtx, rtx); +extern const char * output_probe_stack_range (rtx, rtx); +extern bool rs6000_emit_set_const (rtx, rtx); +extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx); +extern int rs6000_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx); +extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx); +extern void rs6000_split_signbit (rtx, rtx); +extern void rs6000_expand_atomic_compare_and_swap (rtx op[]); +extern void rs6000_expand_atomic_exchange (rtx op[]); +extern void rs6000_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx); +extern void rs6000_emit_swdiv (rtx, rtx, rtx, bool); +extern void rs6000_emit_swsqrt (rtx, rtx, bool); +extern void output_toc (FILE *, rtx, int, machine_mode); +extern rtx rs6000_longcall_ref (rtx); +extern void rs6000_fatal_bad_address (rtx); +extern rtx create_TOC_reference (rtx, rtx); +extern void rs6000_split_multireg_move (rtx, rtx); +extern void rs6000_emit_le_vsx_move (rtx, rtx, machine_mode); +extern bool valid_sf_si_move (rtx, rtx, machine_mode); +extern void rs6000_emit_move (rtx, rtx, machine_mode); +extern rtx rs6000_secondary_memory_needed_rtx (machine_mode); +extern machine_mode rs6000_secondary_memory_needed_mode (machine_mode); +extern rtx (*rs6000_legitimize_reload_address_ptr) (rtx, machine_mode, + int, int, int, int *); +extern bool rs6000_legitimate_offset_address_p (machine_mode, rtx, + bool, bool); +extern rtx rs6000_find_base_term (rtx); +extern rtx rs6000_return_addr (int, rtx); +extern void rs6000_output_symbol_ref (FILE*, rtx); +extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int); +extern void rs6000_emit_popcount (rtx, rtx); +extern void rs6000_emit_parity (rtx, rtx); + +extern rtx rs6000_machopic_legitimize_pic_address (rtx, machine_mode, + rtx); +extern rtx rs6000_address_for_fpconvert (rtx); +extern rtx rs6000_address_for_altivec (rtx); +extern rtx rs6000_allocate_stack_temp (machine_mode, bool, bool); +extern int rs6000_loop_align (rtx); +extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool); +#endif /* RTX_CODE */ + +#ifdef TREE_CODE +extern unsigned int rs6000_data_alignment (tree, unsigned int, enum data_align); +extern bool rs6000_special_adjust_field_align_p (tree, unsigned int); +extern unsigned int rs6000_special_round_type_align (tree, unsigned int, + unsigned int); +extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int, + unsigned int); +extern tree altivec_resolve_overloaded_builtin (location_t, tree, void *); +extern rtx rs6000_libcall_value (machine_mode); +extern rtx rs6000_va_arg (tree, tree); +extern int function_ok_for_sibcall (tree); +extern int rs6000_reg_parm_stack_space (tree, bool); +extern void rs6000_asm_weaken_decl (FILE *, tree, const char *, const char *); +extern void rs6000_xcoff_declare_function_name (FILE *, const char *, tree); +extern void rs6000_xcoff_declare_object_name (FILE *, const char *, tree); +extern void rs6000_xcoff_asm_output_aligned_decl_common (FILE *, tree, + const char *, + unsigned HOST_WIDE_INT, + unsigned HOST_WIDE_INT); +extern void rs6000_elf_declare_function_name (FILE *, const char *, tree); +extern bool rs6000_elf_in_small_data_p (const_tree); +#ifdef ARGS_SIZE_RTX +/* expr.h defines ARGS_SIZE_RTX and `enum direction' */ +extern enum direction function_arg_padding (machine_mode, const_tree); +#endif /* ARGS_SIZE_RTX */ + +#endif /* TREE_CODE */ + +extern int direct_return (void); +extern int first_reg_to_save (void); +extern int first_fp_reg_to_save (void); +extern void output_ascii (FILE *, const char *, int); +extern void rs6000_gen_section_name (char **, const char *, const char *); +extern void output_function_profiler (FILE *, int); +extern void output_profile_hook (int); +extern int rs6000_trampoline_size (void); +extern alias_set_type get_TOC_alias_set (void); +extern void rs6000_emit_prologue (void); +extern void rs6000_emit_load_toc_table (int); +extern unsigned int rs6000_dbx_register_number (unsigned int, unsigned int); +extern void rs6000_emit_epilogue (int); +extern void rs6000_expand_split_stack_prologue (void); +extern void rs6000_split_stack_space_check (rtx, rtx); +extern void rs6000_emit_eh_reg_restore (rtx, rtx); +extern const char * output_isel (rtx *); +extern void rs6000_call_aix (rtx, rtx, rtx, rtx); +extern void rs6000_sibcall_aix (rtx, rtx, rtx, rtx); +extern void rs6000_aix_asm_output_dwarf_table_ref (char *); +extern void get_ppc476_thunk_name (char name[32]); +extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins); +extern const char *rs6000_overloaded_builtin_name (enum rs6000_builtins); +extern int rs6000_store_data_bypass_p (rtx_insn *, rtx_insn *); +extern HOST_WIDE_INT rs6000_builtin_mask_calculate (void); +extern void rs6000_asm_output_dwarf_pcrel (FILE *file, int size, + const char *label); +extern void rs6000_asm_output_dwarf_datarel (FILE *file, int size, + const char *label); + +/* Declare functions in rs6000-c.c */ + +extern void rs6000_pragma_longcall (struct cpp_reader *); +extern void rs6000_cpu_cpp_builtins (struct cpp_reader *); +#ifdef TREE_CODE +extern bool rs6000_pragma_target_parse (tree, tree); +#endif +extern void rs6000_target_modify_macros (bool, HOST_WIDE_INT, HOST_WIDE_INT); +extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, + HOST_WIDE_INT); + +#if TARGET_MACHO +char *output_call (rtx_insn *, rtx *, int, int); +#endif + +#ifdef NO_DOLLAR_IN_LABEL +const char * rs6000_xcoff_strip_dollar (const char *); +#endif + +void rs6000_final_prescan_insn (rtx_insn *, rtx *operand, int num_operands); + +extern bool rs6000_hard_regno_mode_ok_p[][FIRST_PSEUDO_REGISTER]; +extern unsigned char rs6000_class_max_nregs[][LIM_REG_CLASSES]; +extern unsigned char rs6000_hard_regno_nregs[][FIRST_PSEUDO_REGISTER]; + +extern bool rs6000_linux_float_exceptions_rounding_supported_p (void); + +/* Pass management. */ +namespace gcc { class context; } +class rtl_opt_pass; + +extern rtl_opt_pass *make_pass_analyze_swaps (gcc::context *); + +#endif /* rs6000-protos.h */ diff --git a/gcc/config/powerpcspe/powerpcspe-tables.opt b/gcc/config/powerpcspe/powerpcspe-tables.opt new file mode 100644 index 00000000000..2ae74f4f400 --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe-tables.opt @@ -0,0 +1,196 @@ +; -*- buffer-read-only: t -*- +; Generated automatically by genopt.sh from powerpcspe-cpus.def. + +; Copyright (C) 2011-2017 Free Software Foundation, Inc. +; +; This file is part of GCC. +; +; GCC is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License as published by the Free +; Software Foundation; either version 3, or (at your option) any later +; version. +; +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY +; WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +; for more details. +; +; You should have received a copy of the GNU General Public License +; along with GCC; see the file COPYING3. If not see +; . + +Enum +Name(rs6000_cpu_opt_value) Type(int) +Known CPUs (for use with the -mcpu= and -mtune= options): + +EnumValue +Enum(rs6000_cpu_opt_value) String(native) Value(RS6000_CPU_OPTION_NATIVE) DriverOnly + +EnumValue +Enum(rs6000_cpu_opt_value) String(401) Value(0) + +EnumValue +Enum(rs6000_cpu_opt_value) String(403) Value(1) + +EnumValue +Enum(rs6000_cpu_opt_value) String(405) Value(2) + +EnumValue +Enum(rs6000_cpu_opt_value) String(405fp) Value(3) + +EnumValue +Enum(rs6000_cpu_opt_value) String(440) Value(4) + +EnumValue +Enum(rs6000_cpu_opt_value) String(440fp) Value(5) + +EnumValue +Enum(rs6000_cpu_opt_value) String(464) Value(6) + +EnumValue +Enum(rs6000_cpu_opt_value) String(464fp) Value(7) + +EnumValue +Enum(rs6000_cpu_opt_value) String(476) Value(8) + +EnumValue +Enum(rs6000_cpu_opt_value) String(476fp) Value(9) + +EnumValue +Enum(rs6000_cpu_opt_value) String(505) Value(10) + +EnumValue +Enum(rs6000_cpu_opt_value) String(601) Value(11) + +EnumValue +Enum(rs6000_cpu_opt_value) String(602) Value(12) + +EnumValue +Enum(rs6000_cpu_opt_value) String(603) Value(13) + +EnumValue +Enum(rs6000_cpu_opt_value) String(603e) Value(14) + +EnumValue +Enum(rs6000_cpu_opt_value) String(604) Value(15) + +EnumValue +Enum(rs6000_cpu_opt_value) String(604e) Value(16) + +EnumValue +Enum(rs6000_cpu_opt_value) String(620) Value(17) + +EnumValue +Enum(rs6000_cpu_opt_value) String(630) Value(18) + +EnumValue +Enum(rs6000_cpu_opt_value) String(740) Value(19) + +EnumValue +Enum(rs6000_cpu_opt_value) String(7400) Value(20) + +EnumValue +Enum(rs6000_cpu_opt_value) String(7450) Value(21) + +EnumValue +Enum(rs6000_cpu_opt_value) String(750) Value(22) + +EnumValue +Enum(rs6000_cpu_opt_value) String(801) Value(23) + +EnumValue +Enum(rs6000_cpu_opt_value) String(821) Value(24) + +EnumValue +Enum(rs6000_cpu_opt_value) String(823) Value(25) + +EnumValue +Enum(rs6000_cpu_opt_value) String(8540) Value(26) + +EnumValue +Enum(rs6000_cpu_opt_value) String(8548) Value(27) + +EnumValue +Enum(rs6000_cpu_opt_value) String(a2) Value(28) + +EnumValue +Enum(rs6000_cpu_opt_value) String(e300c2) Value(29) + +EnumValue +Enum(rs6000_cpu_opt_value) String(e300c3) Value(30) + +EnumValue +Enum(rs6000_cpu_opt_value) String(e500mc) Value(31) + +EnumValue +Enum(rs6000_cpu_opt_value) String(e500mc64) Value(32) + +EnumValue +Enum(rs6000_cpu_opt_value) String(e5500) Value(33) + +EnumValue +Enum(rs6000_cpu_opt_value) String(e6500) Value(34) + +EnumValue +Enum(rs6000_cpu_opt_value) String(860) Value(35) + +EnumValue +Enum(rs6000_cpu_opt_value) String(970) Value(36) + +EnumValue +Enum(rs6000_cpu_opt_value) String(cell) Value(37) + +EnumValue +Enum(rs6000_cpu_opt_value) String(ec603e) Value(38) + +EnumValue +Enum(rs6000_cpu_opt_value) String(G3) Value(39) + +EnumValue +Enum(rs6000_cpu_opt_value) String(G4) Value(40) + +EnumValue +Enum(rs6000_cpu_opt_value) String(G5) Value(41) + +EnumValue +Enum(rs6000_cpu_opt_value) String(titan) Value(42) + +EnumValue +Enum(rs6000_cpu_opt_value) String(power3) Value(43) + +EnumValue +Enum(rs6000_cpu_opt_value) String(power4) Value(44) + +EnumValue +Enum(rs6000_cpu_opt_value) String(power5) Value(45) + +EnumValue +Enum(rs6000_cpu_opt_value) String(power5+) Value(46) + +EnumValue +Enum(rs6000_cpu_opt_value) String(power6) Value(47) + +EnumValue +Enum(rs6000_cpu_opt_value) String(power6x) Value(48) + +EnumValue +Enum(rs6000_cpu_opt_value) String(power7) Value(49) + +EnumValue +Enum(rs6000_cpu_opt_value) String(power8) Value(50) + +EnumValue +Enum(rs6000_cpu_opt_value) String(power9) Value(51) + +EnumValue +Enum(rs6000_cpu_opt_value) String(powerpc) Value(52) + +EnumValue +Enum(rs6000_cpu_opt_value) String(powerpc64) Value(53) + +EnumValue +Enum(rs6000_cpu_opt_value) String(powerpc64le) Value(54) + +EnumValue +Enum(rs6000_cpu_opt_value) String(rs64) Value(55) + diff --git a/gcc/config/powerpcspe/powerpcspe.c b/gcc/config/powerpcspe/powerpcspe.c new file mode 100644 index 00000000000..73d608fd805 --- /dev/null +++ b/gcc/config/powerpcspe/powerpcspe.c @@ -0,0 +1,43668 @@ +/* Subroutines used for code generation on IBM RS/6000. + Copyright (C) 1991-2017 Free Software Foundation, Inc. + Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "rtl.h" +#include "tree.h" +#include "memmodel.h" +#include "gimple.h" +#include "cfghooks.h" +#include "cfgloop.h" +#include "df.h" +#include "tm_p.h" +#include "stringpool.h" +#include "expmed.h" +#include "optabs.h" +#include "regs.h" +#include "ira.h" +#include "recog.h" +#include "cgraph.h" +#include "diagnostic-core.h" +#include "insn-attr.h" +#include "flags.h" +#include "alias.h" +#include "fold-const.h" +#include "stor-layout.h" +#include "calls.h" +#include "print-tree.h" +#include "varasm.h" +#include "explow.h" +#include "expr.h" +#include "output.h" +#include "dbxout.h" +#include "common/common-target.h" +#include "langhooks.h" +#include "reload.h" +#include "sched-int.h" +#include "gimplify.h" +#include "gimple-fold.h" +#include "gimple-iterator.h" +#include "gimple-ssa.h" +#include "gimple-walk.h" +#include "intl.h" +#include "params.h" +#include "tm-constrs.h" +#include "tree-vectorizer.h" +#include "target-globals.h" +#include "builtins.h" +#include "context.h" +#include "tree-pass.h" +#include "except.h" +#if TARGET_XCOFF +#include "xcoffout.h" /* get declarations of xcoff_*_section_name */ +#endif +#if TARGET_MACHO +#include "gstab.h" /* for N_SLINE */ +#endif +#include "case-cfn-macros.h" +#include "ppc-auxv.h" + +/* This file should be included last. */ +#include "target-def.h" + +#ifndef TARGET_NO_PROTOTYPE +#define TARGET_NO_PROTOTYPE 0 +#endif + +#define min(A,B) ((A) < (B) ? (A) : (B)) +#define max(A,B) ((A) > (B) ? (A) : (B)) + +/* Structure used to define the rs6000 stack */ +typedef struct rs6000_stack { + int reload_completed; /* stack info won't change from here on */ + int first_gp_reg_save; /* first callee saved GP register used */ + int first_fp_reg_save; /* first callee saved FP register used */ + int first_altivec_reg_save; /* first callee saved AltiVec register used */ + int lr_save_p; /* true if the link reg needs to be saved */ + int cr_save_p; /* true if the CR reg needs to be saved */ + unsigned int vrsave_mask; /* mask of vec registers to save */ + int push_p; /* true if we need to allocate stack space */ + int calls_p; /* true if the function makes any calls */ + int world_save_p; /* true if we're saving *everything*: + r13-r31, cr, f14-f31, vrsave, v20-v31 */ + enum rs6000_abi abi; /* which ABI to use */ + int gp_save_offset; /* offset to save GP regs from initial SP */ + int fp_save_offset; /* offset to save FP regs from initial SP */ + int altivec_save_offset; /* offset to save AltiVec regs from initial SP */ + 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 varargs_save_offset; /* offset to save the varargs registers */ + int ehrd_offset; /* offset to EH return data */ + int ehcr_offset; /* offset to EH CR field data */ + int reg_size; /* register size (4 or 8) */ + HOST_WIDE_INT vars_size; /* variable save area size */ + int parm_size; /* outgoing parameter size */ + int save_size; /* save area size */ + int fixed_size; /* fixed size of stack frame */ + int gp_size; /* size of saved GP registers */ + int fp_size; /* size of saved FP registers */ + int altivec_size; /* size of saved AltiVec registers */ + int cr_size; /* size to hold CR if not in fixed area */ + int vrsave_size; /* size to hold VRSAVE */ + int altivec_padding_size; /* size of altivec alignment padding */ + int spe_gp_size; /* size of 64-bit GPR save size for SPE */ + int spe_padding_size; + HOST_WIDE_INT total_size; /* total bytes allocated for stack */ + int spe_64bit_regs_used; + int savres_strategy; +} rs6000_stack_t; + +/* A C structure for machine-specific, per-function data. + This is added to the cfun structure. */ +typedef struct GTY(()) machine_function +{ + /* Whether the instruction chain has been scanned already. */ + int spe_insn_chain_scanned_p; + /* Flags if __builtin_return_address (n) with n >= 1 was used. */ + int ra_needs_full_frame; + /* Flags if __builtin_return_address (0) was used. */ + int ra_need_lr; + /* Cache lr_save_p after expansion of builtin_eh_return. */ + int lr_save_state; + /* Whether we need to save the TOC to the reserved stack location in the + function prologue. */ + bool save_toc_in_prologue; + /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4 + varargs save area. */ + HOST_WIDE_INT varargs_save_offset; + /* Temporary stack slot to use for SDmode copies. This slot is + 64-bits wide and is allocated early enough so that the offset + does not overflow the 16-bit load/store offset field. */ + rtx sdmode_stack_slot; + /* Alternative internal arg pointer for -fsplit-stack. */ + rtx split_stack_arg_pointer; + bool split_stack_argp_used; + /* Flag if r2 setup is needed with ELFv2 ABI. */ + bool r2_setup_needed; + /* The number of components we use for separate shrink-wrapping. */ + int n_components; + /* The components already handled by separate shrink-wrapping, which should + not be considered by the prologue and epilogue. */ + bool gpr_is_wrapped_separately[32]; + bool fpr_is_wrapped_separately[32]; + bool lr_is_wrapped_separately; +} machine_function; + +/* Support targetm.vectorize.builtin_mask_for_load. */ +static GTY(()) tree altivec_builtin_mask_for_load; + +/* Set to nonzero once AIX common-mode calls have been defined. */ +static GTY(()) int common_mode_defined; + +/* Label number of label created for -mrelocatable, to call to so we can + get the address of the GOT section */ +static int rs6000_pic_labelno; + +#ifdef USING_ELFOS_H +/* Counter for labels which are to be placed in .fixup. */ +int fixuplabelno = 0; +#endif + +/* Whether to use variant of AIX ABI for PowerPC64 Linux. */ +int dot_symbols; + +/* 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. The type is unsigned since not all things that + include powerpcspe.h also include machmode.h. */ +unsigned rs6000_pmode; + +/* Width in bits of a pointer. */ +unsigned rs6000_pointer_size; + +#ifdef HAVE_AS_GNU_ATTRIBUTE +# ifndef HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE +# define HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE 0 +# endif +/* Flag whether floating point values have been passed/returned. + Note that this doesn't say whether fprs are used, since the + Tag_GNU_Power_ABI_FP .gnu.attributes value this flag controls + should be set for soft-float values passed in gprs and ieee128 + values passed in vsx registers. */ +static bool rs6000_passes_float; +static bool rs6000_passes_long_double; +/* Flag whether vector values have been passed/returned. */ +static bool rs6000_passes_vector; +/* Flag whether small (<= 8 byte) structures have been returned. */ +static bool rs6000_returns_struct; +#endif + +/* Value is TRUE if register/mode pair is acceptable. */ +bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER]; + +/* Maximum number of registers needed for a given register class and mode. */ +unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES]; + +/* How many registers are needed for a given register and mode. */ +unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER]; + +/* Map register number to register class. */ +enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER]; + +static int dbg_cost_ctrl; + +/* Built in types. */ +tree rs6000_builtin_types[RS6000_BTI_MAX]; +tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT]; + +/* Flag to say the TOC is initialized */ +int toc_initialized, need_toc_init; +char toc_label_name[10]; + +/* Cached value of rs6000_variable_issue. This is cached in + rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */ +static short cached_can_issue_more; + +static GTY(()) section *read_only_data_section; +static GTY(()) section *private_data_section; +static GTY(()) section *tls_data_section; +static GTY(()) section *tls_private_data_section; +static GTY(()) section *read_only_private_data_section; +static GTY(()) section *sdata2_section; +static GTY(()) section *toc_section; + +struct builtin_description +{ + const HOST_WIDE_INT mask; + const enum insn_code icode; + const char *const name; + const enum rs6000_builtins code; +}; + +/* Describe the vector unit used for modes. */ +enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES]; +enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES]; + +/* Register classes for various constraints that are based on the target + switches. */ +enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX]; + +/* Describe the alignment of a vector. */ +int rs6000_vector_align[NUM_MACHINE_MODES]; + +/* Map selected modes to types for builtins. */ +static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2]; + +/* What modes to automatically generate reciprocal divide estimate (fre) and + reciprocal sqrt (frsqrte) for. */ +unsigned char rs6000_recip_bits[MAX_MACHINE_MODE]; + +/* Masks to determine which reciprocal esitmate instructions to generate + automatically. */ +enum rs6000_recip_mask { + RECIP_SF_DIV = 0x001, /* Use divide estimate */ + RECIP_DF_DIV = 0x002, + RECIP_V4SF_DIV = 0x004, + RECIP_V2DF_DIV = 0x008, + + RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */ + RECIP_DF_RSQRT = 0x020, + RECIP_V4SF_RSQRT = 0x040, + RECIP_V2DF_RSQRT = 0x080, + + /* Various combination of flags for -mrecip=xxx. */ + RECIP_NONE = 0, + RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV + | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT + | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT), + + RECIP_HIGH_PRECISION = RECIP_ALL, + + /* On low precision machines like the power5, don't enable double precision + reciprocal square root estimate, since it isn't accurate enough. */ + RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT)) +}; + +/* -mrecip options. */ +static struct +{ + const char *string; /* option name */ + unsigned int mask; /* mask bits to set */ +} recip_options[] = { + { "all", RECIP_ALL }, + { "none", RECIP_NONE }, + { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV + | RECIP_V2DF_DIV) }, + { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) }, + { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) }, + { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT + | RECIP_V2DF_RSQRT) }, + { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) }, + { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) }, +}; + +/* Used by __builtin_cpu_is(), mapping from PLATFORM names to values. */ +static const struct +{ + const char *cpu; + unsigned int cpuid; +} cpu_is_info[] = { + { "power9", PPC_PLATFORM_POWER9 }, + { "power8", PPC_PLATFORM_POWER8 }, + { "power7", PPC_PLATFORM_POWER7 }, + { "power6x", PPC_PLATFORM_POWER6X }, + { "power6", PPC_PLATFORM_POWER6 }, + { "power5+", PPC_PLATFORM_POWER5_PLUS }, + { "power5", PPC_PLATFORM_POWER5 }, + { "ppc970", PPC_PLATFORM_PPC970 }, + { "power4", PPC_PLATFORM_POWER4 }, + { "ppca2", PPC_PLATFORM_PPCA2 }, + { "ppc476", PPC_PLATFORM_PPC476 }, + { "ppc464", PPC_PLATFORM_PPC464 }, + { "ppc440", PPC_PLATFORM_PPC440 }, + { "ppc405", PPC_PLATFORM_PPC405 }, + { "ppc-cell-be", PPC_PLATFORM_CELL_BE } +}; + +/* Used by __builtin_cpu_supports(), mapping from HWCAP names to masks. */ +static const struct +{ + const char *hwcap; + int mask; + unsigned int id; +} cpu_supports_info[] = { + /* AT_HWCAP masks. */ + { "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0 }, + { "altivec", PPC_FEATURE_HAS_ALTIVEC, 0 }, + { "arch_2_05", PPC_FEATURE_ARCH_2_05, 0 }, + { "arch_2_06", PPC_FEATURE_ARCH_2_06, 0 }, + { "archpmu", PPC_FEATURE_PERFMON_COMPAT, 0 }, + { "booke", PPC_FEATURE_BOOKE, 0 }, + { "cellbe", PPC_FEATURE_CELL_BE, 0 }, + { "dfp", PPC_FEATURE_HAS_DFP, 0 }, + { "efpdouble", PPC_FEATURE_HAS_EFP_DOUBLE, 0 }, + { "efpsingle", PPC_FEATURE_HAS_EFP_SINGLE, 0 }, + { "fpu", PPC_FEATURE_HAS_FPU, 0 }, + { "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, 0 }, + { "mmu", PPC_FEATURE_HAS_MMU, 0 }, + { "notb", PPC_FEATURE_NO_TB, 0 }, + { "pa6t", PPC_FEATURE_PA6T, 0 }, + { "power4", PPC_FEATURE_POWER4, 0 }, + { "power5", PPC_FEATURE_POWER5, 0 }, + { "power5+", PPC_FEATURE_POWER5_PLUS, 0 }, + { "power6x", PPC_FEATURE_POWER6_EXT, 0 }, + { "ppc32", PPC_FEATURE_32, 0 }, + { "ppc601", PPC_FEATURE_601_INSTR, 0 }, + { "ppc64", PPC_FEATURE_64, 0 }, + { "ppcle", PPC_FEATURE_PPC_LE, 0 }, + { "smt", PPC_FEATURE_SMT, 0 }, + { "spe", PPC_FEATURE_HAS_SPE, 0 }, + { "true_le", PPC_FEATURE_TRUE_LE, 0 }, + { "ucache", PPC_FEATURE_UNIFIED_CACHE, 0 }, + { "vsx", PPC_FEATURE_HAS_VSX, 0 }, + + /* AT_HWCAP2 masks. */ + { "arch_2_07", PPC_FEATURE2_ARCH_2_07, 1 }, + { "dscr", PPC_FEATURE2_HAS_DSCR, 1 }, + { "ebb", PPC_FEATURE2_HAS_EBB, 1 }, + { "htm", PPC_FEATURE2_HAS_HTM, 1 }, + { "htm-nosc", PPC_FEATURE2_HTM_NOSC, 1 }, + { "isel", PPC_FEATURE2_HAS_ISEL, 1 }, + { "tar", PPC_FEATURE2_HAS_TAR, 1 }, + { "vcrypto", PPC_FEATURE2_HAS_VEC_CRYPTO, 1 }, + { "arch_3_00", PPC_FEATURE2_ARCH_3_00, 1 }, + { "ieee128", PPC_FEATURE2_HAS_IEEE128, 1 } +}; + +/* Newer LIBCs explicitly export this symbol to declare that they provide + the AT_PLATFORM and AT_HWCAP/AT_HWCAP2 values in the TCB. We emit a + reference to this symbol whenever we expand a CPU builtin, so that + we never link against an old LIBC. */ +const char *tcb_verification_symbol = "__parse_hwcap_and_convert_at_platform"; + +/* True if we have expanded a CPU builtin. */ +bool cpu_builtin_p; + +/* Pointer to function (in powerpcspe-c.c) that can define or undefine target + macros that have changed. Languages that don't support the preprocessor + don't link in powerpcspe-c.c, so we can't call it directly. */ +void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, HOST_WIDE_INT); + +/* Simplfy register classes into simpler classifications. We assume + GPR_REG_TYPE - FPR_REG_TYPE are ordered so that we can use a simple range + check for standard register classes (gpr/floating/altivec/vsx) and + floating/vector classes (float/altivec/vsx). */ + +enum rs6000_reg_type { + NO_REG_TYPE, + PSEUDO_REG_TYPE, + GPR_REG_TYPE, + VSX_REG_TYPE, + ALTIVEC_REG_TYPE, + FPR_REG_TYPE, + SPR_REG_TYPE, + CR_REG_TYPE, + SPE_ACC_TYPE, + SPEFSCR_REG_TYPE +}; + +/* Map register class to register type. */ +static enum rs6000_reg_type reg_class_to_reg_type[N_REG_CLASSES]; + +/* First/last register type for the 'normal' register types (i.e. general + purpose, floating point, altivec, and VSX registers). */ +#define IS_STD_REG_TYPE(RTYPE) IN_RANGE(RTYPE, GPR_REG_TYPE, FPR_REG_TYPE) + +#define IS_FP_VECT_REG_TYPE(RTYPE) IN_RANGE(RTYPE, VSX_REG_TYPE, FPR_REG_TYPE) + + +/* Register classes we care about in secondary reload or go if legitimate + address. We only need to worry about GPR, FPR, and Altivec registers here, + along an ANY field that is the OR of the 3 register classes. */ + +enum rs6000_reload_reg_type { + RELOAD_REG_GPR, /* General purpose registers. */ + RELOAD_REG_FPR, /* Traditional floating point regs. */ + RELOAD_REG_VMX, /* Altivec (VMX) registers. */ + RELOAD_REG_ANY, /* OR of GPR, FPR, Altivec masks. */ + N_RELOAD_REG +}; + +/* For setting up register classes, loop through the 3 register classes mapping + into real registers, and skip the ANY class, which is just an OR of the + bits. */ +#define FIRST_RELOAD_REG_CLASS RELOAD_REG_GPR +#define LAST_RELOAD_REG_CLASS RELOAD_REG_VMX + +/* Map reload register type to a register in the register class. */ +struct reload_reg_map_type { + const char *name; /* Register class name. */ + int reg; /* Register in the register class. */ +}; + +static const struct reload_reg_map_type reload_reg_map[N_RELOAD_REG] = { + { "Gpr", FIRST_GPR_REGNO }, /* RELOAD_REG_GPR. */ + { "Fpr", FIRST_FPR_REGNO }, /* RELOAD_REG_FPR. */ + { "VMX", FIRST_ALTIVEC_REGNO }, /* RELOAD_REG_VMX. */ + { "Any", -1 }, /* RELOAD_REG_ANY. */ +}; + +/* Mask bits for each register class, indexed per mode. Historically the + compiler has been more restrictive which types can do PRE_MODIFY instead of + PRE_INC and PRE_DEC, so keep track of sepaate bits for these two. */ +typedef unsigned char addr_mask_type; + +#define RELOAD_REG_VALID 0x01 /* Mode valid in register.. */ +#define RELOAD_REG_MULTIPLE 0x02 /* Mode takes multiple registers. */ +#define RELOAD_REG_INDEXED 0x04 /* Reg+reg addressing. */ +#define RELOAD_REG_OFFSET 0x08 /* Reg+offset addressing. */ +#define RELOAD_REG_PRE_INCDEC 0x10 /* PRE_INC/PRE_DEC valid. */ +#define RELOAD_REG_PRE_MODIFY 0x20 /* PRE_MODIFY valid. */ +#define RELOAD_REG_AND_M16 0x40 /* AND -16 addressing. */ +#define RELOAD_REG_QUAD_OFFSET 0x80 /* quad offset is limited. */ + +/* Register type masks based on the type, of valid addressing modes. */ +struct rs6000_reg_addr { + enum insn_code reload_load; /* INSN to reload for loading. */ + enum insn_code reload_store; /* INSN to reload for storing. */ + enum insn_code reload_fpr_gpr; /* INSN to move from FPR to GPR. */ + enum insn_code reload_gpr_vsx; /* INSN to move from GPR to VSX. */ + enum insn_code reload_vsx_gpr; /* INSN to move from VSX to GPR. */ + enum insn_code fusion_gpr_ld; /* INSN for fusing gpr ADDIS/loads. */ + /* INSNs for fusing addi with loads + or stores for each reg. class. */ + enum insn_code fusion_addi_ld[(int)N_RELOAD_REG]; + enum insn_code fusion_addi_st[(int)N_RELOAD_REG]; + /* INSNs for fusing addis with loads + or stores for each reg. class. */ + enum insn_code fusion_addis_ld[(int)N_RELOAD_REG]; + enum insn_code fusion_addis_st[(int)N_RELOAD_REG]; + addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks. */ + bool scalar_in_vmx_p; /* Scalar value can go in VMX. */ + bool fused_toc; /* Mode supports TOC fusion. */ +}; + +static struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES]; + +/* Helper function to say whether a mode supports PRE_INC or PRE_DEC. */ +static inline bool +mode_supports_pre_incdec_p (machine_mode mode) +{ + return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_INCDEC) + != 0); +} + +/* Helper function to say whether a mode supports PRE_MODIFY. */ +static inline bool +mode_supports_pre_modify_p (machine_mode mode) +{ + return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_MODIFY) + != 0); +} + +/* Given that there exists at least one variable that is set (produced) + by OUT_INSN and read (consumed) by IN_INSN, return true iff + IN_INSN represents one or more memory store operations and none of + the variables set by OUT_INSN is used by IN_INSN as the address of a + store operation. If either IN_INSN or OUT_INSN does not represent + a "single" RTL SET expression (as loosely defined by the + implementation of the single_set function) or a PARALLEL with only + SETs, CLOBBERs, and USEs inside, this function returns false. + + This rs6000-specific version of store_data_bypass_p checks for + certain conditions that result in assertion failures (and internal + compiler errors) in the generic store_data_bypass_p function and + returns false rather than calling store_data_bypass_p if one of the + problematic conditions is detected. */ + +int +rs6000_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn) +{ + rtx out_set, in_set; + rtx out_pat, in_pat; + rtx out_exp, in_exp; + int i, j; + + in_set = single_set (in_insn); + if (in_set) + { + if (MEM_P (SET_DEST (in_set))) + { + out_set = single_set (out_insn); + if (!out_set) + { + out_pat = PATTERN (out_insn); + if (GET_CODE (out_pat) == PARALLEL) + { + for (i = 0; i < XVECLEN (out_pat, 0); i++) + { + out_exp = XVECEXP (out_pat, 0, i); + if ((GET_CODE (out_exp) == CLOBBER) + || (GET_CODE (out_exp) == USE)) + continue; + else if (GET_CODE (out_exp) != SET) + return false; + } + } + } + } + } + else + { + in_pat = PATTERN (in_insn); + if (GET_CODE (in_pat) != PARALLEL) + return false; + + for (i = 0; i < XVECLEN (in_pat, 0); i++) + { + in_exp = XVECEXP (in_pat, 0, i); + if ((GET_CODE (in_exp) == CLOBBER) || (GET_CODE (in_exp) == USE)) + continue; + else if (GET_CODE (in_exp) != SET) + return false; + + if (MEM_P (SET_DEST (in_exp))) + { + out_set = single_set (out_insn); + if (!out_set) + { + out_pat = PATTERN (out_insn); + if (GET_CODE (out_pat) != PARALLEL) + return false; + for (j = 0; j < XVECLEN (out_pat, 0); j++) + { + out_exp = XVECEXP (out_pat, 0, j); + if ((GET_CODE (out_exp) == CLOBBER) + || (GET_CODE (out_exp) == USE)) + continue; + else if (GET_CODE (out_exp) != SET) + return false; + } + } + } + } + } + return store_data_bypass_p (out_insn, in_insn); +} + +/* Return true if we have D-form addressing in altivec registers. */ +static inline bool +mode_supports_vmx_dform (machine_mode mode) +{ + return ((reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_OFFSET) != 0); +} + +/* Return true if we have D-form addressing in VSX registers. This addressing + is more limited than normal d-form addressing in that the offset must be + aligned on a 16-byte boundary. */ +static inline bool +mode_supports_vsx_dform_quad (machine_mode mode) +{ + return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_QUAD_OFFSET) + != 0); +} + + +/* Target cpu costs. */ + +struct processor_costs { + const int mulsi; /* cost of SImode multiplication. */ + const int mulsi_const; /* cost of SImode multiplication by constant. */ + const int mulsi_const9; /* cost of SImode mult by short constant. */ + const int muldi; /* cost of DImode multiplication. */ + const int divsi; /* cost of SImode division. */ + const int divdi; /* cost of DImode division. */ + const int fp; /* cost of simple SFmode and DFmode insns. */ + const int dmul; /* cost of DFmode multiplication (and fmadd). */ + const int sdiv; /* cost of SFmode division (fdivs). */ + const int ddiv; /* cost of DFmode division (fdiv). */ + const int cache_line_size; /* cache line size in bytes. */ + const int l1_cache_size; /* size of l1 cache, in kilobytes. */ + const int l2_cache_size; /* size of l2 cache, in kilobytes. */ + const int simultaneous_prefetches; /* number of parallel prefetch + operations. */ + const int sfdf_convert; /* cost of SF->DF conversion. */ +}; + +const struct processor_costs *rs6000_cost; + +/* Processor costs (relative to an add) */ + +/* Instruction size costs on 32bit processors. */ +static const +struct processor_costs size32_cost = { + COSTS_N_INSNS (1), /* mulsi */ + COSTS_N_INSNS (1), /* mulsi_const */ + COSTS_N_INSNS (1), /* mulsi_const9 */ + COSTS_N_INSNS (1), /* muldi */ + COSTS_N_INSNS (1), /* divsi */ + COSTS_N_INSNS (1), /* divdi */ + COSTS_N_INSNS (1), /* fp */ + COSTS_N_INSNS (1), /* dmul */ + COSTS_N_INSNS (1), /* sdiv */ + COSTS_N_INSNS (1), /* ddiv */ + 32, /* cache line size */ + 0, /* l1 cache */ + 0, /* l2 cache */ + 0, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction size costs on 64bit processors. */ +static const +struct processor_costs size64_cost = { + COSTS_N_INSNS (1), /* mulsi */ + COSTS_N_INSNS (1), /* mulsi_const */ + COSTS_N_INSNS (1), /* mulsi_const9 */ + COSTS_N_INSNS (1), /* muldi */ + COSTS_N_INSNS (1), /* divsi */ + COSTS_N_INSNS (1), /* divdi */ + COSTS_N_INSNS (1), /* fp */ + COSTS_N_INSNS (1), /* dmul */ + COSTS_N_INSNS (1), /* sdiv */ + COSTS_N_INSNS (1), /* ddiv */ + 128, /* cache line size */ + 0, /* l1 cache */ + 0, /* l2 cache */ + 0, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on RS64A processors. */ +static const +struct processor_costs rs64a_cost = { + COSTS_N_INSNS (20), /* mulsi */ + COSTS_N_INSNS (12), /* mulsi_const */ + COSTS_N_INSNS (8), /* mulsi_const9 */ + COSTS_N_INSNS (34), /* muldi */ + COSTS_N_INSNS (65), /* divsi */ + COSTS_N_INSNS (67), /* divdi */ + COSTS_N_INSNS (4), /* fp */ + COSTS_N_INSNS (4), /* dmul */ + COSTS_N_INSNS (31), /* sdiv */ + COSTS_N_INSNS (31), /* ddiv */ + 128, /* cache line size */ + 128, /* l1 cache */ + 2048, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on MPCCORE processors. */ +static const +struct processor_costs mpccore_cost = { + COSTS_N_INSNS (2), /* mulsi */ + COSTS_N_INSNS (2), /* mulsi_const */ + COSTS_N_INSNS (2), /* mulsi_const9 */ + COSTS_N_INSNS (2), /* muldi */ + COSTS_N_INSNS (6), /* divsi */ + COSTS_N_INSNS (6), /* divdi */ + COSTS_N_INSNS (4), /* fp */ + COSTS_N_INSNS (5), /* dmul */ + COSTS_N_INSNS (10), /* sdiv */ + COSTS_N_INSNS (17), /* ddiv */ + 32, /* cache line size */ + 4, /* l1 cache */ + 16, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC403 processors. */ +static const +struct processor_costs ppc403_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (33), /* divsi */ + COSTS_N_INSNS (33), /* divdi */ + COSTS_N_INSNS (11), /* fp */ + COSTS_N_INSNS (11), /* dmul */ + COSTS_N_INSNS (11), /* sdiv */ + COSTS_N_INSNS (11), /* ddiv */ + 32, /* cache line size */ + 4, /* l1 cache */ + 16, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC405 processors. */ +static const +struct processor_costs ppc405_cost = { + COSTS_N_INSNS (5), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (3), /* mulsi_const9 */ + COSTS_N_INSNS (5), /* muldi */ + COSTS_N_INSNS (35), /* divsi */ + COSTS_N_INSNS (35), /* divdi */ + COSTS_N_INSNS (11), /* fp */ + COSTS_N_INSNS (11), /* dmul */ + COSTS_N_INSNS (11), /* sdiv */ + COSTS_N_INSNS (11), /* ddiv */ + 32, /* cache line size */ + 16, /* l1 cache */ + 128, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC440 processors. */ +static const +struct processor_costs ppc440_cost = { + COSTS_N_INSNS (3), /* mulsi */ + COSTS_N_INSNS (2), /* mulsi_const */ + COSTS_N_INSNS (2), /* mulsi_const9 */ + COSTS_N_INSNS (3), /* muldi */ + COSTS_N_INSNS (34), /* divsi */ + COSTS_N_INSNS (34), /* divdi */ + COSTS_N_INSNS (5), /* fp */ + COSTS_N_INSNS (5), /* dmul */ + COSTS_N_INSNS (19), /* sdiv */ + COSTS_N_INSNS (33), /* ddiv */ + 32, /* cache line size */ + 32, /* l1 cache */ + 256, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC476 processors. */ +static const +struct processor_costs ppc476_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (11), /* divsi */ + COSTS_N_INSNS (11), /* divdi */ + COSTS_N_INSNS (6), /* fp */ + COSTS_N_INSNS (6), /* dmul */ + COSTS_N_INSNS (19), /* sdiv */ + COSTS_N_INSNS (33), /* ddiv */ + 32, /* l1 cache line size */ + 32, /* l1 cache */ + 512, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC601 processors. */ +static const +struct processor_costs ppc601_cost = { + COSTS_N_INSNS (5), /* mulsi */ + COSTS_N_INSNS (5), /* mulsi_const */ + COSTS_N_INSNS (5), /* mulsi_const9 */ + COSTS_N_INSNS (5), /* muldi */ + COSTS_N_INSNS (36), /* divsi */ + COSTS_N_INSNS (36), /* divdi */ + COSTS_N_INSNS (4), /* fp */ + COSTS_N_INSNS (5), /* dmul */ + COSTS_N_INSNS (17), /* sdiv */ + COSTS_N_INSNS (31), /* ddiv */ + 32, /* cache line size */ + 32, /* l1 cache */ + 256, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC603 processors. */ +static const +struct processor_costs ppc603_cost = { + COSTS_N_INSNS (5), /* mulsi */ + COSTS_N_INSNS (3), /* mulsi_const */ + COSTS_N_INSNS (2), /* mulsi_const9 */ + COSTS_N_INSNS (5), /* muldi */ + COSTS_N_INSNS (37), /* divsi */ + COSTS_N_INSNS (37), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (4), /* dmul */ + COSTS_N_INSNS (18), /* sdiv */ + COSTS_N_INSNS (33), /* ddiv */ + 32, /* cache line size */ + 8, /* l1 cache */ + 64, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC604 processors. */ +static const +struct processor_costs ppc604_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (20), /* divsi */ + COSTS_N_INSNS (20), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (18), /* sdiv */ + COSTS_N_INSNS (32), /* ddiv */ + 32, /* cache line size */ + 16, /* l1 cache */ + 512, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC604e processors. */ +static const +struct processor_costs ppc604e_cost = { + COSTS_N_INSNS (2), /* mulsi */ + COSTS_N_INSNS (2), /* mulsi_const */ + COSTS_N_INSNS (2), /* mulsi_const9 */ + COSTS_N_INSNS (2), /* muldi */ + COSTS_N_INSNS (20), /* divsi */ + COSTS_N_INSNS (20), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (18), /* sdiv */ + COSTS_N_INSNS (32), /* ddiv */ + 32, /* cache line size */ + 32, /* l1 cache */ + 1024, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC620 processors. */ +static const +struct processor_costs ppc620_cost = { + COSTS_N_INSNS (5), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (3), /* mulsi_const9 */ + COSTS_N_INSNS (7), /* muldi */ + COSTS_N_INSNS (21), /* divsi */ + COSTS_N_INSNS (37), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (18), /* sdiv */ + COSTS_N_INSNS (32), /* ddiv */ + 128, /* cache line size */ + 32, /* l1 cache */ + 1024, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC630 processors. */ +static const +struct processor_costs ppc630_cost = { + COSTS_N_INSNS (5), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (3), /* mulsi_const9 */ + COSTS_N_INSNS (7), /* muldi */ + COSTS_N_INSNS (21), /* divsi */ + COSTS_N_INSNS (37), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (17), /* sdiv */ + COSTS_N_INSNS (21), /* ddiv */ + 128, /* cache line size */ + 64, /* l1 cache */ + 1024, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on Cell processor. */ +/* COSTS_N_INSNS (1) ~ one add. */ +static const +struct processor_costs ppccell_cost = { + COSTS_N_INSNS (9/2)+2, /* mulsi */ + COSTS_N_INSNS (6/2), /* mulsi_const */ + COSTS_N_INSNS (6/2), /* mulsi_const9 */ + COSTS_N_INSNS (15/2)+2, /* muldi */ + COSTS_N_INSNS (38/2), /* divsi */ + COSTS_N_INSNS (70/2), /* divdi */ + COSTS_N_INSNS (10/2), /* fp */ + COSTS_N_INSNS (10/2), /* dmul */ + COSTS_N_INSNS (74/2), /* sdiv */ + COSTS_N_INSNS (74/2), /* ddiv */ + 128, /* cache line size */ + 32, /* l1 cache */ + 512, /* l2 cache */ + 6, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC750 and PPC7400 processors. */ +static const +struct processor_costs ppc750_cost = { + COSTS_N_INSNS (5), /* mulsi */ + COSTS_N_INSNS (3), /* mulsi_const */ + COSTS_N_INSNS (2), /* mulsi_const9 */ + COSTS_N_INSNS (5), /* muldi */ + COSTS_N_INSNS (17), /* divsi */ + COSTS_N_INSNS (17), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (17), /* sdiv */ + COSTS_N_INSNS (31), /* ddiv */ + 32, /* cache line size */ + 32, /* l1 cache */ + 512, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC7450 processors. */ +static const +struct processor_costs ppc7450_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (3), /* mulsi_const */ + COSTS_N_INSNS (3), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (23), /* divsi */ + COSTS_N_INSNS (23), /* divdi */ + COSTS_N_INSNS (5), /* fp */ + COSTS_N_INSNS (5), /* dmul */ + COSTS_N_INSNS (21), /* sdiv */ + COSTS_N_INSNS (35), /* ddiv */ + 32, /* cache line size */ + 32, /* l1 cache */ + 1024, /* l2 cache */ + 1, /* streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPC8540 processors. */ +static const +struct processor_costs ppc8540_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (19), /* divsi */ + COSTS_N_INSNS (19), /* divdi */ + COSTS_N_INSNS (4), /* fp */ + COSTS_N_INSNS (4), /* dmul */ + COSTS_N_INSNS (29), /* sdiv */ + COSTS_N_INSNS (29), /* ddiv */ + 32, /* cache line size */ + 32, /* l1 cache */ + 256, /* l2 cache */ + 1, /* prefetch streams /*/ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on E300C2 and E300C3 cores. */ +static const +struct processor_costs ppce300c2c3_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (19), /* divsi */ + COSTS_N_INSNS (19), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (4), /* dmul */ + COSTS_N_INSNS (18), /* sdiv */ + COSTS_N_INSNS (33), /* ddiv */ + 32, + 16, /* l1 cache */ + 16, /* l2 cache */ + 1, /* prefetch streams /*/ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPCE500MC processors. */ +static const +struct processor_costs ppce500mc_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (14), /* divsi */ + COSTS_N_INSNS (14), /* divdi */ + COSTS_N_INSNS (8), /* fp */ + COSTS_N_INSNS (10), /* dmul */ + COSTS_N_INSNS (36), /* sdiv */ + COSTS_N_INSNS (66), /* ddiv */ + 64, /* cache line size */ + 32, /* l1 cache */ + 128, /* l2 cache */ + 1, /* prefetch streams /*/ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPCE500MC64 processors. */ +static const +struct processor_costs ppce500mc64_cost = { + COSTS_N_INSNS (4), /* mulsi */ + COSTS_N_INSNS (4), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (14), /* divsi */ + COSTS_N_INSNS (14), /* divdi */ + COSTS_N_INSNS (4), /* fp */ + COSTS_N_INSNS (10), /* dmul */ + COSTS_N_INSNS (36), /* sdiv */ + COSTS_N_INSNS (66), /* ddiv */ + 64, /* cache line size */ + 32, /* l1 cache */ + 128, /* l2 cache */ + 1, /* prefetch streams /*/ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPCE5500 processors. */ +static const +struct processor_costs ppce5500_cost = { + COSTS_N_INSNS (5), /* mulsi */ + COSTS_N_INSNS (5), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (5), /* muldi */ + COSTS_N_INSNS (14), /* divsi */ + COSTS_N_INSNS (14), /* divdi */ + COSTS_N_INSNS (7), /* fp */ + COSTS_N_INSNS (10), /* dmul */ + COSTS_N_INSNS (36), /* sdiv */ + COSTS_N_INSNS (66), /* ddiv */ + 64, /* cache line size */ + 32, /* l1 cache */ + 128, /* l2 cache */ + 1, /* prefetch streams /*/ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on PPCE6500 processors. */ +static const +struct processor_costs ppce6500_cost = { + COSTS_N_INSNS (5), /* mulsi */ + COSTS_N_INSNS (5), /* mulsi_const */ + COSTS_N_INSNS (4), /* mulsi_const9 */ + COSTS_N_INSNS (5), /* muldi */ + COSTS_N_INSNS (14), /* divsi */ + COSTS_N_INSNS (14), /* divdi */ + COSTS_N_INSNS (7), /* fp */ + COSTS_N_INSNS (10), /* dmul */ + COSTS_N_INSNS (36), /* sdiv */ + COSTS_N_INSNS (66), /* ddiv */ + 64, /* cache line size */ + 32, /* l1 cache */ + 128, /* l2 cache */ + 1, /* prefetch streams /*/ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on AppliedMicro Titan processors. */ +static const +struct processor_costs titan_cost = { + COSTS_N_INSNS (5), /* mulsi */ + COSTS_N_INSNS (5), /* mulsi_const */ + COSTS_N_INSNS (5), /* mulsi_const9 */ + COSTS_N_INSNS (5), /* muldi */ + COSTS_N_INSNS (18), /* divsi */ + COSTS_N_INSNS (18), /* divdi */ + COSTS_N_INSNS (10), /* fp */ + COSTS_N_INSNS (10), /* dmul */ + COSTS_N_INSNS (46), /* sdiv */ + COSTS_N_INSNS (72), /* ddiv */ + 32, /* cache line size */ + 32, /* l1 cache */ + 512, /* l2 cache */ + 1, /* prefetch streams /*/ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on POWER4 and POWER5 processors. */ +static const +struct processor_costs power4_cost = { + COSTS_N_INSNS (3), /* mulsi */ + COSTS_N_INSNS (2), /* mulsi_const */ + COSTS_N_INSNS (2), /* mulsi_const9 */ + COSTS_N_INSNS (4), /* muldi */ + COSTS_N_INSNS (18), /* divsi */ + COSTS_N_INSNS (34), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (17), /* sdiv */ + COSTS_N_INSNS (17), /* ddiv */ + 128, /* cache line size */ + 32, /* l1 cache */ + 1024, /* l2 cache */ + 8, /* prefetch streams /*/ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on POWER6 processors. */ +static const +struct processor_costs power6_cost = { + COSTS_N_INSNS (8), /* mulsi */ + COSTS_N_INSNS (8), /* mulsi_const */ + COSTS_N_INSNS (8), /* mulsi_const9 */ + COSTS_N_INSNS (8), /* muldi */ + COSTS_N_INSNS (22), /* divsi */ + COSTS_N_INSNS (28), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (13), /* sdiv */ + COSTS_N_INSNS (16), /* ddiv */ + 128, /* cache line size */ + 64, /* l1 cache */ + 2048, /* l2 cache */ + 16, /* prefetch streams */ + 0, /* SF->DF convert */ +}; + +/* Instruction costs on POWER7 processors. */ +static const +struct processor_costs power7_cost = { + COSTS_N_INSNS (2), /* mulsi */ + COSTS_N_INSNS (2), /* mulsi_const */ + COSTS_N_INSNS (2), /* mulsi_const9 */ + COSTS_N_INSNS (2), /* muldi */ + COSTS_N_INSNS (18), /* divsi */ + COSTS_N_INSNS (34), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (13), /* sdiv */ + COSTS_N_INSNS (16), /* ddiv */ + 128, /* cache line size */ + 32, /* l1 cache */ + 256, /* l2 cache */ + 12, /* prefetch streams */ + COSTS_N_INSNS (3), /* SF->DF convert */ +}; + +/* Instruction costs on POWER8 processors. */ +static const +struct processor_costs power8_cost = { + COSTS_N_INSNS (3), /* mulsi */ + COSTS_N_INSNS (3), /* mulsi_const */ + COSTS_N_INSNS (3), /* mulsi_const9 */ + COSTS_N_INSNS (3), /* muldi */ + COSTS_N_INSNS (19), /* divsi */ + COSTS_N_INSNS (35), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (14), /* sdiv */ + COSTS_N_INSNS (17), /* ddiv */ + 128, /* cache line size */ + 32, /* l1 cache */ + 256, /* l2 cache */ + 12, /* prefetch streams */ + COSTS_N_INSNS (3), /* SF->DF convert */ +}; + +/* Instruction costs on POWER9 processors. */ +static const +struct processor_costs power9_cost = { + COSTS_N_INSNS (3), /* mulsi */ + COSTS_N_INSNS (3), /* mulsi_const */ + COSTS_N_INSNS (3), /* mulsi_const9 */ + COSTS_N_INSNS (3), /* muldi */ + COSTS_N_INSNS (8), /* divsi */ + COSTS_N_INSNS (12), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (13), /* sdiv */ + COSTS_N_INSNS (18), /* ddiv */ + 128, /* cache line size */ + 32, /* l1 cache */ + 512, /* l2 cache */ + 8, /* prefetch streams */ + COSTS_N_INSNS (3), /* SF->DF convert */ +}; + +/* Instruction costs on POWER A2 processors. */ +static const +struct processor_costs ppca2_cost = { + COSTS_N_INSNS (16), /* mulsi */ + COSTS_N_INSNS (16), /* mulsi_const */ + COSTS_N_INSNS (16), /* mulsi_const9 */ + COSTS_N_INSNS (16), /* muldi */ + COSTS_N_INSNS (22), /* divsi */ + COSTS_N_INSNS (28), /* divdi */ + COSTS_N_INSNS (3), /* fp */ + COSTS_N_INSNS (3), /* dmul */ + COSTS_N_INSNS (59), /* sdiv */ + COSTS_N_INSNS (72), /* ddiv */ + 64, + 16, /* l1 cache */ + 2048, /* l2 cache */ + 16, /* prefetch streams */ + 0, /* SF->DF convert */ +}; + + +/* Table that classifies rs6000 builtin functions (pure, const, etc.). */ +#undef RS6000_BUILTIN_0 +#undef RS6000_BUILTIN_1 +#undef RS6000_BUILTIN_2 +#undef RS6000_BUILTIN_3 +#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 +#undef RS6000_BUILTIN_X + +#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) \ + { NAME, ICODE, MASK, ATTR }, + +struct rs6000_builtin_info_type { + const char *name; + const enum insn_code icode; + const HOST_WIDE_INT mask; + const unsigned attr; +}; + +static const struct rs6000_builtin_info_type rs6000_builtin_info[] = +{ +#include "powerpcspe-builtin.def" +}; + +#undef RS6000_BUILTIN_0 +#undef RS6000_BUILTIN_1 +#undef RS6000_BUILTIN_2 +#undef RS6000_BUILTIN_3 +#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 +#undef RS6000_BUILTIN_X + +/* Support for -mveclibabi= to control which vector library to use. */ +static tree (*rs6000_veclib_handler) (combined_fn, tree, tree); + + +static bool rs6000_debug_legitimate_address_p (machine_mode, rtx, bool); +static bool spe_func_has_64bit_regs_p (void); +static struct machine_function * rs6000_init_machine_status (void); +static int rs6000_ra_ever_killed (void); +static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *); +static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *); +static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *); +static tree rs6000_builtin_vectorized_libmass (combined_fn, tree, tree); +static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT); +static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool); +static bool rs6000_debug_rtx_costs (rtx, machine_mode, int, int, int *, bool); +static int rs6000_debug_address_cost (rtx, machine_mode, addr_space_t, + bool); +static int rs6000_debug_adjust_cost (rtx_insn *, int, rtx_insn *, int, + unsigned int); +static bool is_microcoded_insn (rtx_insn *); +static bool is_nonpipeline_insn (rtx_insn *); +static bool is_cracked_insn (rtx_insn *); +static bool is_load_insn (rtx, rtx *); +static bool is_store_insn (rtx, rtx *); +static bool set_to_load_agen (rtx_insn *,rtx_insn *); +static bool insn_terminates_group_p (rtx_insn *, enum group_termination); +static bool insn_must_be_first_in_group (rtx_insn *); +static bool insn_must_be_last_in_group (rtx_insn *); +static void altivec_init_builtins (void); +static tree builtin_function_type (machine_mode, machine_mode, + machine_mode, machine_mode, + enum rs6000_builtins, const char *name); +static void rs6000_common_init_builtins (void); +static void paired_init_builtins (void); +static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx); +static void spe_init_builtins (void); +static void htm_init_builtins (void); +static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx); +static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx); +static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx); +static rs6000_stack_t *rs6000_stack_info (void); +static void is_altivec_return_reg (rtx, void *); +int easy_vector_constant (rtx, machine_mode); +static rtx rs6000_debug_legitimize_address (rtx, rtx, machine_mode); +static rtx rs6000_legitimize_tls_address (rtx, enum tls_model); +static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, + bool, bool); +#if TARGET_MACHO +static void macho_branch_islands (void); +#endif +static rtx rs6000_legitimize_reload_address (rtx, machine_mode, int, int, + int, int *); +static rtx rs6000_debug_legitimize_reload_address (rtx, machine_mode, int, + int, int, int *); +static bool rs6000_mode_dependent_address (const_rtx); +static bool rs6000_debug_mode_dependent_address (const_rtx); +static enum reg_class rs6000_secondary_reload_class (enum reg_class, + machine_mode, rtx); +static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class, + machine_mode, + rtx); +static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class); +static enum reg_class rs6000_debug_preferred_reload_class (rtx, + enum reg_class); +static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class, + machine_mode); +static bool rs6000_debug_secondary_memory_needed (enum reg_class, + enum reg_class, + machine_mode); +static bool rs6000_cannot_change_mode_class (machine_mode, + machine_mode, + enum reg_class); +static bool rs6000_debug_cannot_change_mode_class (machine_mode, + machine_mode, + enum reg_class); +static bool rs6000_save_toc_in_prologue_p (void); +static rtx rs6000_internal_arg_pointer (void); + +rtx (*rs6000_legitimize_reload_address_ptr) (rtx, machine_mode, int, int, + int, int *) + = rs6000_legitimize_reload_address; + +static bool (*rs6000_mode_dependent_address_ptr) (const_rtx) + = rs6000_mode_dependent_address; + +enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class, + machine_mode, rtx) + = rs6000_secondary_reload_class; + +enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class) + = rs6000_preferred_reload_class; + +bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class, + machine_mode) + = rs6000_secondary_memory_needed; + +bool (*rs6000_cannot_change_mode_class_ptr) (machine_mode, + machine_mode, + enum reg_class) + = rs6000_cannot_change_mode_class; + +const int INSN_NOT_AVAILABLE = -1; + +static void rs6000_print_isa_options (FILE *, int, const char *, + HOST_WIDE_INT); +static void rs6000_print_builtin_options (FILE *, int, const char *, + HOST_WIDE_INT); +static HOST_WIDE_INT rs6000_disable_incompatible_switches (void); + +static enum rs6000_reg_type register_to_reg_type (rtx, bool *); +static bool rs6000_secondary_reload_move (enum rs6000_reg_type, + enum rs6000_reg_type, + machine_mode, + secondary_reload_info *, + bool); +rtl_opt_pass *make_pass_analyze_swaps (gcc::context*); +static bool rs6000_keep_leaf_when_profiled () __attribute__ ((unused)); +static tree rs6000_fold_builtin (tree, int, tree *, bool); + +/* Hash table stuff for keeping track of TOC entries. */ + +struct GTY((for_user)) toc_hash_struct +{ + /* `key' will satisfy CONSTANT_P; in fact, it will satisfy + ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */ + rtx key; + machine_mode key_mode; + int labelno; +}; + +struct toc_hasher : ggc_ptr_hash +{ + static hashval_t hash (toc_hash_struct *); + static bool equal (toc_hash_struct *, toc_hash_struct *); +}; + +static GTY (()) hash_table *toc_hash_table; + +/* Hash table to keep track of the argument types for builtin functions. */ + +struct GTY((for_user)) builtin_hash_struct +{ + tree type; + machine_mode mode[4]; /* return value + 3 arguments. */ + unsigned char uns_p[4]; /* and whether the types are unsigned. */ +}; + +struct builtin_hasher : ggc_ptr_hash +{ + static hashval_t hash (builtin_hash_struct *); + static bool equal (builtin_hash_struct *, builtin_hash_struct *); +}; + +static GTY (()) hash_table *builtin_hash_table; + + +/* Default register names. */ +char rs6000_reg_names[][8] = +{ + "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", "10", "11", "12", "13", "14", "15", + "16", "17", "18", "19", "20", "21", "22", "23", + "24", "25", "26", "27", "28", "29", "30", "31", + "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", "10", "11", "12", "13", "14", "15", + "16", "17", "18", "19", "20", "21", "22", "23", + "24", "25", "26", "27", "28", "29", "30", "31", + "mq", "lr", "ctr","ap", + "0", "1", "2", "3", "4", "5", "6", "7", + "ca", + /* AltiVec registers. */ + "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", "10", "11", "12", "13", "14", "15", + "16", "17", "18", "19", "20", "21", "22", "23", + "24", "25", "26", "27", "28", "29", "30", "31", + "vrsave", "vscr", + /* SPE registers. */ + "spe_acc", "spefscr", + /* Soft frame pointer. */ + "sfp", + /* HTM SPR registers. */ + "tfhar", "tfiar", "texasr", + /* SPE High registers. */ + "0", "1", "2", "3", "4", "5", "6", "7", + "8", "9", "10", "11", "12", "13", "14", "15", + "16", "17", "18", "19", "20", "21", "22", "23", + "24", "25", "26", "27", "28", "29", "30", "31" +}; + +#ifdef TARGET_REGNAMES +static const char alt_reg_names[][8] = +{ + "%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", + "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15", + "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23", + "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31", + "mq", "lr", "ctr", "ap", + "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7", + "ca", + /* AltiVec registers. */ + "%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", "vscr", + /* SPE registers. */ + "spe_acc", "spefscr", + /* Soft frame pointer. */ + "sfp", + /* HTM SPR registers. */ + "tfhar", "tfiar", "texasr", + /* SPE High registers. */ + "%rh0", "%rh1", "%rh2", "%rh3", "%rh4", "%rh5", "%rh6", "%rh7", + "%rh8", "%rh9", "%rh10", "%r11", "%rh12", "%rh13", "%rh14", "%rh15", + "%rh16", "%rh17", "%rh18", "%rh19", "%rh20", "%rh21", "%rh22", "%rh23", + "%rh24", "%rh25", "%rh26", "%rh27", "%rh28", "%rh29", "%rh30", "%rh31" +}; +#endif + +/* Table of valid machine attributes. */ + +static const struct attribute_spec rs6000_attribute_table[] = +{ + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler, + affects_type_identity } */ + { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute, + false }, + { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute, + false }, + { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute, + false }, + { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute, + false }, + { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute, + false }, +#ifdef SUBTARGET_ATTRIBUTE_TABLE + SUBTARGET_ATTRIBUTE_TABLE, +#endif + { NULL, 0, 0, false, false, false, NULL, false } +}; + +#ifndef TARGET_PROFILE_KERNEL +#define TARGET_PROFILE_KERNEL 0 +#endif + +/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */ +#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO)) + +/* Initialize the GCC target structure. */ +#undef TARGET_ATTRIBUTE_TABLE +#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table +#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES +#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes +#undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P +#define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p + +#undef TARGET_ASM_ALIGNED_DI_OP +#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP + +/* Default unaligned ops are only provided for ELF. Find the ops needed + for non-ELF systems. */ +#ifndef OBJECT_FORMAT_ELF +#if TARGET_XCOFF +/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on + 64-bit targets. */ +#undef TARGET_ASM_UNALIGNED_HI_OP +#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2," +#undef TARGET_ASM_UNALIGNED_SI_OP +#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4," +#undef TARGET_ASM_UNALIGNED_DI_OP +#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8," +#else +/* For Darwin. */ +#undef TARGET_ASM_UNALIGNED_HI_OP +#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t" +#undef TARGET_ASM_UNALIGNED_SI_OP +#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t" +#undef TARGET_ASM_UNALIGNED_DI_OP +#define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t" +#undef TARGET_ASM_ALIGNED_DI_OP +#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t" +#endif +#endif + +/* This hook deals with fixups for relocatable code and DI-mode objects + in 64-bit code. */ +#undef TARGET_ASM_INTEGER +#define TARGET_ASM_INTEGER rs6000_assemble_integer + +#if defined (HAVE_GAS_HIDDEN) && !TARGET_MACHO +#undef TARGET_ASM_ASSEMBLE_VISIBILITY +#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility +#endif + +#undef TARGET_SET_UP_BY_PROLOGUE +#define TARGET_SET_UP_BY_PROLOGUE rs6000_set_up_by_prologue + +#undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS +#define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS rs6000_get_separate_components +#undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB +#define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB rs6000_components_for_bb +#undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS +#define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS rs6000_disqualify_components +#undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS +#define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS rs6000_emit_prologue_components +#undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS +#define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS rs6000_emit_epilogue_components +#undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS +#define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS rs6000_set_handled_components + +#undef TARGET_EXTRA_LIVE_ON_ENTRY +#define TARGET_EXTRA_LIVE_ON_ENTRY rs6000_live_on_entry + +#undef TARGET_INTERNAL_ARG_POINTER +#define TARGET_INTERNAL_ARG_POINTER rs6000_internal_arg_pointer + +#undef TARGET_HAVE_TLS +#define TARGET_HAVE_TLS HAVE_AS_TLS + +#undef TARGET_CANNOT_FORCE_CONST_MEM +#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem + +#undef TARGET_DELEGITIMIZE_ADDRESS +#define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address + +#undef TARGET_CONST_NOT_OK_FOR_DEBUG_P +#define TARGET_CONST_NOT_OK_FOR_DEBUG_P rs6000_const_not_ok_for_debug_p + +#undef TARGET_LEGITIMATE_COMBINED_INSN +#define TARGET_LEGITIMATE_COMBINED_INSN rs6000_legitimate_combined_insn + +#undef TARGET_ASM_FUNCTION_PROLOGUE +#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue +#undef TARGET_ASM_FUNCTION_EPILOGUE +#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue + +#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA +#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra + +#undef TARGET_LEGITIMIZE_ADDRESS +#define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address + +#undef TARGET_SCHED_VARIABLE_ISSUE +#define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue + +#undef TARGET_SCHED_ISSUE_RATE +#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate +#undef TARGET_SCHED_ADJUST_COST +#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost +#undef TARGET_SCHED_ADJUST_PRIORITY +#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority +#undef TARGET_SCHED_IS_COSTLY_DEPENDENCE +#define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence +#undef TARGET_SCHED_INIT +#define TARGET_SCHED_INIT rs6000_sched_init +#undef TARGET_SCHED_FINISH +#define TARGET_SCHED_FINISH rs6000_sched_finish +#undef TARGET_SCHED_REORDER +#define TARGET_SCHED_REORDER rs6000_sched_reorder +#undef TARGET_SCHED_REORDER2 +#define TARGET_SCHED_REORDER2 rs6000_sched_reorder2 + +#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD +#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead + +#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD +#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard + +#undef TARGET_SCHED_ALLOC_SCHED_CONTEXT +#define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context +#undef TARGET_SCHED_INIT_SCHED_CONTEXT +#define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context +#undef TARGET_SCHED_SET_SCHED_CONTEXT +#define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context +#undef TARGET_SCHED_FREE_SCHED_CONTEXT +#define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context + +#undef TARGET_SCHED_CAN_SPECULATE_INSN +#define TARGET_SCHED_CAN_SPECULATE_INSN rs6000_sched_can_speculate_insn + +#undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD +#define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load +#undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT +#define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \ + rs6000_builtin_support_vector_misalignment +#undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE +#define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable +#undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST +#define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \ + rs6000_builtin_vectorization_cost +#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE +#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \ + rs6000_preferred_simd_mode +#undef TARGET_VECTORIZE_INIT_COST +#define TARGET_VECTORIZE_INIT_COST rs6000_init_cost +#undef TARGET_VECTORIZE_ADD_STMT_COST +#define TARGET_VECTORIZE_ADD_STMT_COST rs6000_add_stmt_cost +#undef TARGET_VECTORIZE_FINISH_COST +#define TARGET_VECTORIZE_FINISH_COST rs6000_finish_cost +#undef TARGET_VECTORIZE_DESTROY_COST_DATA +#define TARGET_VECTORIZE_DESTROY_COST_DATA rs6000_destroy_cost_data + +#undef TARGET_INIT_BUILTINS +#define TARGET_INIT_BUILTINS rs6000_init_builtins +#undef TARGET_BUILTIN_DECL +#define TARGET_BUILTIN_DECL rs6000_builtin_decl + +#undef TARGET_FOLD_BUILTIN +#define TARGET_FOLD_BUILTIN rs6000_fold_builtin +#undef TARGET_GIMPLE_FOLD_BUILTIN +#define TARGET_GIMPLE_FOLD_BUILTIN rs6000_gimple_fold_builtin + +#undef TARGET_EXPAND_BUILTIN +#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin + +#undef TARGET_MANGLE_TYPE +#define TARGET_MANGLE_TYPE rs6000_mangle_type + +#undef TARGET_INIT_LIBFUNCS +#define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs + +#if TARGET_MACHO +#undef TARGET_BINDS_LOCAL_P +#define TARGET_BINDS_LOCAL_P darwin_binds_local_p +#endif + +#undef TARGET_MS_BITFIELD_LAYOUT_P +#define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p + +#undef TARGET_ASM_OUTPUT_MI_THUNK +#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk + +#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK +#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true + +#undef TARGET_FUNCTION_OK_FOR_SIBCALL +#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall + +#undef TARGET_REGISTER_MOVE_COST +#define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost +#undef TARGET_MEMORY_MOVE_COST +#define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost +#undef TARGET_CANNOT_COPY_INSN_P +#define TARGET_CANNOT_COPY_INSN_P rs6000_cannot_copy_insn_p +#undef TARGET_RTX_COSTS +#define TARGET_RTX_COSTS rs6000_rtx_costs +#undef TARGET_ADDRESS_COST +#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0 + +#undef TARGET_DWARF_REGISTER_SPAN +#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span + +#undef TARGET_INIT_DWARF_REG_SIZES_EXTRA +#define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra + +#undef TARGET_MEMBER_TYPE_FORCES_BLK +#define TARGET_MEMBER_TYPE_FORCES_BLK rs6000_member_type_forces_blk + +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE rs6000_promote_function_mode + +#undef TARGET_RETURN_IN_MEMORY +#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory + +#undef TARGET_RETURN_IN_MSB +#define TARGET_RETURN_IN_MSB rs6000_return_in_msb + +#undef TARGET_SETUP_INCOMING_VARARGS +#define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs + +/* Always strict argument naming on rs6000. */ +#undef TARGET_STRICT_ARGUMENT_NAMING +#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true +#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED +#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true +#undef TARGET_SPLIT_COMPLEX_ARG +#define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true +#undef TARGET_MUST_PASS_IN_STACK +#define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack +#undef TARGET_PASS_BY_REFERENCE +#define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference +#undef TARGET_ARG_PARTIAL_BYTES +#define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes +#undef TARGET_FUNCTION_ARG_ADVANCE +#define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance +#undef TARGET_FUNCTION_ARG +#define TARGET_FUNCTION_ARG rs6000_function_arg +#undef TARGET_FUNCTION_ARG_BOUNDARY +#define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary + +#undef TARGET_BUILD_BUILTIN_VA_LIST +#define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list + +#undef TARGET_EXPAND_BUILTIN_VA_START +#define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start + +#undef TARGET_GIMPLIFY_VA_ARG_EXPR +#define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg + +#undef TARGET_EH_RETURN_FILTER_MODE +#define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode + +#undef TARGET_SCALAR_MODE_SUPPORTED_P +#define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p + +#undef TARGET_VECTOR_MODE_SUPPORTED_P +#define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p + +#undef TARGET_FLOATN_MODE +#define TARGET_FLOATN_MODE rs6000_floatn_mode + +#undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN +#define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn + +#undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP +#define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip + +#undef TARGET_MD_ASM_ADJUST +#define TARGET_MD_ASM_ADJUST rs6000_md_asm_adjust + +#undef TARGET_OPTION_OVERRIDE +#define TARGET_OPTION_OVERRIDE rs6000_option_override + +#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION +#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \ + rs6000_builtin_vectorized_function + +#undef TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION +#define TARGET_VECTORIZE_BUILTIN_MD_VECTORIZED_FUNCTION \ + rs6000_builtin_md_vectorized_function + +#undef TARGET_STACK_PROTECT_GUARD +#define TARGET_STACK_PROTECT_GUARD rs6000_init_stack_protect_guard + +#if !TARGET_MACHO +#undef TARGET_STACK_PROTECT_FAIL +#define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail +#endif + +#ifdef HAVE_AS_TLS +#undef TARGET_ASM_OUTPUT_DWARF_DTPREL +#define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel +#endif + +/* Use a 32-bit anchor range. This leads to sequences like: + + addis tmp,anchor,high + add dest,tmp,low + + where tmp itself acts as an anchor, and can be shared between + accesses to the same 64k page. */ +#undef TARGET_MIN_ANCHOR_OFFSET +#define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1 +#undef TARGET_MAX_ANCHOR_OFFSET +#define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff +#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P +#define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p +#undef TARGET_USE_BLOCKS_FOR_DECL_P +#define TARGET_USE_BLOCKS_FOR_DECL_P rs6000_use_blocks_for_decl_p + +#undef TARGET_BUILTIN_RECIPROCAL +#define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal + +#undef TARGET_EXPAND_TO_RTL_HOOK +#define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot + +#undef TARGET_INSTANTIATE_DECLS +#define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls + +#undef TARGET_SECONDARY_RELOAD +#define TARGET_SECONDARY_RELOAD rs6000_secondary_reload + +#undef TARGET_LEGITIMATE_ADDRESS_P +#define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p + +#undef TARGET_MODE_DEPENDENT_ADDRESS_P +#define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p + +#undef TARGET_LRA_P +#define TARGET_LRA_P rs6000_lra_p + +#undef TARGET_COMPUTE_PRESSURE_CLASSES +#define TARGET_COMPUTE_PRESSURE_CLASSES rs6000_compute_pressure_classes + +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE rs6000_can_eliminate + +#undef TARGET_CONDITIONAL_REGISTER_USAGE +#define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage + +#undef TARGET_SCHED_REASSOCIATION_WIDTH +#define TARGET_SCHED_REASSOCIATION_WIDTH rs6000_reassociation_width + +#undef TARGET_TRAMPOLINE_INIT +#define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init + +#undef TARGET_FUNCTION_VALUE +#define TARGET_FUNCTION_VALUE rs6000_function_value + +#undef TARGET_OPTION_VALID_ATTRIBUTE_P +#define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p + +#undef TARGET_OPTION_SAVE +#define TARGET_OPTION_SAVE rs6000_function_specific_save + +#undef TARGET_OPTION_RESTORE +#define TARGET_OPTION_RESTORE rs6000_function_specific_restore + +#undef TARGET_OPTION_PRINT +#define TARGET_OPTION_PRINT rs6000_function_specific_print + +#undef TARGET_CAN_INLINE_P +#define TARGET_CAN_INLINE_P rs6000_can_inline_p + +#undef TARGET_SET_CURRENT_FUNCTION +#define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function + +#undef TARGET_LEGITIMATE_CONSTANT_P +#define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p + +#undef TARGET_VECTORIZE_VEC_PERM_CONST_OK +#define TARGET_VECTORIZE_VEC_PERM_CONST_OK rs6000_vectorize_vec_perm_const_ok + +#undef TARGET_CAN_USE_DOLOOP_P +#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost + +#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV +#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV rs6000_atomic_assign_expand_fenv + +#undef TARGET_LIBGCC_CMP_RETURN_MODE +#define TARGET_LIBGCC_CMP_RETURN_MODE rs6000_abi_word_mode +#undef TARGET_LIBGCC_SHIFT_COUNT_MODE +#define TARGET_LIBGCC_SHIFT_COUNT_MODE rs6000_abi_word_mode +#undef TARGET_UNWIND_WORD_MODE +#define TARGET_UNWIND_WORD_MODE rs6000_abi_word_mode + +#undef TARGET_OFFLOAD_OPTIONS +#define TARGET_OFFLOAD_OPTIONS rs6000_offload_options + +#undef TARGET_C_MODE_FOR_SUFFIX +#define TARGET_C_MODE_FOR_SUFFIX rs6000_c_mode_for_suffix + +#undef TARGET_INVALID_BINARY_OP +#define TARGET_INVALID_BINARY_OP rs6000_invalid_binary_op + +#undef TARGET_OPTAB_SUPPORTED_P +#define TARGET_OPTAB_SUPPORTED_P rs6000_optab_supported_p + +#undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS +#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1 + + +/* Processor table. */ +struct rs6000_ptt +{ + const char *const name; /* Canonical processor name. */ + const enum processor_type processor; /* Processor type enum value. */ + const HOST_WIDE_INT target_enable; /* Target flags to enable. */ +}; + +static struct rs6000_ptt const processor_target_table[] = +{ +#define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS }, +#include "powerpcspe-cpus.def" +#undef RS6000_CPU +}; + +/* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the + name is invalid. */ + +static int +rs6000_cpu_name_lookup (const char *name) +{ + size_t i; + + if (name != NULL) + { + for (i = 0; i < ARRAY_SIZE (processor_target_table); i++) + if (! strcmp (name, processor_target_table[i].name)) + return (int)i; + } + + return -1; +} + + +/* Return number of consecutive hard regs needed starting at reg REGNO + to hold something of mode MODE. + 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. */ + +static int +rs6000_hard_regno_nregs_internal (int regno, machine_mode mode) +{ + unsigned HOST_WIDE_INT reg_size; + + /* 128-bit floating point usually takes 2 registers, unless it is IEEE + 128-bit floating point that can go in vector registers, which has VSX + memory addressing. */ + if (FP_REGNO_P (regno)) + reg_size = (VECTOR_MEM_VSX_P (mode) || FLOAT128_VECTOR_P (mode) + ? UNITS_PER_VSX_WORD + : UNITS_PER_FP_WORD); + + else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) + reg_size = UNITS_PER_SPE_WORD; + + else if (ALTIVEC_REGNO_P (regno)) + reg_size = UNITS_PER_ALTIVEC_WORD; + + /* The value returned for SCmode in the E500 double case is 2 for + ABI compatibility; storing an SCmode value in a single register + would require function_arg and rs6000_spe_function_arg to handle + SCmode so as to pass the value correctly in a pair of + registers. */ + else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode + && !DECIMAL_FLOAT_MODE_P (mode) && SPE_SIMD_REGNO_P (regno)) + reg_size = UNITS_PER_FP_WORD; + + else + reg_size = UNITS_PER_WORD; + + return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size; +} + +/* Value is 1 if hard register REGNO can hold a value of machine-mode + MODE. */ +static int +rs6000_hard_regno_mode_ok (int regno, machine_mode mode) +{ + int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1; + + if (COMPLEX_MODE_P (mode)) + mode = GET_MODE_INNER (mode); + + /* PTImode can only go in GPRs. Quad word memory operations require even/odd + register combinations, and use PTImode where we need to deal with quad + word memory operations. Don't allow quad words in the argument or frame + pointer registers, just registers 0..31. */ + if (mode == PTImode) + return (IN_RANGE (regno, FIRST_GPR_REGNO, LAST_GPR_REGNO) + && IN_RANGE (last_regno, FIRST_GPR_REGNO, LAST_GPR_REGNO) + && ((regno & 1) == 0)); + + /* VSX registers that overlap the FPR registers are larger than for non-VSX + implementations. Don't allow an item to be split between a FP register + and an Altivec register. Allow TImode in all VSX registers if the user + asked for it. */ + if (TARGET_VSX && VSX_REGNO_P (regno) + && (VECTOR_MEM_VSX_P (mode) + || FLOAT128_VECTOR_P (mode) + || reg_addr[mode].scalar_in_vmx_p + || (TARGET_VSX_TIMODE && mode == TImode) + || (TARGET_VADDUQM && mode == V1TImode))) + { + if (FP_REGNO_P (regno)) + return FP_REGNO_P (last_regno); + + if (ALTIVEC_REGNO_P (regno)) + { + if (GET_MODE_SIZE (mode) != 16 && !reg_addr[mode].scalar_in_vmx_p) + return 0; + + return ALTIVEC_REGNO_P (last_regno); + } + } + + /* The GPRs can hold any mode, but values bigger than one register + cannot go past R31. */ + if (INT_REGNO_P (regno)) + return INT_REGNO_P (last_regno); + + /* The float registers (except for VSX vector modes) can only hold floating + modes and DImode. */ + if (FP_REGNO_P (regno)) + { + if (FLOAT128_VECTOR_P (mode)) + return false; + + if (SCALAR_FLOAT_MODE_P (mode) + && (mode != TDmode || (regno % 2) == 0) + && FP_REGNO_P (last_regno)) + return 1; + + if (GET_MODE_CLASS (mode) == MODE_INT) + { + if(GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD) + return 1; + + if (TARGET_VSX_SMALL_INTEGER) + { + if (mode == SImode) + return 1; + + if (TARGET_P9_VECTOR && (mode == HImode || mode == QImode)) + return 1; + } + } + + if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT + && PAIRED_VECTOR_MODE (mode)) + return 1; + + return 0; + } + + /* The CR register can only hold CC modes. */ + if (CR_REGNO_P (regno)) + return GET_MODE_CLASS (mode) == MODE_CC; + + if (CA_REGNO_P (regno)) + return mode == Pmode || mode == SImode; + + /* AltiVec only in AldyVec registers. */ + if (ALTIVEC_REGNO_P (regno)) + return (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) + || mode == V1TImode); + + /* ...but GPRs can hold SIMD data on the SPE in one register. */ + if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode)) + return 1; + + /* We cannot put non-VSX TImode or PTImode anywhere except general register + and it must be able to fit within the register set. */ + + return GET_MODE_SIZE (mode) <= UNITS_PER_WORD; +} + +/* Print interesting facts about registers. */ +static void +rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name) +{ + int r, m; + + for (r = first_regno; r <= last_regno; ++r) + { + const char *comma = ""; + int len; + + if (first_regno == last_regno) + fprintf (stderr, "%s:\t", reg_name); + else + fprintf (stderr, "%s%d:\t", reg_name, r - first_regno); + + len = 8; + for (m = 0; m < NUM_MACHINE_MODES; ++m) + if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r]) + { + if (len > 70) + { + fprintf (stderr, ",\n\t"); + len = 8; + comma = ""; + } + + if (rs6000_hard_regno_nregs[m][r] > 1) + len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m), + rs6000_hard_regno_nregs[m][r]); + else + len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m)); + + comma = ", "; + } + + if (call_used_regs[r]) + { + if (len > 70) + { + fprintf (stderr, ",\n\t"); + len = 8; + comma = ""; + } + + len += fprintf (stderr, "%s%s", comma, "call-used"); + comma = ", "; + } + + if (fixed_regs[r]) + { + if (len > 70) + { + fprintf (stderr, ",\n\t"); + len = 8; + comma = ""; + } + + len += fprintf (stderr, "%s%s", comma, "fixed"); + comma = ", "; + } + + if (len > 70) + { + fprintf (stderr, ",\n\t"); + comma = ""; + } + + len += fprintf (stderr, "%sreg-class = %s", comma, + reg_class_names[(int)rs6000_regno_regclass[r]]); + comma = ", "; + + if (len > 70) + { + fprintf (stderr, ",\n\t"); + comma = ""; + } + + fprintf (stderr, "%sregno = %d\n", comma, r); + } +} + +static const char * +rs6000_debug_vector_unit (enum rs6000_vector v) +{ + const char *ret; + + switch (v) + { + case VECTOR_NONE: ret = "none"; break; + case VECTOR_ALTIVEC: ret = "altivec"; break; + case VECTOR_VSX: ret = "vsx"; break; + case VECTOR_P8_VECTOR: ret = "p8_vector"; break; + case VECTOR_PAIRED: ret = "paired"; break; + case VECTOR_SPE: ret = "spe"; break; + case VECTOR_OTHER: ret = "other"; break; + default: ret = "unknown"; break; + } + + return ret; +} + +/* Inner function printing just the address mask for a particular reload + register class. */ +DEBUG_FUNCTION char * +rs6000_debug_addr_mask (addr_mask_type mask, bool keep_spaces) +{ + static char ret[8]; + char *p = ret; + + if ((mask & RELOAD_REG_VALID) != 0) + *p++ = 'v'; + else if (keep_spaces) + *p++ = ' '; + + if ((mask & RELOAD_REG_MULTIPLE) != 0) + *p++ = 'm'; + else if (keep_spaces) + *p++ = ' '; + + if ((mask & RELOAD_REG_INDEXED) != 0) + *p++ = 'i'; + else if (keep_spaces) + *p++ = ' '; + + if ((mask & RELOAD_REG_QUAD_OFFSET) != 0) + *p++ = 'O'; + else if ((mask & RELOAD_REG_OFFSET) != 0) + *p++ = 'o'; + else if (keep_spaces) + *p++ = ' '; + + if ((mask & RELOAD_REG_PRE_INCDEC) != 0) + *p++ = '+'; + else if (keep_spaces) + *p++ = ' '; + + if ((mask & RELOAD_REG_PRE_MODIFY) != 0) + *p++ = '+'; + else if (keep_spaces) + *p++ = ' '; + + if ((mask & RELOAD_REG_AND_M16) != 0) + *p++ = '&'; + else if (keep_spaces) + *p++ = ' '; + + *p = '\0'; + + return ret; +} + +/* Print the address masks in a human readble fashion. */ +DEBUG_FUNCTION void +rs6000_debug_print_mode (ssize_t m) +{ + ssize_t rc; + int spaces = 0; + bool fuse_extra_p; + + fprintf (stderr, "Mode: %-5s", GET_MODE_NAME (m)); + for (rc = 0; rc < N_RELOAD_REG; rc++) + fprintf (stderr, " %s: %s", reload_reg_map[rc].name, + rs6000_debug_addr_mask (reg_addr[m].addr_mask[rc], true)); + + if ((reg_addr[m].reload_store != CODE_FOR_nothing) + || (reg_addr[m].reload_load != CODE_FOR_nothing)) + fprintf (stderr, " Reload=%c%c", + (reg_addr[m].reload_store != CODE_FOR_nothing) ? 's' : '*', + (reg_addr[m].reload_load != CODE_FOR_nothing) ? 'l' : '*'); + else + spaces += sizeof (" Reload=sl") - 1; + + if (reg_addr[m].scalar_in_vmx_p) + { + fprintf (stderr, "%*s Upper=y", spaces, ""); + spaces = 0; + } + else + spaces += sizeof (" Upper=y") - 1; + + fuse_extra_p = ((reg_addr[m].fusion_gpr_ld != CODE_FOR_nothing) + || reg_addr[m].fused_toc); + if (!fuse_extra_p) + { + for (rc = 0; rc < N_RELOAD_REG; rc++) + { + if (rc != RELOAD_REG_ANY) + { + if (reg_addr[m].fusion_addi_ld[rc] != CODE_FOR_nothing + || reg_addr[m].fusion_addi_ld[rc] != CODE_FOR_nothing + || reg_addr[m].fusion_addi_st[rc] != CODE_FOR_nothing + || reg_addr[m].fusion_addis_ld[rc] != CODE_FOR_nothing + || reg_addr[m].fusion_addis_st[rc] != CODE_FOR_nothing) + { + fuse_extra_p = true; + break; + } + } + } + } + + if (fuse_extra_p) + { + fprintf (stderr, "%*s Fuse:", spaces, ""); + spaces = 0; + + for (rc = 0; rc < N_RELOAD_REG; rc++) + { + if (rc != RELOAD_REG_ANY) + { + char load, store; + + if (reg_addr[m].fusion_addis_ld[rc] != CODE_FOR_nothing) + load = 'l'; + else if (reg_addr[m].fusion_addi_ld[rc] != CODE_FOR_nothing) + load = 'L'; + else + load = '-'; + + if (reg_addr[m].fusion_addis_st[rc] != CODE_FOR_nothing) + store = 's'; + else if (reg_addr[m].fusion_addi_st[rc] != CODE_FOR_nothing) + store = 'S'; + else + store = '-'; + + if (load == '-' && store == '-') + spaces += 5; + else + { + fprintf (stderr, "%*s%c=%c%c", (spaces + 1), "", + reload_reg_map[rc].name[0], load, store); + spaces = 0; + } + } + } + + if (reg_addr[m].fusion_gpr_ld != CODE_FOR_nothing) + { + fprintf (stderr, "%*sP8gpr", (spaces + 1), ""); + spaces = 0; + } + else + spaces += sizeof (" P8gpr") - 1; + + if (reg_addr[m].fused_toc) + { + fprintf (stderr, "%*sToc", (spaces + 1), ""); + spaces = 0; + } + else + spaces += sizeof (" Toc") - 1; + } + else + spaces += sizeof (" Fuse: G=ls F=ls v=ls P8gpr Toc") - 1; + + if (rs6000_vector_unit[m] != VECTOR_NONE + || rs6000_vector_mem[m] != VECTOR_NONE) + { + fprintf (stderr, "%*s vector: arith=%-10s mem=%s", + spaces, "", + rs6000_debug_vector_unit (rs6000_vector_unit[m]), + rs6000_debug_vector_unit (rs6000_vector_mem[m])); + } + + fputs ("\n", stderr); +} + +#define DEBUG_FMT_ID "%-32s= " +#define DEBUG_FMT_D DEBUG_FMT_ID "%d\n" +#define DEBUG_FMT_WX DEBUG_FMT_ID "%#.12" HOST_WIDE_INT_PRINT "x: " +#define DEBUG_FMT_S DEBUG_FMT_ID "%s\n" + +/* Print various interesting information with -mdebug=reg. */ +static void +rs6000_debug_reg_global (void) +{ + static const char *const tf[2] = { "false", "true" }; + const char *nl = (const char *)0; + int m; + size_t m1, m2, v; + char costly_num[20]; + char nop_num[20]; + char flags_buffer[40]; + const char *costly_str; + const char *nop_str; + const char *trace_str; + const char *abi_str; + const char *cmodel_str; + struct cl_target_option cl_opts; + + /* Modes we want tieable information on. */ + static const machine_mode print_tieable_modes[] = { + QImode, + HImode, + SImode, + DImode, + TImode, + PTImode, + SFmode, + DFmode, + TFmode, + IFmode, + KFmode, + SDmode, + DDmode, + TDmode, + V8QImode, + V4HImode, + V2SImode, + V16QImode, + V8HImode, + V4SImode, + V2DImode, + V1TImode, + V32QImode, + V16HImode, + V8SImode, + V4DImode, + V2TImode, + V2SFmode, + V4SFmode, + V2DFmode, + V8SFmode, + V4DFmode, + CCmode, + CCUNSmode, + CCEQmode, + }; + + /* Virtual regs we are interested in. */ + const static struct { + int regno; /* register number. */ + const char *name; /* register name. */ + } virtual_regs[] = { + { STACK_POINTER_REGNUM, "stack pointer:" }, + { TOC_REGNUM, "toc: " }, + { STATIC_CHAIN_REGNUM, "static chain: " }, + { RS6000_PIC_OFFSET_TABLE_REGNUM, "pic offset: " }, + { HARD_FRAME_POINTER_REGNUM, "hard frame: " }, + { ARG_POINTER_REGNUM, "arg pointer: " }, + { FRAME_POINTER_REGNUM, "frame pointer:" }, + { FIRST_PSEUDO_REGISTER, "first pseudo: " }, + { FIRST_VIRTUAL_REGISTER, "first virtual:" }, + { VIRTUAL_INCOMING_ARGS_REGNUM, "incoming_args:" }, + { VIRTUAL_STACK_VARS_REGNUM, "stack_vars: " }, + { VIRTUAL_STACK_DYNAMIC_REGNUM, "stack_dynamic:" }, + { VIRTUAL_OUTGOING_ARGS_REGNUM, "outgoing_args:" }, + { VIRTUAL_CFA_REGNUM, "cfa (frame): " }, + { VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM, "stack boundry:" }, + { LAST_VIRTUAL_REGISTER, "last virtual: " }, + }; + + fputs ("\nHard register information:\n", stderr); + rs6000_debug_reg_print (FIRST_GPR_REGNO, LAST_GPR_REGNO, "gr"); + rs6000_debug_reg_print (FIRST_FPR_REGNO, LAST_FPR_REGNO, "fp"); + rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO, + LAST_ALTIVEC_REGNO, + "vs"); + rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr"); + rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr"); + rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr"); + rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca"); + rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave"); + rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr"); + rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a"); + rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f"); + + fputs ("\nVirtual/stack/frame registers:\n", stderr); + for (v = 0; v < ARRAY_SIZE (virtual_regs); v++) + fprintf (stderr, "%s regno = %3d\n", virtual_regs[v].name, virtual_regs[v].regno); + + fprintf (stderr, + "\n" + "d reg_class = %s\n" + "f reg_class = %s\n" + "v reg_class = %s\n" + "wa reg_class = %s\n" + "wb reg_class = %s\n" + "wd reg_class = %s\n" + "we reg_class = %s\n" + "wf reg_class = %s\n" + "wg reg_class = %s\n" + "wh reg_class = %s\n" + "wi reg_class = %s\n" + "wj reg_class = %s\n" + "wk reg_class = %s\n" + "wl reg_class = %s\n" + "wm reg_class = %s\n" + "wo reg_class = %s\n" + "wp reg_class = %s\n" + "wq reg_class = %s\n" + "wr reg_class = %s\n" + "ws reg_class = %s\n" + "wt reg_class = %s\n" + "wu reg_class = %s\n" + "wv reg_class = %s\n" + "ww reg_class = %s\n" + "wx reg_class = %s\n" + "wy reg_class = %s\n" + "wz reg_class = %s\n" + "wA reg_class = %s\n" + "wH reg_class = %s\n" + "wI reg_class = %s\n" + "wJ reg_class = %s\n" + "wK reg_class = %s\n" + "\n", + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wb]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_we]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wg]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wh]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wi]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wj]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wk]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wl]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wm]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wo]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wp]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wq]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wr]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wt]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wu]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wv]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ww]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wx]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wy]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wz]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wA]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wH]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wI]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wJ]], + reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wK]]); + + nl = "\n"; + for (m = 0; m < NUM_MACHINE_MODES; ++m) + rs6000_debug_print_mode (m); + + fputs ("\n", stderr); + + for (m1 = 0; m1 < ARRAY_SIZE (print_tieable_modes); m1++) + { + machine_mode mode1 = print_tieable_modes[m1]; + bool first_time = true; + + nl = (const char *)0; + for (m2 = 0; m2 < ARRAY_SIZE (print_tieable_modes); m2++) + { + machine_mode mode2 = print_tieable_modes[m2]; + if (mode1 != mode2 && MODES_TIEABLE_P (mode1, mode2)) + { + if (first_time) + { + fprintf (stderr, "Tieable modes %s:", GET_MODE_NAME (mode1)); + nl = "\n"; + first_time = false; + } + + fprintf (stderr, " %s", GET_MODE_NAME (mode2)); + } + } + + if (!first_time) + fputs ("\n", stderr); + } + + if (nl) + fputs (nl, stderr); + + if (rs6000_recip_control) + { + fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control); + + for (m = 0; m < NUM_MACHINE_MODES; ++m) + if (rs6000_recip_bits[m]) + { + fprintf (stderr, + "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n", + GET_MODE_NAME (m), + (RS6000_RECIP_AUTO_RE_P (m) + ? "auto" + : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")), + (RS6000_RECIP_AUTO_RSQRTE_P (m) + ? "auto" + : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none"))); + } + + fputs ("\n", stderr); + } + + if (rs6000_cpu_index >= 0) + { + const char *name = processor_target_table[rs6000_cpu_index].name; + HOST_WIDE_INT flags + = processor_target_table[rs6000_cpu_index].target_enable; + + sprintf (flags_buffer, "-mcpu=%s flags", name); + rs6000_print_isa_options (stderr, 0, flags_buffer, flags); + } + else + fprintf (stderr, DEBUG_FMT_S, "cpu", ""); + + if (rs6000_tune_index >= 0) + { + const char *name = processor_target_table[rs6000_tune_index].name; + HOST_WIDE_INT flags + = processor_target_table[rs6000_tune_index].target_enable; + + sprintf (flags_buffer, "-mtune=%s flags", name); + rs6000_print_isa_options (stderr, 0, flags_buffer, flags); + } + else + fprintf (stderr, DEBUG_FMT_S, "tune", ""); + + cl_target_option_save (&cl_opts, &global_options); + rs6000_print_isa_options (stderr, 0, "rs6000_isa_flags", + rs6000_isa_flags); + + rs6000_print_isa_options (stderr, 0, "rs6000_isa_flags_explicit", + rs6000_isa_flags_explicit); + + rs6000_print_builtin_options (stderr, 0, "rs6000_builtin_mask", + rs6000_builtin_mask); + + rs6000_print_isa_options (stderr, 0, "TARGET_DEFAULT", TARGET_DEFAULT); + + fprintf (stderr, DEBUG_FMT_S, "--with-cpu default", + OPTION_TARGET_CPU_DEFAULT ? OPTION_TARGET_CPU_DEFAULT : ""); + + switch (rs6000_sched_costly_dep) + { + case max_dep_latency: + costly_str = "max_dep_latency"; + break; + + case no_dep_costly: + costly_str = "no_dep_costly"; + break; + + case all_deps_costly: + costly_str = "all_deps_costly"; + break; + + case true_store_to_load_dep_costly: + costly_str = "true_store_to_load_dep_costly"; + break; + + case store_to_load_dep_costly: + costly_str = "store_to_load_dep_costly"; + break; + + default: + costly_str = costly_num; + sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep); + break; + } + + fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str); + + switch (rs6000_sched_insert_nops) + { + case sched_finish_regroup_exact: + nop_str = "sched_finish_regroup_exact"; + break; + + case sched_finish_pad_groups: + nop_str = "sched_finish_pad_groups"; + break; + + case sched_finish_none: + nop_str = "sched_finish_none"; + break; + + default: + nop_str = nop_num; + sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops); + break; + } + + fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str); + + switch (rs6000_sdata) + { + default: + case SDATA_NONE: + break; + + case SDATA_DATA: + fprintf (stderr, DEBUG_FMT_S, "sdata", "data"); + break; + + case SDATA_SYSV: + fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv"); + break; + + case SDATA_EABI: + fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi"); + break; + + } + + switch (rs6000_traceback) + { + case traceback_default: trace_str = "default"; break; + case traceback_none: trace_str = "none"; break; + case traceback_part: trace_str = "part"; break; + case traceback_full: trace_str = "full"; break; + default: trace_str = "unknown"; break; + } + + fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str); + + switch (rs6000_current_cmodel) + { + case CMODEL_SMALL: cmodel_str = "small"; break; + case CMODEL_MEDIUM: cmodel_str = "medium"; break; + case CMODEL_LARGE: cmodel_str = "large"; break; + default: cmodel_str = "unknown"; break; + } + + fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str); + + switch (rs6000_current_abi) + { + case ABI_NONE: abi_str = "none"; break; + case ABI_AIX: abi_str = "aix"; break; + case ABI_ELFv2: abi_str = "ELFv2"; break; + case ABI_V4: abi_str = "V4"; break; + case ABI_DARWIN: abi_str = "darwin"; break; + default: abi_str = "unknown"; break; + } + + fprintf (stderr, DEBUG_FMT_S, "abi", abi_str); + + if (rs6000_altivec_abi) + fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true"); + + if (rs6000_spe_abi) + fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true"); + + if (rs6000_darwin64_abi) + fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true"); + + if (rs6000_float_gprs) + fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true"); + + fprintf (stderr, DEBUG_FMT_S, "fprs", + (TARGET_FPRS ? "true" : "false")); + + fprintf (stderr, DEBUG_FMT_S, "single_float", + (TARGET_SINGLE_FLOAT ? "true" : "false")); + + fprintf (stderr, DEBUG_FMT_S, "double_float", + (TARGET_DOUBLE_FLOAT ? "true" : "false")); + + fprintf (stderr, DEBUG_FMT_S, "soft_float", + (TARGET_SOFT_FLOAT ? "true" : "false")); + + fprintf (stderr, DEBUG_FMT_S, "e500_single", + (TARGET_E500_SINGLE ? "true" : "false")); + + fprintf (stderr, DEBUG_FMT_S, "e500_double", + (TARGET_E500_DOUBLE ? "true" : "false")); + + if (TARGET_LINK_STACK) + fprintf (stderr, DEBUG_FMT_S, "link_stack", "true"); + + fprintf (stderr, DEBUG_FMT_S, "lra", TARGET_LRA ? "true" : "false"); + + if (TARGET_P8_FUSION) + { + char options[80]; + + strcpy (options, (TARGET_P9_FUSION) ? "power9" : "power8"); + if (TARGET_TOC_FUSION) + strcat (options, ", toc"); + + if (TARGET_P8_FUSION_SIGN) + strcat (options, ", sign"); + + fprintf (stderr, DEBUG_FMT_S, "fusion", options); + } + + fprintf (stderr, DEBUG_FMT_S, "plt-format", + TARGET_SECURE_PLT ? "secure" : "bss"); + fprintf (stderr, DEBUG_FMT_S, "struct-return", + aix_struct_return ? "aix" : "sysv"); + fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]); + fprintf (stderr, DEBUG_FMT_S, "sched_groups", tf[!!rs6000_sched_groups]); + fprintf (stderr, DEBUG_FMT_S, "align_branch", + tf[!!rs6000_align_branch_targets]); + fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size); + fprintf (stderr, DEBUG_FMT_D, "long_double_size", + rs6000_long_double_type_size); + fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority", + (int)rs6000_sched_restricted_insns_priority); + fprintf (stderr, DEBUG_FMT_D, "Number of standard builtins", + (int)END_BUILTINS); + fprintf (stderr, DEBUG_FMT_D, "Number of rs6000 builtins", + (int)RS6000_BUILTIN_COUNT); + + fprintf (stderr, DEBUG_FMT_D, "Enable float128 on VSX", + (int)TARGET_FLOAT128_ENABLE_TYPE); + + if (TARGET_VSX) + fprintf (stderr, DEBUG_FMT_D, "VSX easy 64-bit scalar element", + (int)VECTOR_ELEMENT_SCALAR_64BIT); + + if (TARGET_DIRECT_MOVE_128) + fprintf (stderr, DEBUG_FMT_D, "VSX easy 64-bit mfvsrld element", + (int)VECTOR_ELEMENT_MFVSRLD_64BIT); +} + + +/* Update the addr mask bits in reg_addr to help secondary reload and go if + legitimate address support to figure out the appropriate addressing to + use. */ + +static void +rs6000_setup_reg_addr_masks (void) +{ + ssize_t rc, reg, m, nregs; + addr_mask_type any_addr_mask, addr_mask; + + for (m = 0; m < NUM_MACHINE_MODES; ++m) + { + machine_mode m2 = (machine_mode) m; + bool complex_p = false; + bool small_int_p = (m2 == QImode || m2 == HImode || m2 == SImode); + size_t msize; + + if (COMPLEX_MODE_P (m2)) + { + complex_p = true; + m2 = GET_MODE_INNER (m2); + } + + msize = GET_MODE_SIZE (m2); + + /* SDmode is special in that we want to access it only via REG+REG + addressing on power7 and above, since we want to use the LFIWZX and + STFIWZX instructions to load it. */ + bool indexed_only_p = (m == SDmode && TARGET_NO_SDMODE_STACK); + + any_addr_mask = 0; + for (rc = FIRST_RELOAD_REG_CLASS; rc <= LAST_RELOAD_REG_CLASS; rc++) + { + addr_mask = 0; + reg = reload_reg_map[rc].reg; + + /* Can mode values go in the GPR/FPR/Altivec registers? */ + if (reg >= 0 && rs6000_hard_regno_mode_ok_p[m][reg]) + { + bool small_int_vsx_p = (small_int_p + && (rc == RELOAD_REG_FPR + || rc == RELOAD_REG_VMX)); + + nregs = rs6000_hard_regno_nregs[m][reg]; + addr_mask |= RELOAD_REG_VALID; + + /* Indicate if the mode takes more than 1 physical register. If + it takes a single register, indicate it can do REG+REG + addressing. Small integers in VSX registers can only do + REG+REG addressing. */ + if (small_int_vsx_p) + addr_mask |= RELOAD_REG_INDEXED; + else if (nregs > 1 || m == BLKmode || complex_p) + addr_mask |= RELOAD_REG_MULTIPLE; + else + addr_mask |= RELOAD_REG_INDEXED; + + /* Figure out if we can do PRE_INC, PRE_DEC, or PRE_MODIFY + addressing. Restrict addressing on SPE for 64-bit types + because of the SUBREG hackery used to address 64-bit floats in + '32-bit' GPRs. If we allow scalars into Altivec registers, + don't allow PRE_INC, PRE_DEC, or PRE_MODIFY. */ + + if (TARGET_UPDATE + && (rc == RELOAD_REG_GPR || rc == RELOAD_REG_FPR) + && msize <= 8 + && !VECTOR_MODE_P (m2) + && !FLOAT128_VECTOR_P (m2) + && !complex_p + && !small_int_vsx_p + && (m2 != DFmode || !TARGET_UPPER_REGS_DF) + && (m2 != SFmode || !TARGET_UPPER_REGS_SF) + && !(TARGET_E500_DOUBLE && msize == 8)) + { + addr_mask |= RELOAD_REG_PRE_INCDEC; + + /* PRE_MODIFY is more restricted than PRE_INC/PRE_DEC in that + we don't allow PRE_MODIFY for some multi-register + operations. */ + switch (m) + { + default: + addr_mask |= RELOAD_REG_PRE_MODIFY; + break; + + case DImode: + if (TARGET_POWERPC64) + addr_mask |= RELOAD_REG_PRE_MODIFY; + break; + + case DFmode: + case DDmode: + if (TARGET_DF_INSN) + addr_mask |= RELOAD_REG_PRE_MODIFY; + break; + } + } + } + + /* GPR and FPR registers can do REG+OFFSET addressing, except + possibly for SDmode. ISA 3.0 (i.e. power9) adds D-form addressing + for 64-bit scalars and 32-bit SFmode to altivec registers. */ + if ((addr_mask != 0) && !indexed_only_p + && msize <= 8 + && (rc == RELOAD_REG_GPR + || ((msize == 8 || m2 == SFmode) + && (rc == RELOAD_REG_FPR + || (rc == RELOAD_REG_VMX + && TARGET_P9_DFORM_SCALAR))))) + addr_mask |= RELOAD_REG_OFFSET; + + /* VSX registers can do REG+OFFSET addresssing if ISA 3.0 + instructions are enabled. The offset for 128-bit VSX registers is + only 12-bits. While GPRs can handle the full offset range, VSX + registers can only handle the restricted range. */ + else if ((addr_mask != 0) && !indexed_only_p + && msize == 16 && TARGET_P9_DFORM_VECTOR + && (ALTIVEC_OR_VSX_VECTOR_MODE (m2) + || (m2 == TImode && TARGET_VSX_TIMODE))) + { + addr_mask |= RELOAD_REG_OFFSET; + if (rc == RELOAD_REG_FPR || rc == RELOAD_REG_VMX) + addr_mask |= RELOAD_REG_QUAD_OFFSET; + } + + /* VMX registers can do (REG & -16) and ((REG+REG) & -16) + addressing on 128-bit types. */ + if (rc == RELOAD_REG_VMX && msize == 16 + && (addr_mask & RELOAD_REG_VALID) != 0) + addr_mask |= RELOAD_REG_AND_M16; + + reg_addr[m].addr_mask[rc] = addr_mask; + any_addr_mask |= addr_mask; + } + + reg_addr[m].addr_mask[RELOAD_REG_ANY] = any_addr_mask; + } +} + + +/* Initialize the various global tables that are based on register size. */ +static void +rs6000_init_hard_regno_mode_ok (bool global_init_p) +{ + ssize_t r, m, c; + int align64; + int align32; + + /* Precalculate REGNO_REG_CLASS. */ + rs6000_regno_regclass[0] = GENERAL_REGS; + for (r = 1; r < 32; ++r) + rs6000_regno_regclass[r] = BASE_REGS; + + for (r = 32; r < 64; ++r) + rs6000_regno_regclass[r] = FLOAT_REGS; + + for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r) + rs6000_regno_regclass[r] = NO_REGS; + + for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r) + rs6000_regno_regclass[r] = ALTIVEC_REGS; + + rs6000_regno_regclass[CR0_REGNO] = CR0_REGS; + for (r = CR1_REGNO; r <= CR7_REGNO; ++r) + rs6000_regno_regclass[r] = CR_REGS; + + rs6000_regno_regclass[LR_REGNO] = LINK_REGS; + rs6000_regno_regclass[CTR_REGNO] = CTR_REGS; + rs6000_regno_regclass[CA_REGNO] = NO_REGS; + rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS; + rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS; + rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS; + rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS; + rs6000_regno_regclass[TFHAR_REGNO] = SPR_REGS; + rs6000_regno_regclass[TFIAR_REGNO] = SPR_REGS; + rs6000_regno_regclass[TEXASR_REGNO] = SPR_REGS; + rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS; + rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS; + + /* Precalculate register class to simpler reload register class. We don't + need all of the register classes that are combinations of different + classes, just the simple ones that have constraint letters. */ + for (c = 0; c < N_REG_CLASSES; c++) + reg_class_to_reg_type[c] = NO_REG_TYPE; + + reg_class_to_reg_type[(int)GENERAL_REGS] = GPR_REG_TYPE; + reg_class_to_reg_type[(int)BASE_REGS] = GPR_REG_TYPE; + reg_class_to_reg_type[(int)VSX_REGS] = VSX_REG_TYPE; + reg_class_to_reg_type[(int)VRSAVE_REGS] = SPR_REG_TYPE; + reg_class_to_reg_type[(int)VSCR_REGS] = SPR_REG_TYPE; + reg_class_to_reg_type[(int)LINK_REGS] = SPR_REG_TYPE; + reg_class_to_reg_type[(int)CTR_REGS] = SPR_REG_TYPE; + reg_class_to_reg_type[(int)LINK_OR_CTR_REGS] = SPR_REG_TYPE; + reg_class_to_reg_type[(int)CR_REGS] = CR_REG_TYPE; + reg_class_to_reg_type[(int)CR0_REGS] = CR_REG_TYPE; + reg_class_to_reg_type[(int)SPE_ACC_REGS] = SPE_ACC_TYPE; + reg_class_to_reg_type[(int)SPEFSCR_REGS] = SPEFSCR_REG_TYPE; + + if (TARGET_VSX) + { + reg_class_to_reg_type[(int)FLOAT_REGS] = VSX_REG_TYPE; + reg_class_to_reg_type[(int)ALTIVEC_REGS] = VSX_REG_TYPE; + } + else + { + reg_class_to_reg_type[(int)FLOAT_REGS] = FPR_REG_TYPE; + reg_class_to_reg_type[(int)ALTIVEC_REGS] = ALTIVEC_REG_TYPE; + } + + /* Precalculate the valid memory formats as well as the vector information, + this must be set up before the rs6000_hard_regno_nregs_internal calls + below. */ + gcc_assert ((int)VECTOR_NONE == 0); + memset ((void *) &rs6000_vector_unit[0], '\0', sizeof (rs6000_vector_unit)); + memset ((void *) &rs6000_vector_mem[0], '\0', sizeof (rs6000_vector_unit)); + + gcc_assert ((int)CODE_FOR_nothing == 0); + memset ((void *) ®_addr[0], '\0', sizeof (reg_addr)); + + gcc_assert ((int)NO_REGS == 0); + memset ((void *) &rs6000_constraints[0], '\0', sizeof (rs6000_constraints)); + + /* The VSX hardware allows native alignment for vectors, but control whether the compiler + believes it can use native alignment or still uses 128-bit alignment. */ + if (TARGET_VSX && !TARGET_VSX_ALIGN_128) + { + align64 = 64; + align32 = 32; + } + else + { + align64 = 128; + align32 = 128; + } + + /* KF mode (IEEE 128-bit in VSX registers). We do not have arithmetic, so + only set the memory modes. Include TFmode if -mabi=ieeelongdouble. */ + if (TARGET_FLOAT128_TYPE) + { + rs6000_vector_mem[KFmode] = VECTOR_VSX; + rs6000_vector_align[KFmode] = 128; + + if (FLOAT128_IEEE_P (TFmode)) + { + rs6000_vector_mem[TFmode] = VECTOR_VSX; + rs6000_vector_align[TFmode] = 128; + } + } + + /* V2DF mode, VSX only. */ + if (TARGET_VSX) + { + rs6000_vector_unit[V2DFmode] = VECTOR_VSX; + rs6000_vector_mem[V2DFmode] = VECTOR_VSX; + rs6000_vector_align[V2DFmode] = align64; + } + + /* V4SF mode, either VSX or Altivec. */ + if (TARGET_VSX) + { + rs6000_vector_unit[V4SFmode] = VECTOR_VSX; + rs6000_vector_mem[V4SFmode] = VECTOR_VSX; + rs6000_vector_align[V4SFmode] = align32; + } + else if (TARGET_ALTIVEC) + { + rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC; + rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC; + rs6000_vector_align[V4SFmode] = align32; + } + + /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads + and stores. */ + if (TARGET_ALTIVEC) + { + rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC; + rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC; + rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC; + rs6000_vector_align[V4SImode] = align32; + rs6000_vector_align[V8HImode] = align32; + rs6000_vector_align[V16QImode] = align32; + + if (TARGET_VSX) + { + rs6000_vector_mem[V4SImode] = VECTOR_VSX; + rs6000_vector_mem[V8HImode] = VECTOR_VSX; + rs6000_vector_mem[V16QImode] = VECTOR_VSX; + } + else + { + rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC; + rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC; + rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC; + } + } + + /* V2DImode, full mode depends on ISA 2.07 vector mode. Allow under VSX to + do insert/splat/extract. Altivec doesn't have 64-bit integer support. */ + if (TARGET_VSX) + { + rs6000_vector_mem[V2DImode] = VECTOR_VSX; + rs6000_vector_unit[V2DImode] + = (TARGET_P8_VECTOR) ? VECTOR_P8_VECTOR : VECTOR_NONE; + rs6000_vector_align[V2DImode] = align64; + + rs6000_vector_mem[V1TImode] = VECTOR_VSX; + rs6000_vector_unit[V1TImode] + = (TARGET_P8_VECTOR) ? VECTOR_P8_VECTOR : VECTOR_NONE; + rs6000_vector_align[V1TImode] = 128; + } + + /* DFmode, see if we want to use the VSX unit. Memory is handled + differently, so don't set rs6000_vector_mem. */ + if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE) + { + rs6000_vector_unit[DFmode] = VECTOR_VSX; + rs6000_vector_align[DFmode] = 64; + } + + /* SFmode, see if we want to use the VSX unit. */ + if (TARGET_P8_VECTOR && TARGET_VSX_SCALAR_FLOAT) + { + rs6000_vector_unit[SFmode] = VECTOR_VSX; + rs6000_vector_align[SFmode] = 32; + } + + /* Allow TImode in VSX register and set the VSX memory macros. */ + if (TARGET_VSX && TARGET_VSX_TIMODE) + { + rs6000_vector_mem[TImode] = VECTOR_VSX; + rs6000_vector_align[TImode] = align64; + } + + /* TODO add SPE and paired floating point vector support. */ + + /* Register class constraints for the constraints that depend on compile + switches. When the VSX code was added, different constraints were added + based on the type (DFmode, V2DFmode, V4SFmode). For the vector types, all + of the VSX registers are used. The register classes for scalar floating + point types is set, based on whether we allow that type into the upper + (Altivec) registers. GCC has register classes to target the Altivec + registers for load/store operations, to select using a VSX memory + operation instead of the traditional floating point operation. The + constraints are: + + d - Register class to use with traditional DFmode instructions. + f - Register class to use with traditional SFmode instructions. + v - Altivec register. + wa - Any VSX register. + wc - Reserved to represent individual CR bits (used in LLVM). + wd - Preferred register class for V2DFmode. + wf - Preferred register class for V4SFmode. + wg - Float register for power6x move insns. + wh - FP register for direct move instructions. + wi - FP or VSX register to hold 64-bit integers for VSX insns. + wj - FP or VSX register to hold 64-bit integers for direct moves. + wk - FP or VSX register to hold 64-bit doubles for direct moves. + wl - Float register if we can do 32-bit signed int loads. + wm - VSX register for ISA 2.07 direct move operations. + wn - always NO_REGS. + wr - GPR if 64-bit mode is permitted. + ws - Register class to do ISA 2.06 DF operations. + wt - VSX register for TImode in VSX registers. + wu - Altivec register for ISA 2.07 VSX SF/SI load/stores. + wv - Altivec register for ISA 2.06 VSX DF/DI load/stores. + ww - Register class to do SF conversions in with VSX operations. + wx - Float register if we can do 32-bit int stores. + wy - Register class to do ISA 2.07 SF operations. + wz - Float register if we can do 32-bit unsigned int loads. + wH - Altivec register if SImode is allowed in VSX registers. + wI - VSX register if SImode is allowed in VSX registers. + wJ - VSX register if QImode/HImode are allowed in VSX registers. + wK - Altivec register if QImode/HImode are allowed in VSX registers. */ + + if (TARGET_HARD_FLOAT && TARGET_FPRS) + rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS; /* SFmode */ + + if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) + rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS; /* DFmode */ + + if (TARGET_VSX) + { + rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS; /* V2DFmode */ + rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS; /* V4SFmode */ + + if (TARGET_VSX_TIMODE) + rs6000_constraints[RS6000_CONSTRAINT_wt] = VSX_REGS; /* TImode */ + + if (TARGET_UPPER_REGS_DF) /* DFmode */ + { + rs6000_constraints[RS6000_CONSTRAINT_ws] = VSX_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wv] = ALTIVEC_REGS; + } + else + rs6000_constraints[RS6000_CONSTRAINT_ws] = FLOAT_REGS; + + if (TARGET_UPPER_REGS_DI) /* DImode */ + rs6000_constraints[RS6000_CONSTRAINT_wi] = VSX_REGS; + else + rs6000_constraints[RS6000_CONSTRAINT_wi] = FLOAT_REGS; + } + + /* Add conditional constraints based on various options, to allow us to + collapse multiple insn patterns. */ + if (TARGET_ALTIVEC) + rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS; + + if (TARGET_MFPGPR) /* DFmode */ + rs6000_constraints[RS6000_CONSTRAINT_wg] = FLOAT_REGS; + + if (TARGET_LFIWAX) + rs6000_constraints[RS6000_CONSTRAINT_wl] = FLOAT_REGS; /* DImode */ + + if (TARGET_DIRECT_MOVE) + { + rs6000_constraints[RS6000_CONSTRAINT_wh] = FLOAT_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wj] /* DImode */ + = rs6000_constraints[RS6000_CONSTRAINT_wi]; + rs6000_constraints[RS6000_CONSTRAINT_wk] /* DFmode */ + = rs6000_constraints[RS6000_CONSTRAINT_ws]; + rs6000_constraints[RS6000_CONSTRAINT_wm] = VSX_REGS; + } + + if (TARGET_POWERPC64) + { + rs6000_constraints[RS6000_CONSTRAINT_wr] = GENERAL_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wA] = BASE_REGS; + } + + if (TARGET_P8_VECTOR && TARGET_UPPER_REGS_SF) /* SFmode */ + { + rs6000_constraints[RS6000_CONSTRAINT_wu] = ALTIVEC_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wy] = VSX_REGS; + rs6000_constraints[RS6000_CONSTRAINT_ww] = VSX_REGS; + } + else if (TARGET_P8_VECTOR) + { + rs6000_constraints[RS6000_CONSTRAINT_wy] = FLOAT_REGS; + rs6000_constraints[RS6000_CONSTRAINT_ww] = FLOAT_REGS; + } + else if (TARGET_VSX) + rs6000_constraints[RS6000_CONSTRAINT_ww] = FLOAT_REGS; + + if (TARGET_STFIWX) + rs6000_constraints[RS6000_CONSTRAINT_wx] = FLOAT_REGS; /* DImode */ + + if (TARGET_LFIWZX) + rs6000_constraints[RS6000_CONSTRAINT_wz] = FLOAT_REGS; /* DImode */ + + if (TARGET_FLOAT128_TYPE) + { + rs6000_constraints[RS6000_CONSTRAINT_wq] = VSX_REGS; /* KFmode */ + if (FLOAT128_IEEE_P (TFmode)) + rs6000_constraints[RS6000_CONSTRAINT_wp] = VSX_REGS; /* TFmode */ + } + + /* Support for new D-form instructions. */ + if (TARGET_P9_DFORM_SCALAR) + rs6000_constraints[RS6000_CONSTRAINT_wb] = ALTIVEC_REGS; + + /* Support for ISA 3.0 (power9) vectors. */ + if (TARGET_P9_VECTOR) + rs6000_constraints[RS6000_CONSTRAINT_wo] = VSX_REGS; + + /* Support for new direct moves (ISA 3.0 + 64bit). */ + if (TARGET_DIRECT_MOVE_128) + rs6000_constraints[RS6000_CONSTRAINT_we] = VSX_REGS; + + /* Support small integers in VSX registers. */ + if (TARGET_VSX_SMALL_INTEGER) + { + rs6000_constraints[RS6000_CONSTRAINT_wH] = ALTIVEC_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wI] = FLOAT_REGS; + if (TARGET_P9_VECTOR) + { + rs6000_constraints[RS6000_CONSTRAINT_wJ] = FLOAT_REGS; + rs6000_constraints[RS6000_CONSTRAINT_wK] = ALTIVEC_REGS; + } + } + + /* Set up the reload helper and direct move functions. */ + if (TARGET_VSX || TARGET_ALTIVEC) + { + if (TARGET_64BIT) + { + reg_addr[V16QImode].reload_store = CODE_FOR_reload_v16qi_di_store; + reg_addr[V16QImode].reload_load = CODE_FOR_reload_v16qi_di_load; + reg_addr[V8HImode].reload_store = CODE_FOR_reload_v8hi_di_store; + reg_addr[V8HImode].reload_load = CODE_FOR_reload_v8hi_di_load; + reg_addr[V4SImode].reload_store = CODE_FOR_reload_v4si_di_store; + reg_addr[V4SImode].reload_load = CODE_FOR_reload_v4si_di_load; + reg_addr[V2DImode].reload_store = CODE_FOR_reload_v2di_di_store; + reg_addr[V2DImode].reload_load = CODE_FOR_reload_v2di_di_load; + reg_addr[V1TImode].reload_store = CODE_FOR_reload_v1ti_di_store; + reg_addr[V1TImode].reload_load = CODE_FOR_reload_v1ti_di_load; + reg_addr[V4SFmode].reload_store = CODE_FOR_reload_v4sf_di_store; + reg_addr[V4SFmode].reload_load = CODE_FOR_reload_v4sf_di_load; + reg_addr[V2DFmode].reload_store = CODE_FOR_reload_v2df_di_store; + reg_addr[V2DFmode].reload_load = CODE_FOR_reload_v2df_di_load; + reg_addr[DFmode].reload_store = CODE_FOR_reload_df_di_store; + reg_addr[DFmode].reload_load = CODE_FOR_reload_df_di_load; + reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_di_store; + reg_addr[DDmode].reload_load = CODE_FOR_reload_dd_di_load; + reg_addr[SFmode].reload_store = CODE_FOR_reload_sf_di_store; + reg_addr[SFmode].reload_load = CODE_FOR_reload_sf_di_load; + + if (FLOAT128_VECTOR_P (KFmode)) + { + reg_addr[KFmode].reload_store = CODE_FOR_reload_kf_di_store; + reg_addr[KFmode].reload_load = CODE_FOR_reload_kf_di_load; + } + + if (FLOAT128_VECTOR_P (TFmode)) + { + reg_addr[TFmode].reload_store = CODE_FOR_reload_tf_di_store; + reg_addr[TFmode].reload_load = CODE_FOR_reload_tf_di_load; + } + + /* Only provide a reload handler for SDmode if lfiwzx/stfiwx are + available. */ + if (TARGET_NO_SDMODE_STACK) + { + reg_addr[SDmode].reload_store = CODE_FOR_reload_sd_di_store; + reg_addr[SDmode].reload_load = CODE_FOR_reload_sd_di_load; + } + + if (TARGET_VSX_TIMODE) + { + reg_addr[TImode].reload_store = CODE_FOR_reload_ti_di_store; + reg_addr[TImode].reload_load = CODE_FOR_reload_ti_di_load; + } + + if (TARGET_DIRECT_MOVE && !TARGET_DIRECT_MOVE_128) + { + reg_addr[TImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxti; + reg_addr[V1TImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv1ti; + reg_addr[V2DFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv2df; + reg_addr[V2DImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv2di; + reg_addr[V4SFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv4sf; + reg_addr[V4SImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv4si; + reg_addr[V8HImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv8hi; + reg_addr[V16QImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv16qi; + reg_addr[SFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxsf; + + reg_addr[TImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprti; + reg_addr[V1TImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv1ti; + reg_addr[V2DFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv2df; + reg_addr[V2DImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv2di; + reg_addr[V4SFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv4sf; + reg_addr[V4SImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv4si; + reg_addr[V8HImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv8hi; + reg_addr[V16QImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv16qi; + reg_addr[SFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprsf; + + if (FLOAT128_VECTOR_P (KFmode)) + { + reg_addr[KFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxkf; + reg_addr[KFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprkf; + } + + if (FLOAT128_VECTOR_P (TFmode)) + { + reg_addr[TFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxtf; + reg_addr[TFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprtf; + } + } + } + else + { + reg_addr[V16QImode].reload_store = CODE_FOR_reload_v16qi_si_store; + reg_addr[V16QImode].reload_load = CODE_FOR_reload_v16qi_si_load; + reg_addr[V8HImode].reload_store = CODE_FOR_reload_v8hi_si_store; + reg_addr[V8HImode].reload_load = CODE_FOR_reload_v8hi_si_load; + reg_addr[V4SImode].reload_store = CODE_FOR_reload_v4si_si_store; + reg_addr[V4SImode].reload_load = CODE_FOR_reload_v4si_si_load; + reg_addr[V2DImode].reload_store = CODE_FOR_reload_v2di_si_store; + reg_addr[V2DImode].reload_load = CODE_FOR_reload_v2di_si_load; + reg_addr[V1TImode].reload_store = CODE_FOR_reload_v1ti_si_store; + reg_addr[V1TImode].reload_load = CODE_FOR_reload_v1ti_si_load; + reg_addr[V4SFmode].reload_store = CODE_FOR_reload_v4sf_si_store; + reg_addr[V4SFmode].reload_load = CODE_FOR_reload_v4sf_si_load; + reg_addr[V2DFmode].reload_store = CODE_FOR_reload_v2df_si_store; + reg_addr[V2DFmode].reload_load = CODE_FOR_reload_v2df_si_load; + reg_addr[DFmode].reload_store = CODE_FOR_reload_df_si_store; + reg_addr[DFmode].reload_load = CODE_FOR_reload_df_si_load; + reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_si_store; + reg_addr[DDmode].reload_load = CODE_FOR_reload_dd_si_load; + reg_addr[SFmode].reload_store = CODE_FOR_reload_sf_si_store; + reg_addr[SFmode].reload_load = CODE_FOR_reload_sf_si_load; + + if (FLOAT128_VECTOR_P (KFmode)) + { + reg_addr[KFmode].reload_store = CODE_FOR_reload_kf_si_store; + reg_addr[KFmode].reload_load = CODE_FOR_reload_kf_si_load; + } + + if (FLOAT128_IEEE_P (TFmode)) + { + reg_addr[TFmode].reload_store = CODE_FOR_reload_tf_si_store; + reg_addr[TFmode].reload_load = CODE_FOR_reload_tf_si_load; + } + + /* Only provide a reload handler for SDmode if lfiwzx/stfiwx are + available. */ + if (TARGET_NO_SDMODE_STACK) + { + reg_addr[SDmode].reload_store = CODE_FOR_reload_sd_si_store; + reg_addr[SDmode].reload_load = CODE_FOR_reload_sd_si_load; + } + + if (TARGET_VSX_TIMODE) + { + reg_addr[TImode].reload_store = CODE_FOR_reload_ti_si_store; + reg_addr[TImode].reload_load = CODE_FOR_reload_ti_si_load; + } + + if (TARGET_DIRECT_MOVE) + { + reg_addr[DImode].reload_fpr_gpr = CODE_FOR_reload_fpr_from_gprdi; + reg_addr[DDmode].reload_fpr_gpr = CODE_FOR_reload_fpr_from_gprdd; + reg_addr[DFmode].reload_fpr_gpr = CODE_FOR_reload_fpr_from_gprdf; + } + } + + if (TARGET_UPPER_REGS_DF) + reg_addr[DFmode].scalar_in_vmx_p = true; + + if (TARGET_UPPER_REGS_DI) + reg_addr[DImode].scalar_in_vmx_p = true; + + if (TARGET_UPPER_REGS_SF) + reg_addr[SFmode].scalar_in_vmx_p = true; + + if (TARGET_VSX_SMALL_INTEGER) + { + reg_addr[SImode].scalar_in_vmx_p = true; + if (TARGET_P9_VECTOR) + { + reg_addr[HImode].scalar_in_vmx_p = true; + reg_addr[QImode].scalar_in_vmx_p = true; + } + } + } + + /* Setup the fusion operations. */ + if (TARGET_P8_FUSION) + { + reg_addr[QImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_qi; + reg_addr[HImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_hi; + reg_addr[SImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_si; + if (TARGET_64BIT) + reg_addr[DImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_di; + } + + if (TARGET_P9_FUSION) + { + struct fuse_insns { + enum machine_mode mode; /* mode of the fused type. */ + enum machine_mode pmode; /* pointer mode. */ + enum rs6000_reload_reg_type rtype; /* register type. */ + enum insn_code load; /* load insn. */ + enum insn_code store; /* store insn. */ + }; + + static const struct fuse_insns addis_insns[] = { + { SFmode, DImode, RELOAD_REG_FPR, + CODE_FOR_fusion_vsx_di_sf_load, + CODE_FOR_fusion_vsx_di_sf_store }, + + { SFmode, SImode, RELOAD_REG_FPR, + CODE_FOR_fusion_vsx_si_sf_load, + CODE_FOR_fusion_vsx_si_sf_store }, + + { DFmode, DImode, RELOAD_REG_FPR, + CODE_FOR_fusion_vsx_di_df_load, + CODE_FOR_fusion_vsx_di_df_store }, + + { DFmode, SImode, RELOAD_REG_FPR, + CODE_FOR_fusion_vsx_si_df_load, + CODE_FOR_fusion_vsx_si_df_store }, + + { DImode, DImode, RELOAD_REG_FPR, + CODE_FOR_fusion_vsx_di_di_load, + CODE_FOR_fusion_vsx_di_di_store }, + + { DImode, SImode, RELOAD_REG_FPR, + CODE_FOR_fusion_vsx_si_di_load, + CODE_FOR_fusion_vsx_si_di_store }, + + { QImode, DImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_di_qi_load, + CODE_FOR_fusion_gpr_di_qi_store }, + + { QImode, SImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_si_qi_load, + CODE_FOR_fusion_gpr_si_qi_store }, + + { HImode, DImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_di_hi_load, + CODE_FOR_fusion_gpr_di_hi_store }, + + { HImode, SImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_si_hi_load, + CODE_FOR_fusion_gpr_si_hi_store }, + + { SImode, DImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_di_si_load, + CODE_FOR_fusion_gpr_di_si_store }, + + { SImode, SImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_si_si_load, + CODE_FOR_fusion_gpr_si_si_store }, + + { SFmode, DImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_di_sf_load, + CODE_FOR_fusion_gpr_di_sf_store }, + + { SFmode, SImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_si_sf_load, + CODE_FOR_fusion_gpr_si_sf_store }, + + { DImode, DImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_di_di_load, + CODE_FOR_fusion_gpr_di_di_store }, + + { DFmode, DImode, RELOAD_REG_GPR, + CODE_FOR_fusion_gpr_di_df_load, + CODE_FOR_fusion_gpr_di_df_store }, + }; + + enum machine_mode cur_pmode = Pmode; + size_t i; + + for (i = 0; i < ARRAY_SIZE (addis_insns); i++) + { + enum machine_mode xmode = addis_insns[i].mode; + enum rs6000_reload_reg_type rtype = addis_insns[i].rtype; + + if (addis_insns[i].pmode != cur_pmode) + continue; + + if (rtype == RELOAD_REG_FPR + && (!TARGET_HARD_FLOAT || !TARGET_FPRS)) + continue; + + reg_addr[xmode].fusion_addis_ld[rtype] = addis_insns[i].load; + reg_addr[xmode].fusion_addis_st[rtype] = addis_insns[i].store; + + if (rtype == RELOAD_REG_FPR && TARGET_P9_DFORM_SCALAR) + { + reg_addr[xmode].fusion_addis_ld[RELOAD_REG_VMX] + = addis_insns[i].load; + reg_addr[xmode].fusion_addis_st[RELOAD_REG_VMX] + = addis_insns[i].store; + } + } + } + + /* Note which types we support fusing TOC setup plus memory insn. We only do + fused TOCs for medium/large code models. */ + if (TARGET_P8_FUSION && TARGET_TOC_FUSION && TARGET_POWERPC64 + && (TARGET_CMODEL != CMODEL_SMALL)) + { + reg_addr[QImode].fused_toc = true; + reg_addr[HImode].fused_toc = true; + reg_addr[SImode].fused_toc = true; + reg_addr[DImode].fused_toc = true; + if (TARGET_HARD_FLOAT && TARGET_FPRS) + { + if (TARGET_SINGLE_FLOAT) + reg_addr[SFmode].fused_toc = true; + if (TARGET_DOUBLE_FLOAT) + reg_addr[DFmode].fused_toc = true; + } + } + + /* Precalculate HARD_REGNO_NREGS. */ + for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r) + for (m = 0; m < NUM_MACHINE_MODES; ++m) + rs6000_hard_regno_nregs[m][r] + = rs6000_hard_regno_nregs_internal (r, (machine_mode)m); + + /* Precalculate HARD_REGNO_MODE_OK. */ + for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r) + for (m = 0; m < NUM_MACHINE_MODES; ++m) + if (rs6000_hard_regno_mode_ok (r, (machine_mode)m)) + rs6000_hard_regno_mode_ok_p[m][r] = true; + + /* Precalculate CLASS_MAX_NREGS sizes. */ + for (c = 0; c < LIM_REG_CLASSES; ++c) + { + int reg_size; + + if (TARGET_VSX && VSX_REG_CLASS_P (c)) + reg_size = UNITS_PER_VSX_WORD; + + else if (c == ALTIVEC_REGS) + reg_size = UNITS_PER_ALTIVEC_WORD; + + else if (c == FLOAT_REGS) + reg_size = UNITS_PER_FP_WORD; + + else + reg_size = UNITS_PER_WORD; + + for (m = 0; m < NUM_MACHINE_MODES; ++m) + { + machine_mode m2 = (machine_mode)m; + int reg_size2 = reg_size; + + /* TDmode & IBM 128-bit floating point always takes 2 registers, even + in VSX. */ + if (TARGET_VSX && VSX_REG_CLASS_P (c) && FLOAT128_2REG_P (m)) + reg_size2 = UNITS_PER_FP_WORD; + + rs6000_class_max_nregs[m][c] + = (GET_MODE_SIZE (m2) + reg_size2 - 1) / reg_size2; + } + } + + if (TARGET_E500_DOUBLE) + rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1; + + /* Calculate which modes to automatically generate code to use a the + reciprocal divide and square root instructions. In the future, possibly + automatically generate the instructions even if the user did not specify + -mrecip. The older machines double precision reciprocal sqrt estimate is + not accurate enough. */ + memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits)); + if (TARGET_FRES) + rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE; + if (TARGET_FRE) + rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE; + if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)) + rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE; + if (VECTOR_UNIT_VSX_P (V2DFmode)) + rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE; + + if (TARGET_FRSQRTES) + rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE; + if (TARGET_FRSQRTE) + rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE; + if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)) + rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE; + if (VECTOR_UNIT_VSX_P (V2DFmode)) + rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE; + + if (rs6000_recip_control) + { + if (!flag_finite_math_only) + warning (0, "-mrecip requires -ffinite-math or -ffast-math"); + if (flag_trapping_math) + warning (0, "-mrecip requires -fno-trapping-math or -ffast-math"); + if (!flag_reciprocal_math) + warning (0, "-mrecip requires -freciprocal-math or -ffast-math"); + if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math) + { + if (RS6000_RECIP_HAVE_RE_P (SFmode) + && (rs6000_recip_control & RECIP_SF_DIV) != 0) + rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE; + + if (RS6000_RECIP_HAVE_RE_P (DFmode) + && (rs6000_recip_control & RECIP_DF_DIV) != 0) + rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE; + + if (RS6000_RECIP_HAVE_RE_P (V4SFmode) + && (rs6000_recip_control & RECIP_V4SF_DIV) != 0) + rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE; + + if (RS6000_RECIP_HAVE_RE_P (V2DFmode) + && (rs6000_recip_control & RECIP_V2DF_DIV) != 0) + rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE; + + if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode) + && (rs6000_recip_control & RECIP_SF_RSQRT) != 0) + rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE; + + if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode) + && (rs6000_recip_control & RECIP_DF_RSQRT) != 0) + rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE; + + if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode) + && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0) + rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE; + + if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode) + && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0) + rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE; + } + } + + /* Update the addr mask bits in reg_addr to help secondary reload and go if + legitimate address support to figure out the appropriate addressing to + use. */ + rs6000_setup_reg_addr_masks (); + + if (global_init_p || TARGET_DEBUG_TARGET) + { + if (TARGET_DEBUG_REG) + rs6000_debug_reg_global (); + + if (TARGET_DEBUG_COST || TARGET_DEBUG_REG) + fprintf (stderr, + "SImode variable mult cost = %d\n" + "SImode constant mult cost = %d\n" + "SImode short constant mult cost = %d\n" + "DImode multipliciation cost = %d\n" + "SImode division cost = %d\n" + "DImode division cost = %d\n" + "Simple fp operation cost = %d\n" + "DFmode multiplication cost = %d\n" + "SFmode division cost = %d\n" + "DFmode division cost = %d\n" + "cache line size = %d\n" + "l1 cache size = %d\n" + "l2 cache size = %d\n" + "simultaneous prefetches = %d\n" + "\n", + rs6000_cost->mulsi, + rs6000_cost->mulsi_const, + rs6000_cost->mulsi_const9, + rs6000_cost->muldi, + rs6000_cost->divsi, + rs6000_cost->divdi, + rs6000_cost->fp, + rs6000_cost->dmul, + rs6000_cost->sdiv, + rs6000_cost->ddiv, + rs6000_cost->cache_line_size, + rs6000_cost->l1_cache_size, + rs6000_cost->l2_cache_size, + rs6000_cost->simultaneous_prefetches); + } +} + +#if TARGET_MACHO +/* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */ + +static void +darwin_rs6000_override_options (void) +{ + /* The Darwin ABI always includes AltiVec, can't be (validly) turned + off. */ + rs6000_altivec_abi = 1; + TARGET_ALTIVEC_VRSAVE = 1; + rs6000_current_abi = ABI_DARWIN; + + if (DEFAULT_ABI == ABI_DARWIN + && TARGET_64BIT) + darwin_one_byte_bool = 1; + + if (TARGET_64BIT && ! TARGET_POWERPC64) + { + rs6000_isa_flags |= OPTION_MASK_POWERPC64; + warning (0, "-m64 requires PowerPC64 architecture, enabling"); + } + if (flag_mkernel) + { + rs6000_default_long_calls = 1; + rs6000_isa_flags |= OPTION_MASK_SOFT_FLOAT; + } + + /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes + Altivec. */ + if (!flag_mkernel && !flag_apple_kext + && TARGET_64BIT + && ! (rs6000_isa_flags_explicit & OPTION_MASK_ALTIVEC)) + rs6000_isa_flags |= OPTION_MASK_ALTIVEC; + + /* Unless the user (not the configurer) has explicitly overridden + it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to + G4 unless targeting the kernel. */ + if (!flag_mkernel + && !flag_apple_kext + && strverscmp (darwin_macosx_version_min, "10.5") >= 0 + && ! (rs6000_isa_flags_explicit & OPTION_MASK_ALTIVEC) + && ! global_options_set.x_rs6000_cpu_index) + { + rs6000_isa_flags |= OPTION_MASK_ALTIVEC; + } +} +#endif + +/* If not otherwise specified by a target, make 'long double' equivalent to + 'double'. */ + +#ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE +#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64 +#endif + +/* Return the builtin mask of the various options used that could affect which + builtins were used. In the past we used target_flags, but we've run out of + bits, and some options like SPE and PAIRED are no longer in + target_flags. */ + +HOST_WIDE_INT +rs6000_builtin_mask_calculate (void) +{ + return (((TARGET_ALTIVEC) ? RS6000_BTM_ALTIVEC : 0) + | ((TARGET_CMPB) ? RS6000_BTM_CMPB : 0) + | ((TARGET_VSX) ? RS6000_BTM_VSX : 0) + | ((TARGET_SPE) ? RS6000_BTM_SPE : 0) + | ((TARGET_PAIRED_FLOAT) ? RS6000_BTM_PAIRED : 0) + | ((TARGET_FRE) ? RS6000_BTM_FRE : 0) + | ((TARGET_FRES) ? RS6000_BTM_FRES : 0) + | ((TARGET_FRSQRTE) ? RS6000_BTM_FRSQRTE : 0) + | ((TARGET_FRSQRTES) ? RS6000_BTM_FRSQRTES : 0) + | ((TARGET_POPCNTD) ? RS6000_BTM_POPCNTD : 0) + | ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL : 0) + | ((TARGET_P8_VECTOR) ? RS6000_BTM_P8_VECTOR : 0) + | ((TARGET_P9_VECTOR) ? RS6000_BTM_P9_VECTOR : 0) + | ((TARGET_P9_MISC) ? RS6000_BTM_P9_MISC : 0) + | ((TARGET_MODULO) ? RS6000_BTM_MODULO : 0) + | ((TARGET_64BIT) ? RS6000_BTM_64BIT : 0) + | ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0) + | ((TARGET_HTM) ? RS6000_BTM_HTM : 0) + | ((TARGET_DFP) ? RS6000_BTM_DFP : 0) + | ((TARGET_HARD_FLOAT) ? RS6000_BTM_HARD_FLOAT : 0) + | ((TARGET_LONG_DOUBLE_128) ? RS6000_BTM_LDBL128 : 0) + | ((TARGET_FLOAT128_TYPE) ? RS6000_BTM_FLOAT128 : 0)); +} + +/* Implement TARGET_MD_ASM_ADJUST. All asm statements are considered + to clobber the XER[CA] bit because clobbering that bit without telling + the compiler worked just fine with versions of GCC before GCC 5, and + breaking a lot of older code in ways that are hard to track down is + not such a great idea. */ + +static rtx_insn * +rs6000_md_asm_adjust (vec &/*outputs*/, vec &/*inputs*/, + vec &/*constraints*/, + vec &clobbers, HARD_REG_SET &clobbered_regs) +{ + clobbers.safe_push (gen_rtx_REG (SImode, CA_REGNO)); + SET_HARD_REG_BIT (clobbered_regs, CA_REGNO); + return NULL; +} + +/* Override command line options. + + Combine build-specific configuration information with options + specified on the command line to set various state variables which + influence code generation, optimization, and expansion of built-in + functions. Assure that command-line configuration preferences are + compatible with each other and with the build configuration; issue + warnings while adjusting configuration or error messages while + rejecting configuration. + + Upon entry to this function: + + This function is called once at the beginning of + compilation, and then again at the start and end of compiling + each section of code that has a different configuration, as + indicated, for example, by adding the + + __attribute__((__target__("cpu=power9"))) + + qualifier to a function definition or, for example, by bracketing + code between + + #pragma GCC target("altivec") + + and + + #pragma GCC reset_options + + directives. Parameter global_init_p is true for the initial + invocation, which initializes global variables, and false for all + subsequent invocations. + + + Various global state information is assumed to be valid. This + includes OPTION_TARGET_CPU_DEFAULT, representing the name of the + default CPU specified at build configure time, TARGET_DEFAULT, + representing the default set of option flags for the default + target, and global_options_set.x_rs6000_isa_flags, representing + which options were requested on the command line. + + Upon return from this function: + + rs6000_isa_flags_explicit has a non-zero bit for each flag that + was set by name on the command line. Additionally, if certain + attributes are automatically enabled or disabled by this function + in order to assure compatibility between options and + configuration, the flags associated with those attributes are + also set. By setting these "explicit bits", we avoid the risk + that other code might accidentally overwrite these particular + attributes with "default values". + + The various bits of rs6000_isa_flags are set to indicate the + target options that have been selected for the most current + compilation efforts. This has the effect of also turning on the + associated TARGET_XXX values since these are macros which are + generally defined to test the corresponding bit of the + rs6000_isa_flags variable. + + The variable rs6000_builtin_mask is set to represent the target + options for the most current compilation efforts, consistent with + the current contents of rs6000_isa_flags. This variable controls + expansion of built-in functions. + + Various other global variables and fields of global structures + (over 50 in all) are initialized to reflect the desired options + for the most current compilation efforts. */ + +static bool +rs6000_option_override_internal (bool global_init_p) +{ + bool ret = true; + bool have_cpu = false; + + /* The default cpu requested at configure time, if any. */ + const char *implicit_cpu = OPTION_TARGET_CPU_DEFAULT; + + HOST_WIDE_INT set_masks; + HOST_WIDE_INT ignore_masks; + int cpu_index; + int tune_index; + struct cl_target_option *main_target_opt + = ((global_init_p || target_option_default_node == NULL) + ? NULL : TREE_TARGET_OPTION (target_option_default_node)); + + /* Print defaults. */ + if ((TARGET_DEBUG_REG || TARGET_DEBUG_TARGET) && global_init_p) + rs6000_print_isa_options (stderr, 0, "TARGET_DEFAULT", TARGET_DEFAULT); + + /* Remember the explicit arguments. */ + if (global_init_p) + rs6000_isa_flags_explicit = global_options_set.x_rs6000_isa_flags; + + /* On 64-bit Darwin, power alignment is ABI-incompatible with some C + library functions, so warn about it. The flag may be useful for + performance studies from time to time though, so don't disable it + entirely. */ + if (global_options_set.x_rs6000_alignment_flags + && rs6000_alignment_flags == MASK_ALIGN_POWER + && DEFAULT_ABI == ABI_DARWIN + && TARGET_64BIT) + warning (0, "-malign-power is not supported for 64-bit Darwin;" + " it is incompatible with the installed C and C++ libraries"); + + /* Numerous experiment shows that IRA based loop pressure + calculation works better for RTL loop invariant motion on targets + with enough (>= 32) registers. It is an expensive optimization. + So it is on only for peak performance. */ + if (optimize >= 3 && global_init_p + && !global_options_set.x_flag_ira_loop_pressure) + flag_ira_loop_pressure = 1; + + /* -fsanitize=address needs to turn on -fasynchronous-unwind-tables in order + for tracebacks to be complete but not if any -fasynchronous-unwind-tables + options were already specified. */ + if (flag_sanitize & SANITIZE_USER_ADDRESS + && !global_options_set.x_flag_asynchronous_unwind_tables) + flag_asynchronous_unwind_tables = 1; + + /* Set the pointer size. */ + if (TARGET_64BIT) + { + rs6000_pmode = (int)DImode; + rs6000_pointer_size = 64; + } + else + { + rs6000_pmode = (int)SImode; + rs6000_pointer_size = 32; + } + + /* Some OSs don't support saving the high part of 64-bit registers on context + switch. Other OSs don't support saving Altivec registers. On those OSs, + we don't touch the OPTION_MASK_POWERPC64 or OPTION_MASK_ALTIVEC settings; + if the user wants either, the user must explicitly specify them and we + won't interfere with the user's specification. */ + + set_masks = POWERPC_MASKS; +#ifdef OS_MISSING_POWERPC64 + if (OS_MISSING_POWERPC64) + set_masks &= ~OPTION_MASK_POWERPC64; +#endif +#ifdef OS_MISSING_ALTIVEC + if (OS_MISSING_ALTIVEC) + set_masks &= ~(OPTION_MASK_ALTIVEC | OPTION_MASK_VSX + | OTHER_VSX_VECTOR_MASKS); +#endif + + /* Don't override by the processor default if given explicitly. */ + set_masks &= ~rs6000_isa_flags_explicit; + + /* Process the -mcpu= and -mtune= argument. If the user changed + the cpu in a target attribute or pragma, but did not specify a tuning + option, use the cpu for the tuning option rather than the option specified + with -mtune on the command line. Process a '--with-cpu' configuration + request as an implicit --cpu. */ + if (rs6000_cpu_index >= 0) + { + cpu_index = rs6000_cpu_index; + have_cpu = true; + } + else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index >= 0) + { + rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index; + have_cpu = true; + } + else if (implicit_cpu) + { + rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (implicit_cpu); + have_cpu = true; + } + else + { + /* PowerPC 64-bit LE requires at least ISA 2.07. */ + const char *default_cpu = ((!TARGET_POWERPC64) + ? "powerpc" + : ((BYTES_BIG_ENDIAN) + ? "powerpc64" + : "powerpc64le")); + + rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu); + have_cpu = false; + } + + gcc_assert (cpu_index >= 0); + + if (have_cpu) + { +#ifndef HAVE_AS_POWER9 + if (processor_target_table[rs6000_cpu_index].processor + == PROCESSOR_POWER9) + { + have_cpu = false; + warning (0, "will not generate power9 instructions because " + "assembler lacks power9 support"); + } +#endif +#ifndef HAVE_AS_POWER8 + if (processor_target_table[rs6000_cpu_index].processor + == PROCESSOR_POWER8) + { + have_cpu = false; + warning (0, "will not generate power8 instructions because " + "assembler lacks power8 support"); + } +#endif +#ifndef HAVE_AS_POPCNTD + if (processor_target_table[rs6000_cpu_index].processor + == PROCESSOR_POWER7) + { + have_cpu = false; + warning (0, "will not generate power7 instructions because " + "assembler lacks power7 support"); + } +#endif +#ifndef HAVE_AS_DFP + if (processor_target_table[rs6000_cpu_index].processor + == PROCESSOR_POWER6) + { + have_cpu = false; + warning (0, "will not generate power6 instructions because " + "assembler lacks power6 support"); + } +#endif +#ifndef HAVE_AS_POPCNTB + if (processor_target_table[rs6000_cpu_index].processor + == PROCESSOR_POWER5) + { + have_cpu = false; + warning (0, "will not generate power5 instructions because " + "assembler lacks power5 support"); + } +#endif + + if (!have_cpu) + { + /* PowerPC 64-bit LE requires at least ISA 2.07. */ + const char *default_cpu = (!TARGET_POWERPC64 + ? "powerpc" + : (BYTES_BIG_ENDIAN + ? "powerpc64" + : "powerpc64le")); + + rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu); + } + } + + /* If we have a cpu, either through an explicit -mcpu= or if the + compiler was configured with --with-cpu=, replace all of the ISA bits + with those from the cpu, except for options that were explicitly set. If + we don't have a cpu, do not override the target bits set in + TARGET_DEFAULT. */ + if (have_cpu) + { + rs6000_isa_flags &= ~set_masks; + rs6000_isa_flags |= (processor_target_table[cpu_index].target_enable + & set_masks); + } + else + { + /* If no -mcpu=, inherit any default options that were cleared via + POWERPC_MASKS. Originally, TARGET_DEFAULT was used to initialize + target_flags via the TARGET_DEFAULT_TARGET_FLAGS hook. When we switched + to using rs6000_isa_flags, we need to do the initialization here. + + If there is a TARGET_DEFAULT, use that. Otherwise fall back to using + -mcpu=powerpc, -mcpu=powerpc64, or -mcpu=powerpc64le defaults. */ + HOST_WIDE_INT flags = ((TARGET_DEFAULT) ? TARGET_DEFAULT + : processor_target_table[cpu_index].target_enable); + rs6000_isa_flags |= (flags & ~rs6000_isa_flags_explicit); + } + + if (rs6000_tune_index >= 0) + tune_index = rs6000_tune_index; + else if (have_cpu) + rs6000_tune_index = tune_index = cpu_index; + else + { + size_t i; + enum processor_type tune_proc + = (TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT); + + tune_index = -1; + for (i = 0; i < ARRAY_SIZE (processor_target_table); i++) + if (processor_target_table[i].processor == tune_proc) + { + rs6000_tune_index = tune_index = i; + break; + } + } + + gcc_assert (tune_index >= 0); + rs6000_cpu = processor_target_table[tune_index].processor; + + /* Pick defaults for SPE related control flags. Do this early to make sure + that the TARGET_ macros are representative ASAP. */ + { + int spe_capable_cpu = + (rs6000_cpu == PROCESSOR_PPC8540 + || rs6000_cpu == PROCESSOR_PPC8548); + + if (!global_options_set.x_rs6000_spe_abi) + rs6000_spe_abi = spe_capable_cpu; + + if (!global_options_set.x_rs6000_spe) + rs6000_spe = spe_capable_cpu; + + if (!global_options_set.x_rs6000_float_gprs) + rs6000_float_gprs = + (rs6000_cpu == PROCESSOR_PPC8540 ? 1 + : rs6000_cpu == PROCESSOR_PPC8548 ? 2 + : 0); + } + + if (global_options_set.x_rs6000_spe_abi + && rs6000_spe_abi + && !TARGET_SPE_ABI) + error ("not configured for SPE ABI"); + + if (global_options_set.x_rs6000_spe + && rs6000_spe + && !TARGET_SPE) + error ("not configured for SPE instruction set"); + + if (main_target_opt != NULL + && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi) + || (main_target_opt->x_rs6000_spe != rs6000_spe) + || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs))) + error ("target attribute or pragma changes SPE ABI"); + + if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3 + || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64 + || rs6000_cpu == PROCESSOR_PPCE5500) + { + if (TARGET_ALTIVEC) + error ("AltiVec not supported in this target"); + if (TARGET_SPE) + error ("SPE not supported in this target"); + } + if (rs6000_cpu == PROCESSOR_PPCE6500) + { + if (TARGET_SPE) + error ("SPE not supported in this target"); + } + + /* Disable Cell microcode if we are optimizing for the Cell + and not optimizing for size. */ + if (rs6000_gen_cell_microcode == -1) + rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL + && !optimize_size); + + /* If we are optimizing big endian systems for space and it's OK to + use instructions that would be microcoded on the Cell, use the + load/store multiple and string instructions. */ + if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode) + rs6000_isa_flags |= ~rs6000_isa_flags_explicit & (OPTION_MASK_MULTIPLE + | OPTION_MASK_STRING); + + /* Don't allow -mmultiple or -mstring on little endian systems + unless the cpu is a 750, because the hardware doesn't support the + instructions used in little endian mode, and causes an alignment + trap. The 750 does not cause an alignment trap (except when the + target is unaligned). */ + + if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750) + { + if (TARGET_MULTIPLE) + { + rs6000_isa_flags &= ~OPTION_MASK_MULTIPLE; + if ((rs6000_isa_flags_explicit & OPTION_MASK_MULTIPLE) != 0) + warning (0, "-mmultiple is not supported on little endian systems"); + } + + if (TARGET_STRING) + { + rs6000_isa_flags &= ~OPTION_MASK_STRING; + if ((rs6000_isa_flags_explicit & OPTION_MASK_STRING) != 0) + warning (0, "-mstring is not supported on little endian systems"); + } + } + + /* If little-endian, default to -mstrict-align on older processors. + Testing for htm matches power8 and later. */ + if (!BYTES_BIG_ENDIAN + && !(processor_target_table[tune_index].target_enable & OPTION_MASK_HTM)) + rs6000_isa_flags |= ~rs6000_isa_flags_explicit & OPTION_MASK_STRICT_ALIGN; + + /* -maltivec={le,be} implies -maltivec. */ + if (rs6000_altivec_element_order != 0) + rs6000_isa_flags |= OPTION_MASK_ALTIVEC; + + /* Disallow -maltivec=le in big endian mode for now. This is not + known to be useful for anyone. */ + if (BYTES_BIG_ENDIAN && rs6000_altivec_element_order == 1) + { + warning (0, N_("-maltivec=le not allowed for big-endian targets")); + rs6000_altivec_element_order = 0; + } + + /* Add some warnings for VSX. */ + if (TARGET_VSX) + { + const char *msg = NULL; + if (!TARGET_HARD_FLOAT || !TARGET_FPRS + || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT) + { + if (rs6000_isa_flags_explicit & OPTION_MASK_VSX) + msg = N_("-mvsx requires hardware floating point"); + else + { + rs6000_isa_flags &= ~ OPTION_MASK_VSX; + rs6000_isa_flags_explicit |= OPTION_MASK_VSX; + } + } + else if (TARGET_PAIRED_FLOAT) + msg = N_("-mvsx and -mpaired are incompatible"); + else if (TARGET_AVOID_XFORM > 0) + msg = N_("-mvsx needs indexed addressing"); + else if (!TARGET_ALTIVEC && (rs6000_isa_flags_explicit + & OPTION_MASK_ALTIVEC)) + { + if (rs6000_isa_flags_explicit & OPTION_MASK_VSX) + msg = N_("-mvsx and -mno-altivec are incompatible"); + else + msg = N_("-mno-altivec disables vsx"); + } + + if (msg) + { + warning (0, msg); + rs6000_isa_flags &= ~ OPTION_MASK_VSX; + rs6000_isa_flags_explicit |= OPTION_MASK_VSX; + } + } + + /* If hard-float/altivec/vsx were explicitly turned off then don't allow + the -mcpu setting to enable options that conflict. */ + if ((!TARGET_HARD_FLOAT || !TARGET_ALTIVEC || !TARGET_VSX) + && (rs6000_isa_flags_explicit & (OPTION_MASK_SOFT_FLOAT + | OPTION_MASK_ALTIVEC + | OPTION_MASK_VSX)) != 0) + rs6000_isa_flags &= ~((OPTION_MASK_P8_VECTOR | OPTION_MASK_CRYPTO + | OPTION_MASK_DIRECT_MOVE) + & ~rs6000_isa_flags_explicit); + + if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET) + rs6000_print_isa_options (stderr, 0, "before defaults", rs6000_isa_flags); + + /* Handle explicit -mno-{altivec,vsx,power8-vector,power9-vector} and turn + off all of the options that depend on those flags. */ + ignore_masks = rs6000_disable_incompatible_switches (); + + /* For the newer switches (vsx, dfp, etc.) set some of the older options, + unless the user explicitly used the -mno-