This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, rs6000] Add support for __builtin_cpu_is() and __builtin_cpu_supports()


This patch adds support for __builtin_cpu_init(), __builtin_cpu_is() and
__builtin_cpu_supports() builtins for PowerPC.  We use the same API as the
x86* builtins of the same name.  These builtins uses the new GLIBC 2.23
feature where we store the AT_PLATFORM, AT_HWCAP and AT_HWCAP2 values in the
Thread Control Block (TCB) which offers very fast access to these values.

As part of the agreement with the GLIBC community, we always emit a reference
to a special symbol exported by LIBCs that support the AT_PLATFORM/AT_HWCAP*
values in the TCB, whenever we expand one of the CPU builtins.  We do this
so that we will never attempt to access the TCB on old LIBCs.  Joseph also
asked that we conditionalize the enabling of this code with a configure time
check for GLIBC's version and that is included here.

I'll note that since GLIBC initializes the TCB before the application gets
control, we don't actually need __builtin_cpu_init(), but we have implemented
it anyway, to keep the same API as x86.  It's just our init expands to nothing.

This passes bootstrap and regtesting with no errors.  Ok for mainline?

Peter


gcc/
	* 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.

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

Index: gcc/config/rs6000/ppc-auxv.h
===================================================================
--- gcc/config/rs6000/ppc-auxv.h	(revision 0)
+++ gcc/config/rs6000/ppc-auxv.h	(working copy)
@@ -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: gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc/config/rs6000/rs6000-builtin.def	(revision 232359)
+++ gcc/config/rs6000/rs6000-builtin.def	(working copy)
@@ -2025,6 +2025,15 @@
 	          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: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 232359)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -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 @@
   { "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.  */
@@ -13381,7 +13464,102 @@
   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)
 {
   rtx pat;
@@ -14709,6 +14887,11 @@
     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:
       {
@@ -15100,6 +15283,14 @@
 				    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)
@@ -31606,6 +31797,17 @@
 
   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: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 232359)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -1362,6 +1362,9 @@
 /* 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)
+
 
 /* Define the classes of registers for register constraints in the
    machine description.  Also define ranges of constants.
Index: gcc/config.in
===================================================================
--- gcc/config.in	(revision 232359)
+++ gcc/config.in	(working copy)
@@ -2068,6 +2068,12 @@
 #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
Index: gcc/configure
===================================================================
--- gcc/configure	(revision 232359)
+++ gcc/configure	(working copy)
@@ -28526,6 +28526,24 @@
 
 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: gcc/configure.ac
===================================================================
--- gcc/configure.ac	(revision 232359)
+++ gcc/configure.ac	(working copy)
@@ -5532,6 +5532,19 @@
 	    [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: gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c	(working copy)
@@ -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");
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]