]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gcc/
authorbergner <bergner@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Jan 2016 20:30:24 +0000 (20:30 +0000)
committerbergner <bergner@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Jan 2016 20:30:24 +0000 (20:30 +0000)
* config/rs6000/ppc-auxv.h: New file.
* config/rs6000/rs6000-builtin.def (cpu_init): Add new builtin.
(cpu_is): Likewise.
(cpu_supports): Likewise.
* config/rs6000/rs6000.c: include "ppc-auxv.h".
(cpu_is_info): New variable.
(cpu_supports_info): Likewise.
(tcb_verification_symbol): Likewise.
(cpu_builtin_p): Likewise.
(cpu_expand_builtin): New function.
(rs6000_expand_ternop_builtin): Add support for CPU builtin functions.
(rs6000_init_builtins): Likewise.
(rs6000_elf_file_end): Emit HWCAP in TCB verification symbol.
* config/rs6000/rs6000.h (TLS_REGNUM): New define.
* configure.ac (gcc_cv_libc_provides_hwcap_in_tcb): New test.
* configure: Regenerate.
* config.in: Likewise.
* doc/extend.texi (PowerPC Built-in Functions): Document
__builtin_cpu_init, __builtin_cpu_is and __builtin_cpu_supports.

gcc/testsuite/
* gcc.target/powerpc/cpu-builtin-1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232634 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config.in
gcc/config/rs6000/ppc-auxv.h [new file with mode: 0644]
gcc/config/rs6000/rs6000-builtin.def
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/configure
gcc/configure.ac
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c [new file with mode: 0644]

index ee05d4966950463319496622843b8dfc3cd4f68f..f2eb93636f02407c71192a7d926dc329818047b6 100644 (file)
@@ -1,3 +1,25 @@
+2016-01-20  Peter Bergner  <bergner@vnet.ibm.com>
+
+       * config/rs6000/ppc-auxv.h: New file.
+       * config/rs6000/rs6000-builtin.def (cpu_init): Add new builtin.
+       (cpu_is): Likewise.
+       (cpu_supports): Likewise.
+       * config/rs6000/rs6000.c: include "ppc-auxv.h".
+       (cpu_is_info): New variable.
+       (cpu_supports_info): Likewise.
+       (tcb_verification_symbol): Likewise.
+       (cpu_builtin_p): Likewise.
+       (cpu_expand_builtin): New function.
+       (rs6000_expand_ternop_builtin): Add support for CPU builtin functions.
+       (rs6000_init_builtins): Likewise.
+       (rs6000_elf_file_end): Emit HWCAP in TCB verification symbol.
+       * config/rs6000/rs6000.h (TLS_REGNUM): New define.
+       * configure.ac (gcc_cv_libc_provides_hwcap_in_tcb): New test.
+       * configure: Regenerate.
+       * config.in: Likewise.
+       * doc/extend.texi (PowerPC Built-in Functions): Document
+       __builtin_cpu_init, __builtin_cpu_is and __builtin_cpu_supports.
+
 2016-01-20  David Edelsohn  <dje.gcc@gmail.com>
 
        PR target/68609
index c3340bb09014e7d396193ac0d9c0c978da685443..1796e1d895e3b091469dc57dc40be90c6476b262 100644 (file)
 #endif
 
 
+/* Define if your target C Library provides the AT_HWCAP value in the TCB */
+#ifndef USED_FOR_TARGET
+#undef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
+#endif
+
+
 /* Define if your target C library provides stack protector support */
 #ifndef USED_FOR_TARGET
 #undef TARGET_LIBC_PROVIDES_SSP
