HP OpenVMS Systems Documentation

Content starts here

OpenVMS MACRO-32 Porting and User's Guide


Previous Contents Index

The associated input file to the /LIBRARY qualifier must be a macro library. The default file type is MLB. The /NOLIBRARY qualifier has the same effect as not specifying the /LIBRARY qualifier, or negates the effects of any /LIBRARY qualifiers specified earlier in the command line.

The compiler can search up to 16 libraries, one of which is always STARLET.MLB. This number applies to a particular compilation, not necessarily to a particular MACRO command. If you enter the MACRO command so that more than one source file is compiled, but the source files are compiled separately, you can specify up to 16 macro libraries for each separate compilation. More than one macro library in a compilation causes the libraries to be searched in reverse order of their specification.

A macro call in a source program causes the compiler to begin the following sequence of searches:

  1. An initial search of the libraries specified with the .LIBRARY directive. The compiler searches these libraries in the reverse order of that in which they were declared.
  2. If the macro definition is not found in any of the libraries specified with the .LIBRARY directive, a search of the libraries specified in the MACRO command line (in the reverse order in which they were specified).
  3. If the macro definition is not found in any of the libraries specified in the command line, a search of STARLET.MLB.

/LIST[=filespec]

/NOLIST

Creates or omits an output listing, and optionally provides an output file specification for it. The default file type for the listing file is LIS. No wildcard characters are allowed in the file specification.

An interactive MACRO command does not produce a listing file by default. The /NOLIST qualifier, present either explicitly or by default, causes errors to be reported on the current output device.

The /LIST qualifier is the default for a MACRO command in a batch job. The /LIST qualifier allows you to control the defaults applied to the output file specification by the placement of the qualifier in the command line.

/MACHINE

/NOMACHINE (default)

Enables machine code listing, if it and the /LIST qualifier are both specified in the command line.

/OBJECT[=filespec]

/NOOBJECT

Creates or omits an object module. It also defines the file specification. By default, the compiler creates an object module with the same file name as the first input file. The default file type for object files is OBJ. No wildcard characters are allowed in the file specification.

The /OBJECT qualifier controls the defaults applied to the output file specification by the placement of the qualifier in the command line.

/OPTIMIZE[=(option[,...])]

/NOOPTIMIZE

Enables or disables optimization options. All options are enabled by default except VAXREGS. (See Section 4.3.1.)
Option Description
[NO]PEEPHOLE Peephole optimization
[NO]SCHEDULE Code scheduling
[NO]ADDRESSES Common base address loading
[NO]REFERENCES Common data referencing
[NO]VAXREGS Allow the use of VAX registers (R0 through R12) as temporary registers when they appear to be unused
ALL All optimizations
NONE No optimizations

Note that /ALL turns on VAXREGS, which may generate incorrect code unless all register usage of all routines in the module have been correctly declared.

/PRESERVE[=(option[,...])]

/NOPRESERVE (default)

Directs the compiler to generate special OpenVMS Alpha assembly code throughout a module for all VAX MACRO instructions that rely on VAX guarantees of operation atomicity or granularity. (See Section 2.10.) The options are:
Option Description
GRANULARITY Preserves the rules of VAX granularity of writes. Specifying /PRESERVE=GRANULARITY causes the compiler to use Alpha Load-locked and Store-conditional instruction sequences in code it generates for VAX instructions that perform byte, word, or unaligned longword writes.
ATOMICITY Preserves atomicity of VAX modify operations. Specifying /PRESERVE=ATOMICITY causes the compiler to use Load...Locked and Store...Conditional instruction sequences in code it generates for instructions with modify operands.

/PRESERVE and /PRESERVE=(GRANULARITY,ATOMICITY) are equivalent. When preservation of both granularity and atomicity is enabled, and the compiler encounters a VAX coding construct that requires both granularity and atomicity guarantees, it enforces atomicity over granularity.

If you are aware of specific sections of VAX MACRO code that require VAX granularity and atomicity guarantees, you can forego compiler enforcement of these guarantees for the entire module and use the .PRESERVE and .NOPRESERVE directives (see Appendix B) to indicate those sections. Therefore, if you can isolate that code where granularity and atomicity must apply, these directives allow you to optimize the generated code by preventing the compiler from generating expanded Alpha code unnecessarily.

Atomicity is guaranteed on multiprocessing systems as well as uniprocessing systems when you specify /PRESERVE=ATOMICITY.

When the /PRESERVE qualifier is present, you can control the number of times compiler-generated code retries a granular or atomic update by specifying the /RETRY_COUNT qualifier.

