Built-ins (The GNU Modula-2 Compiler)

### 2.21 Accessing GNU Modula-2 Built-ins ¶

This section describes the built-in constants and functions defined in GNU Modula-2. The following compiler constants can be accessed using the `__ATTRIBUTE__` `__BUILTIN__` keywords. These are not part of the Modula-2 language and they may differ depending upon the target architecture but they provide a method whereby common libraries can interface to a different underlying architecture.

The built-in constants are: `BITS_PER_UNIT`, `BITS_PER_WORD`, `BITS_PER_CHAR` and `UNITS_PER_WORD`. They are integrated into GNU Modula-2 by an extension to the `ConstFactor` rule:

    ConstFactor := ConstQualidentOrSet | Number | ConstString |
                   "(" ConstExpression ")" | "NOT" ConstFactor |
                   ConstAttribute =:

    ConstAttribute := "__ATTRIBUTE__" "__BUILTIN__" "(" "(" Ident ")" ")" =:

Here is an example taken from the ISO library `SYSTEM.def`:

    CONST
       BITSPERLOC    = __ATTRIBUTE__ __BUILTIN__ ((BITS_PER_UNIT)) ;
       LOCSPERWORD   = __ATTRIBUTE__ __BUILTIN__ ((UNITS_PER_WORD)) ;

Built-in functions are transparent to the end user. All built-in functions are declared in `DEFINITION MODULE`s and are imported as and when required. Built-in functions are declared in definition modules by using the `__BUILTIN__` keyword. Here is a section of the ISO library `LongMath.def` which demonstrates this feature.

    PROCEDURE __BUILTIN__ sqrt (x: LONGREAL): LONGREAL;
      (* Returns the square root of x *)

This indicates that the function `sqrt` will be implemented using the gcc built-in maths library. If gcc cannot utilize the built-in function (for example if the programmer requested the address of `sqrt`) then code is generated to call the alternative function implemented in the `IMPLEMENTATION` `MODULE`.

Sometimes a function exported from the `DEFINITION` `MODULE` will have a different name from the built-in function within gcc. In such cases the mapping between the GNU Modula-2 function name and the gcc name is expressed using the keywords `__ATTRIBUTE__` `__BUILTIN__` `((Ident))`. For example the function `sqrt` in `LongMath.def` maps onto the gcc built-in function `sqrtl` and this is expressed as:

    PROCEDURE __ATTRIBUTE__ __BUILTIN__ ((sqrtl)) sqrt
                                        (x: LONGREAL) : LONGREAL;
      (* Returns the positive square root of x *)

