6.2 Built-In Functions

Sections 6.2.1 and 6.2.2 describe the DEC C built-in functions available in all compiler modes on OpenVMS Alpha and OpenVMS VAX systems.

These functions allow you to directly access hardware and machine instructions to perform operations that are cumbersome, slow, or impossible in other C compilers.

These functions are very efficient because they are built into the DEC C compiler. This means that a call to one of these functions does not result in a reference to a function in the DEC C Run-Time Library (RTL) or to a function in your program. 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 or Alpha machine instructions, the result is small, fast code.

Some of these built-in 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 discussed in the following sections 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. VAX C required you to place the #pragma builtins preprocessor directive, rather than #include <builtins.h>, in your source file before using one or more built-in functions. DEC C supports #pragma builtins for compatibility with VAX C, but Digital recommends using #include <builtins.h> for compatibility with DEC C on other platforms.)


Note
DEC C implements #pragma builtins as if it were #include <builtins.h>; if you get an error from #pragma builtins, it is the same kind of error you would get if you specified #include <builtins.h>.

Some of the built-in functions have optional arguments or allow a particular argument to have one of many different types. To describe all valid combinations of arguments, the following built-in function descriptions 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 behaves as if the corresponding prototype were in scope of the call. The compiler, therefore, performs the argument checking and conversions specified by that prototype.

The majority of the built-in functions are named after the processor instruction that they generate. The built-in functions provide direct and unencumbered access to those VAX instructions. Any inherent limitations to those instructions are limitations to the built-in functions as well. For instance, the MOVC3 instruction and the _MOVC3 built-in function can move at most 65,535 characters.

For more information on these built-in functions, see the corresponding machine instruction in the VAX MACRO and Instruction Set Reference Manual, Alpha Architecture Handbook, or Alpha Architecture Reference Manual. In particular, refer to the structure of queue entries manipulated by the built-in queue functions.

6.2.1 Built-In Functions for OpenVMS Alpha Systems (Alpha only)

The following sections describe the DEC C built-in functions available on OpenVMS Alpha systems.

6.2.1.1 Translation Macros for VAX C Built-in Functions

On DEC C for OpenVMS Alpha Systems, the <builtins.h> header file contains macro definitions that translate some VAX C built-in functions to the equivalent DEC C for OpenVMS Alpha built-in functions. Consequently, the following VAX C built-in functions are effectively supported:


_BBCCI
_BBSSI
_INSQHI
_INSQTI
_INSQUE
_REMQHI
_REMQTI
_REMQUE
_PROBER
_PROBEW

For more detail on any of these functions, see <builtins.h> or the description of the corresponding native Alpha function in this chapter. For example, for a description of _INSQHI, see __PAL_INSQHIL.

6.2.1.2 Intrinsic Functions-ASMs

DEC C supports in-line assembly code, commonly called ASMs on UNIX platforms.

Like builtin-functions, ASMs are implemented with a function-call syntax. But unlike built-in functions, to use ASMs you must include the <c_asm.h> header file containing prototypes for the three types of ASMs, and the #pragma intrinsic preprocessor directive.

These functions have the following format:

__int64  asm(const char *, . . . );   /* for integer operations,
like MULQ */
float fasm(const char *, . . . );    /* for single precision float
instructions, like MULS */
double dasm(const char *, . . . );    /* for double precision float
instructions, like MULT */

#pragma intrinsic (asm, fasm, dasm)
const char *
The first argument to the asm, fasm, or dasm function contains the instruction(s) to be generated inline and the metalanguage that describes the interpretation of the arguments.
. . .
The source and destination arguments (if any) for the instruction being generated, and any other values used in the generated instructions.

These values are made available to the instructions through the normal argument passing conventions of the calling standard (the first integer argument is available in register R16).

The #pragma intrinsic directive in the <c_asm.h> header file is required when using ASMs. It notifies the compiler that:

The metalanguage for the argument references has the following form:

<metalanguage_sequence> : <register_alias>
                        | <register_number>
                        | <register_macro>
                        ;

<register_number>       : "$" number
                        ;

<register_macro>        : "%" <macro_sequence>
                        ;

<macro_sequence>        : number
                        | <register_name>
                        | "f" number | "F" number
                        | "r" number | "R" number
                        ;

<register_name> :     /* argument registers: R16-R21 */
                     "a0" | "a1" | "a2" | "a3" | "a4" | "a5"

                     /* return value: R0 or F0, depending on type */
                   | "v0"

                     /* scratch registers: R1, R22-R24, R28 */
                   | "t0" | "t1" | "t2" | "t3" | "t4"

                     /* save registers: R2-R15 */
                   | "s0" | "s1" | "s2" | "s3" | "s4"  | "s5"  | "s6"  | "s7"
                   | "s8" | "s7" | "s8" | "s9" | "s10" | "s11" | "s12" | "s13"

                     /* stack pointer: R30 */
                   | "sp" | "SP" | "$sp" | "$SP"

                   | "RA" | "ra"           /* return addr:        R26  */
                   | "PV" | "pv"           /* procedure value:    R27  */
                   | "AI" | "ai"           /* arg info:           R25  */
                   | "FP" | "fp"           /* frame pointer:      R29  */
                   | "RZ" | "rz" | "zero"  /* sink/source: R31 == zero */

Syntactically, the metalanguage can appear anywhere within an instruction sequence.

The literal string that contains instructions, operands, and metalanguage must follow the general form:

<string_contents>       :  <instruction_seq>
                        |  <string_contents> ";" <instruction_seq>
                        |  error
                        |  <string_contents> error
                        ;

<instruction_seq>       :  instruction_operand
                        |  directive
                        ;

An instruction_operand is generally recognized as an assembly language instruction separated by whitespace from a sequence of comma-separated operands.

You can code multiple instruction sequences into one literal string, separating them by semicolons.

Since the C language concatentates adjacent string literals into a single string, successive instructions can be written as separate strings, one per line (as is normally done in assembly language) as long as each instruction is terminated by a semicolon (as shown in the examples).

There are semantic and syntax rules associated with ASMs:

6.2.1.3 Absolute Value ( __ABS)

The __ABS built-in is functionally equivalent to its counterpart, abs, in the standard header file <stdlib.h>.

Its format is also the same:

#include <stdlib.h>
int  __ABS (int x);

This built-in does, however, offer performance improvements because there is less call overhead associated with its use.

If you include <stdlib.h>, the built-in is automatically used for all occurrences of abs. To disable the built-in, use #undef abs.

6.2.1.4 Acquire and Release Longword Semaphore (__ACQUIRE_SEM_LONG, __RELEASE_SEM_LONG)

The __ACQUIRE_SEM_LONG and __RELEASE_SEM_LONG functions provide a counted semaphore capability where the positive value of a longword is interpreted as the number of resources available.

The __ACQUIRE_SEM_LONG function loops until the longword has a positive value and then decrements it within a load-locked/store- conditional sequence; it then issues a memory barrier. This function returns 1 if the resource count was successfully decremented within the specified number of retries, and 0 otherwise. With no explicit retry count, the function does not return until it succeeds.

The __RELEASE_SEM_LONG function issues a memory barrier and then does an __ATOMIC_INCREMENT_LONG on the longword.

The __ACQUIRE_SEM_LONG function has one of the following formats:

int  __ACQUIRE_SEM_LONG (volatile void *address);
int  __ACQUIRE_SEM_LONG_RETRY (volatile void *address, int
retry);

The __RELEASE_SEM_LONG function has the following format:

int  __RELEASE_SEM_LONG (volatile void *address);
address
The longword-aligned address of the resource count.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the longword.

6.2.1.5 Add Aligned Word Interlocked ( __ADAWI)

The __ADAWI function adds its source operand to the destination. This function is interlocked against similar operations by other processors or devices in the system.

This function has the following format:

int  __ADAWI (short src, volatile short *dest);
src
The value to be added to the destination.
dest
A pointer to the destination. The destination must be aligned on a word boundary. (You can achieve alignment using the _align storage-class modifier.)

The __ADAWI function returns a simulated VAX processor status longword (PSL), the lower 4 bits of which are significant. These 4 bits are the condition codes and are defined as follows:

