HP OpenVMS Systems Documentation
HP OpenVMS Programming Concepts Manual
18.5.4 Parameter Passing Mechanisms for I64
The parameter passing mechanisms for I64 are generally the same as for
Alpha and are included here for completeness. Two notable difference
between Alpha and I64 are that the first six parameter slots are passed
in registers for Alpha, while for I64 the first eight parameter slots
are passed in registers; and that I64 passes VAX floating-point
parameters in general registers.
Parameter slots are allocated for each parameter, based on the parameter passing mechanism, type, and size, treating each parameter in sequence, from left to right. The rules for allocating parameter slots and placing the contents within the slot are given in Table 18-10. The allocation column of the table indicates how parameter slots are allocated to each type of parameter.
OpenVMS does not support passing the I64 double-precision extended floating-point type (__float80), although that type may be used from time to time in code generation sequences.
This placement policy does not ensure that parameters greater than 64
bits in size will fall on a natural alignment boundary if passed in
memory. Such parameters may need to be copied by the called procedure
into an aligned temporary prior to use, or accessed in a way that does
not depend on natural alignment.
The first eight parameter slots (64 bytes) are passed in registers, according to the rules in this section.
When IEEE floating-point parameters are passed in floating-point registers, they are passed in the register format, rounded to the appropriate precision. They are never passed in the general registers unless part of an aggregate, in which case they are passed in the aggregate memory format. When VAX floating-point parameters are passed in general registers, they are passed in memory format.
Parameters allocated beyond the eighth parameter slot are never passed in registers.
Unsigned integral (except unsigned 32-bit), set, and VAX floating-point values passed in registers are zero-filled; signed integral values as well as unsigned 32-bit integral values are sign-extended to 64 bits. For all other types passed in the general registers, unused bits are undefined.
1OpenVMS also provides symbols of the form DSC64$K_DTYPE_xxx for each type designator.
18.5.6 Argument Information (AI) Register
In addition to the normal parameters, an implicit argument information value is passed in register R25, the Argument Information (AI) register. This value is shown in Figure 18-12. Note that I64 passes eight arguments in registers, while Alpha passes six arguments in registers.
Figure 18-12 Argument Information Register Representation
Argument Count is an unsigned byte that specifies the number of 64-bit argument slots used for the argument list. (Note that single- and double-precision complex values use two slots, which is reflected in this count.)
Argument Register Information is a contiguous group of eight 3-bit fields that correspond to the eight arguments passed in registers. The first group, bits <10:8>, describes the first argument; the second group, bits <13:11>, describes the second argument; and so on. The encoding for each group is described in Table 18-13.
18.5.7 Memory Stack Parameters
The remainder of the parameter list, beginning with slot 8, is passed
in the outgoing parameter area of the memory stack frame, as described
in the HP OpenVMS Calling Standard. Parameters are mapped directly to memory, with
slot 8 placed at location SP+16, slot 9 placed at location SP+24, and
so on. Each argument is stored in memory as a series of one or more
64-bit storage units, with unused bits in the last unit undefined.
The rules above support variable-argument list functions in both the K&R and the ANSI dialects of the C language. (Note that argument location is independent of whether a prototype is in scope.)
The nth argument is in either Rn or Fn
regardless of the type of parameter in the preceding register slot.
Therefore, a function with variable arguments may assume that the
variable arguments that lie within the first eight argument slots can
be found in either the stacked input integer registers (IN0-IN7), or in
the floating-point parameter registers (F8-F15). Using the information
codes from the the AI (Argument Information) register (see
Table 18-13), the function can then store these registers to memory
using the 16-byte scratch area for IN6/F14 and IN7/F15, and up to 48
bytes at the base of its own stack frame for IN0/F8-IN5/F13, as
necessary. This arrangement places all of the variable parameters in
one contiguous block of memory.
Whenever the address is formed of a formal parameter that is passed in
a register, the compiler must store the parameter to the stack, as it
would for a variable argument list.
The placement of arguments in general registers versus floating-point
registers does not depend on any notion or concept of a prototype being
in scope. It is therefore applicable to all languages at all times.
There must be no difference in behavior between a floating-point
parameter passed directly in a register and a floating-point parameter
that has been stored to memory and reloaded. In either case, the
floating-point value must be the same. This implies that floating-point
parameters passed in floating-point registers must be explicitly
rounded to the proper precision by the caller.
When you are passing an input scalar value to an OpenVMS system
routine, you usually pass it either by reference or by value. You
usually pass output scalar arguments by reference to OpenVMS system
routines. An output scalar argument is the address of a location where
some scalar output of the routine will be stored.
Arrays are passed to OpenVMS system routines by reference or by descriptor.
Sometimes the routine knows the length and dimensions of the array to be received, as in the case of the table passed to LIB$CRC_TABLE. Arrays such as this are normally passed by reference.
In other cases, the routine actually analyzes and operates on the input
array. The routine does not necessarily know the length or dimensions
of such an input array, so a descriptor is necessary to provide the
information the routine needs to describe the array accurately.
Strings are passed by descriptor to OpenVMS system routines. Table 18-14 lists the string-passing descriptors recognized by a system routine.
An OpenVMS system routine writes strings according to the following types of semantics:
18.9 Combinations of Descriptor Class and Data Type
Some combinations of descriptor class and data type are not permitted, either because they are not meaningful or because the calling standard does not recognize them. Possibly, the same function can be performed with more than one combination. This section describes the restrictions on the combinations of descriptor classes and data types. These restrictions help to keep procedure interfaces simple by allowing a procedure to accept a limited set of argument formats without sacrificing functional flexibility.
The tables in Figures 18-13, 18-14, and 18-15 show all possible combinations of descriptor classes and data types. For example, Figure 18-13 shows that your program can pass an argument to an OpenVMS system routine whose descriptor class is DSC$K_CLASS_A (array descriptor) and whose data type is unsigned byte (DSC$K_DTYPE_BU). The calling standard does not permit your program to pass an argument whose descriptor class is DSC$K_CLASS_D (dynamic string) and whose data type is unsigned byte.
A descriptor with data type DSC$K_DTYPE_DSC (24) points to a descriptor that has class DSC$K_CLASS_D (2) and data type DSC$K_DTYPE_T (14). All other class and data type combinations in the target descriptor are reserved for future definition in the standard.
The scale factor for DSC$K_CLASS_SD is always a decimal data type. It does not vary with the data type of the data described by the descriptor.
Figure 18-13 Atomic Data Types and Descriptor Classes
Figure 18-14 String Data Types and Descriptor Classes
Figure 18-15 Miscellaneous Data Types and Descriptor Classes