Warning

If /PRESERVE=ATOMICITY is turned on, any unaligned data references will result in a fatal reserved operand fault. See Section 2.10.5. If /PRESERVE=GRANULARITY is turned on, unaligned word references to addresses assumed aligned will also cause a fatal reserved operand fault.

/RETRY_COUNT=count

Specifies to the compiler the number of times the following operations should be performed in generated code:
  • Retries of operations performed in source by a VAX interlocked instruction
  • Retries of atomic or granular updates if the /PRESERVE qualifier or .PRESERVE directive is present

If the /RETRY_COUNT qualifier is not present, the compiler generates code that performs an infinite number of retries of these operations.

/SHOW[=(function[,...])]

/NOSHOW[=(function[,...])]

Provides initial settings for the functions controlled by the compiler directives .SHOW and .NOSHOW.

You can specify one or more of the following functions:

CONDITIONALS Lists unsatisfied conditional code associated with .IF and .ENDC MACRO directives.
CALLS Lists macro calls and repeat range expansions.
DEFINITIONS Lists macro definitions.
EXPANSIONS Lists macro expansions.
BINARY Lists binary code generated by the expansion of macro calls.

/SYMBOLS

/NOSYMBOLS (default)

Generates a symbol table and psect synopsis table for the listing file if it and the /LIST qualifier are both specified in the command line.

/TIE (default)

/NOTIE

Ensures that proper external callouts are generated for translated images. Translated images are images that were translated with the DECMigrate (also known as VEST) facility. The Translated Image Environment (TIE) allows translated images to execute as if on an OpenVMS VAX system. Use /NOTIE for better performance if you do not make calls to translated images.

/UNALIGNED

/NOUNALIGNED (default)

Forces the compiler to use unaligned loads and stores for all register-based memory references (except those that are FP--based or SP--based or are references to local aligned static data).

By default, the compiler assumes that addresses in registers used as base pointers (except those that are FP--based or SP--based) are longword-aligned at routine entry, and generates code to load BYTE, WORD, and LONG data accordingly. This can result in run-time alignment faults, with significant performance impact, if the assumption is incorrect. Specifying /UNALIGNED causes the compiler to generate code assuming pointers are unaligned. This code is significantly larger, but is more efficient than handling an alignment fault.

Note

The compiler does not track quadword register alignment. For quadword memory references (such as in VAX MOVQ instructions), the compiler assumes the base address is quadword aligned, unless it has determined the address may not be longword-aligned in its register tracking code. Quadword references in OpenVMS Alpha built-in uses are always assumed to be quadword aligned. Since these must be in new code, the data should be properly aligned.

The /UNALIGNED qualifier is generally appropriate only for modules where data is often unaligned, but which are not sufficiently performance sensitive to merit the correction of the data alignment in the source.

/WARN=[[option]...]

/NOWARN

Turns off all informational level or warning level messages. Both are on by default.
Option Description
INFO Turns on all informational level messages
NOINFO Turns off all informational level messages
WARN Turns on all informational and warning level messages
NOWARN Turns off all informational and warning level messages


Appendix B
Compiler Directives

This appendix begins by briefly describing the compiler's support of the VAX MACRO assembler directives. Then it lists the specialized directives of the MACRO-32 Compiler for OpenVMS Alpha and describes each one in detail.

B.1 Support of VAX MACRO Assembler Directives

The compiler supports most of the standard VAX MACRO assembler directives discussed in the VAX MACRO and Instruction Set Reference Manual. However, the following directives that are supported by the VAX MACRO assembler do not make sense for compiled code. Consequently, the compiler flags them and continues execution. You can disable the flagging of these directives by specifying /NOFLAG=DIRECTIVES.

  • .ENABLE and .DISABLE ABSOLUTE---for forcing absolute addressing modes
  • .ENABLE and .DISABLE TRUNCATION---for enabling floating point truncation
  • .LINK---for specifying linker options in a linker options file
  • .DEFAULT---for setting displacement lengths
  • .OPDEF and .REFn ---for defining opcodes
  • Alignment directives (.ALIGN, .EVEN, and .ODD) in code psects
  • .TRANSFER (see Section 3.7)
  • .MASK

Note

The length of the argument to a .ASCID directive is limited to 996 characters when using the MACRO-32 Compiler for OpenVMS Alpha. No such restriction exists in the VAX MACRO Assembler.

B.2 Compiler Directives

