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

#### 7.13.23.2 Basic PowerPC Built-in Functions Available on ISA 2.05 ¶

The basic built-in functions described in this section are available on the PowerPC family of processors starting with ISA 2.05 or later. Unless specific options are explicitly disabled on the command line, specifying option `-mcpu=power6` has the effect of enabling the `-mpowerpc64`, `-mpowerpc-gpopt`, `-mpowerpc-gfxopt`, `-mmfcrf`, `-mpopcntb`, `-mfprnd`, `-mcmpb`, `-mhard-dfp`, and `-mrecip-precision` options. Specify the `-maltivec` option explicitly in combination with the above options if desired.

The following functions require option `-mcmpb`.

    unsigned long long __builtin_cmpb (unsigned long long int, unsigned long long int);
    unsigned int __builtin_cmpb (unsigned int, unsigned int);

The `__builtin_cmpb` function performs a byte-wise compare on the contents of its two arguments, returning the result of the byte-wise comparison as the returned value. For each byte comparison, the corresponding byte of the return value holds 0xff if the input bytes are equal and 0 if the input bytes are not equal. If either of the arguments to this built-in function is wider than 32 bits, the function call expands into the form that expects `unsigned long long int` arguments which is only available on 64-bit targets.

The following built-in functions are available when hardware decimal floating point (`-mhard-dfp`) is available:

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

    The __builtin_set_fpscr_drn builtin allows changing the three decimal
    floating point rounding mode bits.  The argument is a 3-bit value.  The
    argument can either be a const int or the value can be stored in
    a variable.
    The builtin uses the ISA 3.0 instruction mffscdrn if available.
    Otherwise the builtin reads the FPSCR, masks the current decimal rounding
    mode bits out and OR's in the new value.

    _Decimal64 __builtin_dfp_quantize (_Decimal64, _Decimal64, const int);
    _Decimal64 __builtin_dfp_quantize (const int, _Decimal64, const int);
    _Decimal128 __builtin_dfp_quantize (_Decimal128, _Decimal128, const int);
    _Decimal128 __builtin_dfp_quantize (const int, _Decimal128, const int);

    The __builtin_dfp_quantize built-in, converts and rounds the second
    argument to the form with the exponent as specified by the first
    argument based on the rounding mode specified by the third argument.
    If the first argument is a decimal floating point value, its exponent is used
    for converting and rounding of the second argument.  If the first argument is a
    5-bit constant integer value, then the value specifies the exponent to be used
    when rounding and converting the second argument.  The third argument is a
    two bit constant integer that specifies the rounding mode.  The possible modes
    are: 00 Round to nearest, ties to even; 01 Round toward 0; 10 Round to nearest,
    ties away from 0; 11 Round according to DRN where DRN is the Decimal Floating
    point field of the FPSCR.

The following functions require `-mhard-float`, `-mpowerpc-gfxopt`, and `-mpopcntb` options.

    double __builtin_recipdiv (double, double);
    float __builtin_recipdivf (float, float);
    double __builtin_rsqrt (double);
    float __builtin_rsqrtf (float);

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 following functions require `-mhard-float` and `-mmultiple` options.

The `__builtin_unpack_longdouble` function takes a `long double` argument and a compile time constant of 0 or 1. If the constant is 0, the first `double` within the `long double` is returned, otherwise the second `double` is returned. The `__builtin_unpack_longdouble` function is only available if `long double` uses the IBM extended double representation.

The `__builtin_pack_longdouble` function takes two `double` arguments and returns a `long double` value that combines the two arguments. The `__builtin_pack_longdouble` function is only available if `long double` uses the IBM extended double representation.

The `__builtin_unpack_ibm128` function takes a `__ibm128` argument and a compile time constant of 0 or 1. If the constant is 0, the first `double` within the `__ibm128` is returned, otherwise the second `double` is returned.

The `__builtin_pack_ibm128` function takes two `double` arguments and returns a `__ibm128` value that combines the two arguments.

Additional built-in functions are available for the 64-bit PowerPC family of processors, for efficient use of 128-bit floating point (`__float128`) values.

Vector select

    vector signed __int128 vec_sel (vector signed __int128,
                   vector signed __int128, vector bool __int128);
    vector signed __int128 vec_sel (vector signed __int128,
                   vector signed __int128, vector unsigned __int128);
    vector unsigned __int128 vec_sel (vector unsigned __int128,
                   vector unsigned __int128, vector bool __int128);
    vector unsigned __int128 vec_sel (vector unsigned __int128,
                   vector unsigned __int128, vector unsigned __int128);
    vector bool __int128 vec_sel (vector bool __int128,
                   vector bool __int128, vector bool __int128);
    vector bool __int128 vec_sel (vector bool __int128,
                   vector bool __int128, vector unsigned __int128);

The instance is an extension of the existing overloaded built-in `vec_sel` that is documented in the PVIPR.

    vector signed __int128 vec_perm (vector signed __int128,
                   vector signed __int128);
    vector unsigned __int128 vec_perm (vector unsigned __int128,
                   vector unsigned __int128);

The instance is an extension of the existing overloaded built-in `vec_perm` that is documented in the PVIPR.