Basic PowerPC Built-in Functions Available on all Configurations (Using the GNU Compiler Collection (GCC))

#### 7.13.23.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);
    double __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` built-in allows changing both of the floating point rounding mode bits and returning the various FPSCR fields before the RN field is updated. The built-in returns a double consisting of the initial value of the FPSCR fields DRN, VE, OE, UE, ZE, XE, NI, and RN bit positions with all other bits set to zero. The built-in argument is a 2-bit value for the new RN field value. The argument can either be an `const int` or stored in a variable. Earlier versions of `__builtin_set_fpscr_rn` returned void. A `__SET_FPSCR_RN_RETURNS_FPSCR__` macro has been added. If defined, then the `__builtin_set_fpscr_rn` built-in returns the FPSCR fields. If not defined, the `__builtin_set_fpscr_rn` does not return a value. If the `-msoft-float` option is used, the `__builtin_set_fpscr_rn` built-in will not return a value.

Built-in Function: `bool` __builtin_ppc_atomic_cas_local `(type *ptr, type *expected, type *desired, bool weak, int success_memorder, int failure_memorder)` ¶

  This built-in function implements a PowerPC-specific atomic compare and exchange operation. It behaves identically to the generic `__atomic_compare_exchange` built-in function, with one key difference: it uses an EH (Extended Hint) value of 1 in the `lbarx`, `lharx`, `lwarx`, or `ldarx` instruction (load-and-reserve indexed).

  The EH bit provides a hint to the processor that the program will perform a subsequent store to the specified location. This hint helps optimize lock contention on PowerPC systems by keeping the lock cacheline in the local processor longer, reducing performance penalties from cache coherence protocol traffic.

  For details on the behavior and semantics of the arguments, refer to the `__atomic_compare_exchange` documentation.

  The first three pointer arguments (ptr, expected, and desired) must point to complete types, and the size of the types they point to must be the same and known at compile time. The types themselves may differ. The supported type sizes are 1, 2, 4, 8, or 16 bytes.