ppc-auxv.h: New file.

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

From-SVN: r232634
This commit is contained in:
Peter Bergner 2016-01-20 14:30:24 -06:00 committed by Peter Bergner
parent 11c7bfe673
commit 26a2e6aed4
11 changed files with 603 additions and 0 deletions

View 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

View File

@ -2074,6 +2074,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

View File

@ -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 */

View 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)

View 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

View 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)
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.

18
gcc/configure vendored
View File

@ -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

View 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

View 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

View 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

View File

@ -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");
}