6.2.1.6 Add Atomic Longword ( __ADD_ATOMIC_LONG)

The __ADD_ATOMIC_LONG function adds the specified expression to the aligned longword pointed to by the address parameter within a load-locked/store-conditional code sequence.

This function has the following format:

int  __ADD_ATOMIC_LONG (void *address, int
expression, ...);
address
The address of the aligned longword.
expression
An integer expression.
. . .
An optional retry count of type int. If specified, the retry count indicates the number of times the operation is attempted (which will be at least once, even if the count argument is 0). If the operation cannot be performed successfully in the specified number of retries, a value of 0 is returned.

A value of 1 is returned upon successful completion.

6.2.1.7 Add Atomic Quadword ( __ADD_ATOMIC_QUAD)

The __ADD_ATOMIC_QUAD function adds the specified expression to the aligned quadword pointed to by the address parameter within a load-locked/store-conditional code sequence.

This function has the following format:

int  __ADD_ATOMIC_QUAD (void *address, int
expression, ...);
address
The address of the aligned quadword.
expression
An integer expression.
. . .
An optional retry count of type int. If specified, the retry count indicates the number of times the operation is attempted (which will be at least once, even if the count argument is 0). If the operation cannot be performed successfully in the specified number of retries, a value of 0 is returned.

A value of 1 is returned upon successful completion.

6.2.1.8 Allocate Bytes from Stack ( __ALLOCA)

The __ALLOCA function allocates n bytes from the stack.

This function has the following format:

void  *__ALLOCA (unsigned int n);
n
The number of bytes to be allocated.

A pointer to the allocated memory is returned.

6.2.1.9 AND Atomic Longword ( __AND_ATOMIC_LONG)

The __AND_ATOMIC_LONG function performs a logical AND of the specified expression with the aligned longword pointed to by the address parameter within a load-locked/store-conditional code sequence.

This function has the following format:

int  __AND_ATOMIC_LONG (void *address, int
expression, ...);
address
The longword-aligned address of the data segment.
expression
An integer expression.
. . .
An optional retry count of type int. If specified, the retry count indicates the number of times the operation is attempted (which will be at least once, even if the count argument is 0). If the operation cannot be performed successfully in the specified number of retries, a value of 0 is returned.

A value of 1 is returned upon successful completion.

6.2.1.10 AND Atomic Quadword ( __AND_ATOMIC_QUAD)

The __AND_ATOMIC_QUAD function performs a logical AND of the specified expression with the aligned quadword pointed to by the address parameter within a load-locked/store-conditional code sequence.

This function has the following format:

int  __AND_ATOMIC_QUAD (void *address, int
expression, ...);
address
The address of the aligned quadword.
expression
An integer expression.
. . .
An optional retry count of type int. If specified, the retry count indicates the number of times the operation is attempted (which will be at least once, even if the count argument is 0). If the operation cannot be performed successfully in the specified number of retries, a value of 0 is returned.

A value of 1 is returned upon successful completion.

6.2.1.11 Atomic Add Longword (__ATOMIC_ADD_LONG)

The __ATOMIC_ADD_LONG function adds the specified expression to the aligned longword pointed to by the address parameter within a load-locked/store-conditional code sequence and returns the value of the longword before the addition was performed.

This function has one of the following formats:

int  __ATOMIC_ADD_LONG (volatile void *address, int
expression);

int  __ATOMIC_ADD_LONG_RETRY (volatile void *address, int
expression, int retry, int *status);
address
The longword-aligned address of the data segment.
expression
An integer expression.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the longword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.12 Atomic Add Quadword (__ATOMIC_ADD_QUAD)

The __ATOMIC_ADD_QUAD function adds the specified expression to the aligned quadword pointed to by the address parameter within a load-locked/store-conditional code sequence and returns the value of the quadword before the addition was performed.

This function has one of the following formats:

int  __ATOMIC_ADD_QUAD (volatile void *address, int
expression);

int  __ATOMIC_ADD_QUAD_RETRY (volatile void *address, int
expression, int retry, int *status);
address
The quadword-aligned address of the data segment.
expression
An integer expression.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the quadword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.13 Atomic AND Longword (__ATOMIC_AND_LONG)

The __ATOMIC_AND_LONG function performs a logical AND of the specified expression with the aligned longword pointed to by the address parameter within a load-locked/store-conditional code sequence and returns the value of the longword before the operation was performed.

This function has one of the following formats:

int  __ATOMIC_AND_LONG (volatile void *address, int
expression);

int  __ATOMIC_AND_LONG_RETRY (volatile void *address, int
expression, int retry, int *status);
address
The longword-aligned address of the data segment.
expression
An integer expression.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the longword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.14 Atomic AND Quadword (__ATOMIC_AND_QUAD)

The __ATOMIC_AND_QUAD function performs a logical AND of the specified expression with the aligned quadword pointed to by the address parameter within a load-locked/store-conditional code sequence and returns the value of the quadword before the operation was performed.

This function has one of the following formats:

int  __ATOMIC_AND_QUAD (volatile void *address, int
expression);

int  __ATOMIC_AND_QUAD_RETRY (volatile void *address, int
expression, int retry, int *status);
address
The quadword-aligned address of the data segment.
expression
An integer expression.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the quadword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.15 Atomic OR Longword (__ATOMIC_OR_LONG)

The __ATOMIC_OR_LONG function performs a logical OR of the specified expression with the aligned longword pointed to by the address parameter within a load-locked/store-conditional code sequence and returns the value of the longword before the operation was performed.

This function has one of the following formats:

int  __ATOMIC_OR_LONG (volatile void *address, int
expression);

int  __ATOMIC_OR_LONG_RETRY (volatile void *address, int
expression, int retry, int *status);
address
The longword-aligned address of the data segment.
expression
An integer expression.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the longword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.16 Atomic OR Quadword (__ATOMIC_OR_QUAD)

The __ATOMIC_OR_QUAD function performs a logical OR of the specified expression with the aligned quadword pointed to by the address parameter within a load-locked/store-conditional code sequence and returns the value of the quadword before the operation was performed.

This function has one of the following formats:

int  __ATOMIC_OR_QUAD (volatile void *address, int
expression);

int  __ATOMIC_OR_QUAD_RETRY (volatile void *address, int
expression, int retry, int *status);
address
The quadword-aligned address of the data segment.
expression
An integer expression.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the quadword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.17 Atomic Increment Longword (__ATOMIC_INCREMENT_LONG)

The __ATOMIC_INCREMENT_LONG function increments by 1 the aligned longword pointed to by the address parameter within a load- locked/store-conditional code sequence and returns the value of the longword before the operation was performed.

This function has the following format:

int  __ATOMIC_INCREMENT_LONG (volatile void *address);
address
The longword-aligned address of the data segment.

6.2.1.18 Atomic Increment Quadword (__ATOMIC_INCREMENT_QUAD)

The __ATOMIC_INCREMENT_QUAD function increments by 1 the aligned quadword pointed to by the address parameter within a load- locked/store-conditional code sequence and returns the value of the quadword before the operation was performed.

This function has the following format:

int  __ATOMIC_INCREMENT_QUAD (volatile void *address);
address
The quadword-aligned address of the data segment.

6.2.1.19 Atomic Decrement Longword (__ATOMIC_DECREMENT_LONG)

The __ATOMIC_DECREMENT_LONG function decrements by 1 the aligned longword pointed to by the address parameter within a load- locked/store-conditional code sequence and returns the value of the longword before the operation was performed.

This function has the following format:

int  __ATOMIC_DECREMENT_LONG (volatile void *address);
address
The longword-aligned address of the data segment.

6.2.1.20 Atomic Decrement Quadword (__ATOMIC_DECREMENT_QUAD)

The __ATOMIC_DECREMENT_QUAD function decrements by 1 the aligned quadword pointed to by the address parameter within a load- locked/store-conditional code sequence and returns the value of the quadword before the operation was performed.

This function has the following format:

int  __ATOMIC_DECREMENT_QUAD (volatile void *address);
address
The quadword-aligned address of the data segment.

6.2.1.21 Atomic Exchange Longword (__ATOMIC_EXCH_LONG)

