User`s guide
How the MACRO Compiler Functions on Different Platforms
2.3 Routine Calls and Declarations
In the prologue code, the compiler must allocate stack space (and stacked
registers on OpenVMS I64 systems) to save any necessary context. This includes
saving any registers that will be preserved by the routine and saving the return
address. If this is a CALL routine, it also includes establishing a new stack
frame and changing the frame pointer (FP) (on OpenVMS Alpha systems, and
on OpenVMS I64 systems, if needed), and may include further manipulation and
storage of the input parameters (see Section 2.4).
In the epilogue code, the compiler must restore any necessary registers, stack
frame information, and the return address, and trim the stack back to its original
position.
2.3.3 When to Declare Entry Points
Any code label that is a possible target of a CALLS, CALLG, JSB, BSBW, or
BSBB instruction must be declared as an entry point. In addition, any code label
must be declared as an entry point using a .JSB_ENTRY or .JSB32_ENTRY
directive if:
• The label can be the target of a global (cross-module) JMP, BRB, or BRW
instruction.
• The label can be the target of an indeterminate branch (such as BRB @(R10)),
where the address of the label has been stored in R10, even if the reference
and the label are within the same module.
• The address of the label is stored in a register or memory location, even if it
is never accessed by the current module.
The OpenVMS calling standard for I64 and Alpha does not provide a way to
access indeterminate code addresses directly. All such accesses are accomplished
using a procedure descriptor to describe the routine and the code address. When
a code label address is stored, the compiler does not know if that address will be
referenced only by the current module, or whether it may be accessed by another
MACRO module or another module written in another language. Whenever a
source instruction stores a code address, the MACRO compiler instead stores the
procedure descriptor address for that code address so that other code can access
it correctly. For a procedure descriptor to exist, the label must be declared as an
entry point. When a stored address is used as a branch destination, the compiler
does not know where that address came from, so it always assumes that the
stored address is the address of a procedure descriptor and uses that descriptor
to pass control to the routine.
OpenVMS I64 systems behave identically to OpenVMS Alpha systems, except the
calling standard uses the term ‘‘function descriptor’’ and the function descriptors
are created by the linker.
2.3.4 Directives for Designating Routine Entry Points
Macros in STARLET.MLB generate directives for designating the entry points to
routines. See Appendix B for the format of each of these macros.
When assembled for OpenVMS VAX systems, the macros are null, except for
.CALL_ENTRY. When compiled for OpenVMS Alpha or OpenVMS I64 systems,
the macros expand to verify the arguments and generate the compiler directives.
Therefore, you can use the following macros in common source modules:
• The .CALL_ENTRY directive logically replaces the .ENTRY directive in
Macro-32 code. However, you do not need to replace the .ENTRY directive
unless you want to use one of the .CALL_ENTRY clauses. If you replace the
2–6 How the MACRO Compiler Functions on Different Platforms