diff --git a/gcc/config/rs6000/ppc-auxv.h b/gcc/config/rs6000/ppc-auxv.h
new file mode 100644 (file)
index 0000000..590fdb8
--- /dev/null
@@ -0,0 +1,105 @@
+/* PowerPC support for accessing the AUXV AT_PLATFORM, AT_HWCAP and AT_HWCAP2
+   values from the Thread Control Block (TCB).
+
+   Copyright (C) 2016 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _PPC_AUXV_H
+#define _PPC_AUXV_H
+
+/* The PLATFORM value stored in the TCB is offset by _DL_FIRST_PLATFORM.  */
+#define _DL_FIRST_PLATFORM             32
+
+/* AT_PLATFORM bits.  These must match the values defined in GLIBC. */
+#define PPC_PLATFORM_POWER4            0
+#define PPC_PLATFORM_PPC970            1
+#define PPC_PLATFORM_POWER5            2
+#define PPC_PLATFORM_POWER5_PLUS       3
+#define PPC_PLATFORM_POWER6            4
+#define PPC_PLATFORM_CELL_BE           5
+#define PPC_PLATFORM_POWER6X           6
+#define PPC_PLATFORM_POWER7            7
+#define PPC_PLATFORM_PPCA2             8
+#define PPC_PLATFORM_PPC405            9
+#define PPC_PLATFORM_PPC440            10
+#define PPC_PLATFORM_PPC464            11
+#define PPC_PLATFORM_PPC476            12
+#define PPC_PLATFORM_POWER8            13
+#define PPC_PLATFORM_POWER9            14
+
+/* AT_HWCAP bits.  These must match the values defined in the Linux kernel.  */
+#define PPC_FEATURE_32              0x80000000
+#define PPC_FEATURE_64              0x40000000
+#define PPC_FEATURE_601_INSTR       0x20000000
+#define PPC_FEATURE_HAS_ALTIVEC     0x10000000
+#define PPC_FEATURE_HAS_FPU         0x08000000
+#define PPC_FEATURE_HAS_MMU         0x04000000
+#define PPC_FEATURE_HAS_4xxMAC      0x02000000
+#define PPC_FEATURE_UNIFIED_CACHE   0x01000000
+#define PPC_FEATURE_HAS_SPE         0x00800000
+#define PPC_FEATURE_HAS_EFP_SINGLE  0x00400000
+#define PPC_FEATURE_HAS_EFP_DOUBLE  0x00200000
+#define PPC_FEATURE_NO_TB           0x00100000
+#define PPC_FEATURE_POWER4          0x00080000
+#define PPC_FEATURE_POWER5          0x00040000
+#define PPC_FEATURE_POWER5_PLUS     0x00020000
+#define PPC_FEATURE_CELL_BE         0x00010000
+#define PPC_FEATURE_BOOKE           0x00008000
+#define PPC_FEATURE_SMT             0x00004000
+#define PPC_FEATURE_ICACHE_SNOOP    0x00002000
+#define PPC_FEATURE_ARCH_2_05       0x00001000
+#define PPC_FEATURE_PA6T            0x00000800
+#define PPC_FEATURE_HAS_DFP         0x00000400
+#define PPC_FEATURE_POWER6_EXT      0x00000200
+#define PPC_FEATURE_ARCH_2_06       0x00000100
+#define PPC_FEATURE_HAS_VSX         0x00000080
+#define PPC_FEATURE_PERFMON_COMPAT  0x00000040
+#define PPC_FEATURE_TRUE_LE         0x00000002
+#define PPC_FEATURE_PPC_LE          0x00000001
+
+/* AT_HWCAP2 bits.  These must match the values defined in the Linux kernel.  */
+#define PPC_FEATURE2_ARCH_2_07      0x80000000
+#define PPC_FEATURE2_HAS_HTM        0x40000000
+#define PPC_FEATURE2_HAS_DSCR       0x20000000
+#define PPC_FEATURE2_HAS_EBB        0x10000000
+#define PPC_FEATURE2_HAS_ISEL       0x08000000
+#define PPC_FEATURE2_HAS_TAR        0x04000000
+#define PPC_FEATURE2_HAS_VEC_CRYPTO 0x02000000
+#define PPC_FEATURE2_HTM_NOSC       0x01000000
+#define PPC_FEATURE2_ARCH_3_00      0x00800000
+#define PPC_FEATURE2_HAS_IEEE128    0x00400000
+
+
+/* Thread Control Block (TCB) offsets of the AT_PLATFORM, AT_HWCAP and
+   AT_HWCAP2 values.  These must match the values defined in GLIBC.  */
+#define TCB_PLATFORM_OFFSET ((TARGET_64BIT) ? -28764 : -28724)
+#define TCB_HWCAP_BASE_OFFSET ((TARGET_64BIT) ? -28776 : -28736)
+#define TCB_HWCAP1_OFFSET \
+  ((BYTES_BIG_ENDIAN) ? TCB_HWCAP_BASE_OFFSET : TCB_HWCAP_BASE_OFFSET+4)
+#define TCB_HWCAP2_OFFSET \
+  ((BYTES_BIG_ENDIAN) ? TCB_HWCAP_BASE_OFFSET+4 : TCB_HWCAP_BASE_OFFSET)
+#define TCB_HWCAP_OFFSET(ID) \
+  (((ID) == 0) ? TCB_HWCAP1_OFFSET : TCB_HWCAP2_OFFSET)
+
+#endif /* _PPC_AUXV_H */
index 709992b37728967715c07725f598ffaf9451ee56..5b82b00449e3a0740e78aad67430a7c373127795 100644 (file)
@@ -2013,6 +2013,15 @@ RS6000_BUILTIN_X (RS6000_BUILTIN_MTFSF, "__builtin_mtfsf",
                  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)