The __ATOMIC_EXCH_LONG function stores the value of the specified expression into the aligned longword pointed to by the address parameter within a load-locked/store-conditional code sequence and returns the value of the longword before the operation was performed.

This function has one of the following formats:

int  __ATOMIC_EXCH_LONG (volatile void *address, int
expression);

int  __ATOMIC_EXCH_LONG_RETRY (volatile void *address, int
expression, int retry, int *status);
address
The longword-aligned address of the data segment.
expression
An integer expression.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the longword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.22 Atomic Exchange Quadword (__ATOMIC_EXCH_QUAD)

The __ATOMIC_EXCH_QUAD function stores the value of the specified expression into the aligned quadword pointed to by the address parameter within a load-locked/store-conditional code sequence and returns the value of the quadword before the operation was performed.

This function has one of the following formats:

int  __ATOMIC_EXCH_QUAD (volatile void *address, int
expression);

int  __ATOMIC_EXCH_QUAD_RETRY (volatile void *address, int
expression, int retry, int *status);
address
The quadword-aligned address of the data segment.
expression
An integer expression.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the quadword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.23 Compare Store Longword ( __CMP_STORE_LONG)

The __CMP_STORE_LONG function has the following format:

int  __CMP_STORE_LONG (volatile void *source, int old_
value, int new_value, volatile void *dest);

This function performs a conditional atomic compare and update operation involving one or two longwords in the same lock region. The value pointed to by source is compared with the longword old_value. If they are equal, the longword new_value is conditionally stored into the value pointed to by dest.

The store will not complete if the compare yields unequal values or if there is an intervening store to the lock region involved. To be in the same lock region, source and dest must point to aligned longwords in the same naturally aligned 16-byte region.

The function returns 0 if the store does not complete, and returns 1 if the store does complete.

6.2.1.24 Compare Store Quadword ( __CMP_STORE_QUAD)

The __CMP_STORE_QUAD function has the following format:

int  __CMP_STORE_QUAD (volatile void *source, int64
old_value, int64 new_value, volatile void
*dest);

This function performs a conditional atomic compare and update operation involving one or two quadwords in the same lock region. The value pointed to by source is compared with the quadword old_value. If they are equal, the quadword new_value is conditionally stored into the value pointed to by dest.

The store will not complete if the compare yields unequal values or if there is an intervening store to the lock region involved. To be in the same lock region, source and dest must point to aligned quadwords in the same naturally aligned 16-byte region.

The function returns 0 if the store does not complete, and returns 1 if the store does complete.

6.2.1.25 Convert G_Floating to F_Floating Chopped ( __CVTGF_C)

The __CVTGF_C function converts a double-precision, VAX G_floating- point number to a single-precision, VAX F_floating-point number. This conversion chops to single-precision; then the 8-bit exponent range is checked for overflow or underflow.

This function has the following format:

float  __CVTGF_C (double operand);
operand
A double-precision, VAX floating-point number.

6.2.1.26 Convert G_Floating to Quadword ( __CVTGQ)

The __CVTGQ function rounds a double-precision, VAX floating-point number to a 64-bit integer value and returns the result.

This function has the following format:

int64  __CVTGQ (double operand);
operand
A double-precision, VAX floating-point number.

6.2.1.27 Convert IEEE T_Floating to IEEE S_Floating Chopped ( __CVTTS_C)

The __CVTTS_C function converts a double-precision, IEEE T_floating- point number to a single-precision, IEEE S_floating-point number. This conversion chops to single-precision; then the 8-bit exponent range is checked for overflow or underflow.

This function has the following format:

float  __CVTTS_C (double operand);
operand
A double-precision, IEEE floating-point number.

6.2.1.28 Convert IEEE T_Floating to Quadword ( __CVTTQ)

The __CVTTQ function rounds a double-precision, IEEE T_floating- point number to a 64-bit integer value and returns the result.

This function has the following format:

int64  __CVTTQ (double operand);
operand
A double-precision, IEEE T_floating-point number.

6.2.1.29 Convert X_Floating to Quadword ( __CVTXQ)

The __CVTXQ function converts an X_floating-point number to a 64-bit integer value and returns the result.

This function has the following format:

int64  __CVTXQ (long double operand);
operand
An X_floating-point number.

6.2.1.30 Convert X_Floating to IEEE T_Floating Chopped ( __CVTXT_C)

The __CVTXT_C function converts an X_floating-point number to an IEEE T_floating-point number and returns the result.

This function has the following format:

double  __CVTXT_C (long double operand);
operand
An X_floating-point number.

6.2.1.31 Copy Sign Built-in Functions

Built-in functions are provided to copy selected portions of single- and double-precision, floating-point numbers.

These built-in functions have the following format:

float   __CPYSF (float operand1, float operand2);
double  __CPYS (double operand1, double operand2);

float   __CPYSNF (float operand1, float operand2);
double  __CPYSN (double operand1, double
operand2);

float   __CPYSEF (float operand1, float operand2);
double  __CPYSE (double operand1, double
operand2);

The copy sign built-ins (__CPYSF and __CPYS) fetch the sign bit in operand1, concatenate it with the exponent and fraction bits from operand2, and return the result.

The copy sign negate built-ins (__CPYSNF and __CPYSN) fetch the sign bit in operand1, complement it, concatenate it with the exponent and fraction bits from operand2, and return the result.

The copy sign exponent built-ins (__CPYSEF and __CPYSE) fetch the sign and exponent bits from operand1, concatenate them with the fraction bits from operand2, and return the result.

6.2.1.32 Cosine ( __COS)

The __COS built-in function is functionally equivalent to its counterpart, cos, in the standard header file <math.h>.

Its format is also the same:

#include <math.h>
double  __COS (double x);
x
A radian value.

This built-in offers performance improvements because there is less call overhead associated with its use.

If you include <math.h>, the built-in is automatically used for all occurrences of cos. To disable the built-in, use #undef cos.

6.2.1.33 Double-Precision, Floating-Point Arithmetic Built-in Functions

The following built-in functions provide double-precision, floating- point chopped arithmetic:
__ADDG_C   __ADDT_C   __SUBG_C   __SUBT_C 
__MULG_C   __MULT_C   __DIVG_C   __DIVT_C 

They have the following format:

double  __op{G,T}_C (double operand1, double
operand2);

Where op is one of ADD, SUB, MUL, DIV, and {G,T} represents VAX or IEEE floating-point arithmetic, respectively.

The result of the arithmetic operation is returned.

6.2.1.34 Floating-Point Absolute Value ( __FABS)

The __FABS built-in function is functionally equivalent to its counterpart, fabs, in the standard header file <math.h>.

Its format is also the same:

#include <math.h>
double  __FABS (double x);
x
A floating-point number.

This built-in offers performance improvements because there is no call overhead associated with its use.

If you include <math.h>, the built-in is automatically used for all occurrences of fab. To disable the built-in, use #undef fab.

6.2.1.35 Long Double-Precision, Floating-Point Arithmetic Built-in Functions

The following built-in functions provide long double-precision, floating-point chopped arithmetic:
__ADDX_C   __SUBX_C 
__MULX_C   __DIVX_C 

They have the following format:

long double  __opX_C (long double operand1, long
double operand2);

Where op is one of ADD, SUB, MUL, DIV.

The result of the arithmetic operation is returned.

6.2.1.36 Longword Absolute Value ( __LABS)

The __LABS built-in is functionally equivalent to its counterpart, labs, in the standard header file <stdlib.h>.

Its format is also the same:

#include <stdlib.h>
long int  __LABS (long int x);
x
An integer.

This built-in offers performance improvements because there is less call overhead associated with its use.

If you include <stdlib.h>, the built-in is automatically used for all occurrences of labs. To disable the built-in, use #undef labs.

6.2.1.37 Lock and Unlock Longword (__LOCK_LONG, __UNLOCK_LONG)

The __LOCK_LONG and __UNLOCK_LONG functions provide a binary spinlock capability based on the low-order bit of a longword.

The __LOCK_LONG function executes in a loop waiting for the bit to be cleared and then sets it within a load-locked/store-conditional sequence; it then issues a memory barrier. The __UNLOCK_LONG function issues a memory barrier and then zeroes the longword.

