Document revision date: 19 July 1999 | |
Previous | Contents | Index |
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.
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:
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.
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. |
This standard defines the usage of the Alpha general-purpose floating-point registers as listed in Table 3-2.
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. |
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:
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:
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:
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)
Field Name | Contents | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
PDSC$W_FLAGS |
The PDSC descriptor flag bits <15:0> are defined as follows:
|
||||||||||||||||||
||
|
|||||||||||||||||||
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:
|
||||||||||||||||||
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 |