Document revision date: 30 March 2001

## OpenVMS Calling Standard

Previous | Contents | Index

### 2.6.2 Exception Synchronization

Every procedure must ensure that no exception can be raised after the current frame is changed (as a result of a CALLx or RET). If a procedure executes any vector instruction that might raise an exception, then a SYNC instruction (a form of the MFVP instruction) must be executed prior to any subsequent CALLx or RET.

However, if the only exceptions that can occur are certain to be reported by an MSYNC instruction that is otherwise needed for memory synchronization, then the SYNC is redundant and can be omitted as an optimization.

Moreover, if the only exceptions that can occur are certain to be reported by one or more MFVP instructions that read the vector control registers, then the SYNC is redundant and can be omitted as an optimization.

## Chapter 3
OpenVMS Alpha Conventions

This chapter describes the fundamental concepts and conventions for calling a procedure in an Alpha environment. The following sections identify register usage and addressing, and focus on aspects of the calling standard that pertain to procedure-to-procedure flow control.

## 3.1 Register Usage

The 64-bit-wide, general-purpose Alpha hardware registers divide into two groups:

- Integer
- Floating point

The first 32 general-purpose registers support integer processing and the second 32 support floating-point operations.

### 3.1.1 Integer Registers

This standard defines the usage of the Alpha general-purpose integer registers as listed in Table 3-1.

Table 3-1 Alpha Integer Registers
Register | Usage
--- | ---
R0 | Function value register. In a standard call that returns a nonfloating-point function result in a register, the result must be returned in this register. In a standard call, this register may be modified by the called procedure without being saved and restored. This register is not to be preserved by any called procedure.
R1 | Conventional scratch register. In a standard call, this register may be modified by the called procedure without being saved and restored. This register is not to be preserved by any called procedure.
R2--15 | Conventional saved registers. If a standard-conforming procedure modifies one of these registers, it must save and restore it.
R16--21 | Argument registers. In a standard call, up to six nonfloating-point items of the argument list are passed in these registers. In a standard call, these registers may be modified by the called procedure without being saved and restored.
R22--24 | Conventional scratch registers. In a standard call, these registers may be modified by the called procedure without being saved and restored.
R25 | Argument information (AI) register. In a standard call, this register describes the argument list. (See Section 3.7.1 for a detailed description.) In a standard call, this register may be modified by the called procedure without being saved and restored.
R26 | Return address (RA) register. In a standard call, the return address must be passed in this register. In a standard call, this register may be modified by the called procedure without being saved and restored.
R27 | Procedure value (PV) register. In a standard call, the procedure value of the procedure being called is passed in this register. In a standard call, this register may be modified by the called procedure without being saved and restored.
R28 | Volatile scratch register. The contents of this register are always unpredictable after any external transfer of control either to or from a procedure. This applies to both standard and nonstandard calls. This register may be used by the operating system for external call fixup, autoloading, and exit sequences.
R29 | Frame pointer (FP). The contents of this register define, among other things, which procedure is considered current. Details of usage and alignment are defined in Section 3.6.
R30 | Stack pointer (SP). This register contains a pointer to the top of the current operating stack. Aspects of its usage and alignment are defined by the hardware architecture. Various software aspects of its usage and alignment are defined in Section 3.7.1.
R31 | ReadAsZero/Sink (RZ). Hardware defines binary 0 as a source operand and sink (no effect) as a result operand.

### 3.1.2 Floating-Point Registers

This standard defines the usage of the Alpha general-purpose floating-point registers as listed in Table 3-2.