The __LOCK_LONG_RETRY function returns 1 if the lock was acquired in the specified number of retries and 0 if the lock was not acquired.

The __LOCK_LONG function has one of the following formats:

int  __LOCK_LONG (volatile void *address);

int  __LOCK_LONG_RETRY (volatile void *address, int
retry);

The __UNLOCK_LONG function has the following format:

int  __UNLOCK_LONG (volatile void *address);
address
The quadword-aligned address of the longword used for the lock.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the longword.

6.2.1.38 Memory Barrier ( __MB)

The __MB function directs the compiler to generate a memory barrier instruction.

This function has the following format:

void  __MB (void);

6.2.1.39 Memory Copy and Set Functions ( __MEMCPY, __MEMMOVE, __MEMSET)

The __MEMCPY, __MEMMOVE, and __MEMSET built-ins are functionally equivalent to their run-time routine counterparts in the standard header file <string.h>.

Their format is also the same:

#include <string.h>
void  *__MEMCPY (void *s1, const void *s2, size_t
size);
void  *__MEMMOVE (void *s1, const void *s2, size_t
size);
void  *__MEMSET (void *s, int value, size_t
size);

These built-ins offer performance improvements because there is less call overhead associated with their use.

If you include <string.h>, the built-ins are automatically used for all occurrences of memcpy, memmove, and memset. To disable the built-ins, use #undef memcpy, #undef memmove, and #undef memset.

6.2.1.40 OR Atomic Longword ( __OR_ATOMIC_LONG)

The __OR_ATOMIC_LONG function performs a logical OR of the specified expression with the aligned longword pointed to by the address parameter within a load-locked/store-conditional code sequence.

This function has the following format:

int  __OR_ATOMIC_LONG (void *address, int
expression, ...);
address
The address of the aligned longword.
expression
An integer expression.
. . .
An optional retry count of type int. If specified, the retry count indicates the number of times the operation is attempted (which will be at least once, even if the count argument is 0). If the operation cannot be performed successfully in the specified number of retries, a value of 0 is returned.

A value of 1 is returned upon successful completion.

6.2.1.41 OR Atomic Quadword ( __OR_ATOMIC_QUAD)

The __OR_ATOMIC_QUAD function performs a logical OR of the specified expression with the aligned quadword pointed to by the address parameter within a load-locked/store-conditional code sequence.

This function has the following format:

int  __OR_ATOMIC_QUAD (void *address, int
expression, ...);
address
The address of the aligned quadword.
expression
An integer expression.
. . .
An optional retry count of type int. If specified, the retry count indicates the number of times the operation is attempted (which will be at least once, even if the count argument is 0). If the operation cannot be performed successfully in the specified number of retries, a value of 0 is returned.

A value of 1 is returned upon successful completion.

6.2.1.42 Privileged Architecture Library Code Instructions

The following sections describe the Privileged Architecture Library Code (PALcode) instructions that are available as built-in functions.

6.2.1.43 __PAL_BPT

This function is provided for program debugging. It switches the processor to kernel mode and pushes registers R2 through R7, the updated PC, and PS onto the kernel stack. It then dispatches to the address in the breakpoint vector, which is stored in a control block.

This function has the following format:

void  __PAL_BPT (void);

6.2.1.44 __PAL_BUGCHK

This function is provided for error reporting. It switches the processor to kernel mode and pushes registers R2 through R7, the updated PC, and PS onto the kernel stack. It then dispatches to the address in the bugcheck vector, which is stored in a control block.

This function has the following format:

void  __PAL_BUGCHK (void);

6.2.1.45 __PAL_CFLUSH

This function flushes at least the entire physical page specified by the page frame number value from any data caches associated with the current processor. After a CFLUSH is done, the first subsequent load on the same processor to an arbitrary address in the target page is fetched from physical memory.

This function has the following format:

void  __PAL_CFLUSH (int value);
value
A page frame number.

6.2.1.46 __PAL_CHME

This function allows a process to change its mode to Executive in a controlled manner. The change in mode also results in a change of stack pointers: the old pointer is saved and the new pointer is loaded. Registers R2 through R7, PS, and PC are pushed onto the selected stack. The saved PC addresses the instruction following the CHME instruction.

This function has the following format:

void  __PAL_CHME (void);

6.2.1.47 __PAL_CHMK

This function allows a process to change its mode to kernel in a controlled manner. The change in mode also results in a change of stack pointers: the old pointer is saved and the new pointer is loaded. Registers R2 through R7, PS, and PC are pushed onto the kernel stack. The saved PC addresses the instruction following the CHMK instruction.

This function has the following format:

void  __PAL_CHMK (void);

6.2.1.48 __PAL_CHMS

This function allows a process to change its mode to Supervisor in a controlled manner. The change in mode also results in a change of stack pointers: the old pointer is saved and the new pointer is loaded. Registers R2 through R7, PS, and PC are pushed onto the selected stack. The saved PC addresses the instruction following the CHMS instruction.

This function has the following format:

void  __PAL_CHMS (void);

6.2.1.49 __PAL_CHMU

This function allows a process to call a routine using the change mode mechanism. Registers R2 through R7, PS, and PC are pushed onto the current stack. The saved PC addresses the instruction following the CHMU instruction.

This function has the following format:

void  __PAL_CHMU (void);

6.2.1.50 __PAL_DRAINA

This function stalls instruction issuing until all prior instructions are guaranteed to complete without incurring aborts.

This function has the following format:

void  __PAL_DRAINA (void);

6.2.1.51 __PAL_GENTRAP

This function is used for reporting run-time software conditions.

This function has the following format:

void  __PAL_GENTRAP (uint64 encoded_software_trap);
encoded_software_trap
The particular software condition that has occurred.

6.2.1.52 __PAL_HALT

This function halts the processor when executed by a process running in kernel mode. This is a privileged function.

This function has the following format:

void  __PAL_HALT (void);

6.2.1.53 __PAL_INSQHIL

This function inserts an entry at the front of a longword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to header and queue entries. The pointers to head and new_entry must not be equal.

This function has the following format:

int  __PAL_INSQHIL (void *head, void *new_
entry);    /* At head, interlocked */
head
A pointer to the queue header. The header must be aligned on a quadword boundary.
new_entry
A pointer to the new entry to be inserted. The entry must be aligned on a longword boundary.

There are three possible return values:

6.2.1.54 __PAL_INSQHILR

This function inserts an entry into the front of a longword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries. The pointers to head and new_entry must not be equal. All parts of the queue must be memory resident.

This function has the following format:

int  __PAL_INSQHILR (void *head, void *new_
entry);   /* At head, interlocked resident */
head
A pointer to the queue header. The header must be aligned on a quadword boundary.
new_entry
A pointer to the new entry to be inserted. The entry must be aligned on a quadword boundary.

There are three possible return values:

6.2.1.55 __PAL_INSQHIQ

This function inserts an entry at the front of a quadword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to header and queue entries. The pointers to head and new_entry must not be equal.

This function has the following format:

int  __PAL_INSQHIQ (void *head, void *new_
entry);    /* At head, interlocked */
head
A pointer to the queue header. The header must be aligned on an octaword boundary.
new_entry
A pointer to the new entry to be inserted. The entry must be aligned on an octaword boundary.

There are three possible return values:

6.2.1.56 __PAL_INSQHIQR

This function inserts an entry into the front of a quadword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries. The pointers to head and new_entry must not be equal. All parts of the queue must be memory resident.

This function has the following format:

int  __PAL_INSQHIQR (void *head, void *new_
entry);   /* At head, interlocked resident */
head
A pointer to the queue header. The header must be aligned on an octaword boundary.
new_entry
A pointer to the new entry to be inserted. The entry must be aligned on an octaword boundary.

There are three possible return values:

6.2.1.57 __PAL_INSQTIL

This function inserts an entry at the end of a longword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to header and queue entries. The pointers to head and new_entry must not be equal.

This function has the following format:

