PowerPC Built-in Functions - Using the GNU Compiler Collection (GCC)
Description: Using the GNU Compiler Collection (GCC)

Next: PowerPC AltiVec/VSX Built-in Functions, Previous: picoChip Built-in Functions, Up: Target Builtins

#### 6.59.19 PowerPC Built-in Functions

The following built-in functions are always available and can be used to check the PowerPC target platform type:

— Built-in Function: void __builtin_cpu_init (void)

> This function is a `nop` on the PowerPC platform and is included solely to maintain API compatibility with the x86 builtins.

— Built-in Function: int __builtin_cpu_is (const char *cpuname)

> This function returns a value of `1` if the run-time CPU is of type cpuname and returns `0` otherwise. The following CPU names can be detected:

> ‘`power9`’
>   IBM POWER9 Server CPU.
> ‘`power8`’
>   IBM POWER8 Server CPU.
> ‘`power7`’
>   IBM POWER7 Server CPU.
> ‘`power6x`’
>   IBM POWER6 Server CPU (RAW mode).
> ‘`power6`’
>   IBM POWER6 Server CPU (Architected mode).
> ‘`power5+`’
>   IBM POWER5+ Server CPU.
> ‘`power5`’
>   IBM POWER5 Server CPU.
> ‘`ppc970`’
>   IBM 970 Server CPU (ie, Apple G5).
> ‘`power4`’
>   IBM POWER4 Server CPU.
> ‘`ppca2`’
>   IBM A2 64-bit Embedded CPU
> ‘`ppc476`’
>   IBM PowerPC 476FP 32-bit Embedded CPU.
> ‘`ppc464`’
>   IBM PowerPC 464 32-bit Embedded CPU.
> ‘`ppc440`’
>   PowerPC 440 32-bit Embedded CPU.
> ‘`ppc405`’
>   PowerPC 405 32-bit Embedded CPU.
> ‘`ppc-cell-be`’
>   IBM PowerPC Cell Broadband Engine Architecture CPU.

> Here is an example:

>               if (__builtin_cpu_is ("power8"))
>                 {
>                    do_power8 (); // POWER8 specific implementation.
>                 }
>               else
>                 {
>                    do_generic (); // Generic implementation.
>                 }

— Built-in Function: int __builtin_cpu_supports (const char *feature)

> This function returns a value of `1` if the run-time CPU supports the HWCAP feature feature and returns `0` otherwise. The following features can be detected:

> ‘`4xxmac`’
>   4xx CPU has a Multiply Accumulator.
> ‘`altivec`’
>   CPU has a SIMD/Vector Unit.
> ‘`arch_2_05`’
>   CPU supports ISA 2.05 (eg, POWER6)
> ‘`arch_2_06`’
>   CPU supports ISA 2.06 (eg, POWER7)
> ‘`arch_2_07`’
>   CPU supports ISA 2.07 (eg, POWER8)
> ‘`arch_3_00`’
>   CPU supports ISA 3.00 (eg, POWER9)
> ‘`archpmu`’
>   CPU supports the set of compatible performance monitoring events.
> ‘`booke`’
>   CPU supports the Embedded ISA category.
> ‘`cellbe`’
>   CPU has a CELL broadband engine.
> ‘`dfp`’
>   CPU has a decimal floating point unit.
> ‘`dscr`’
>   CPU supports the data stream control register.
> ‘`ebb`’
>   CPU supports event base branching.
> ‘`efpdouble`’
>   CPU has a SPE double precision floating point unit.
> ‘`efpsingle`’
>   CPU has a SPE single precision floating point unit.
> ‘`fpu`’
>   CPU has a floating point unit.
> ‘`htm`’
>   CPU has hardware transaction memory instructions.
> ‘`htm-nosc`’
>   Kernel aborts hardware transactions when a syscall is made.
> ‘`ic_snoop`’
>   CPU supports icache snooping capabilities.
> ‘`ieee128`’
>   CPU supports 128-bit IEEE binary floating point instructions.
> ‘`isel`’
>   CPU supports the integer select instruction.
> ‘`mmu`’
>   CPU has a memory management unit.
> ‘`notb`’
>   CPU does not have a timebase (eg, 601 and 403gx).
> ‘`pa6t`’
>   CPU supports the PA Semi 6T CORE ISA.
> ‘`power4`’
>   CPU supports ISA 2.00 (eg, POWER4)
> ‘`power5`’
>   CPU supports ISA 2.02 (eg, POWER5)
> ‘`power5+`’
>   CPU supports ISA 2.03 (eg, POWER5+)
> ‘`power6x`’
>   CPU supports ISA 2.05 (eg, POWER6) extended opcodes mffgpr and mftgpr.
> ‘`ppc32`’
>   CPU supports 32-bit mode execution.
> ‘`ppc601`’
>   CPU supports the old POWER ISA (eg, 601)
> ‘`ppc64`’
>   CPU supports 64-bit mode execution.
> ‘`ppcle`’
>   CPU supports a little-endian mode that uses address swizzling.
> ‘`smt`’
>   CPU support simultaneous multi-threading.
> ‘`spe`’
>   CPU has a signal processing extension unit.
> ‘`tar`’
>   CPU supports the target address register.
> ‘`true_le`’
>   CPU supports true little-endian mode.
> ‘`ucache`’
>   CPU has unified I/D cache.
> ‘`vcrypto`’
>   CPU supports the vector cryptography instructions.
> ‘`vsx`’
>   CPU supports the vector-scalar extension.