The MACRO-32 Compiler for OpenVMS Alpha provides the following specialized directives:

  • .BRANCH_LIKELY
  • .BRANCH_UNLIKELY
  • .CALL_ENTRY
  • .DEFINE_PAL
  • .DISABLE
  • .ENABLE
  • .EXCEPTION_ENTRY
  • .GLOBAL_LABEL
  • .JSB_ENTRY
  • .JSB32_ENTRY
  • .LINKAGE_PSECT
  • .PRESERVE
  • .SET_REGISTERS
  • .SYMBOL_ALIGNMENT

You can use certain arguments to these directives to indicate register sets. You express a register set by listing the registers, separated by commas, within angle brackets. For example:


<R1,R2,R3>

If only one register is in the set, no angle brackets are used. For example:


R1

.BRANCH_LIKELY

Instructs the compiler that the following branch will likely be taken. Therefore, the compiler generates code that incorporates that assumption.

Format

.BRANCH_LIKELY

There are no parameters for this directive.


Example


MOVL (R0),R1
.BRANCH_LIKELY
BNEQ    10$
  .
  .
  .
10$
      

The compiler will move the code between the BNEQ instruction and label 10$ to the end of the module, and change the BNEQ 10$ to a BEQL to the moved code. It will then continue immediately following the BEQL instruction with generation of the code starting at label 10$. This will eliminate the delay that occurs on Alpha systems for a mispredicted branch.


.BRANCH_UNLIKELY

Instructs the compiler that the following branch will likely not be taken. Therefore, the compiler generates code that incorporates that assumption.

Format

.BRANCH_UNLIKELY

There are no parameters for this directive.


Description

The .BRANCH_UNLIKELY directive instructs the compiler that the following conditional branch will likely not be taken. The compiler then generates code that incorporates that assumption.

Alpha system hardware predicts that forward conditional branches are not taken. Therefore, if a .BRANCH_UNLIKELY directive precedes a branch that will be in the forward direction, it has no effect. However, if it precedes a branch that would be backward, code is generated to force the branch to be forward, to an out-of-line branch back to the actual branch destination.

.BRANCH_UNLIKELY should be used only in cases where the branch is very unlikely, not just less frequent than the fall-through case.


Example


        MOVL    #QUEUE,R0            ;Get queue header
10$:    MOVL    (R0),R0              ;Get entry from queue
        BEQL    20$                  ;Forward branch assumed unlikely
        .
        .                            ;Process queue entry
        .
        TSTL    (R0)                 ;More than one entry (known to be unlikely)
        .BRANCH_UNLIKELY
        BNEQ    10$                  ;This branch made into forward
20$:                                 ;conditional branch
      

The .BRANCH_UNLIKELY directive is used here because the Alpha hardware would predict a backward branch to 10$ as likely to be taken. The programmer knows it is a rare case, so the directive is used to change the branch to a forward branch, which is predicted not taken.


.CALL_ENTRY

Declares the entry point of a called routine to the compiler. This entry declaration will save and restore the full 64 bits of any registers (except R0 and R1) that are modified by the routine and are not declared as scratch or output.

Format

.CALL_ENTRY [max_args] [,home_args=TRUE|FALSE] [,quad_args=TRUE|FALSE] [,input] [,output] [,scratch] [,preserve] [,label]


Parameters

max_args

Maximum number of arguments the called procedure expects. The compiler uses this value as the number of longwords it allocates in the fixed temporary region of the stack frame, if the argument list must be homed. If homing is not necessary, the max_args count is not required. The compiler flags procedure entry points, where max_args has not been specified, that require homed argument lists.

Note that, for .CALL_ENTRY routines in which max_args exceeds 14, the compiler uses the received argument count, or max_args, whichever is smaller, when homing the argument list.

home_args=TRUE|FALSE

Indication to the compiler that the called procedure's argument list should or should not be homed. The home_args argument overrides the compiler's default logic, as explained in Section 2.3.1, for determining the circumstances under which an argument list must be homed.

quad_args=TRUE|FALSE

Indication to the compiler that the called procedure's argument list will have quadword references.

input=<>

Register set that indicates those registers from which the routine receives input values.

This register set informs the compiler that the registers specified have meaningful values at routine entry and are unavailable for use as temporary registers even before the first compiler-detected use of the registers. Specifying registers in this register set affects compiler temporary register usage in two cases:

  • If you are using the VAXREGS optimization switch. This optimization allows the compiler to use as temporary registers any of the VAX registers which are not explicitly being used by the VAX MACRO code.
  • If you are explicitly using any of the Alpha registers (R13 and above).