int  __PAL_INSQTIL (void *head, void *new_
entry);    /* At tail, interlocked */
head
A pointer to the queue header. The header must be aligned on a quadword boundary.
new_entry
A pointer to the new entry to be inserted. The entry must be aligned on a quadword boundary.

There are three possible return values:

6.2.1.58 __PAL_INSQTILR

This function inserts an entry at the end of a longword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries. The pointers to head and new_entry must not be equal. All parts of the queue must be memory resident.

This function has the following format:

int  __PAL_INSQTILR (void *head, void *new_
entry);   /* At tail, interlocked resident */
head
A pointer to the queue header. The header must be aligned on a quadword boundary.
new_entry
A pointer to the new entry to be inserted. The entry must be aligned on a quadword boundary.

There are three possible return values:

6.2.1.59 __PAL_INSQTIQ

This function inserts an entry at the end of a quadword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to header and queue entries. The pointers to head and new_entry must not be equal.

This function has the following format:

int  __PAL_INSQTIQ (void *head, void *new_
entry);    /* At tail, interlocked */
head
A pointer to the queue header. The header must be aligned on an octaword boundary.
new_entry
A pointer to the new entry to be inserted. The entry must be aligned on an octaword boundary.

There are three possible return values:

6.2.1.60 __PAL_INSQTIQR

This function inserts an entry at the end of a quadword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries. The pointers to head and new_entry must not be equal. All parts of the queue must be memory resident.

This function has the following format:

int  __PAL_INSQTIQR (void *head, void *new_
entry);   /* At tail, interlocked resident */
head
A pointer to the queue header. The header must be aligned on an octaword boundary.
new_entry
A pointer to the new entry to be inserted. The entry must be aligned on an octaword boundary.

There are three possible return values:

6.2.1.61 __PAL_INSQUEL

This function inserts a new entry after an existing entry into a longword queue. This function must have write access to header and queue entries.

This function has the following format:

int  __PAL_INSQUEL (void *predecessor, void *new_
entry);
predecessor
A pointer to an existing entry in the queue.
new_entry
A pointer to the new entry to be inserted.

There are two possible return values:

6.2.1.62 __PAL_INSQUEL_D

This function inserts a new entry after an existing entry into a longword queue deferred. This function must have write access to header and queue entries.

This function has the following format:

int  __PAL_INSQUEL_D (void **predecessor, void *new_
entry);    /* Deferred */
predecessor
A pointer to a pointer to the predecessor entry.
new_entry
A pointer to the new entry to be inserted.

There are two possible return values:

6.2.1.63 __PAL_INSQUEQ

This function inserts a new entry after an existing entry into a quadword queue. This function must have write access to header and queue entries.

This function has the following format:

int  __PAL_INSQUEQ (void *predecessor, void *new_
entry);
predecessor
A pointer to an existing entry in the queue.
new_entry
A pointer to the new entry to be inserted.

There are two possible return values:

6.2.1.64 __PAL_INSQUEQ_D

This function inserts a new entry after an existing entry into a quadword queue deferred. This function must have write access to header and queue entries.

This function has the following format:

int  __PAL_INSQUEQ_D (void **predecessor, void *new_
entry);    /* Deferred */
predecessor
A pointer to a pointer to the predecessor entry.
new_entry
A pointer to the new entry to be inserted.

There are two possible return values:

6.2.1.65 __PAL_LDQP

This function returns the quadword-aligned memory object specified by address.

This function has the following format:

uint64  __PAL_LDQP (void *address);
address
A pointer to the quadword-aligned memory object to be returned.

If the object pointed to by address is not quadword- aligned, the result is unpredictable.

6.2.1.66 __PAL_STQP

This function writes the quadword value to the memory location pointed to by address.

This function has the following format:

void  __PAL_STQP (void *address, uint64 value);
address
Memory location to be written to.
value
Quadword value to be stored.

If the location pointed to by address is not quadword- aligned, the result is unpredictable.

6.2.1.67 __PAL_MFPR_XXXX

These privileged functions return the contents of a particular processor register. The XXXX indicates the processor register to be read.

These functions have the following format:

unsigned int  __PAL_MFPR_ASTEN (void);    /* AST Enable */
unsigned int  __PAL_MFPR_ASTSR (void);    /* AST Summary Register */
void  *__PAL_MFPR_ESP (void);            /* Executive Stack Pointer
*/
int  __PAL_MFPR_FEN (void);              /* Floating-Point Enable */
int  __PAL_MFPR_IPL (void);               /* Interrupt Priority
Level */
int  __PAL_MFPR_MCES (void);             /* Machine Check Error
Summary */
void  *__PAL_MFPR_PCBB (void);           /* Privileged Context Block
Base */
int64  __PAL_MFPR_PRBR (void);           /* Processor Base Register
*/
int  __PAL_MFPR_PTBR (void);             /* Page Table Base Register
*/
void  *__PAL_MFPR_SCBB (void);           /* System Control Block
Base */
unsigned  int  __PAL_MFPR_SISR (void);     /* Software Interrupt
Summary Register */
void  *__PAL_MFPR_SSP (void);            /* Supervisor Stack Pointer
*/
int64  __PAL_MFPR_TBCHK (void *address);   /* Translation
Buffer Check */
void  *__PAL_MFPR_USP (void);            /* User Stack Pointer */
void  *__PAL_MFPR_VPTB (void);           /* Virtual Page Table */
int64  __PAL_MFPR_WHAMI (void);          /* Who Am I */

6.2.1.68 __PAL_MTPR_XXXX

These privileged functions load a value into one of the special processor registers. The XXXX indicates the processor register to be loaded.

These functions have the following format:

void  __PAL_MTPR_ASTEN (unsigned int mask);  /* AST Enable
*/
void  __PAL_MTPR_ASTSR (unsigned int mask);  /* AST Summary
Register */
void  __PAL_MTPR_DATFX (int value);          /* Data
Alignment Trap Fixup */
void  __PAL_MTPR_ESP (void *address);        /* Executive
Stack Pointer */
void  __PAL_MTPR_FEN (int value);            /* Floating-
Point Enable */
void  __PAL_MTPR_IPIR (int64 number);        /*
Interprocessor Interrupt Request */
int  __PAL_MTPR_IPL (int value);              /* Interrupt
Priority Level */
void  __PAL_MTPR_MCES (int value);           /* Machine
Check Error Summary */
void  __PAL_MTPR_PRBR (int64 value);         /* Processor
Base Register */
void  __PAL_MTPR_SCBB (void *address);       /* System
Control Block Base */
void  __PAL_MTPR_SIRR (int level);            /* Software
Interrupt Request Register */
void  __PAL_MTPR_SSP (int *address);         /* Supervisor
Stack Pointer */
void  __PAL_MTPR_TBIA (void);                /* User Stack Pointer
*/
void  __PAL_MTPR_TBIAP (void);               /* Translation Buffer
Invalidate All Process */
void  __PAL_MTPR_TBIS (void *address);       /* Translation
Buffer Invalidate Single */
void  __PAL_MTPR_TBISD (void *address);      /* Translation
Buffer Invalidate Single Data */
void  __PAL_MTPR_TBISI (void *address);       /*
Translation Buffer Invalidate Single Instruction */
void  __PAL_MTPR_USP (void *address);        /* User Stack
Pointer */
void  __PAL_MTPR_VPTB (void *address);       /* Virtual
Page Table */

6.2.1.69 __PAL_PROBER

This function checks the read accessibility of the first and last byte of the given address and length pair.

This function has the following format:

int  __PAL_PROBER (const void *base_address, int
length, char mode);
base_address
The pointer to the memory segment to be tested for read access.
length
The length of the memory segment, in bytes.
mode
The processor mode used for checking access.

There are two possible return values:

6.2.1.70 __PAL_PROBEW

This function checks the write accessibility of the first and last byte of the given address and length pair.

This function has the following format:

int  __PAL_PROBEW (const void *base_address, int
length, char mode);
base_address
The pointer to the memory segment to be tested for write access.
length
The length of the memory segment, in bytes.
mode
The processor mode used for checking access.

There are two possible return values:

6.2.1.71 __PAL_RD_PS

This function returns the Processor Status (PS).

This function has the following format:

uint64  __PAL_RD_PS (void);

