VMS Help  —  CC  Language topics, Builtin Functions
  Built-in functions allow you to directly access hardware and
  machine instructions to perform operations that are cumbersome,
  slow, or impossible in pure C.

  These functions are very efficient because they are built into the
  VSI C compiler.  This means that a call to one of these functions
  does not result in a reference to a function in the C run-time
  library or in your programs.  Instead, the compiler generates the
  machine instructions necessary to carry out the function directly
  at the call site.  Because most of these built-in functions closely
  correspond to single VAX, Alpha, or Itanium machine instructions,
  the result is small, fast code.

  Some of these functions (such as those that operate on strings or
  bits) are of general interest.  Others (such as the functions
  dealing with process context) are of interest if you are writing
  device drivers or other privileged software.  Some of the functions
  are privileged and unavailable to user mode programs.

  Be sure to include the <builtins.h> header file in your source
  program to access these built-in functions.

  VSI C supports the #pragma builtins preprocessor directive for
  compatibility with VAX C, but it is not required.

  Some of the built-in functions have optional arguments or allow a
  particular argument to have one of many different types.  To
  describe different valid combinations of arguments, the description
  of each built-in function may list several different prototypes for
  the function.  As long as a call to a built-in function matches one
  of the prototypes listed, the call is valid.  Furthermore, any
  valid call to a built-in function acts as if the corresponding
  prototype was in scope, so the compiler performs the argument
  checking and argument conversions specified by that prototype.

  The majority of the built-in functions are named after the machine
  instruction that they generate.  For more information on these
  built-in functions, see the documentation on the corresponding
  machine instruction.  In particular, see that reference for the
  structure of queue entries manipulated by the queue built-in
  functions.

1  –  Alpha Compatibility

  The VSI C built-in functions available on OpenVMS Alpha systems are
  also available on I64 systems, with some differences:

   o  There is no support for the asm, fasm, and dasm intrinsics
      (declared in the <c_asm.h> header file).

   o  The functionality provided by the special-case treatment of R26
      on an Alpha system asm, as in asm("MOV R26,R0"), is provided by
      a new built-in function for I64 systems:

      __int64 __RETURN_ADDRESS(void);

   o  The only PAL function calls implemented as built-in functions
      within the compiler are the 24 queue-manipulation builtins.
      The queue manipulation builtins generate calls to new OpenVMS
      system services SYS$<name>, where <name> is the name of the
      builtin with the leading underscores removed.

      Any other OpenVMS PAL calls are supported through macros
      defined in the <pal_builtins.h> header file included in the
      <builtins.h> header file.  Typically, the macros in
      <pal_builtins.h> transform an invocation of an Alpha system
      builtin into a call to a system service that performs the
      equivalent function on an I64 system.  Two notable exceptions
      are __PAL_GENTRAP and __PAL_BUGCHK, which instead invoke the
      I64 specific compiler builtin __break2.

   o  There is no support for the various floating-point built-in
      functions used by the OPenVMS math library (for example,
      operations with chopped rounding and conversions).

   o  For most built-in functions that take a retry count, the
      compiler issues a warning message, evaluates the count for
      possible side effects, ignores it, and then invokes the same
      function without a retry count.  This is necessary because the
      retry behavior allowed by Alpha load-locked/store-conditional
      sequences does not exist on I64 systems.  There are two
      exceptions to this:  __LOCK_LONG_RETRY and
      __ACQUIRE_SEM_LONG_RETRY; in these cases, the retry behavior
      involves comparisons of data values, not just
      load-locked/store-conditional.

   o  The __CMP_STORE_LONG and __CMP_STORE_QUAD built-in functions
      produce either a warning or an error, depending on whether or
      not the compiler can determine if the source and destination
      addresses are identical.  If the addresses are identical, the
      compiler treats the builtin as the new __CMP_SWAP_ form and
      issues a warning.  Otherwise it is an error.