Table 3-2 Alpha Floating-Point Registers
Register | Usage
--- | ---
F0 | Floating-point function value register. In a standard call that returns a floating-point result in a register, this register is used to return the real part of the result. In a standard call, this register may be modified by the called procedure without being saved and restored.
F1 | Floating-point function value register. In a standard call that returns a complex floating-point result in registers, this register is used to return the imaginary part of the result. In a standard call, this register may be modified by the called procedure without being saved and restored.
F2--9 | Conventional saved registers. If a standard-conforming procedure modifies one of these registers, it must save and restore it.
F10--15 | Conventional scratch registers. In a standard call, these registers may be modified by the called procedure without being saved and restored.
F16--21 | Argument registers. In a standard call, up to six floating-point arguments may be passed by value in these registers. In a standard call, these registers may be modified by the called procedure without being saved and restored.
F22--30 | Conventional scratch registers. In a standard call, these registers may be modified by the called procedure without being saved and restored.
F31 | ReadAsZero/Sink. Hardware defines binary 0 as a source operand and sink (no effect) as a result operand.

## 3.2 Address Representation

An address is a 64-bit value used to denote a position in memory. However, for compatibility with OpenVMS VAX, many Alpha applications and user-mode facilities operate in such a manner that addresses are restricted only to values that are representable in 32 bits. This allows Alpha addresses often to be stored and manipulated as 32-bit longword values. In such cases, the 32-bit address value is always implicitly or explicitly sign extended to form a 64-bit address for use by the Alpha hardware.

## 3.3 Procedure Representation

One distinguishing characteristic of any calling standard is how procedures are represented. The term used to denote the value that uniquely identifies a procedure is a procedure value. If the value identifies a bound procedure, it is called a bound procedure value.

In the Alpha portion of this calling standard, all procedure values are defined to be the address of the data structure (a procedure descriptor) that describes that procedure. So, any procedure can be invoked by calling the address stored at offset 8 from the address represented by the procedure value.

Note that a simple (unbound) procedure value is defined as the address of that procedure's descriptor (see Section 3.4). This provides slightly different conventions than would be used if the address of the procedure's code were used as it is in many calling standards.

A bound procedure value is defined as the address of a bound procedure descriptor that provides the necessary information for the bound procedure to be called (see Section 3.7.4).

## 3.4 Procedure Types

This standard defines the following basic types of procedures:

- Stack frame procedure---Maintains its caller's context on the stack
- Register frame procedure---Maintains its caller's context in registers
- Null frame procedure---Does not establish a context and, therefore, executes in the context of its caller

A compiler can choose which type of procedure to generate based on the requirements of the procedure in question. A calling procedure does not need to know what type of procedure it is calling.

Every procedure must have an associated structure that describes which type of procedure it is and other procedure characteristics. This structure, called a procedure descriptor, is a quadword-aligned data structure that provides basic information about a procedure. This data structure is used to interpret the call chain at any point in a thread's execution. It is typically built at compile time and usually is not accessed at run time except to support exception processing or other rarely executed code.

Read access to procedure descriptors is done through a procedure interface described in Section 3.6.2. This allows for future compatible extensions to these structures.

The purpose of defining a procedure descriptor for a procedure and making that procedure descriptor accessible to the run-time system is twofold:

- To make invocations of that procedure visible to and interpretable by facilities such as the debugger, exception-handling system, and the unwinder.
- To ensure that the context of the caller saved by the called procedure can be restored if an unwind occurs. (For a description of unwinding, see Section 6.7.)

### 3.4.1 Stack Frame Procedures

The stack frame of a procedure consists of a fixed part (the size of which is known at compile time) and an optional variable part. Certain optimizations can be done if the optional variable part is not present. Compilers must also recognize unusual situations, such as the following, that can effectively cause a variable part of the stack to exist:

- A called routine may use the stack as a means to return certain types of function values (see Section 3.8.7 for more information).
- A called routine that allocates stack space may take an exception in its routine prologue before it becomes current. This situation must be considered since the stack expansion happens in the context of the caller (see Section 3.7.5 for more information).
  For this reason, a fixed-stack usage version of this procedure type cannot make standard calls.

The variable-stack usage version of this type of procedure is referred to as full function and can make standard calls to other procedures.

### 3.4.2 Procedure Descriptor for Procedures with a Stack Frame

A stack frame procedure descriptor (PDSC) built by a compiler provides information about a procedure with a stack frame. The minimum size of the descriptor is 32 bytes defined by constant PDSC$K_MIN_STACK_SIZE. An optional PDSC extension in 8-byte increments supports exception-handling requirements.

