Next: Basic PowerPC Built-in Functions Available on ISA 2.05, Up: Basic PowerPC Built-in Functions

##### 6.60.22.1 Basic PowerPC Built-in Functions Available on all Configurations

— 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 `__builtin_cpu_is` function requires GLIBC 2.23 or newer which exports the hardware capability bits. GCC defines the macro `__BUILTIN_CPU_SUPPORTS__` if the `__builtin_cpu_supports` built-in function is fully supported.

> If GCC was configured to use a GLIBC before 2.23, the built-in function `__builtin_cpu_is` always returns a 0 and the compiler issues a warning.

> The following CPU names can be detected:

> ``power10`'
>   IBM POWER10 Server CPU.
> ``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:

>               #ifdef __BUILTIN_CPU_SUPPORTS__
>                 if (__builtin_cpu_is ("power8"))
>                   {
>                      do_power8 (); // POWER8 specific implementation.
>                   }
>                 else
>               #endif
>                   {
>                      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 `__builtin_cpu_supports` function requires GLIBC 2.23 or newer which exports the hardware capability bits. GCC defines the macro `__BUILTIN_CPU_SUPPORTS__` if the `__builtin_cpu_supports` built-in function is fully supported.

> If GCC was configured to use a GLIBC before 2.23, the built-in function `__builtin_cpu_supports` always returns a 0 and the compiler issues a warning.

> 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.0 (eg, POWER9)
> ``arch_3_1`'
>   CPU supports ISA 3.1 (eg, POWER10)
> ``archpmu`'
>   CPU supports the set of compatible performance monitoring events.
> ``booke`'
>   CPU supports the Embedded ISA category.
> ``cellbe`'
>   CPU has a CELL broadband engine.
> ``darn`'
>   CPU supports the `darn` (deliver a random number) instruction.
> ``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.
> ``htm-no-suspend`'
>   CPU supports hardware transaction memory but does not support the `tsuspend.` instruction.
> ``ic_snoop`'
>   CPU supports icache snooping capabilities.
> ``ieee128`'
>   CPU supports 128-bit IEEE binary floating point instructions.
> ``isel`'
>   CPU supports the integer select instruction.
> ``mma`'
>   CPU supports the matrix-multiply assist instructions.
> ``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.
> ``scv`'
>   Kernel supports system call vectored.
> ``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:

>               #ifdef __BUILTIN_CPU_SUPPORTS__
>                 if (__builtin_cpu_supports ("fpu"))
>                   {
>                      asm("fadd %0,%1,%2" : "=d"(dst) : "d"(src1), "d"(src2));
>                   }
>                 else
>               #endif
>                   {
>                      dst = __fadd (src1, src2); // Software FP addition function.
>                   }

The following built-in functions are also available on all PowerPC processors:

         uint64_t __builtin_ppc_get_timebase ();
         unsigned long __builtin_ppc_mftb ();
         double __builtin_unpack_ibm128 (__ibm128, int);
         __ibm128 __builtin_pack_ibm128 (double, double);
         double __builtin_mffs (void);
         void __builtin_mtfsf (const int, double);
         void __builtin_mtfsb0 (const int);
         void __builtin_mtfsb1 (const int);
         void __builtin_set_fpscr_rn (int);

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 `__builtin_mffs` return the value of the FPSCR register. Note, ISA 3.0 supports the `__builtin_mffsl()` which permits software to read the control and non-sticky status bits in the FSPCR without the higher latency associated with accessing the sticky status bits. The `__builtin_mtfsf` takes a constant 8-bit integer field mask and a double precision floating point argument and generates the `mtfsf` (extended mnemonic) instruction to write new values to selected fields of the FPSCR. The `__builtin_mtfsb0` and `__builtin_mtfsb1` take the bit to change as an argument. The valid bit range is between 0 and 31. The builtins map to the `mtfsb0` and `mtfsb1` instructions which take the argument and add 32. Hence these instructions only modify the FPSCR[32:63] bits by changing the specified bit to a zero or one respectively. The `__builtin_set_fpscr_rn` builtin allows changing both of the floating point rounding mode bits. The argument is a 2-bit value. The argument can either be a `const int` or stored in a variable. The builtin uses the ISA 3.0 instruction `mffscrn` if available, otherwise it reads the FPSCR, masks the current rounding mode bits out and OR's in the new value.