HP OpenVMS Systems Documentation
HP OpenVMS MACRO Compiler
Porting VAX MACRO code already running on OpenVMS Alpha to OpenVMS I64 is a relatively simple process. In contrast to porting from OpenVMS VAX, most VAX MACRO code will recompile with no changes required.
Due to differences in the calling standards between OpenVMS Alpha and OpenVMS I64, the compiler needs to know about:
You need to add linkage direcives (.CALL_LINKAGE, .DEFINE_LINKAGE) to
tell the compiler about routines that return values in registers other
than R0/R1 and about routines written in a language other than Macro-32
that are called with a JSB/BSBW instruction. In addition, you need to
add the .USE_LINKAGE directive at each indirect CALLS/CALLG instruction
if the routine has a nonstandard return. Add the .USE_LINKAGE directive
at each indirect JSB/BSBW instruction if the routine is written in a
language other than Macro-32. See Appendix B, Specialized Directives for more information.
1.5 Identifying Nonportable VAX MACRO Coding Practices
When examining a VAX MACRO module that you intend to compile to OpenVMS Alpha or OpenVMS I64 object code, you need to look for nonportable coding constructs. The occurrence of these in a module can make porting take longer than it would otherwise. Although the compiler can identify many of these practices, recognizing them yourself will speed up the porting effort. For more information about nonportable MACRO coding practices, including some that occur less frequently and are less easy to detect, see Chapter 3.
TSTL (SP)+ ; remove return address RSB ; return to caller's caller
POPL R0 ; remove the return address SUBL #structure_size,SP ; allocate stack space for caller PUSHL R0 ; replace the return address
POPL R1 ; hold return address PUSHL structure ; build structure for caller ; ; code continues ; JMP (R1) ; return to caller
MOVAL routine_label,-(SP) RSB
PUSHAL routine_label RSB
MOVL SP,FP SUBL #data_area,SP
MOVL #fake_psl,-(SP) MOVAL target_label,-(SP) ; all three REI
MOVPSL -(SP) MOVAL target_label,-(SP) ; force AST delivery only REI
MOVL #fake_psl,-(SP) BSBW DOREI ; ; code continues ; DOREI: REI
Section 1.3 describes a recommended process for porting VAX MACRO code to OpenVMS Alpha or OpenVMS I64. Although this process might provide a mechanism for porting code efficiently, it cannot by itself guarantee that the porting effort will be consistent among the engineers who are performing the porting, or will be intelligible to the engineers who will later need to debug and test ported code. To ensure that the porting effort proceeds uniformly and that its effects on source code are well documented, an engineering group should establish coding conventions that are relevant to the goals of the effort.
Naturally, any methodology an engineering group adopts should be shaped by that group's development environment, including those procedures the group follows for tool management, source code control, common code, and testing. The coding conventions an engineering group should evaluate include:
When designing a VAX MACRO code porting effort, consider the benefits
of maintaining common sources for OpenVMS VAX, OpenVMS Alpha, and
OpenVMS I64 systems. It is advantageous to an engineering group to
have only one copy of its sources to maintain and enhance, and common
sources help ensure common user interfaces. However, if you find that
you are conditionalizing so much source code that it is no longer
intelligible, take steps to restructure the code into
architecture-specific and architecture-independent pieces. If the
number of these pieces becomes unmanageable, create separate
1.7.1 Including Compiler Directive Definitions
A successful compilation does not preclude VAX MACRO code in a source file from also processing successfully under the VAX MACRO assembler. If you added any compiler directives to your code, they will be resolved by the library SYS$LIBRARY:STARLET.MLB when the code is assembled. The assembler automatically searches this library for any undefined macros. After finding these definitions, the assembler will ignore occurrences of the compiler directives.
However, if you are using OpenVMS VAX Version 6.0 or earlier, you must first extract the directive definitions from SYS$LIBRARY:STARLET.MLB on OpenVMS Alpha or OpenVMS I64 and insert them into your SYS$LIBRARY:STARLET.MLB on OpenVMS VAX. For example:
LIB/EXTRACT=.JSB_ENTRY/OUT=JSB_ENTRY.MAR SYS$LIBRARY:STARLET.MLB . . . LIB/INSERT SYS$LIBRARY:STARLET.MLB JSB_ENTRY.MAR
Note that many of the definitions of the compiler directives refer to
other macros. Make sure to extract not only the definitions of all the
compiler directives used in your code but also all the associated
macros and insert them into SYS$LIBRARY:STARLET.MLB on your OpenVMS VAX
1.7.2 Removing VAX Dependencies
If you must make changes to source files because they contain certain coding practices that cannot be directly compiled into Alpha or Itanium code, you might still be able to generate images for both OpenVMS VAX and OpenVMS Alpha and/or OpenVMS I64 systems from common VAX MACRO sources.
Removing such VAX dependencies so that the same code can run on both OpenVMS VAX and OpenVMS Alpha and/or OpenVMS I64 systems can yield great benefits during the porting process. You can debug single modules or groups of modules of the ported code by building and testing the modules in the VAX environment or the Alpha environment, if the code has already been ported to run there. This can greatly speed your debugging process.
In some cases, you must define and implement procedures for conditionalizing the source files (as described in Section 1.7.3) or for providing separate sources for OpenVMS VAX and OpenVMS Alpha and/or OpenVMS I64 systems.
If the code runs in an inner mode, it is unlikely that an effort to
generate OpenVMS VAX and OpenVMS Alpha and/or OpenVMS I64 images
from common VAX MACRO sources will be fully successful. Because
inner-mode code interoperates with the executive, it is vulnerable to
the differences between OpenVMS VAX and OpenVMS Alpha and/or
OpenVMS I64 system interfaces and executive data structures. However,
user-mode code is generally immune from architectural dependencies and
can more easily serve as the basis for common code.
1.7.3 Conditionalizing Architecture-Specific Code
Conditionalizing VAX MACRO code requires the use of the SYS$LIBRARY:ARCH_DEFS.MAR file with architecture-specific symbols:
If you choose to make code in a common source module conditional on architecture type, include ARCH_DEFS.MAR on the command line in your assembly and compilation and use .IF DF VAX or .IF DF ALPHA or .IF DF IA64.
A code pattern to avoid, and, in fact, to search for and change in already ported code, is the use of the following:
.IF DF VAX . . . ; VAX code .IFF . . . ; Alpha code . . . ; will it work for IA64 .ENDC
.IF DF ALPHA . . . ; Alpha code .IFF . . . ; VAX code, will likely fail for IA64 .ENDC
The best code would be:
.IF DF VAX . . . ; VAX code .IFF .IF DF ALPHA . . . ; Alpha code .IFF .IF DF IA64 . . . ; IA64 code .IFF .ERROR . . . .ENDC .ENDC .ENDC
; This is the VAX version of ARCH_DEFS.MAR, which contains ; architectural definitions for compiling sources for ; VAX systems. ; VAX = 1 VAXPAGE = 1 ADDRESSBITS = 32
Any other symbols in ARCH_DEFS.MAR on OpenVMS Alpha or OpenVMS I64 are specific to OpenVMS Alpha or OpenVMS I64 source code and are not guaranteed to be included from release to release.
The MACRO Compiler for OpenVMS Systems has been designed to help you port VAX MACRO source code from OpenVMS VAX to OpenVMS Alpha or OpenVMS I64. When operating on VAX MACRO code that complies with the restrictions and guidelines described in this manual, the compiler produces a valid OpenVMS Alpha or OpenVMS I64 object module that preserves the semantics of the original VAX MACRO source and adheres to the OpenVMS Alpha or OpenVMS I64 calling standard.
This chapter contains the following topics:
OpenVMS Alpha systems and OpenVMS I64 systems employ 32 integer registers, R0 through R31. Code generated by the OpenVMS Alpha compiler uses Alpha registers R0 through R12 as if they were VAX registers, and the OpenVMS I64 compiler automatically maps VAX registers to alternate Itanium registers. Thus, VAX MACRO code usage of these registers (for instance, as input to JSB routines) does not have to change to achieve a correct compilation. VAX MACRO instructions (such as MOVL and ADDL) use the lower 32 bits of the Alpha or Itanium register involved in the operation. The compiler maintains a sign-extended 64-bit form of this value in the register.
Registers R13 and above are also available to VAX MACRO code that will be compiled to OpenVMS Alpha or OpenVMS I64 object format. If you decide to use these registers, review the following constraints:
The Itanium architecture and OpenVMS I64 have several important differences compared to the Alpha architecture and OpenVMS Alpha.
OpenVMS I64 systems employ 32 integer registers, R0 through R31, with R0 being a read-only register that contains 0. This is different from OpenVMS Alpha, where R31 is a read-write register that contains 0.
In addition, the OpenVMS I64 calling standard has been written to be highly compatible with the Intel calling standard, and is quite different from the OpenVMS Alpha calling standard. For example, the standard return registers on OpenVMS I64 are R8/R9, not R0/R1 as on OpenVMS Alpha. The OpenVMS I64 calling standard reserves R1 as the GP (global pointer), does not include a standardized FP (frame pointer), and only has R4 through R7 as preserved across calls, not R2 through R15 as on OpenVMS Alpha.
Since Macro-32 source code is written with the OpenVMS VAX and OpenVMS Alpha calling standards in mind, the compiler performs several transformations to allow existing code to compile unmodified with the OpenVMS I64 compiler.
First, the compiler maps the registers in the Macro-32 source program to different registers on the I64 hardware. This allows existing programs to use "MOVL SS$_NORMAL, R0" and have the generated code return the value in R8 as prescribed by the calling standard. Table 2-1 shows the register mappings for OpenVMS VAX/OpenVMS Alpha to OpenVMS I64.
|OpenVMS VAX/OpenVMS Alpha register in source code||OpenVMS I64 register used in generated code|
|R26||Itanium stacked register|
|R27||Itanium stacked register|
|R28||Itanium stacked register|
The register mapping was carefully chosen based on which registers were preserved across calls, which registers may be modified across calls, and which registers are volatile and do not even survive into or out of a call.
As on OpenVMS Alpha, Macro-32 references to AP are mapped by the compiler to the appropriate location depending on whether the arguments have been saved to the stack. To support references to FP, the compiler creates an FP value where needed. The compiler supports references to 0(FP) to establish condition handlers just like on OpenVMS VAX and OpenVMS Alpha.
Any references to register numbers elsewhere in this manual refer to the VAX/Alpha register with that number. The mapping to an actual Itanium register is totally transparent to the Macro-32 source code (and most of the compiler).
The compiler does not provide any syntax for accessing Itanium registers directly without going through the mapping table.
The automatic register mapping done by the compiler allows many Macro-32 programs (including those that access Alpha registers R16-R31) to compile without modificiations.
Note, however, that use of registers R16-R21 as routine parameters on OpenVMS Alpha is not portable to OpenVMS I64. Use PUSHL to pass parameters to a CALL, and use 4(AP), 8(AP), and so forth in the called routine to refer to them. The compiler will generate the correct register references instead of the stack references implied by the VAX operands.
On OpenVMS I64 systems, the compiler continues to recognize many of the EVAX_* built-ins that provide direct access to Alpha instructions on OpenVMS Alpha systems. These built-ins will generate one or more Itanium instructions to perform the same logical operation. See Appendix C for a complete list of which EVAX_* built-ins are also supported on I64 systems.