> Here is an example:

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

These built-in functions are available for the PowerPC family of processors:

         float __builtin_recipdivf (float, float);
         float __builtin_rsqrtf (float);
         double __builtin_recipdiv (double, double);
         double __builtin_rsqrt (double);
         uint64_t __builtin_ppc_get_timebase ();
         unsigned long __builtin_ppc_mftb ();
         double __builtin_unpack_longdouble (long double, int);
         long double __builtin_pack_longdouble (double, double);

The `vec_rsqrt`, `__builtin_rsqrt`, and `__builtin_rsqrtf` functions generate multiple instructions to implement the reciprocal sqrt functionality using reciprocal sqrt estimate instructions.

The `__builtin_recipdiv`, and `__builtin_recipdivf` functions generate multiple instructions to implement division using the reciprocal estimate instructions.

The `__builtin_ppc_get_timebase` and `__builtin_ppc_mftb` functions generate instructions to read the Time Base Register. The `__builtin_ppc_get_timebase` function may generate multiple instructions and always returns the 64 bits of the Time Base Register. The `__builtin_ppc_mftb` function always generates one instruction and returns the Time Base Register value as an unsigned long, throwing away the most significant word on 32-bit environments.

The following built-in functions are available for the PowerPC family of processors, starting with ISA 2.06 or later (`-mcpu=power7` or `-mpopcntd`):

         long __builtin_bpermd (long, long);
         int __builtin_divwe (int, int);
         int __builtin_divweo (int, int);
         unsigned int __builtin_divweu (unsigned int, unsigned int);
         unsigned int __builtin_divweuo (unsigned int, unsigned int);
         long __builtin_divde (long, long);
         long __builtin_divdeo (long, long);
         unsigned long __builtin_divdeu (unsigned long, unsigned long);
         unsigned long __builtin_divdeuo (unsigned long, unsigned long);
         unsigned int cdtbcd (unsigned int);
         unsigned int cbcdtd (unsigned int);
         unsigned int addg6s (unsigned int, unsigned int);

The `__builtin_divde`, `__builtin_divdeo`, `__builtin_divdeu`, `__builtin_divdeou` functions require a 64-bit environment support ISA 2.06 or later.

The following built-in functions are available for the PowerPC family of processors when hardware decimal floating point (`-mhard-dfp`) is available:

         _Decimal64 __builtin_dxex (_Decimal64);
         _Decimal128 __builtin_dxexq (_Decimal128);
         _Decimal64 __builtin_ddedpd (int, _Decimal64);
         _Decimal128 __builtin_ddedpdq (int, _Decimal128);
         _Decimal64 __builtin_denbcd (int, _Decimal64);
         _Decimal128 __builtin_denbcdq (int, _Decimal128);
         _Decimal64 __builtin_diex (_Decimal64, _Decimal64);
         _Decimal128 _builtin_diexq (_Decimal128, _Decimal128);
         _Decimal64 __builtin_dscli (_Decimal64, int);
         _Decimal128 __builtin_dscliq (_Decimal128, int);
         _Decimal64 __builtin_dscri (_Decimal64, int);
         _Decimal128 __builtin_dscriq (_Decimal128, int);
         unsigned long long __builtin_unpack_dec128 (_Decimal128, int);
         _Decimal128 __builtin_pack_dec128 (unsigned long long, unsigned long long);

The following built-in functions are available for the PowerPC family of processors when the Vector Scalar (vsx) instruction set is available:

         unsigned long long __builtin_unpack_vector_int128 (vector __int128_t, int);
         vector __int128_t __builtin_pack_vector_int128 (unsigned long long,
                                                         unsigned long long);