The following module `Builtins.def` enumerates the list of built-in functions which can be accessed in GNU Modula-2. It also serves to define the parameter and return value for each function:

    DEFINITION MODULE Builtins ;

    FROM SYSTEM IMPORT ADDRESS ;

    (* Floating point intrinsic procedure functions.  *)

    PROCEDURE __BUILTIN__ isnanf (x: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isnan (x: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isnanl (x: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ isfinitef (x: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isfinite (x: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isfinitel (x: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ sinf (x: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ sin (x: REAL) : REAL ;
    PROCEDURE __BUILTIN__ sinl (x: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ cosf (x: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ cos (x: REAL) : REAL ;
    PROCEDURE __BUILTIN__ cosl (x: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ sqrtf (x: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ sqrt (x: REAL) : REAL ;
    PROCEDURE __BUILTIN__ sqrtl (x: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ atan2f (x, y: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ atan2 (x, y: REAL) : REAL ;
    PROCEDURE __BUILTIN__ atan2l (x, y: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ fabsf (x: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ fabs (x: REAL) : REAL ;
    PROCEDURE __BUILTIN__ fabsl (x: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ logf (x: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ log (x: REAL) : REAL ;
    PROCEDURE __BUILTIN__ logl (x: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ expf (x: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ exp (x: REAL) : REAL ;
    PROCEDURE __BUILTIN__ expl (x: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ log10f (x: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ log10 (x: REAL) : REAL ;
    PROCEDURE __BUILTIN__ log10l (x: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ exp10f (x: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ exp10 (x: REAL) : REAL ;
    PROCEDURE __BUILTIN__ exp10l (x: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ ilogbf (x: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ ilogb (x: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ ilogbl (x: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ huge_val () : REAL ;
    PROCEDURE __BUILTIN__ huge_valf () : SHORTREAL ;
    PROCEDURE __BUILTIN__ huge_vall () : LONGREAL ;

    PROCEDURE __BUILTIN__ modf (x: REAL; VAR y: REAL) : REAL ;
    PROCEDURE __BUILTIN__ modff (x: SHORTREAL;
                                 VAR y: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ modfl (x: LONGREAL; VAR y: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ signbit (r: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ signbitf (s: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ signbitl (l: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ nextafter (x, y: REAL) : REAL ;
    PROCEDURE __BUILTIN__ nextafterf (x, y: SHORTREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ nextafterl (x, y: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ nexttoward (x: REAL; y: LONGREAL) : REAL ;
    PROCEDURE __BUILTIN__ nexttowardf (x: SHORTREAL; y: LONGREAL) : SHORTREAL ;
    PROCEDURE __BUILTIN__ nexttowardl (x, y: LONGREAL) : LONGREAL ;

    PROCEDURE __BUILTIN__ scalbln (x: REAL; n: LONGINT) : REAL ;
    PROCEDURE __BUILTIN__ scalblnf (x: SHORTREAL; n: LONGINT) : SHORTREAL ;
    PROCEDURE __BUILTIN__ scalblnl (x: LONGREAL; n: LONGINT) : LONGREAL ;

    PROCEDURE __BUILTIN__ scalbn (x: REAL; n: INTEGER) : REAL ;
    PROCEDURE __BUILTIN__ scalbnf (x: SHORTREAL; n: INTEGER) : SHORTREAL ;
    PROCEDURE __BUILTIN__ scalbnl (x: LONGREAL; n: INTEGER) : LONGREAL ;

    PROCEDURE __BUILTIN__ isgreater (x, y: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isgreaterf (x, y: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isgreaterl (x, y: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ isgreaterequal (x, y: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isgreaterequalf (x, y: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isgreaterequall (x, y: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ isless (x, y: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ islessf (x, y: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ islessl (x, y: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ islessequal (x, y: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ islessequalf (x, y: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ islessequall (x, y: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ islessgreater (x, y: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ islessgreaterf (x, y: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ islessgreaterl (x, y: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ isunordered (x, y: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isunorderedf (x, y: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isunorderedl (x, y: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ iseqsig (x, y: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ iseqsigf (x, y: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ iseqsigl (x, y: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ isnormal (r: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isnormalf (s: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isnormall (l: LONGREAL) : INTEGER ;

    PROCEDURE __BUILTIN__ isinf_sign (r: REAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isinf_signf (s: SHORTREAL) : INTEGER ;
    PROCEDURE __BUILTIN__ isinf_signl (l: LONGREAL) : INTEGER ;

    (* Complex arithmetic intrincic procedure functions.  *)

    PROCEDURE __BUILTIN__ cabsf (z: SHORTCOMPLEX) : SHORTREAL ;
    PROCEDURE __BUILTIN__ cabs (z: COMPLEX) : REAL ;
    PROCEDURE __BUILTIN__ cabsl (z: LONGCOMPLEX) : LONGREAL ;

    PROCEDURE __BUILTIN__ cargf (z: SHORTCOMPLEX) : SHORTREAL ;
    PROCEDURE __BUILTIN__ carg (z: COMPLEX) : REAL ;
    PROCEDURE __BUILTIN__ cargl (z: LONGCOMPLEX) : LONGREAL ;

    PROCEDURE __BUILTIN__ conjf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ conj (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ conjl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ cpowerf (base: SHORTCOMPLEX;
                                   exp: SHORTREAL) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ cpower (base: COMPLEX; exp: REAL) : COMPLEX ;
    PROCEDURE __BUILTIN__ cpowerl (base: LONGCOMPLEX;
                                   exp: LONGREAL) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ csqrtf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ csqrt (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ csqrtl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ cexpf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ cexp (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ cexpl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ clnf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ cln (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ clnl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ csinf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ csin (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ csinl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ ccosf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ ccos (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ ccosl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ ctanf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ ctan (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ ctanl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ carcsinf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ carcsin (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ carcsinl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ carccosf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ carccos (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ carccosl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    PROCEDURE __BUILTIN__ carctanf (z: SHORTCOMPLEX) : SHORTCOMPLEX ;
    PROCEDURE __BUILTIN__ carctan (z: COMPLEX) : COMPLEX ;
    PROCEDURE __BUILTIN__ carctanl (z: LONGCOMPLEX) : LONGCOMPLEX ;

    (* memory and string intrincic procedure functions *)

    PROCEDURE __BUILTIN__ alloca (i: CARDINAL) : ADDRESS ;
    PROCEDURE __BUILTIN__ memcpy (dest, src: ADDRESS;
                                  nbytes: CARDINAL) : ADDRESS ;
    PROCEDURE __BUILTIN__ index (s: ADDRESS; c: INTEGER) : ADDRESS ;
    PROCEDURE __BUILTIN__ rindex (s: ADDRESS; c: INTEGER) : ADDRESS ;
    PROCEDURE __BUILTIN__ memcmp (s1, s2: ADDRESS;
                                  nbytes: CARDINAL) : INTEGER ;
    PROCEDURE __BUILTIN__ memset (s: ADDRESS; c: INTEGER;
                                  nbytes: CARDINAL) : ADDRESS ;
    PROCEDURE __BUILTIN__ memmove (s1, s2: ADDRESS;
                                   nbytes: CARDINAL) : ADDRESS ;
    PROCEDURE __BUILTIN__ strcat (dest, src: ADDRESS) : ADDRESS ;
    PROCEDURE __BUILTIN__ strncat (dest, src: ADDRESS;
                                   nbytes: CARDINAL) : ADDRESS ;
    PROCEDURE __BUILTIN__ strcpy (dest, src: ADDRESS) : ADDRESS ;
    PROCEDURE __BUILTIN__ strncpy (dest, src: ADDRESS;
                                   nbytes: CARDINAL) : ADDRESS ;
    PROCEDURE __BUILTIN__ strcmp (s1, s2: ADDRESS) : INTEGER ;
    PROCEDURE __BUILTIN__ strncmp (s1, s2: ADDRESS;
                                   nbytes: CARDINAL) : INTEGER ;
    PROCEDURE __BUILTIN__ strlen (s: ADDRESS) : INTEGER ;
    PROCEDURE __BUILTIN__ strstr (haystack, needle: ADDRESS) : ADDRESS ;
    PROCEDURE __BUILTIN__ strpbrk (s, accept: ADDRESS) : ADDRESS ;
    PROCEDURE __BUILTIN__ strspn (s, accept: ADDRESS) : CARDINAL ;
    PROCEDURE __BUILTIN__ strcspn (s, accept: ADDRESS) : CARDINAL ;
    PROCEDURE __BUILTIN__ strchr (s: ADDRESS; c: INTEGER) : ADDRESS ;
    PROCEDURE __BUILTIN__ strrchr (s: ADDRESS; c: INTEGER) : ADDRESS ;

    PROCEDURE __BUILTIN__ clz (value: CARDINAL) : INTEGER ;
    PROCEDURE __BUILTIN__ clzll (value: LONGCARD) : INTEGER ;
    PROCEDURE __BUILTIN__ ctz (value: CARDINAL) : INTEGER ;
    PROCEDURE __BUILTIN__ ctzll (value: LONGCARD) : INTEGER ;

    (*
       longjmp - this GCC builtin restricts the val to always 1.
    *)
    (* do not use these two builtins, as gcc, only really
       anticipates that the Ada front end should use them
       and it only uses them in its runtime exception handling.
       We leave them here in the hope that someday they will
       behave more like their libc counterparts.  *)

    PROCEDURE __BUILTIN__ longjmp (env: ADDRESS; val: INTEGER) ;
    PROCEDURE __BUILTIN__ setjmp (env: ADDRESS) : INTEGER ;

    (*
       frame_address - returns the address of the frame.
                       The current frame is obtained if level is 0,
                       the next level up if level is 1 etc.
    *)

    PROCEDURE __BUILTIN__ frame_address (level: CARDINAL) : ADDRESS ;

    (*
       return_address - returns the return address of function.
                        The current function return address is
                        obtained if level is 0,
                        the next level up if level is 1 etc.
    *)

    PROCEDURE __BUILTIN__ return_address (level: CARDINAL) : ADDRESS ;

    (*
       alloca_trace - this is a no-op which is used for internal debugging.
    *)

    PROCEDURE alloca_trace (returned: ADDRESS; nBytes: CARDINAL) : ADDRESS ;

    END Builtins.

Although this module exists and will result in the generation of in-line code if optimization flags are passed to GNU Modula-2, users are advised to utilize the same functions from more generic libraries. The built-in mechanism will be applied to these generic libraries where appropriate. Note for the mathematical routines to be in-lined you need to specify the ‘`-ffast-math -O`’ options.