===================================================================
@@ -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 */
===================================================================
@@ -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)
===================================================================
@@ -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
===================================================================
@@ -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.
===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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");
+}