User`s guide
MACRO Support for 64-Bit Addressing
5.2 Passing 64-Bit Values
The $SETUP_CALL64 macro initializes the state for a 64-bit call. It is required
before $PUSH_ARG64 or $CALL64 can be used. If the number of arguments
is greater than six on OpenVMS Alpha or eight on OpenVMS I64, this macro
creates a local JSB routine, which is invoked to perform the call. Otherwise, the
argument loads and call are inline and very efficient. Note that the argument
count specified in the $SETUP_CALL64 does not include a pound sign (#).
(The standard call sequence requires octaword alignment of the stack with its
arguments at the top. The JSB routine facilitates this alignment.)
The inline option can be used to force a call with greater than six or eight
arguments to be done without a local JSB routine. However, there are restrictions
on its use (see Appendix E).
The $PUSH_ARG64 macro moves the argument directly to the correct argument
register or stack location. It is not actually a stack push, but it is the analog of
the PUSHL instructions used in a 32-bit call.
The $CALL64 macro sets up the argument count register and invokes the target
routine. If a JSB routine was created, it ends the routine. It reports an error if
the number of arguments pushed does not match the count specified in $SETUP_
CALL64. Both $CALL64 and $PUSH_ARG64 check that $SETUP_CALL64 has
been invoked prior to their use.
Keep these points in mind when using $SETUP_CALL64, $PUSH_ARG64, and
$CALL64:
• The arguments are read as aligned quadwords. To pass a longword from
memory, move it to a register first, and then use that register in $PUSH_
ARG64, as shown in the example in Section 5.2.1. Similarly, if you know the
quadword you want to pass is unaligned, move the value to a register first.
Also, keep in mind that indexed operands, such as (R4)[R0], will be evaluated
using quadword indexing when used in $PUSH_ARG64.
• If the number of arguments is greater than six on OpenVMS Alpha or
eight on OpenVMS I64, so that a local JSB routine is created, no SP or AP
references are allowed between the $SETUP_CALL64 and $CALL64. The
$PUSH_ARG64 and $CALL64 macros do report uses of these registers in
operands, but they are not allowed in other instructions in this range though
such use will not be flagged. To pass an AP- or SP-based argument in this
case, move it to a register before the $SETUP_CALL64 invocation.
• OpenVMS Alpha systems only: If the number of arguments is greater than
six, do not rely on values in registers above R15 surviving the $SETUP_
CALL64 invocation. Use a nonscratch register as a temporary register
instead. For example, suppose you want to pass a value from a stack location,
and the call has more than six arguments. In this case, you need to move the
value to a register. Rather than using a scratch register such as R28, use a
VAX register, such as R0. If all the VAX registers are in use, use R13, R14, or
R15.
• OpenVMS Alpha systems only: It is safe to use the scratch registers above
R16 within the range between the $SETUP_CALL64 and the $CALL64.
However, you must be careful not to use an argument register that has
already been loaded. The argument registers are loaded in downward order,
from R21 through R16. So, suppose a call passes six arguments. It is not safe
to use R21 after the first $PUSH_ARG64, because that has loaded R21. The
$PUSH_ARG64 macro checks for operands that refer to argument registers
that have already been loaded. If any are found, the compiler reports a
MACRO Support for 64-Bit Addressing 5–3