+
 /* Darwin CfString builtin.  */
 BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS,
              RS6000_BTC_MISC)
index 539446ce45ff58d875c082c2778fa1a78826fbb5..b0ce68e5b3896437f6048de1c5b7f0f224875328 100644 (file)
@@ -71,6 +71,7 @@
 #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"
@@ -293,6 +294,88 @@ static struct
   { "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 rs6000-c.c) that can define or undefine target
    macros that have changed.  Languages that don't support the preprocessor
    don't link in rs6000-c.c, so we can't call it directly.  */
@@ -13380,6 +13463,101 @@ htm_expand_builtin (tree exp, rtx target, bool * expandedp)
   return NULL_RTX;
 }
 
+/* Expand the CPU builtin in FCODE and store the result in TARGET.  */
+
+static rtx
+cpu_expand_builtin (enum rs6000_builtins fcode, tree exp ATTRIBUTE_UNUSED,
+                   rtx target)
+{
+  /* __builtin_cpu_init () is a nop, so expand to nothing.  */
+  if (fcode == RS6000_BUILTIN_CPU_INIT)
+    return const0_rtx;
+
+  if (target == 0 || GET_MODE (target) != SImode)
+    target = gen_reg_rtx (SImode);
+
+#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
+  tree arg = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
+  if (TREE_CODE (arg) != STRING_CST)
+    {
+      error ("builtin %s only accepts a string argument",
+            rs6000_builtin_info[(size_t) fcode].name);
+      return const0_rtx;
+    }
+
+  if (fcode == RS6000_BUILTIN_CPU_IS)
+    {
+      const char *cpu = TREE_STRING_POINTER (arg);
+      rtx cpuid = NULL_RTX;
+      for (size_t i = 0; i < ARRAY_SIZE (cpu_is_info); i++)
+       if (strcmp (cpu, cpu_is_info[i].cpu) == 0)
+         {
+           /* The CPUID value in the TCB is offset by _DL_FIRST_PLATFORM.  */
+           cpuid = GEN_INT (cpu_is_info[i].cpuid + _DL_FIRST_PLATFORM);
+           break;
+         }
+      if (cpuid == NULL_RTX)
+       {
+         /* Invalid CPU argument.  */
+         error ("cpu %s is an invalid argument to builtin %s",
+                cpu, rs6000_builtin_info[(size_t) fcode].name);
+         return const0_rtx;
+       }
+
+      rtx platform = gen_reg_rtx (SImode);
+      rtx tcbmem = gen_const_mem (SImode,
+                                 gen_rtx_PLUS (Pmode,
+                                               gen_rtx_REG (Pmode, TLS_REGNUM),
+                                               GEN_INT (TCB_PLATFORM_OFFSET)));
+      emit_move_insn (platform, tcbmem);
+      emit_insn (gen_eqsi3 (target, platform, cpuid));
+    }
+  else if (fcode == RS6000_BUILTIN_CPU_SUPPORTS)
+    {
+      const char *hwcap = TREE_STRING_POINTER (arg);
+      rtx mask = NULL_RTX;
+      int hwcap_offset;
+      for (size_t i = 0; i < ARRAY_SIZE (cpu_supports_info); i++)
+       if (strcmp (hwcap, cpu_supports_info[i].hwcap) == 0)
+         {
+           mask = GEN_INT (cpu_supports_info[i].mask);
+           hwcap_offset = TCB_HWCAP_OFFSET (cpu_supports_info[i].id);
+           break;
+         }
+      if (mask == NULL_RTX)
+       {
+         /* Invalid HWCAP argument.  */
+         error ("hwcap %s is an invalid argument to builtin %s",
+                hwcap, rs6000_builtin_info[(size_t) fcode].name);
+         return const0_rtx;
+       }
+
+      rtx tcb_hwcap = gen_reg_rtx (SImode);
+      rtx tcbmem = gen_const_mem (SImode,
+                                 gen_rtx_PLUS (Pmode,
+                                               gen_rtx_REG (Pmode, TLS_REGNUM),
+                                               GEN_INT (hwcap_offset)));
+      emit_move_insn (tcb_hwcap, tcbmem);
+      rtx scratch1 = gen_reg_rtx (SImode);
+      emit_insn (gen_rtx_SET (scratch1, gen_rtx_AND (SImode, tcb_hwcap, mask)));
+      rtx scratch2 = gen_reg_rtx (SImode);
+      emit_insn (gen_eqsi3 (scratch2, scratch1, const0_rtx));
+      emit_insn (gen_rtx_SET (target, gen_rtx_XOR (SImode, scratch2, const1_rtx)));
+    }
+
+  /* Record that we have expanded a CPU builtin, so that we can later
+     emit a reference to the special symbol exported by LIBC to ensure we
+     do not link against an old LIBC that doesn't support this feature.  */
+  cpu_builtin_p = true;
+
+#else
+  /* For old LIBCs, always return FALSE.  */
+  emit_move_insn (target, GEN_INT (0));
+#endif /* TARGET_LIBC_PROVIDES_HWCAP_IN_TCB */
+
+  return target;
+}
+
 static rtx
 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
 {
@@ -14706,6 +14884,11 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
     case RS6000_BUILTIN_MTFSF:
       return rs6000_expand_mtfsf_builtin (CODE_FOR_rs6000_mtfsf, exp);
 
+    case RS6000_BUILTIN_CPU_INIT:
+    case RS6000_BUILTIN_CPU_IS:
+    case RS6000_BUILTIN_CPU_SUPPORTS:
+      return cpu_expand_builtin (fcode, exp, target);
+
     case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
     case ALTIVEC_BUILTIN_MASK_FOR_STORE:
       {
@@ -15095,6 +15278,14 @@ rs6000_init_builtins (void)
                                    NULL_TREE);
   def_builtin ("__builtin_mtfsf", ftype, RS6000_BUILTIN_MTFSF);
 
+  ftype = build_function_type_list (void_type_node, NULL_TREE);
+  def_builtin ("__builtin_cpu_init", ftype, RS6000_BUILTIN_CPU_INIT);
+
+  ftype = build_function_type_list (bool_int_type_node, const_ptr_type_node,
+                                   NULL_TREE);
+  def_builtin ("__builtin_cpu_is", ftype, RS6000_BUILTIN_CPU_IS);
+  def_builtin ("__builtin_cpu_supports", ftype, RS6000_BUILTIN_CPU_SUPPORTS);
+
 #if TARGET_XCOFF
   /* AIX libm provides clog as __clog.  */
   if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
@@ -31601,6 +31792,17 @@ rs6000_elf_file_end (void)
 
   if (flag_split_stack)
     file_end_indicate_split_stack ();
+
+  if (cpu_builtin_p)
+    {
+      /* We have expanded a CPU builtin, so we need to emit a reference to
+        the special symbol that LIBC uses to declare it supports the
+        AT_PLATFORM and AT_HWCAP/AT_HWCAP2 in the TCB feature.  */
+      switch_to_section (data_section);
+      fprintf (asm_out_file, "\t.align %u\n", TARGET_32BIT ? 2 : 3);
+      fprintf (asm_out_file, "\t%s %s\n",
+              TARGET_32BIT ? ".long" : ".quad", tcb_verification_symbol);
+    }
 }
 #endif
 