2  –  <builtins.h>

  The <builtins.h> header file contains a section at the top
  conditionalized to just __ia64 with the support for built-in
  functions specific to I64 systems.  This includes macro definitions
  for all of the registers that can be specified to the __getReg,
  __setReg, __getIndReg, and __setIndReg built-in functions.
  Parameters that are const-qualified require an argument that is a
  compile-time constant.

     Notes:

      o  The <builtins.h> header file contains comments noting which
         built-in functions are not available or are not the
         preferred form for I64 systems.  The compiler issues
         diagnostics where using a different built-in function for
         I64 systems would be preferable.

      o  The comments in <builtins.h> reflect only what is explicitly
         present in that header file itself, and in the compiler
         implementation.  You should also consult the content and
         comments in <pal_builtins.h> to determine more accurately
         what functionality is effectively provided by including
         <builtins.h>.  For example, if a program explicitly declares
         one of the Alpha built-in functions and invokes it without
         having included <builtins.h>, the compiler might issue a
         BIFNOTAVAIL error message, regardless of whether or not the
         function is available through a system service.  If the
         compilation does include <builtins.h>, and BIFNOTAVAIL is
         issued, then either there is no support at all for the
         built-in function or a new version of <pal_builtins.h> is
         needed.

3  –  __break

  Generates a break instruction with an immediate.

  Syntax:

       void __break (const int __break_arg);

4  –  __break2

  Implements the Alpha __PAL_GENTRAP and __PAL_BUGCHK built-in
  functions on OpenVMS I64 systems.

  The __break2 function is equivalent to the __break function with
  the second parameter passed in general register 17:

  R17 = __R17_value; __break (__break_code);

  Syntax:

       void __break2 (__Integer_Constant __break_code, unsigned
       __int64 __r17_value);

5  –  CMP SWAP LONG

  Performs a conditional atomic compare and exchange operation on a
  longword.  The longword pointed to by source is read and compared
  with the longword old_value.  If they are equal, the longword
  new_value is written into the longword pointed to by source.  The
  read and write is performed atomically, with no intervening access
  to the same memory region.

  The function returns 1 if the write occurs, and 0 otherwise.

  Syntax:

       int __CMP_SWAP_LONG (volatile void *source, int old_value, int
       new_value);

6  –  CMP SWAP QUAD

  Performs a conditional atomic compare and exchange operation on a
  quadword.  The quadword pointed to by source is read and compared
  with the quadword old_value.  If they are equal, the quadword
  new_value is written into the quadword pointed to by source.  The
  read and write is performed atomically, with no intervening access
  to the same memory region.

  The function returns 1 if the write occurs, and 0 otherwise.

  Syntax:

       int __CMP_SWAP_QUAD (volatile void *source, int old_value, int
       new_value);

7  –  CMP SWAP LONG ACQ

  Performs a conditional atomic compare and exchange operation with
  acquire semantics on a longword.  The longword pointed to by source
  is read and compared with the longword old_value.  If they are
  equal, the longword new_value is written into the longword pointed
  to by source.  The read and write is performed atomically, with no
  intervening access to the same memory region.

  Acquire memory ordering guarantees that the memory read/write is
  made visible before all subsequent data accesses to the same memory
  location by other processors.

  The function returns 1 if the write occurs, and 0 otherwise.

  Syntax:

       int __CMP_SWAP_LONG_ACQ (volatile void *source, int old_value,
       int new_value);

8  –  CMP SWAP QUAD ACQ

  Performs a conditional atomic compare and exchange operation with
  acquire semantics on a quadword.  The quadword pointed to by source
  is read and compared with the quadword old_value.  If they are
  equal, the quadword new_value is written into the quadword pointed
  to by source.  The read and write is performed atomically, with no
  intervening access to the same memory region.

  Acquire memory ordering guarantees that the memory read/write is
  made visible before all subsequent memory data accesses to the same
  memory location by other processors.

  The function returns 1 if the write occurs, and 0 otherwise.

  Syntax:

       int __CMP_SWAP_QUAD_ACQ (volatile void *source, int old_value,
       int new_value);

9  –  CMP SWAP LONG REL

  Performs a conditional atomic compare and exchange operation with
  release semantics on a longword.  The longword pointed to by source
  is read and compared with the longword old_value.  If they are
  equal, the longword new_value is written into the longword pointed
  to by source.  The read and write is performed atomically, with no
  intervening access to the same memory region.

  Release memory ordering guarantees that the memory read/write is
  made visible after all previous data memory acceses to the same
  memory location by other processors.

  The function returns 1 if the write occurs, and 0 otherwise.

  Syntax:

       int __CMP_SWAP_LONG_REL (volatile void *source, int old_value,
       int new_value);

10  –  CMP SWAP QUAD REL

  Performs a conditional atomic compare and exchange operation with
  release semantics on a quadword.  The quadword pointed to by source
  is read and compared with the quadword old_value.  If they are
  equal, the quadword new_value is written into the quadword pointed
  to by source.  The read and write is performed atomically, with no
  intervening access to the same memory region.

  Release memory ordering guarantees that the memory read/write is
  made visible after all previous data memory acceses to the same
  memory location by other processors.

  The function returns 1 if the write occurs, and 0 otherwise.

  Syntax:

       int __CMP_SWAP_QUAD_REL (volatile void *source, int old_value,
       int new_value);

