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:
parent
11c7bfe673
commit
26a2e6aed4
@ -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
|
||||
|
@ -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
|
||||
|
105
gcc/config/rs6000/ppc-auxv.h
Normal file
105
gcc/config/rs6000/ppc-auxv.h
Normal 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 */
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
18
gcc/configure
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
65
gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c
Normal file
65
gcc/testsuite/gcc.target/powerpc/cpu-builtin-1.c
Normal 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");
|
||||
}
|
Loading…
Reference in New Issue
Block a user