index 6b0e64e693d3526b8716890d5a7a7f4e2ee0262b..8c6bd07dd5e58cbe887533f9057288d65a96a57a 100644 (file)
@@ -1361,6 +1361,9 @@ enum data_align { align_abi, align_opt, align_both };
 /* Place to put static chain when calling a function that requires it.  */
 #define STATIC_CHAIN_REGNUM 11
 
+/* Base register for access to thread local storage variables.  */
+#define TLS_REGNUM ((TARGET_64BIT) ? 13 : 2)
+
 \f
 /* Define the classes of registers for register constraints in the
    machine description.  Also define ranges of constants.
index 7db75526dd22c70ca0c5a0384415b5c5cb6adce0..42e97a8a8af9d61f63091e2ad1161ba501968d06 100755 (executable)
@@ -28539,6 +28539,24 @@ $as_echo "#define TARGET_DEFAULT_LONG_DOUBLE_128 1" >>confdefs.h
 
 fi
 
+# Check if the target LIBC supports exporting the AT_PLATFORM and AT_HWCAP
+# values in the TCB.  Currently, only GLIBC 2.23 and later support this.
+gcc_cv_libc_provides_hwcap_in_tcb=no
+case "$target" in
+  powerpc*-*-linux*)
+
+if test $glibc_version_major -gt 2 \
+  || ( test $glibc_version_major -eq 2 && test $glibc_version_minor -ge 23 ); then :
+  gcc_cv_libc_provides_hwcap_in_tcb=yes
+fi
+    ;;
+esac
+if test x$gcc_cv_libc_provides_hwcap_in_tcb = xyes; then
+
+$as_echo "#define TARGET_LIBC_PROVIDES_HWCAP_IN_TCB 1" >>confdefs.h
+
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dl_iterate_phdr in target C library" >&5
 $as_echo_n "checking dl_iterate_phdr in target C library... " >&6; }
 gcc_cv_target_dl_iterate_phdr=unknown
index 8d3a86943afae0e5ce7249f2f0049385014d0994..bf38dfe986baf98760417fc2e984dd75cc2b9c71 100644 (file)
@@ -5544,6 +5544,19 @@ if test x$gcc_cv_target_ldbl128 = xyes; then
            [Define if TFmode long double should be the default])
 fi
 
+# Check if the target LIBC supports exporting the AT_PLATFORM and AT_HWCAP
+# values in the TCB.  Currently, only GLIBC 2.23 and later support this.
+gcc_cv_libc_provides_hwcap_in_tcb=no
+case "$target" in
+  powerpc*-*-linux*)
+    GCC_GLIBC_VERSION_GTE_IFELSE([2], [23], [gcc_cv_libc_provides_hwcap_in_tcb=yes], )
+    ;;
+esac
+if test x$gcc_cv_libc_provides_hwcap_in_tcb = xyes; then
+  AC_DEFINE(TARGET_LIBC_PROVIDES_HWCAP_IN_TCB, 1,
+           [Define if your target C Library provides the AT_HWCAP value in the TCB])
+fi
+
 AC_MSG_CHECKING(dl_iterate_phdr in target C library)
 gcc_cv_target_dl_iterate_phdr=unknown
 case "$target" in
index a78282211ddef9cbe51e5b8c0df546141a02304b..0dab6465b70c4b4310e47f57c3071287b2016324 100644 (file)
@@ -13527,6 +13527,162 @@ implementing assertions.
 @node PowerPC Built-in Functions
 @subsection PowerPC Built-in Functions
 
+The following built-in functions are always available and can be used to
+check the PowerPC target platform type:
+
+@deftypefn {Built-in Function} void __builtin_cpu_init (void)
+This function is a @code{nop} on the PowerPC platform and is included solely
+to maintain API compatibility with the x86 builtins.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_cpu_is (const char *@var{cpuname})
+This function returns a value of @code{1} if the run-time CPU is of type
+@var{cpuname} and returns @code{0} otherwise. The following CPU names can be
+detected:
+
+@table @samp
+@item power9
+IBM POWER9 Server CPU.
+@item power8
+IBM POWER8 Server CPU.
+@item power7
+IBM POWER7 Server CPU.
+@item power6x
+IBM POWER6 Server CPU (RAW mode).
+@item power6
+IBM POWER6 Server CPU (Architected mode).
+@item power5+
+IBM POWER5+ Server CPU.
+@item power5
+IBM POWER5 Server CPU.
+@item ppc970
+IBM 970 Server CPU (ie, Apple G5).
+@item power4
+IBM POWER4 Server CPU.
+@item ppca2
+IBM A2 64-bit Embedded CPU
+@item ppc476
+IBM PowerPC 476FP 32-bit Embedded CPU.
+@item ppc464
+IBM PowerPC 464 32-bit Embedded CPU.
+@item ppc440
+PowerPC 440 32-bit Embedded CPU.
+@item ppc405
+PowerPC 405 32-bit Embedded CPU.
+@item ppc-cell-be
+IBM PowerPC Cell Broadband Engine Architecture CPU.
+@end table
+
+Here is an example:
+@smallexample
+if (__builtin_cpu_is ("power8"))
+  @{
+     do_power8 (); // POWER8 specific implementation.
+  @}
+else
+  @{
+     do_generic (); // Generic implementation.
+  @}
+@end smallexample
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_cpu_supports (const char *@var{feature})
+This function returns a value of @code{1} if the run-time CPU supports the HWCAP
+feature @var{feature} and returns @code{0} otherwise. The following features can be
+detected:
+
+@table @samp
+@item 4xxmac
+4xx CPU has a Multiply Accumulator.
+@item altivec
+CPU has a SIMD/Vector Unit.
+@item arch_2_05
+CPU supports ISA 2.05 (eg, POWER6)
+@item arch_2_06
+CPU supports ISA 2.06 (eg, POWER7)
+@item arch_2_07
+CPU supports ISA 2.07 (eg, POWER8)
+@item arch_3_00
+CPU supports ISA 3.00 (eg, POWER9)
+@item archpmu
+CPU supports the set of compatible performance monitoring events.
+@item booke
+CPU supports the Embedded ISA category.
+@item cellbe
+CPU has a CELL broadband engine.
+@item dfp
+CPU has a decimal floating point unit.
+@item dscr
+CPU supports the data stream control register.
+@item ebb
+CPU supports event base branching.
+@item efpdouble
+CPU has a SPE double precision floating point unit.
+@item efpsingle
+CPU has a SPE single precision floating point unit.
+@item fpu
+CPU has a floating point unit.
+@item htm
+CPU has hardware transaction memory instructions.
+@item htm-nosc
+Kernel aborts hardware transactions when a syscall is made.
+@item ic_snoop
+CPU supports icache snooping capabilities.
+@item ieee128
+CPU supports 128-bit IEEE binary floating point instructions.
+@item isel
+CPU supports the integer select instruction.
+@item mmu
+CPU has a memory management unit.
+@item notb
+CPU does not have a timebase (eg, 601 and 403gx).
+@item pa6t
+CPU supports the PA Semi 6T CORE ISA.
+@item power4
+CPU supports ISA 2.00 (eg, POWER4)
+@item power5
+CPU supports ISA 2.02 (eg, POWER5)
+@item power5+
+CPU supports ISA 2.03 (eg, POWER5+)
+@item power6x
+CPU supports ISA 2.05 (eg, POWER6) extended opcodes mffgpr and mftgpr.
+@item ppc32
+CPU supports 32-bit mode execution.
+@item ppc601
+CPU supports the old POWER ISA (eg, 601)
+@item ppc64
+CPU supports 64-bit mode execution.
+@item ppcle
+CPU supports a little-endian mode that uses address swizzling.
+@item smt
+CPU support simultaneous multi-threading.
+@item spe
+CPU has a signal processing extension unit.
+@item tar
+CPU supports the target address register.
+@item true_le
+CPU supports true little-endian mode.
+@item ucache
+CPU has unified I/D cache.
+@item vcrypto
+CPU supports the vector cryptography instructions.
+@item vsx
+CPU supports the vector-scalar extension.
+@end table
+
+Here is an example:
+@smallexample
+if (__builtin_cpu_supports ("fpu"))
+  @{
+     asm("fadd %0,%1,%2" : "=d"(dst) : "d"(src1), "d"(src2));
+  @}
+else
+  @{
+     dst = __fadd (src1, src2); // Software FP addition function.
+  @}
+@end smallexample
+@end deftypefn
+
 These built-in functions are available for the PowerPC family of
 processors:
 @smallexample
index a2c9ba919dcdae76a048430577ab69bf8f1a7961..bd23b3654838d7f602c2582b689e74e653570daa 100644 (file)
@@ -1,3 +1,7 @@
+2016-01-20  Peter Bergner  <bergner@vnet.ibm.com>
+
+       * gcc.target/powerpc/cpu-builtin-1.c: New test.
+
 2016-01-20  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 
        PR c/24293
diff --git a/gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c b/gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c
new file mode 100644 (file)
index 0000000..a0e3041
--- /dev/null
@@ -0,0 +1,65 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+
+void
+use_cpu_is_builtins (unsigned int *p)
+{
+  p[0] = __builtin_cpu_is ("power9");
+  p[1] = __builtin_cpu_is ("power8");
+  p[2] = __builtin_cpu_is ("power7");
+  p[3] = __builtin_cpu_is ("power6x");
+  p[4] = __builtin_cpu_is ("power6");
+  p[5] = __builtin_cpu_is ("power5+");
+  p[6] = __builtin_cpu_is ("power5");
+  p[7] = __builtin_cpu_is ("ppc970");
+  p[8] = __builtin_cpu_is ("power4");
+  p[9] = __builtin_cpu_is ("ppca2");
+  p[10] = __builtin_cpu_is ("ppc476");
+  p[11] = __builtin_cpu_is ("ppc464");
+  p[12] = __builtin_cpu_is ("ppc440");
+  p[13] = __builtin_cpu_is ("ppc405");
+  p[14] = __builtin_cpu_is ("ppc-cell-be");
+}
+
+void
+use_cpu_supports_builtins (unsigned int *p)
+{
+  p[0] = __builtin_cpu_supports ("4xxmac");
+  p[1] = __builtin_cpu_supports ("altivec");
+  p[2] = __builtin_cpu_supports ("arch_2_05");
+  p[3] = __builtin_cpu_supports ("arch_2_06");
+  p[4] = __builtin_cpu_supports ("arch_2_07");
+  p[5] = __builtin_cpu_supports ("arch_3_00");
+  p[6] = __builtin_cpu_supports ("archpmu");
+  p[7] = __builtin_cpu_supports ("booke");
+  p[8] = __builtin_cpu_supports ("cellbe");
+  p[9] = __builtin_cpu_supports ("dfp");
+  p[10] = __builtin_cpu_supports ("dscr");
+  p[11] = __builtin_cpu_supports ("ebb");
+  p[12] = __builtin_cpu_supports ("efpdouble");
+  p[13] = __builtin_cpu_supports ("efpsingle");
+  p[14] = __builtin_cpu_supports ("fpu");
+  p[15] = __builtin_cpu_supports ("htm");
+  p[16] = __builtin_cpu_supports ("htm-nosc");
+  p[17] = __builtin_cpu_supports ("ic_snoop");
+  p[18] = __builtin_cpu_supports ("ieee128");
+  p[19] = __builtin_cpu_supports ("isel");
+  p[20] = __builtin_cpu_supports ("mmu");
+  p[21] = __builtin_cpu_supports ("notb");
+  p[22] = __builtin_cpu_supports ("pa6t");
+  p[23] = __builtin_cpu_supports ("power4");
+  p[24] = __builtin_cpu_supports ("power5");
+  p[25] = __builtin_cpu_supports ("power5+");
+  p[26] = __builtin_cpu_supports ("power6x");
+  p[27] = __builtin_cpu_supports ("ppc32");
+  p[28] = __builtin_cpu_supports ("ppc601");
+  p[29] = __builtin_cpu_supports ("ppc64");
+  p[30] = __builtin_cpu_supports ("ppcle");
+  p[31] = __builtin_cpu_supports ("smt");
+  p[32] = __builtin_cpu_supports ("spe");
+  p[33] = __builtin_cpu_supports ("tar");
+  p[34] = __builtin_cpu_supports ("true_le");
+  p[35] = __builtin_cpu_supports ("ucache");
+  p[36] = __builtin_cpu_supports ("vcrypto");
+  p[37] = __builtin_cpu_supports ("vsx");
+}