11  –  RETURN ADDRESS

  Produces the address to which the function containing the built-in
  call will return as a 64-bit integer (on Alpha systems, the value
  of R26 on entry to the function; on I64 systems, the value of B0 on
  entry to the function).

  This built-in function cannot be used within a function specified
  to use nonstandard linkage.

  Syntax:

       __int64 __RETURN_ADDRESS (void);

12  –  __dsrlz

  Serializes data.  Maps to the srlz.d instruction.

  Syntax:

       void __dsrlz (void);

13  –  __fc

  Flushes a cache line associated with the address given by the
  argument.  Maps to the fcr instruction.

  Syntax:

       void __fc (__int64 __address);

14  –  __flushrs

  Flushes the register stack.

  Syntax:

       void __flushrs (void);

15  –  __fwb

  Flushes the write buffers.  Maps to the fwb instruction.

  Syntax:

       void __fwb (void);

16  –  getIndReg

  Returns the value of an indexed register.  The function accesses a
  register (index) in a register file (whichIndReg) of 64-bit
  registers.

  Syntax:

       unsigned __int64 __getIndReg (const int whichIndReg, __int64
       index);

17  –  getReg

  Gets the value from a hardware register based on the register index
  specified.  This function produces a corresponding mov = r
  instruction.

  Syntax:

       unsigned __int64 __getReg (const int whichReg);

18  –  InterlockedCompareExchange acq

  Atomically compares and exchanges the value specified by the first
  argument (a 64-bit pointer).  This function maps to the
  cmpxchg4.acq instruction with appropriate setup.

  The value at *Destination is compared with the value specified by
  Comparand.  If they are equal, Newval is written to *Destination,
  and Oldval is returned.  The exchange will have taken place if the
  value returned is equal to the Comparand.  The following algorithm
  is used:

  ar.ccv = Comparand;
  Oldval = *Destination;         //Atomic
  if (ar.ccv == *Destination)    //Atomic
      *Destination = Newval;     //Atomic
  return Oldval;

  Those parts of the algorithm marked "Atomic" are performed
  atomically by the cmpxchg4.acq instruction.  This instruction has
  acquire ordering semantics; that is, the memory read/write is made
  visible prior to all subsequent data memory accesses of the
  Destination by other processors.

  Syntax:

       unsigned __int64 _InterlockedCompareExchange_acq (volatile
       unsigned int *Destination, unsigned __int64 Newval, unsigned
       __int64 Comparand);

19  –  InterlockedCompareExchange64 acq

  Same as the _InterlockedCompareExchange_acq function, except that
  those parts of the algorithm that are marked "Atomic" are performed
  by the cmpxchg8.acq instruction.

  Syntax:

       unsigned __int64 _InterlockedCompareExchange64_acq (volatile
       unsigned int64 *Destination, unsigned __int64 Newval, unsigned
       __int64 Comparand);

20  –  InterlockedCompareExchange rel

  Same as the _InterlockedCompareExchange_acq function except that
  those parts of the algorithm that are marked "Atomic" are performed
  by the cmpxchg4.rel instruction with release ordering semantics;
  that is, the memory read/write is made visible after all previous
  memory accesses of the Destination by other processors.

  Syntax:

       unsigned __int64 _InterlockedCompareExchange_rel (volatile
       unsigned int *Destination, unsigned __int64 Newval, unsigned
       __int64 Comparand);

21  –  InterlockedCompareExchange64 rel

  Same as the _InterlockedCompareExchange_rel function, except that
  those parts of the algorithm that are marked "Atomic" are performed
  by the cmpxchg8.rel instruction.

  Syntax:

       unsigned __int64 _InterlockedCompareExchange64_rel (volatile
       unsigned int64 *Destination, unsigned __int64 Newval, unsigned
       __int64 Comparand);

22  –  __invalat

  Invalidates ALAT.  Maps to the invala instruction.

  Syntax:

       void __invalat (void);

23  –  __invala

  Same as the __invalat function.

  Syntax:

       void __invala (void);

24  –  __isrlz

  Executes the serialize instruction.  Maps to the srlz.i
  instruction.

  Syntax:

       void __isrlz (void);