The fields defined in the stack frame descriptor are illustrated in Figure 3_1 and described in Table 3-3.

Figure 3-1 Stack Frame Procedure Descriptor (PDSC)

Table 3-3 Contents of Stack Frame Procedure Descriptor (PDSC)
Field Name | Contents
--- | ---
PDSC$W_FLAGS | The PDSC descriptor flag bits <15:0> are defined as follows:
PDSC$V_KIND | A 4-bit field <3:0> that identifies the type of procedure descriptor. For a procedure with a stack frame, this field must specify a value 9 (defined by constant PDSC$K_KIND_FP_STACK).
PDSC$V_HANDLER_VALID | If set to 1, this descriptor has an extension for the stack handler (PDSC$Q_STACK_HANDLER) information.
PDSC$V_HANDLER_REINVOKABLE | If set to 1, the handler can be reinvoked, allowing an occurrence of another exception while the handler is already active. If this bit is set to 0, the exception handler cannot be reinvoked. Note that this bit must be 0 when PDSC$V_HANDLER_VALID is 0.
PDSC$V_HANDLER_DATA_VALID | If set to 1, the HANDLER_VALID bit must be 1, the PDSC extension STACK_HANDLER_DATA field contains valid data for the exception handler, and the address of PDSC$Q_STACK_HANDLER_DATA will be passed to the exception handler as defined in Section 6.2.
PDSC$V_BASE_REG_IS_FP | If this bit is set to 0, the SP is the base register to which PDSC$L_SIZE is added during an unwind. A fixed amount of storage is allocated in the procedure entry sequence, and SP is modified by this procedure only in the entry and exit code sequence. In this case, FP typically contains the address of the procedure descriptor for the procedure. A procedure for which this bit is 0 cannot make standard calls. If this bit is set to 1, FP is the base address and the procedure has a minimum amount of stack storage specified by PDSC$L_SIZE. A variable amount of stack storage can be allocated by modifying SP in the entry and exit code of this procedure.
PDSC$V_REI_RETURN | If set to 1, the procedure expects the stack at entry to be set, so an REI instruction correctly returns from the procedure. Also, if set, the contents of the RSA$Q_SAVED_RETURN field in the register save area are unpredictable and the return address is found on the stack (see Figure 3-4).
Bit 9 | Must be 0 (reserved).
PDSC$V_BASE_FRAME | For compiled code, this bit must be set to 0. If set to 1, this bit indicates the logical base frame of a stack that precedes all frames corresponding to user code. The interpretation and use of this frame and whether there are any predecessor frames is system software defined (and subject to change).
PDSC$V_TARGET_INVO | If set to 1, the exception handler for this procedure is invoked when this procedure is the target invocation of an unwind. Note that a procedure is the target invocation of an unwind if it is the procedure in which execution resumes following completion of the unwind. For more information, see Chapter 6. If set to 0, the exception handler for this procedure is not invoked. Note that when PDSC$V_HANDLER_VALID is 0, this bit must be 0.
PDSC$V_NATIVE | For compiled code, this bit must be set to 1.
PDSC$V_NO_JACKET | For compiled code, this bit must be set to 1.
PDSC$V_TIE_FRAME | For compiled code, this bit must be 0. Reserved for use by system software.
Bit 15 | Must be 0 (reserved).
PDSC$W_RSA_OFFSET | Signed offset in bytes between the stack frame base (SP or FP as indicated by PDSC$V_BASE_REG_IS_FP) and the register save area. This field must be a multiple of 8, so that PDSC$W_RSA_OFFSET added to the contents of SP or FP (PDSC$V_BASE_REG_IS_FP) yields a quadword-aligned address.
PDSC$V_FUNC_RETURN | A 4-bit field <11:8> that describes which registers are used for the function value return (if there is one) and what format is used for those registers. Table 3-7 lists and describes the possible encoded values of PDSC$V_FUNC_RETURN.
PDSC$V_EXCEPTION_MODE | A 3-bit field <14:12> that encodes the caller's desired exception-reporting behavior when calling certain mathematically oriented library routines. The possible values for this field are defined as follows:
Value | Name | Meaning
--- | --- | ---
0 | PDSC$K_EXCEPTION_MODE_SIGNAL | Raise exceptions for all error conditions except for underflows producing a 0 result. This is the default mode.
1 | PDSC$K_EXCEPTION_MODE_SIGNAL_ALL | Raise exceptions for all error conditions (including underflow).
2 | PDSC$K_EXCEPTION_MODE_SIGNAL_SILENT | Raise no exceptions. Create only finite values (no infinities, denormals, or NaNs). In this mode, either the function result or the C language `errno` variable must be examined for any error indication.
3 | PDSC$K_EXCEPTION_MODE_FULL_IEEE | Raise no exceptions except as controlled by separate IEEE exception enable bits. Create infinities, denormals, or NaN values according to the IEEE floating-point standard.
4 | PDSC$K_EXCEPTION_MODE_CALLER | Perform the exception-mode behavior specified by this procedure's caller.
PDSC$W_SIGNATURE_OFFSET | A 16-bit signed byte offset from the start of the procedure descriptor. This offset designates the start of the procedure signature block (if any). A 0 in this field indicates that no signature information is present. Note that in a bound procedure descriptor (as described in Section 3.7.4), signature information might be present in the related procedure descriptor. A 1 in this field indicates a standard default signature. An offset value of 1 is not otherwise a valid offset because both procedure descriptors and signature blocks must be quadword aligned.
PDSC$Q_ENTRY | Absolute address of the first instruction of the entry code sequence for the procedure.
PDSC$L_SIZE | Unsigned size, in bytes, of the fixed portion of the stack frame for this procedure. The size must be a multiple of 16 bytes to maintain the minimum stack alignment required by the Alpha hardware architecture and stack alignment during a call (defined in Section 3.7.1). PDSC$L_SIZE cannot be 0 for a stack-frame type procedure, since the stack frame must include space for the register save area. The value of SP at entry to this procedure can be calculated by adding PDSC$L_SIZE to the value SP or FP, as indicated by PDSC$V_BASE_REG_IS_FP.
PDSC$W_ENTRY_LENGTH | Unsigned offset, in bytes, from the entry point to the first instruction in the procedure code segment following the procedure prologue (that is, following the instruction that updates FP to establish this procedure as the current procedure).
PDSC$L_IREG_MASK | Bit vector (0--31) specifying the integer registers that are saved in the register save area on entry to the procedure. The least significant bit corresponds to register R0. Never set bits 31, 30, 28, 1, and 0 of this mask, since R31 is the integer read-as-zero register, R30 is the stack pointer, R28 is always assumed to be destroyed during a procedure call or return, and R1 and R0 are never preserved registers. In this calling standard, bit 29 (corresponding to the FP) must always be set.
PDSC$L_FREG_MASK | Bit vector (0--31) specifying the floating-point registers saved in the register save area on entry to the procedure. The least significant bit corresponds to register F0. Never set bit 31 of this mask, since it corresponds to the floating-point read-as-zero register.
PDSC$Q_STACK_HANDLER | Absolute address to the procedure descriptor for a run-time static exception-handling procedure. This part of the procedure descriptor is optional. It must be supplied if either PDSC$V_HANDLER_VALID is 1 or PDSC$V_HANDLER_DATA_VALID is 1 (which requires that PDSC$V_HANDLER_VALID be 1). If PDSC$V_HANDLER_VALID is 0, then the contents or existence of PDSC$Q_STACK_HANDLER is unpredictable.
PDSC$Q_STACK_HANDLER_DATA | Data (quadword) for the exception handler. This is an optional quadword and needs to be supplied only if PDSC$V_HANDLER_DATA_VALID is 1. If PDSC$V_HANDLER_DATA_VALID is 0, then the contents or existence of PDSC$Q_STACK_HANDLER_DATA is unpredictable.

Previous | Next | Contents | Index

| privacy and legal statement |
5973PRO_002.HTML