These macros reside in the directory SYS$LIBRARY:STARLET.MLB and
can be used by both application code and system code.
The page macros accommodate for 64-bit addresses. The support is
provided by the QUAD=NO/YES parameter.
You can use certain arguments to these macros to indicate
register sets. To express a register set, list the registers,
separated by commas, within angle brackets. For example:
<R1,R2,R3>
If the set contains only one register, the angle brackets are not
required.
1 – $SETUP CALL64
Initializes the call sequence.
Format
$SETUP_CALL64 arg_count, inline=true | false
1.1 – Parameters
arg_count
The number of arguments in the call.
inline
Forces inline expansion, rather than creation of a JSB routine,
when set to TRUE. If there are six or fewer arguments on
OpenVMS Alpha, or eight or fewer on OpenVMS I64, the default
is inline=false.
1.2 – Description
This macro initializes the state for a 64-bit call. It must be
used before using $PUSH_ARG64 and $CALL64.
If there are six or fewer arguments on OpenVMS Alpha, or eight or
fewer on OpenVMS I64, the code is always in line.
By default, if there are more than six arguments on OpenVMS
Alpha or eight arguments on OpenVMS I64, this macro creates a
JSB routine that is invoked to perform the actual call. However,
if the inline option is specified as inline=true, the code is
generated in line.
This option should be enabled only if the code in which it
appears has a fixed stack depth. A fixed stack depth can be
assumed if no RUNTIMSTK or VARSIZSTK messages have been reported.
Otherwise, if the stack alignment is not at least quadword,
there might be many alignment faults in the called routine
and in anything the called routine calls. The default behavior
(inline=false) does not have this problem.
If there are more than six arguments on OpenVMS Alpha or eight
arguments on OpenVMS I64, there can be no references to AP or
SP between a $SETUP_CALL64 and the matching $CALL64, because
the $CALL64 code may be in a separate JSB routine. In addition,
temporary registers (R16 and above) may not survive the $SETUP_
CALL64.
NOTE
The $SETUP_CALL64, $PUSH_ARG64, and $CALL64 macros are
intended to be used in an inline sequence. That is, you
cannot branch into the middle of a $SETUP_CALL64/$PUSH_
ARG64/$CALL64 sequence, nor can you branch around $PUSH_
ARG64 macros or branch out of the sequence to avoid the
$CALL64.
2 – $PUSH ARG64
Does the equivalent of argument pushes for a call.
Format
$PUSH_ARG64 argument
2.1 – Parameters
argument
The argument to be pushed.
2.2 – Description
This macro pushes a 64-bit argument for a 64-bit call. The macro
$SETUP_CALL64 must be used before you can use $PUSH_ARG64.
Arguments will be read as aligned quadwords. That is, $PUSH_ARG64
4(R0) will read the quadword at 4(R0), and push the quadword. Any
indexed operations will be done in quadword mode.
To push a longword value from memory as a quadword, first move it
into a register with a longword instruction, and then use $PUSH_
ARG64 on the register. Similarly, to push a quadword value that
you know is not aligned, move it to a temporary register first,
and then use $PUSH_ARG64.
If the call contains more than six arguments on OpenVMS Alpha or
eight arguments on OpenVMS I64, this macro checks for SP or AP
references in the argument.
If the call contains more than six arguments on OpenVMS Alpha or
eight arguments on OpenVMS I64, SP references are not allowed,
and AP references are allowed only if the inline option is used.
Note that $PUSH_ARG64 cannot be in conditional code. $PUSH_
ARG64 updates several symbols, such as the remaining argument
count. Attempting to write code that branches around a $PUSH_
ARG64 in the middle of a $SETUP_CALL64/$CALL64 sequence will not
work properly.
3 – $CALL64
Invokes the target routine.
Format
$CALL64 call_target
3.1 – Parameters
call_target
The routine to be invoked.
3.2 – Description
This macro calls the specified routine, assuming $SETUP_CALL64
has been used to specify the argument count, and $PUSH_ARG64 has
been used to push the quadword arguments. This macro checks that
the number of pushes matches what was specified in the setup
call.
The call_target operand must not be AP- or SP-based.
4 – $IS 32BITS
Checks the sign extension of the low 32 bits of a 64-bit value
and directs the program flow based on the outcome of the check.
Format
$IS_32BITS quad_arg, leq_32bits, gtr_32bits, temp_reg=22
4.1 – Parameters
quad_arg
A 64-bit quantity, either in a register or in an aligned quadword
memory location.
leq_32bits
Label to branch to if quad_arg is a 32-bit sign-extended value.
gtr_32bits
Label to branch to if quad_arg is greater than 32 bits.
temp_reg=22
Register to use as a temporary register for holding the low
longword of the source value-R22 is the default.
4.2 – Description
$IS_32BITS checks the sign extension of the low 32 bits of a 64-
bit value and directs the program flow based on the outcome of
the check.
4.3 – Examples
1.$is_32bits R9, 10$
In this example, the compiler checks the sign extension of
the low 32 bits of the 64-bit value at R9 using the default
temporary register, R22. Depending on the type of branch
and the outcome of the test, the program either branches or
continues in line.
2.$is_32bits 4(R8), 20$, 30$, R28
In this example, the compiler checks the sign extension of
the low 32 bits of the 64-bit value at 4(R8) using R28 as a
temporary register and, based on the check, branches to either
20$ or 30$.
5 – $IS DESC64
Tests the specified descriptor to determine if it is a 64-bit
format descriptor, and directs the program flow based on the
outcome of the test.
Format
$IS_DESC desc_addr, target, size=long | quad
5.1 – Parameters
desc_addr
The address of the descriptor to test.
target
The label to branch to if the descriptor is in 64-bit format.
size=long|quad
The size of the address pointing to the descriptor. The default
value is size=long.
5.2 – Description
$IS_DESC64 tests the fields that distinguish a 64-bit descriptor
from a 32-bit descriptor. If it is in 64-bit form, a branch is
taken to the specified target. The address to be tested is read
as a longword, unless size=quad is specified.
5.3 – Examples
1.$is_desc64 r9, 10$
In this example, the descriptor pointed to by R9 is tested, and
if it is in 64-bit form, a branch to 10$ is taken.
2.$is_desc64 8(r0), 20$, size=quad
In this example, the quadword at 8(R0) is read, and the
descriptor it points to is tested. If it is in 64-bit form,
a branch to 20$ is taken.