In either of these cases, if you do not specify a register that is being used as input in the input argument, the compiler may use the register as a temporary register, corrupting the input value.

This register set has no effect on the compiler's default register preservation behavior. If you are not using the VAXREGS optimization switch or any of the Alpha registers, the input mask is used only to document your routine.

output=<>

Register set that indicates those registers to which the routine assigns values that are returned to the routine's caller. Registers included in this register set are not saved and restored by the compiler, even if they are modified by the routine.

This register set also informs the compiler that the registers specified have meaningful values at routine exit and are unavailable for use as temporary registers even after the last compiler-detected use of the registers. Specifying registers in this register set affects compiler temporary register usage in two cases:

  • If you are using the VAXREGS optimization switch. This optimization allows the compiler to use as temporary registers any of the VAX registers which are not explicitly being used by the VAX MACRO code.
  • If you are explicitly using any of the Alpha registers (R13 and above).

In either of these cases, if you do not specify a register that is being used as output in the output argument, the compiler may use the register as a temporary register, corrupting the output value.

scratch=<>

Register set that indicates registers that are used within the routine but which should not be saved and restored at routine entry and exit. The caller of the routine does not expect to receive output values nor does it expect the registers to be preserved. Registers included in this register set are not saved and restored by the compiler, even if they are modified by the routine.

This also pertains to the compiler's temporary register usage. The compiler may use registers R13 and above as temporary registers if they are unused in the routine source code. Because R13 through R15 must be preserved, if modified, according to the OpenVMS Alpha calling standard, the compiler preserves those registers if it uses them.

However, if they appear in the scratch register set declaration, the compiler will not preserve them if it uses them as temporary registers. As a result, these registers may be scratched at routine exit, even if they were not used in the routine source but are in the scratch set. If the VAXREGS optimization is used, this applies to registers R2 through R12, as well.

preserve=<>

Register set that indicates those registers that should be preserved over the routine call. This should include only those registers that are modified and whose full 64-bit contents should be saved and restored.

This register set causes registers to be preserved whether or not they would have been preserved automatically by the compiler. Note that because R0 and R1 are scratch registers, by calling standard definition, the compiler never saves and restores them unless you specify them in this register set.

This register set overrides the output and scratch register sets. If you specify a register both in the preserve register set and in the output or scratch register sets, the compiler will report the warning:


%AMAC-W-REGDECCON, register declaration conflict in routine A

label=name

Optionally specify a label as in a VAX MACRO .ENTRY directive. This can be used if a module is to be common between VAX and Alpha, the VAX version needs to reference the entry with a .MASK directive, and the Alpha version needs to use one or more of the special .CALL_ENTRY parameters. When the label parameter is specified and the symbol VAX is defined, an .ENTRY directive is used. (See Section 1.6.3). If the symbol VAX is not defined, it creates the label and does a normal .CALL_ENTRY. Note that label is not the first parameter. Therefore, you cannot simply replace .ENTRY with .CALL_ENTRY. You must use the label parameter declaration.

.DEFINE_PAL

Defines an arbitrary PALcode function such that it can be called later in the MACRO source.

Format

.DEFINE_PAL name, pal_opcode, [,operand_descriptor_list]


Parameters

name

Name of the PALcode function. The compiler applies the prefix EVAX_ to the specified name (for instance, EVAX_MTPR_USP).

pal_opcode

Opcode value of the PALcode function. PALcode opcodes are listed in the Alpha Architecture Reference Manual.

Be sure to use angle brackets around the function code when specifying it in hexadecimal format (^X). If you specify the function code in decimal format, angle brackets are not necessary.

operand_descriptor_list

A list of operand descriptors that specifies the number of operands and the type of each. Up to 6 operand descriptors are allowed in the list. Be careful to specify operands correctly so that the compiler can correctly track register and stack usage. Table B-1 lists the operand descriptors.

Table B-1 Operand Descriptors
Access Type Data Type
  Byte Word Longword Octaword
Address AB AW AL AQ
Read-only RB RW RL RQ
Modify MB MW ML MQ
Write-only WB WW WL WQ

Description

By default, the compiler defines many OpenVMS Alpha PALcode instructions as built-ins. These are listed in Appendix C. If you need to use an OpenVMS Alpha PALcode instruction that is not available as a compiler built-in, you must define the built-in yourself using the .DEFINE_PAL directive.

Example


.DEFINE_PAL MTPR_USP, <^X23>, RQ
      

Note

This is an example---the compiler compiles MTPR instructions directly to PAL calls.


Previous Next Contents Index