25  –  __itcd

  Inserts an entry into the data translation cache.  Maps to the
  itc.d instruction

  Syntax:

       void __itcd (__int64 pa);

26  –  __itci

  Inserts an entry into the instruction translation cache.  Maps to
  the itc.i instruction.

  Syntax:

       void __itci (__int64 pa);

27  –  __itrd

  Maps to the itr.d instruction.

  Syntax:

       void __itrd (__int64 whichTransReg, __int64 pa);

28  –  __itri

  Maps to the itr.i instruction.

  Syntax:

       void __itri (__int64 whichTransReg, __int64 pa);

29  –  __loadrs

  Loads the register stack.

  Syntax:

       void __loadrs (void);

30  –  __prober

  Determines whether read access to the virtual address specified by
  __address bits {60:0} and the region register indexed by __address
  bits {63:61} is permitted at the privilege level given by __mode
  bits {1:0}.  It returns 1 if the access is permitted, and 0
  otherwise.

  This function can probe only with equal or lower privilege levels.
  If the specified privilege level is higher (lower number), then the
  probe is performed with the current privilege level.

  This function is the same as the Intel __probe_r function.

  Syntax:

       int __prober (__int64 __address, unsigned int __mode);

31  –  __probew

  Determines whether write access to the virtual address specified by
  __address bits {60:0} and the region register indexed by __address
  bits {63:61}, is permitted at the privilege level given by __mode
  bits {1:0}.  It returns 1 if the access is permitted, and 0
  otherwise.

  This function can probe only with equal or lower privilege levels.
  If the specified privilege level is higher (lower number), then the
  probe is performed with the current privilege level.

  This function is the same as the Intel __probe_w function.

  Syntax:

       int __probew (__int64 __address, unsigned int __mode);

32  –  __ptce

  Maps to the ptc.e instruction.

  Syntax:

       void __ptce (__int64 va);

33  –  __ptcl

  Purges the local translation cache.  Maps to the ptc.l r,r
  instruction.

  Syntax:

       void __ptcl (__int64 va, __int64 pagesz);

34  –  __ptcg

  Purges the global translation cache.  Maps to the ptc.g r,r
  instruction.

  Syntax:

       void __ptcg (__int64 va, __int64 pagesz);

35  –  __ptcga

  Purges the global translation cache and ALAT.  Maps to the ptc.ga
  r,r instruction.

  Syntax:

       void __ptcga (__int64 va, __int64 pagesz);

36  –  __ptri

  Purges the instruction translation register.  Maps to the ptr.i r,r
  instruction.

  Syntax:

       void __ptri (__int64 va, __int64 pagesz);

37  –  __ptrd

  Purges the data translation register.  Maps to the ptr.d r,r
  instruction.

  Syntax:

       void __ptrd (__int64 va, __int64 pagesz);

38  –  __rum

  Resets the user mask.

  Syntax:

       void __rum (int mask);

39  –  __rsm

  Resets the system mask bits of the PSR.  Maps to the rsm imm24
  instruction.

  Syntax:

       void __rsm (int mask);

40  –  setIndReg

  Copies a value into an indexed register.  The function accesses a
  register (index) in a register file (whichIndReg) of 64-bit
  registers.

  Syntax:

       void __setIndReg (const int whichIndReg, __int64 index,
       unsigned __int64 value);

41  –  setReg

  Sets the value for a hardware register based on the register index
  specified.  This function produces a corresponding mov = r
  instruction.

  Syntax:

       void __int64 __setReg (const int whichReg, unsigned __int64
       value);

42  –  __ssm

  Sets the system mask.

  Syntax:

       void __ssm (int mask);

43  –  __sum

  Sets the user mask bits of the PSR.  Maps to the sum imm24
  instruction.

  Syntax:

       void __sum (int mask);

44  –  __synci

  Enables memory synchronization.  Maps to the sync.i instruction.

  Syntax:

       void __synci (void);

45  –  __tak

  Returns the translation access key.

  Syntax:

       unsigned int __tak (__int64 __address);

46  –  __tpa

  Translates a virtual address to a physical address.

  Syntax:

       __int64 __tpa(__int64 __address);

47  –  __thash

  Generates a translation hash entry address.  Maps to the thash r =
  r instruction.

  Syntax:

       void __thash(__int64 __address);

48  –  __ttag

  Generates a translation hash entry tag.  Maps to the ttag r=r
  instruction.

  Syntax:

       void __ttag(__int64 __address);
Close Help