User`s guide

How the MACRO Compiler Functions on Different Platforms
2.4 Declaring CALL Entry Points
where n represents the highest argument referenced, as detected by the
compiler.
2.4.2 Saving Modified Registers
A well-behaved VAX MACRO CALL routine passes all parameters via the
argument list and saves all necessary registers via the register mask in the
.ENTRY declaration. However, some routines do not adhere to these standards
and may pass parameters via registers or save and restore the contents of the
necessary registers within the routine with instructions such as PUSHL and
POPL.
Using PUSHL and POPL to save and restore registers on an OpenVMS Alpha or
OpenVMS I64 system is insufficient because these instructions save only the low
32 bits of the register. To avoid register corruption, the compiler automatically
saves and restores the full 64-bit values of any register modified within the
routine (except R0 and R1), in addition to the registers specified in the register
save mask. This means that any registers that were intended to pass an output
value out of the called routine will no longer do so. You must either pass the
output via the standard argument list or declare the register to be output with
the output parameter in the .CALL_ENTRY declaration (see Section 2.6). On
OpenVMS I64 systems, you must use the .CALL_LINKAGE directive when
calling such a routine since the I64 calling standard forces the compiler to save
various registers around the call.
2.4.3 Modifying the Argument Pointer
If a routine modifies AP, the compiler changes all uses of AP in that routine to
R12 and reports all such modifications. Although traversing the argument list in
this way is not supported, you can obtain similar results by explicitly moving the
address 0(AP) to R12 and specifying home_args=TRUE in the entry point. R12
will point to a VAX format argument list.
2.4.4 Establishing Dynamic Condition Handlers in Called Routines
To establish a dynamic condition handler in a called routine, it is necessary to
store a condition handler address in the frame. The compiler generates a static
condition handler for .CALL_ENTRY routines that modify 0(FP). The static
handler invokes the dynamic handler or returns if no condition handler address
has been stored in the frame.
For performance reasons, on OpenVMS Alpha systems, the compiler does not
automatically insert a TRAPB instruction at the end of every routine that
establishes a condition handler. Because of the indeterminate nature of traps
on an Alpha system, this could allow traps from instructions near the very end
of the routine to be processed after the frame pointer has been changed in the
routine epilogue code, with the result that the declared handler would not process
the trap. If it is essential that any traps generated in the routine be processed
by the declared handler, insert an EVAX_TRAPB built-in immediately before the
RET instruction that ends the routine.
2–10 How the MACRO Compiler Functions on Different Platforms