6.2.1.72 __PAL_REMQHIL

This function removes the first entry from a longword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries.

This function has the following format:

int  __PAL_REMQHIL (void *head, void **removed_
entry);    /* At head, interlocked */
head
A pointer to the queue header. The header must be aligned on a quadword boundary.
removed_entry
A pointer to the address of the entry removed from the queue.

There are four possible return values:

6.2.1.73 __PAL_REMQHILR

This function removes the first entry from a longword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries. All parts of the queue must be memory resident.

This function has the following format:

int  __PAL_REMQHILR (void *head, void **removed_
entry);    /* At head, interlocked resident */
head
A pointer to the queue header. The header must be aligned on a quadword boundary.
removed_entry
A pointer to the address of the entry removed from the queue.

There are four possible return values:

6.2.1.74 __PAL_REMQHIQ

This function removes the first entry from a quadword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries.

This function has the following format:

int  __PAL_REMQHIQ (void *head, void **removed_
entry);    /* At head, interlocked */
head
A pointer to the queue header. The header must be aligned on an octaword boundary.
removed_entry
A pointer to the address of the entry removed from the queue.

There are four possible return values:

6.2.1.75 __PAL_REMQHIQR

This function removes the first entry from a quadword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries. All parts of the queue must be memory resident.

This function has the following format:

int  __PAL_REMQHIQR (void *head, void **removed_
entry);    /* At head, interlocked resident */
head
A pointer to the queue header. The header must be aligned on an octaword boundary.
removed_entry
A pointer to the address of the entry removed from the queue.

There are four possible return values:

6.2.1.76 __PAL_REMQTIL

This function removes the last entry from a longword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries.

This function has the following format:

int  __PAL_REMQTIL (void *head, void **removed_
entry);    /* At tail, interlocked */
head
A pointer to the queue header. The header must be aligned on a quadword boundary.
removed_entry
A pointer to the address of the entry removed from the queue.

There are four possible return values:

6.2.1.77 __PAL_REMQTILR

This function removes the last entry from a longword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries. All parts of the queue must be memory resident.

This function has the following format:

int  __PAL_REMQTILR (void *head, void **removed_
entry);    /* At tail, interlocked resident */
head
A pointer to the queue header. The header must be aligned on a quadword boundary.
removed_entry
A pointer to the address of the entry removed from the queue.

There are four possible return values:

6.2.1.78 __PAL_REMQTIQ

This function removes the last entry from a quadword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries.

This function has the following format:

int  __PAL_REMQTIQ (void *head, void **removed_
entry);    /* At tail, interlocked */
head
A pointer to the queue header. The header must be aligned on an octaword boundary.
removed_entry
A pointer to the address of the entry removed from the queue.

There are four possible return values:

6.2.1.79 __PAL_REMQTIQR

This function removes the last entry from a quadword queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system. This function must have write access to the header and queue entries. All parts of the queue must be memory resident.

This function has the following format:

int  __PAL_REMQTIQR (void *head, void **removed_
entry);    /* At tail, interlocked resident */
head
A pointer to the queue header. The header must be aligned on an octaword boundary.
removed_entry
A pointer to the address of the entry removed from the queue.

There are four possible return values:

6.2.1.80 __PAL_REMQUEL

This function removes an entry from a longword queue. This function must have write access to header and queue entries.

This function has the following format:

int  _PAL_REMQUEL (void *entry, void **removed_
entry);
entry
A pointer to the queue entry to be removed.
removed_entry
A pointer to the address of the entry removed from the queue.

There are three possible return values:

6.2.1.81 __PAL_REMQUEL_D

This function removes an entry from a longword queue deferred. This function must have write access to header and queue entries.

This function has the following format:

int  __PAL_REMQUEL_D (void **entry, void **removed_
entry);    /* Deferred */
entry
A pointer to a pointer to the queue entry to be removed.
removed_entry
A pointer to the address of the entry removed from the queue.

There are three possible return values:

6.2.1.82 __PAL_REMQUEQ

This function removes an entry from a quadword queue. This function must have write access to header and queue entries.

This function has the following format:

int  __PAL_REMQUEQ (void *entry, void **removed_
entry);
entry
A pointer to the queue entry to be removed.
removed_entry
A pointer to the address of the entry removed from the queue.

There are three possible return values:

6.2.1.83 __PAL_REMQUEQ_D

This function removes an entry from a quadword queue deferred. This function must have write access to header and queue entries.

This function has the following format:

int   __PAL_REMQUEQ_D (void **entry, void **removed_
entry);    /* Deferred */
entry
A pointer to a pointer to the queue entry to be removed.
removed_entry
A pointer to the address of the entry removed from the queue.

There are three possible return values:

6.2.1.84 __PAL_SWPCTX

This function returns ownership of the data structure that contains the current hardware privileged context (the HWPCB) to the operating system and passes ownership of the new HWPCB to the processor.

This function has the following format:

void   __PAL_SWPCTX (void *address);
address
A pointer to the new HWPCB.

6.2.1.85 __PAL_SWASTEN

This function swaps the previous state of the Asynchronous System Trap (AST) enable bit for the new state. The new state is supplied in bit 0 of new_state_mask. The previous state is returned, zero-extended.

A check is made to determine if an AST is pending. If the enabling conditions are present for an AST at the completion of this instruction, the AST occurs before the next instruction.

This function has the following format:

unsigned int   __PAL_SWASTEN (int new_state_mask);
new_state_mask
An integer whose 0 bit is the new state of the AST enable bit.

6.2.1.86 __PAL_WR_PS_SW

This function writes the low-order three bits of mask into the Processor Status software field (PS<SW>).

This function has the following format:

void  __PAL_WR_PS_SW (int mask);
mask
An integer whose low-order three bits are written into PS<SW>.

6.2.1.87 Read Process Cycle Counter ( __RPCC)

The __RPCC function reads the current process cycle counter.

This function has the following format:

uint64  __RPCC (void);

6.2.1.88 Sine ( __SIN)

The __SIN built-in is functionally equivalent to its counterpart, sin, in the standard header file <math.h>.

Its format is also the same:

#include <math.h>
double  __SIN (double x);
x
A radian value.

This built-in offers performance improvements because there is less call overhead associated with its use.

If you include <math.h>, the built-in is automatically used for all occurrences of sin. To disable the built-in, use #undef sin.

6.2.1.89 Single-Precision, Floating-Point Arithmetic Built-in Functions

The following built-in functions provide single-precision, floating- point chopped arithmetic:
__ADDF_C   __ADDS_C   __SUBF_C   __SUBS_C 
__MULF_C   __MULS_C   __DIVF_C   __DIVS_C 

They have the following format:

float  __op{F,S}_C (float operand1, float
operand2);

Where op is one of ADD, SUB, MUL, DIV, and {F,S} represents VAX or IEEE floating-point arithmetic, respectively.

The result of the arithmetic operation is returned.

6.2.1.90 Test for Bit Clear then Clear Bit Interlocked (__INTERLOCKED_TESTBITCC_QUAD)

The __INTERLOCKED_TESTBITCC_QUAD function performs the following functions in interlocked fashion:

  1. Returns the complement of the specified bit before being cleared.

  2. Clears the bit.

This function has one of the following formats:

int  __INTERLOCKED_TESTBITCC_QUAD (volatile void *address,
int bit_position);

int  __INTERLOCKED_TESTBITCC_QUAD_RETRY (volatile void
*address, int bit_position, int retry,
int *status);
address
The quadword-aligned base address of the bit field.
bit_ position
The position within the field of the bit that you want cleared, in the range of 0 to 63.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the quadword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.91 Test for Bit Clear then Clear Bit Interlocked (__TESTBITCCI)

The __TESTBITCCI function performs the following operations in interlocked fashion:

This function has the following format:

int  __TESTBITCCI (void *address, int position,
...);
address
The base address of the field.
position
The position within the field of the bit that you want cleared.
. . .
An optional retry count of type int. If specified, the retry count indicates the number of times the operation is attempted (which will be at least once, even if the count argument is 0).

6.2.1.92 Test for Bit Set Then Set Bit Interlocked (__INTERLOCKED_TESTBITSS_QUAD)

The __INTERLOCKED_TESTBITSS_QUAD function performs the following functions in interlocked fashion:

  1. Returns the value of the specified bit before being set.

  2. Sets the bit.

This function has one of the following formats:

int  __INTERLOCKED_TESTBITSS_QUAD (volatile void *address,
int bit_position);

int  __INTERLOCKED_TESTBITSS_QUAD_RETRY (volatile void
*address, int expression, int retry,
int *status);
address
The quadword-aligned base address of the bit field.
bit_ position
The position within the field of the bit that you want cleared, in the range of 0 to 63.
retry
A retry count of type int that indicates the number of times the operation is attempted (which is at least once, even if the retry argument is 0). If the operation cannot be performed successfully in the specified number of retries, the function returns without updating the longword.
status
A pointer to an integer that is set to 0 if the operation did not succeed within the specified number of retries, and set to 1 if the operation succeeded.

6.2.1.93 Test for Bit Set then Set Bit Interlocked (__TESTBITSSI)

The __TESTBITSSI function performs the following operations in interlocked fashion:

This function has the following format:

int  __TESTBITSSI (void *address, int position,
...);
address
The base address of the field.
position
The position within the field of the bit that you want set.
. . .
An optional retry count of type int. If specified, the retry count indicates the number of times the operation is attempted (which will be at least once, even if the count argument is 0).

6.2.1.94 Trap Barrier Instruction ( __TRAPB)

The __TRAPB function allows software to guarantee that, in a pipeline implementation, all previous arithmetic instructions will be completed without incurring any arithmetic traps before any instructions after the TRAPB instruction are issued.

This function has the following format:

void  __TRAPB (void);

6.2.1.95 Unsigned Quadword Multiply High ( __UMULH)

The __UMULH function performs a quadword multiply high instruction.

This function has the following format:

uint64  __UMULH (uint64 operand1, uint64
operand2);
operand1
A 64-bit unsigned integer.
operand2
A 64-bit unsigned integer.

The two operands are multiplied as unsigned integers to produce a 128-bit result. The high-order 64 bits are returned. Note that uint64 is a typedef for the Alpha data type unsigned __int64.

6.2.2 Built-In Functions for OpenVMS VAX Systems (VAX only)

The following sections describe the DEC C built-in functions available on OpenVMS VAX systems.

The DEC C built-in functions use enumerated typedefs to define possible return values. We recommend that you use the enumerated types to store and compare return values.

6.2.2.1 Add Aligned Word Interlocked ( _ADAWI)

The _ADAWI function adds its source operand to the destination. This function is interlocked against similar operations by other processors or devices in the system.

The _ADAWI function has the following format:

typedef enum { _adawi_sum_neg=-1,  _adawi_sum_zero,  _adawi_sum_pos}
  _ADAWI_STATUS;

_ADAWI_STATUS  _ADAWI (short  __src,  short *__
dest);
__src
The value to be added to the destination.
__dest
A pointer to the destination. The destination must be aligned on a word boundary. (You can achieve alignment using the _align storage-class modifier.)

There are three possible return values:

6.2.2.2 Branch on Bit Clear-Clear Interlocked ( _BBCCI)

The _BBCCI function performs the following functions in interlocked fashion:

The _BBCCI function has the following format:

typedef enum { _bbcci_oldval_1,  _bbcci_oldval_0}  _BBCCI_STATUS;

_BBCCI_STATUS  _BBCCI (int  __position,  void *__
address);
__position
The position of the bit within the field.
__address
The base address of the field.

The return value of _bbcci_oldval_1 (0) or _bbcci_oldval_0 (1) is the complement of the value of the specified bit before being cleared.

6.2.2.3 Branch on Bit Set-Set Interlocked ( _BBSSI)

The _BBSSI function performs the following functions in interlocked fashion:

The _BBSSI function has the following format:

typedef enum { _bbssi_oldval_0,  _bbcci_oldval_1}  _BBSSI_STATUS;

_BBSSI_STATUS  _BBSSI (int  __position,  void *__
address);
__position
The position of the bit within the field.
__address
The base address of the field.

The return value of _bbssi_oldval_0 (0) or _bbssi_oldval_1 (1) is the value of the specified bit before being set.

6.2.2.4 Find First Clear Bit ( _FFC)

The _FFC function finds the position of the first clear bit in a field. The bits are tested for clear status starting at bit 0 and extending to the highest bit in the field.

The _FFC function has the following format:

typedef enum { _ff_bit_not_found,  _ff_bit_found}  _FF_STATUS;

_FF_STATUS  _FFC (int  __start,  char  __
size,  const void *__base,  int *__
positionbox);
__start
The start position of the field.
__size
The size of the field, in bits. The size must be a value from 0 to 32 bits.
__base
The address of the field.
__position
The address of an integer to receive the position of the clear bit. If no bit is clear, the integer is set to the position of the first bit past the last bit tested.

There are two possible return values:

6.2.2.5 Find First Set Bit ( _FFS)

The _FFS function finds the position of the first set bit in a field. The bits are tested for set status starting at bit 0 and extending to the highest bit in the field.

The _FFS function has the following format:

typedef enum { _ff_bit_not_found,  _ff_bit_found}  _FF_STATUS;

_FF_STATUS  _FFS (int  __start,  char  __
size,  const void *__base,  int *__
positionbox);
__start
The start position of the field.
__size
The size of the field, in bits. The size must be a value from 0 to 32 bits.
__base
The address of the field.
__position
The address of an integer to receive the position of the set bit. If no bit is set, the integer is set to the position of the first bit past the last bit tested.

There are two possible return values:

6.2.2.6 Halt ( _HALT)

The _HALT function halts the processor when executed by a process running in kernel mode. This is a privileged function.

The _HALT function has the following format:

void  _HALT (void);

6.2.2.7 Insert Entry into Queue at Head Interlocked ( _INSQHI)

The _INSQHI function inserts an entry into the front of a queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system.

The _INSQHI function has the following format:

typedef enum {_insqi_inserted_many, _insqi_not_inserted, _insqi_
inserted_only} _INSQI_STATUS;

_INSQI_STATUS  _INSQHI (void *__new_entry,  void *__
head);
__new_entry
A pointer to the new entry to be inserted. The entry must be aligned on a quadword boundary. (You can achieve alignment using the _align storage-class modifier.)
__head
A pointer to the queue header. The header must be aligned on a quadword boundary. (You can achieve alignment using the _align storage-class modifier.)

There are three possible return values:

6.2.2.8 Insert Entry into Queue at Tail Interlocked ( _INSQTI)

The _INSQTI function inserts an entry at the end of a queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system.

The _INSQTI function has the following format:

typedef enum {_insqi_inserted_many, _insqi_not_inserted, _insqi_
inserted_only} _INSQI_STATUS;

_INSQI_STATUS  _INSQTI (void *__new_entry,  void *__
head);
__new_entry
A pointer to the new entry to be inserted. The entry must be aligned on a quadword boundary. (You can achieve alignment using the _align storage-class modifier.)
__head
A pointer to the queue header. The header must be aligned on a quadword boundary. (You can achieve alignment using the _align storage-class modifier.)

There are three possible return values:

6.2.2.9 Insert Entry in Queue ( _INSQUE)

The _INSQUE function inserts a new entry into a queue following an existing entry.

The _INSQUE function has the following format:

typedef enum { _insque_inserted_only,  _insque_inserted_many}  _
INSQUE_STATUS;

_INSQUE_STATUS  _INSQUE (void *__new_entry,  void *__
predecessor);
__new_entry
A pointer to the new entry to be inserted.
__predecessor
A pointer to an existing entry in the queue.

There are two possible return values:

6.2.2.10 Locate Character ( _LOCC)

The _LOCC function locates the first character in a string matching the target character.

The _LOCC function has the following format:

unsigned short _LOCC (char  __target,  unsigned short
 __length,  const char  *__string,  ...);
__target
The character being searched.
__length
The length of the searched string. The length must be a value from 0 to 65,535.
__string
A pointer to the searched string.
. . .
An optional position argument, which is a pointer to a pointer to char. If the searched character is found, this output argument is updated to point to the character found. If the character is not found, this argument is set to the address one byte beyond the string.

If the target character is found, the return value is the number of bytes remaining in the string; otherwise, the return value is 0.

6.2.2.11 Move from Processor Register ( _MFPR)

The _MFPR function returns the contents of a processor register. This is a privileged function.

The _MFPR function has the following formats:

void _MFPR (int register_num, int *destination);
void _MFPR (int register_num, unsigned int
*destination);
register_num
The number of the privileged register to be read.
destination
A pointer to the location receiving the value from the register. This location can be a signed or unsigned int.

6.2.2.12 Move Character 3 Operand ( _MOVC3)

The _MOVC3 function copies a block of memory.

The _MOVC3 function has the following format:

void  _MOVC3 (unsigned short  __length,  const char *_
_src,  char *__dest,  ...);
__length
The length of the source string, in bytes. The length must be a value from 0 to 65,535.
__src
A pointer to the source string.
__dest
A pointer to the destination memory.
. . .
One or two optional arguments:

6.2.2.13 Move Character 5 Operand ( _MOVC5)

The _MOVC5 function allows the source string specified by the pointer and length pair to be moved to the destination string specified by the other pointer and length pair. If the source string is smaller than the destination string, the destination string is padded with the specified character.

The _MOVC5 function has the following format:

void  _MOVC5 (unsigned short  __srclen,  const char *_
_src,  char __fill,
              unsigned short  __destlen,  char *__
dest, ...);
__srclen
The length of the source string, in bytes. The length must be a value from 0 to 65,535.
__src
A pointer to the source string.
__fill
The fill character to be used if the source string is smaller than the destination string.
__destlen
The length of the destination string, in bytes. The length must be a value from 0 to 65,535.
__dest
A pointer to the destination string.
. . .
One to three optional arguments:

6.2.2.14 Move from Processor Status Longword ( _MOVPSL)

The _MOVPSL function stores the value of the Processor Status Longword (PSL).

The _MOVPSL function has the following format:

void  _MOVPSL (void *__psl);
__psl
The address of the location for storing the value of the PSL.

6.2.2.15 Move to Processor Register ( _MTPR)

The _MTPR function loads a value into one of the special processor registers. It is a privileged function.

The _MTPR function has the following format:

int _MTPR (int src, int register_num);
src
The value to store into the processor register.
register_num
The number of a privileged register to be updated.

The return value is the V condition flag from the Processor Status Longword (PSL).

6.2.2.16 Probe Read Accessibility ( _PROBER)

The _PROBER function checks to see if you can read the first and last byte of the given address and length pair.

The _PROBER function has the following format:

typedef enum { _probe_not_accessible,  _probe_accessible}  _PROBE_
STATUS;

_PROBE_STATUS  _PROBER (char  __mode,  unsigned
short  __length,  const void *__address);
__mode
The processor mode used for checking the access.
__length
The length of the memory segment, in bytes. The length must be a value from 0 to 65,535.
__address
The pointer to the memory segment to be tested for read access.

There are two possible return values:

6.2.2.17 Probe Write Accessibility ( _PROBEW)

The _PROBEW function checks the write accessibility of the first and last byte of the given address and length pair.

The _PROBEW function has the following format:

typedef enum { _probe_not_accessible,  _probe_accessible}  _PROBE_
STATUS;

_PROBE_STATUS  _PROBEW (char  __mode,  unsigned
short  __length,  const void *__address);
__mode
The processor mode used for checking the access.
__length
The length of the memory segment, in bytes. The length must be a value from 0 to 65,535.
__address
The pointer to the memory segment to be tested for write access.

There are two possible return values:

6.2.2.18 Read General-Purpose Register ( _READ_GPR)

The _READ_GPR function returns the value of a general-purpose register.

The _READ_GPR function has the following format:

int _READ_GPR (int register_num);
register_num
An integer constant expression giving the number of the general- purpose register to be read.

The return value is the value of the general-purpose register.

6.2.2.19 Remove Entry from Queue at Head Interlocked ( _REMQHI)

The _REMQHI function removes the first entry from the queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system.

The _REMQHI function has the following format:

typedef enum { _remqi_removed_more,  _remqi_not_removed,  _remqi_
removed_empty,
               _remqi_empty}  _REMQI_STATUS;

_REMQI_STATUS  _REMQHI (void *__head,  void *__
removed_entry);
__head
A pointer to the queue header. The header must be aligned on a quadword boundary. (You can achieve alignment using the _align storage-class modifier.)
__removed_entry
A pointer that _REMQHI sets to point to the removed entry.

There are four possible return values:

6.2.2.20 Remove Entry from Queue at Tail Interlocked ( _REMQTI)

The _REMQTI function removes the last entry from the queue in an indivisible manner. This operation is interlocked against similar operations by other processors or devices in the system.

The _REMQTI function has the following format:

typedef enum { _remqi_removed_more,  _remqi_not_removed,  _remqi_
removed_empty,
               _remqi_empty}  _REMQI_STATUS;

_REMQI_STATUS  _REMQTI (void *__head,  void *__
removed_entry);
__head
A pointer to the queue header. The header must be aligned on a quadword boundary. (You can achieve alignment using the _align storage-class modifier.)
__removed_entry
A pointer to a pointer that _REMQTI sets to point to the removed entry.

There are four possible return values:

6.2.2.21 Remove Entry from Queue ( _REMQUE)

The _REMQUE function removes an entry from a queue.

The _REMQUE function has the following format:

typedef enum { _remque_removed_more,  _remque_removed_empty,
               _remque_empty}  _REMQUE_STATUS;

_REMQUE_STATUS  _REMQUE (void *__entry,  void *__
removed_entry);
__entry
A pointer to the queue entry to be removed.
__removed_entry
A pointer to a pointer that _REMQUE sets to the address of the entry removed from the queue.

There are three possible return values:

6.2.2.22 Scan Characters ( _SCANC)

The _SCANC function locates the first character in a string with the desired attributes. The attributes are specified through a table and a mask.

The _SCANC function has the following format:

unsigned short  _SCANC (unsigned short  __length,  const
char *__string,
                       const char *__table,  char  __
mask, ...);
__length
The length of the string to be scanned, in bytes. The length must be a value from 0 to 65,535.
__string
A pointer to the string to be scanned.
__table
A pointer to the table.
__mask
The mask.
. . .
An optional match argument, which is a pointer to a pointer to char. The _SCANC function sets this output argument to the address of the byte that matched. (If no match occurs, this argument is set to the address of the byte following the string.)

The return value is the number of bytes remaining in the string if a match was found; otherwise, the return value is 0.

6.2.2.23 Skip Character ( _SKPC)

The _SKPC function locates the first character in a string that does not match the target character.

The _SKPC function has the following format:

unsigned short  _SKPC (char  __target,  unsigned
short  __length,  const char *__string,  ... );
__target
The target character.
__length
The length of the string, in bytes. The length must be a value from 0 to 65,535.
__string
A pointer to the string to be scanned.
. . .
An optional position argument, which is a pointer to a pointer to char. The _SKPC function sets this output argument to the address of the nonmatching character. (If all the characters in the string match, this argument is set to the address of the first byte beyond the string.)

The return value is the number of bytes remaining in the string if an unequal byte was located; otherwise, the return value is 0.

6.2.2.24 Span Characters ( _SPANC)

The _SPANC function locates the first character in a string without certain attributes. The attributes are specified through a table and a mask.

The _SPANC function has the following format:

unsigned short  _SPANC (unsigned short  __length,  const
char *__string,
                      const char *__table,  char  __
mask, ...);
__length
The length of the string, in bytes. The length must be a value from 0 to 65,535.
__string
A pointer. It points to the string to be scanned.
__table
A pointer to the table.
__mask
The mask.
. . .
An optional position argument, which is a pointer to a pointer to char. The _SPANC function sets this output argument to the address of the nonmatching character. (If all the characters in the string match, this argument is set to the address of the first byte beyond the string.)

The return value is the number of bytes remaining in the string if a match was found; otherwise, the return value is 0.


Previous Page | Next Page | Table of Contents | Index