1  MACRO
   Invokes the MACRO-32 Compiler for OpenVMS I64 to compile one or
   more VAX MACRO assembly language source files into native OpenVMS
   I64 object code.

   Format

     MACRO/MIGRATION  filespec[+...]

                                  NOTE

      For OpenVMS I64, the MACRO command defaults to /MIGRATION.
 

2  Parameters
 

filespec[+...]

   Specifies a VAX MACRO assembly language source file to be
   compiled. If you specify more than one file, separate the
   file specifications with plus signs (+).  File specifications
   separated by plus signs are concatenated into one input file and
   produce a single object file and, if indicated, a listing file.

                                  NOTE

      Unlike the VAX assembler, the MACRO compiler does not
      support the creation of separate object files when the
      source files are separated by a comma (,).

   You cannot include a wildcard character in a file specification.
   For each file specification, the compiler command supplies a
   default file type of MAR.

   The compiler creates output files of one version higher than the
   highest version existing in the target directory.
 

2  Description
   The qualifiers to the MACRO/MIGRATION command serve as either
   command (global) qualifiers or positional qualifiers. A command
   qualifier affects all the files specified in the command. A
   positional qualifier affects only the file that it qualifies.
   All MACRO/MIGRATION qualifiers except /LIBRARY are usable as
   either command or positional qualifiers. The /LIBRARY qualifier
   is a positional qualifier only.

   Many of the qualifiers take one or more arguments. If you specify
   only one argument, you can omit the parentheses.

   The compiler supports most of the standard MACRO qualifiers.
   Some of these qualifiers have additional options unique to the
   compiler and some of them are missing one or more VAX MACRO
   options. The compiler also supports several qualifiers unique to
   the compiler. All of these qualifiers are shown in the following
   table:

   Standard MACRO Qualifiers           Unique Qualifiers

   /DEBUG (with additional options)    /FLAG
   /DIAGNOSTICS                        /MACHINE
   /DISABLE (with additional options)  /OPTIMIZE
   /ENABLE (with additional options)   /PRESERVE
   /LIBRARY                            /RETRY_COUNT
   /LIST                               /SYMBOLS
   /OBJECT                             /TIE
   /SHOW                               /UNALIGNED
                                       /WARN
 

2  Qualifiers
 

/DEBUG

      /DEBUG=(option[,...])
      /NODEBUG

   Includes or excludes local symbols in the symbol table or
   traceback information in the object module. You can specify one
   or more of the following options:

   Option      Description

   ALL         Makes local symbols and traceback information in
               the object module available to the debugger. This
               qualifier is equivalent to /ENABLE=(DEBUG,TRACEBACK).

   NONE        Makes local symbols and traceback information
               in the object module unavailable to the
               debugger. This qualifier is equivalent to
               /DISABLE=(DEBUG,TRACEBACK).

   SYMBOLS     Makes all local symbols in the object module
               available and all traceback information unavailable
               to the debugger. This qualifier is equivalent to
               /ENABLE=SYMBOLS.

   TRACEBACK   Makes traceback information in the object module
               available and local symbols unavailable to
               the debugger. This qualifier is equivalent to
               /ENABLE=TRACEBACK.

   The default value for /DEBUG is ALL. The /DEBUG
   qualifier overrides /ENABLE=(DEBUG,TRACEBACK) or
   /DISABLE=(DEBUG,TRACEBACK), regardless of their order on the
   command line.

                                  NOTE

      Debugging can be simplified by specifying /NOOPTIMIZE. This
      qualifier prevents the movement of generated code across
      source line boundaries.

   For more information about debugging, see the OpenVMS Debugger
   Manual.
 

/DIAGNOSTICS

      /DIAGNOSTICS[=filespec]
      /NODIAGNOSTICS (default)

   Creates a file containing assembler messages and diagnostic
   information. If you omit the file specification, the default file
   name is the same as the source program; the default file type is
   DIA.

   No wildcard characters are allowed in the file specification.

   The diagnostics file is reserved for use with layered products,
   such as the VAX Language-Sensitive Editor (LSE).
 

/DISABLE

      /DISABLE=(option[,...])
      /NODISABLE

   Provides initial settings for the compiler functions that can be
   controlled by the .DISABLE and .ENABLE MACRO directives.

   You can specify one or more of the following functions:

   Option      Description

   DEBUG       Excludes local symbol table information in
               the object file for use with the debugger.
               If the /DEBUG qualifier is also specified,
               it overrides /DISABLE=(DEBUG,TRACEBACK) or
               /ENABLE=(DEBUG,TRACEBACK), regardless of their order
               on the command line.

   FLAGGING    Deactivates compiler flagging.

   GLOBAL      Disables the assumption that undefined symbols are
               external symbols.

   OVERFLOW    Deactivates production of overflow trap code for the
               following opcodes: ADDx, ADWC, INCx, ADAWI, SUBx,
               SBWC, DECx, MNEGx, MULx, CVTxy, (where x is greater
               than y, for example CVTLB), AOBxx, ACBL, and SOBxx.

   QUADWORD    Disables support for quadword literal and address
               expressions.

   SUPPRESSION Prevents the listing of unreferenced symbols in the
               symbol table.

   TRACEBACK   Disables the provision of traceback information
               to the debugger. If the /DEBUG qualifier is also
               specified, it overrides /DISABLE=(DEBUG,TRACEBACK) or
               /ENABLE=(DEBUG,TRACEBACK), regardless of their order
               on the command line.

   By default, at compiler activation, FLAGGING, GLOBAL, and
   SUPPRESSION are enabled, and DEBUG, OVERFLOW, QUADWORD, and
   TRACEBACK are disabled.

   The /NODISABLE qualifier has the same effect as omitting the
   /DISABLE qualifier. It can also be used to negate the effects of
   any /DISABLE qualifiers specified earlier in the command line.

                                  NOTE

      If /DISABLE is used two or more times in the command line,
      the last /DISABLE will override all previous uses of
      /DISABLE. The options not specified in the final /DISABLE
      will revert to their default values.

      Furthermore, if /ENABLE and /DISABLE are used in the same
      command line for the same option, /DISABLE will always
      prevail, regardless of its position in the command line.

      Workaround: If you want to disable two or more options,
      specify them in the following way:

      /DISABLE=(xxxx, yyyy)
 

/ENABLE

      /ENABLE=(option[,...])
      /NOENABLE

   Provides initial settings for the compiler functions that can be
   controlled by the .DISABLE and .ENABLE MACRO directives.

   You can specify one or more of the following functions:

   Option      Description

   DEBUG       Includes local symbol table information in
               the object file for use with the debugger.
               If the /DEBUG qualifier is also specified,
               it overrides /ENABLE=(DEBUG,TRACEBACK) or
               /DISABLE=(DEBUG,TRACEBACK), regardless of their order
               on the command line.

   FLAGGING    Activates compiler flagging.

   GLOBAL      Assumes undefined symbols are external symbols.

   OVERFLOW    Activates production of overflow trap code for the
               following opcodes: ADDx, ADWC, INCx, ADAWI, SUBx,
               SBWC, DECx, MNEGx, MULx, CVTxy (where x is greater
               than y, for example CVTLB), AOBxx, ACBL, and SOBxx.

   QUADWORD    Provides support for quadword literal and address
               expressions.

   SUPPRESSION Provides listing of unreferenced symbols in the
               symbol table.

   TRACEBACK   Provides traceback information to the debugger.
               If the /DEBUG qualifier is also specified,
               it overrides /ENABLE=(DEBUG,TRACEBACK) or
               /DISABLE=(DEBUG,TRACEBACK), regardless of their order
               on the command line.

   By default, at compiler activation, FLAGGING, GLOBAL, TRACEBACK,
   and SUPPRESSION are enabled, and DEBUG, OVERFLOW, and QUADWORD
   are disabled.

   The /NOENABLE qualifier has the same effect as not specifying the
   /ENABLE qualifier. It can also be used to negate the effects of
   any /ENABLE qualifiers specified earlier in the command line.

                                  NOTE

      For every option of the /ENABLE qualifier, if /ENABLE and
      /DISABLE are used in the same command line for the same
      option, /DISABLE will always prevail, regardless of its
      position in the command line.

      You may want to enable an option previously disabled through
      the use of a symbol. For example, you may have incorporated
      the following frequently used options into the DCL symbol
      MAC, as follows:

      MAC::== MACRO/MIGRATION/NOTIE/DISABLE=FLAGGING

      To enable FLAGGING using the symbol MAC, issue the following
      command:

      $ MAC /NODISABLE/ENABLE=FLAGGING
 

/FLAG

      /FLAG=(option[,...])
      /NOFLAG

   Specifies which classes of informational messages the compiler
   reports. The options are:

   Option          Description

   ALIGNMENT       Reports unaligned stack and memory references.

   ALL             Enables all options.

   ARGLIST         Reports that the argument list has been homed.

   BAD_FIELD_      Reports BBC/BBS instructions that attempt to use
   USAGE           bits beyond 31.
   (I64 only)

   CODEGEN         Reports run-time code generation, such as self-
                   modifying code.

   COMPILER_       Prints compiler version to SYS$ERROR.
   VERSION
   (I64 only)

   DIRECTIVES      Reports unsupported directives.

   HINTS           Reports input/output/auto-preserved register
                   hints.

   INDIRECT_       Reports CALLS/CALLG instructions that have an
   CALLS           indirect target and are not preceded by a .USE_
   (I64 only)      LINKAGE directive.

   INDIRECT_JSB    Reports JSB instructions that have an indirect
   (I64 only)      target and are not preceded by a .USE_LINKAGE
                   directive.

   INSTRUCTIONS    Reports instructions that use absolute addresses
                   that might compile correctly, but should be
                   examined anyway, because the desired absolute
                   address might be different on the system.

   JUMPS           Reports branches between routines.

   LINKAGE         Reports linkage information provided to the
   (I64 only)      OpenVMS linker.

   NONE            Disables all options.

   STACK           Reports all messages caused by user stack
                   manipulation.

   At compiler activation, the default is /FLAG=(ALIGNMENT, ARGLIST,
   CODEGEN, DIRECTIVES, INSTRUCTIONS, JUMPS, STACK).

                                  NOTE

      Use of the /NOFLAG and /FLAG qualifiers together to
      activate a specific subset of cross-compiler messages
      does not work as expected. When used together, as in
      /NOFLAG/FLAG=(keyword,keyword), instead of activating only
      the messages specified by the keywords, all cross-compiler
      messages are activated. However, use of /FLAG=(none,keyword)
      activates only those messages specified by the keyword.

   Note that specifying /NOFLAG or /FLAG=NONE does not disable the
   reporting of coding constructs that would prevent a successful
   compilation. The compiler continues to report code that you must
   change, such as an up-level stack reference.
 

/LIBRARY

      /LIBRARY
      /NOLIBRARY

   Positional qualifier.

   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 if the macro is undefined:

   1. The libraries specified with the .LIBRARY directive are
      searched first, in reverse order of the order 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

      /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

      /MACHINE
      /NOMACHINE (default)

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

/OBJECT

      /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

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

   Enables or disables optimization options. All options are enabled
   by default except VAXREGS.

   The options are:

   Option         Description

   [NO]PEEPHOLE   Peephole optimization
   [NO]SCHEDULE   Code scheduling
   [NO]ADDRESSES  Common base address loading
   [NO]REFERENCES Common data referencing
   ALL            All optimizations
   NONE           No optimizations


/PRESERVE

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

   Directs the compiler to generate special OpenVMS Alpha or OpenVMS
   I64 code throughout a module for all VAX MACRO instructions that
   rely on VAX guarantees of operation atomicity or granularity.

   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 or the Itanium
                  compare-exchange (cmpxchg) instruction 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 Alpha Load-locked and Store-
                  conditional instruction sequences or the Itanium
                  compare-exchange (cmpxchg) instruction in code
                  it generates for VAX 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 may not
   need the compiler to enforce these guarantees for the entire
   module. Instead, you can use the .PRESERVE and .NOPRESERVE
   directives to apply the guarantees only to those sections.
   Because the compiler does not need to generate expanded code
   for the entire module, these these directives can help optimize
   the code.

   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.
      If /PRESERVE=GRANULARITY is turned on, unaligned word
      references to addresses assumed aligned will also cause a
      fatal reserved operand fault.
 

/RETRY_COUNT

      /RETRY_COUNT=count

   Specifies to the compiler the number of times the following
   operations should be performed in generated code:

   o  Retries of operations performed in source by a VAX interlocked
      instruction

   o  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

      /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:

   Option        Description

   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

      /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

      /TIE
      /NOTIE (default) 

   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

      /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 and OpenVMS I64 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

      /WARN=[[option]...]
      /NOWARN

   Turns off all informational level or warning level messages. Both
   are on by default. The options are:

   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
 

2  VAX_MACRO_Assembler_Directives
   The MACRO Compiler for OpenVMS Systems supports most of the
   standard VAX MACRO assembler directives discussed in the VAX
   MACRO and Instruction Set Reference Manual. However, some
   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.

   The directives that you can disable are:

   o  .ENABLE and .DISABLE ABSOLUTE-for forcing absolute addressing
      modes

   o  .ENABLE and .DISABLE TRUNCATION-for enabling floating point
      truncation

   o  .LINK-for specifying linker options in a linker options file

   o  .DEFAULT-for setting displacement lengths

   o  .OPDEF and .REFn-for defining opcodes

   o  Alignment directives (.ALIGN, .EVEN, and .ODD) in code psects

   o  .TRANSFER

   o  .MASK

                                  NOTE

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

2  MACRO_Compiler_Directives
   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 needed.
   For example:

   R1
 

3  .BRANCH_LIKELY
   Instructs the compiler that the following branch will likely be
   taken.

   Format

     .BRANCH_LIKELY

   There are no parameters for this directive.
 

4  Description
   The Alpha hardware predicts that forward conditional branches
   are not taken and that backwards conditional branches are taken.
   Based on the Alpha architecture, those assumptions are built into
   the compiler and influences the code generated for conditional
   branches.

   When .BRANCH_LIKELY precedes a forward conditional branch, the
   compiler will change the conditional branch and reorder the code
   such that the unlikely path will be a forward branch instead of
   the likely branch.

   The Itanium architecture includes branch prediction explicitly on
   each branch instruction. However, the compiler will still reorder
   the code to conform to the assumption that forward branches are
   not taken and backward branches are taken. The compiler will set
   the branch prediction flags as appropriate.
 

4  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$.
 

3  .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.
 

4  Description
   See the description of the .BRANCH_LIKELY directive for the
   assumptions used by the compiler when predicting branches.

   On OpenVMS I64 systems, when .BRANCH_UNLIKELY precedes a
   conditional backwards branch, the compiler will use the
   appropriate branch prediction flags on the generated Itanium
   instruction.

   .BRANCH_UNLIKELY has no effect if it precedes a conditional
   forwards branch.
 

4  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.
 

3  .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=number] [,home_args=TRUE|FALSE]

                  [,quad_args=TRUE|FALSE] [,input] [,output]

                  [,scratch] [,preserve] [,label]
 

4  Parameters
 

max_args=number

   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 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
   this case:

   o  If you are explicitly using any of the Alpha or Itanium
      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.
 

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
   this case:

   o  If you are explicitly using any of the Alpha or Itanium
      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.

   On OpenVMS I64 systems, the compiler will not use these registers
   as temporary registers.
 

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. Registers R16 and
   above are not allowed. 

   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 OpenVMS
   VAX and OpenVMS Alpha or OpenVMS I64, if the OpenVMS VAX version
   needs to reference the entry with a .MASK directive, and if the
   OpenVMS Alpha or OpenVMS I64 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. 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.
 

3  .CALL_LINKAGE
   OpenVMS I64 only.

   Associates a named or anonymous linkage with a routine name. When
   the compiler sees a CALLS, CALLG, JSB, BSBB, or BSBW instruction
   with the routine name as the target, it will use the associated
   linkage to decide which registers need to be saved and restored
   around the call.

   Format

     .CALL_LINKAGE  routine_name [,linkage_name] [,input] [,output]

                    [,scratch] [,preserve]
 

4  Parameters
 

routine_name

   The name of a routine to be associated with the linkage.
 

linkage_name = 

   The name of a linkage previously defined with the .DEFINE_LINKAGE
   directive. If you specify a linkage_name, you cannot specify an
   input, output, scratch, or preserve parameter.
 

input=<>

   Register set that indicates those registers from which the
   routine_name receives input values. This parameter is for
   documentation purposes only.

   If you specify an input register set, you cannot specify a
   linkage_name.
 

output=<>

   Register set that indicates those registers to which the routine_
   name assigns values that are returned to the routine's caller.
   Registers included in this register set are not saved and
   restored around the call.

   If you specify an output register set, you cannot specify a
   linkage_name.
 

scratch=<>

   Register set that indicates registers that are used within the
   routine.

   If you specify a scratch register set, you cannot specify a
   linkage_name.
 

preserve=<>

   Register set that indicates those registers which the routine_
   name will preserve. Registers included in this register set are
   not saved and restored around a call to the routine, since the
   called routine will perform that task.

   If you specify a preserve register set, you cannot specify a
   linkage_name.
 

3  .DEFINE_LINKAGE
   OpenVMS I64 only.

   Defines a named linkage that can be used with subsequent .CALL_
   LINKAGE or .USE_LINKAGE directives.

   Format

     .DEFINE_LINKAGE  linkage_name [,input] [,output] [,scratch]

                      [,preserve]
 

4  Parameters
 

linkage_name

   The name of a linkage to be defined.
 

input=<>

   Register set that indicates those registers from which a routine
   with this linkage receives input values. This parameter is for
   documentation purposes only.
 

output=<>

   Register set that indicates those registers to which a routine
   with this linkage assigns values that are returned to the
   routine's caller. Registers included in this register set are
   not saved and restored around the call.
 

scratch=<>

   Register set that indicates registers that are used within a
   routine with this linkage. This parameter is for documentation
   purposes only.
 

preserve=<>

   Register set that indicates those registers which a routine with
   this linkage will preserve. Registers included in this register
   set are not saved and restored around a call to the routine,
   since the called routine will perform that task.
 

3  .DISABLE
   Disables compiler features over a range of source code.

   Format

     .DISABLE  argument-list
 

4  Parameters
 

argument-list

   You can use one or more of the symbolic arguments listed in the
   following table:

   Option      Description

   DEBUG       Excludes local symbol table information in the object
               file for use with the debugger.
   FLAGGING    Deactivates compiler flagging.
   GLOBAL      Disables the assumption that undefined symbols are
               external symbols.
   OVERFLOW    Deactivates production of overflow trap code for the
               following opcodes: ADDx, ADWC, INCx, ADAWI, SUBx,
               SBWC, DECx, MNEGx, MULx, CVTxy (where x is greater
               than y, for example CVTLB), AOBxx, ACBL, and SOBxx.
   QUADWORD    Disables support for quadword literal and address
               expressions.
   SUPPRESSION Stops the listing of unreferenced symbols in the
               symbol table.
   TRACEBACK   Stops providing traceback information to the
               debugger.
 

3  .ENABLE
   Enables compiler features over a range of source code.

   Format

     .ENABLE  argument-list
 

4  Parameters
 

argument-list

   You can use one or more of the symbolic arguments listed in the
   following table:

   Option      Description

   DEBUG       Includes local symbol table information in the
               object file for use with the debugger. For this
               to take effect, you must compile with /DEBUG or
               /ENABLE=DEBUG.
   FLAGGING    Activates compiler flagging.
   GLOBAL      Assumes undefined symbols are external symbols.
   OVERFLOW    Activates production of overflow trap code for the
               following opcodes: ADDx, ADWC, INCx, ADAWI, SUBx,
               SBWC, DECx, MNEGx, MULx, CVTxy (where x is greater
               than y, for example CVTLB), AOBxx, ACBL, and SOBxx.
   QUADWORD    Provides support for quadword literal and address
               expressions.
   SUPPRESSION Provides a listing of unreferenced symbols in the
               symbol table.
   TRACEBACK   Provides traceback information to the debugger. For
               this to take effect, you must compile with /DEBUG or
               /ENABLE=TRACEBACK.
 

3  .GLOBAL_LABEL
   Declares a global label in a routine that is not an entry point
   to the routine.

   Format

     Label: .GLOBAL_LABEL

   There are no parameters for this directive.
 

4  Description
   The .GLOBAL_LABEL directive declares a global label within a
   routine that is not a routine entry point. Unless declared with
   .GLOBAL_LABEL, global labels in code (specified with "::") are
   assumed to be entry point labels, which require declaration. If
   they are not declared, they are flagged as errors.

   The compiler also allows the address of a global label to be
   stored (for instance, by means of  PUSHAL instruction). (The
   compiler flags as an error any attempt to store a label that has
   not been declared as a global label or an entry point.)

   By using the .GLOBAL_LABEL directive, you are acknowledging that
   the stored code address will not be the target of a CALL or JSB
   instruction. Global labels must appear inside routine boundaries.

   Labels declared with the .GLOBAL_LABEL directive can be used as
   the newpc argument in calls to the $UNWIND (Unwind Call Stack)
   system service because it allows the address of the label to be
   stored.

   However, there is no provision in the compiler to automatically
   adjust the stack pointer at such labels to remove arguments
   passed on the stack or compensate for stack alignment. If
   the call stack is unwound back to an alternate PC in the
   calling routine, the stack may still contain arguments and
   alignment bytes, and any stack-based references that expect this
   adjustment to the caller's original stack depth (which happened
   automatically on VAX) will be incorrect.

   Code that contains labels declared with this directive that are
   to be used as alternate PC targets for $UNWIND must be examined
   carefully to ensure correct behavior, with particular emphasis on
   any references based on the stack pointer.
 

3  .JSB_ENTRY
   Declares the entry point of a JSB 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. See also .JSB32_ENTRY.

   Format

     .JSB_ENTRY  [input] [,output] [,scratch] [,preserve]
 

4  Parameters
 

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
   this case:

   o  If you are explicitly using any of the Alpha or Itanium
      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
   this case:

   o  If you are explicitly using any of the Alpha or Itanium
      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.

   On OpenVMS I64 systems, the compiler will not use these registers
   as temporary registers.
 

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 following warning:

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


3  .JSB32_ENTRY
   Declares the entry point of a JSB routine to the compiler. This
   directive does not preserve any VAX register values (R2 through
   R12) unless the PRESERVE parameter is specified. The routine
   itself may save and restore registers by pushing them on the
   stack, but this will not preserve the upper 32 bits of the
   registers. See also .JSB_ENTRY.

                                WARNING

      The .JSB32_ENTRY directive can be a great time-saver if you
      are sure that you can use it. If you use .JSB32_ENTRY in a
      situation where the upper 32 bits of a register are being
      used, it may cause very obscure and difficult-to-track bugs
      by corrupting a 64-bit value that may be several calling
      levels above the offending routine.

      .JSB32_ENTRY should never be used in an AST routine,
      condition handler, or any other code that can be executed
      asynchronously.

   Format

     .JSB32_ENTRY  [input] [,output] [,scratch] [,preserve]
 

4  Parameters
 

input=<>

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

   For the .JSB32_ENTRY directive, this register set is used only to
   document your code.
 

output=<>

   Register set that indicates those registers to which the routine
   assigns values that are returned to the routine's caller.

   For the .JSB32_ENTRY directive, this register set is used only to
   document your code.
 

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.

   Because R2 through R12 are not preserved by default, their
   inclusion in the scratch is for documentation purposes only.
 

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 by the
   compiler. By default, no registers are preserved by the .JSB32_
   ENTRY directive.

   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
 

4  Description
   The .JSB32_ENTRY directive is an alternative way of declaring a
   JSB entry point. It is designed to streamline the declaration of
   VAX MACRO routines that operate within a well-defined, bounded
   application environment, such as that of a single application
   or a self-contained subsystem. For any routine declared with the
   .JSB32_ENTRY directive, the compiler does not automatically save
   or restore any VAX registers (R2 through R12), therefore leaving
   the current 32-bit operation untouched. When you use the .JSB32_
   ENTRY directive to declare a JSB entry point, you are responsible
   for declaring and saving registers which must be preserved.

   If the externally visible entry points of a subsystem can be
   called from the 64-bit environment, those entry points should
   not be declared with .JSB32_ENTRY. Instead, .JSB_ENTRY (or .CALL_
   ENTRY) should be used so that the full 64-bit register values are
   saved, if necessary.
 

3  .PRESERVE
   Directs the compiler to generate special OpenVMS Alpha or OpenVMS
   I64 code throughout a module for all VAX MACRO instructions that
   rely on VAX guarantees of operation atomicity or granularity.

   Format

     .[NO]PRESERVE  argument-list
 

4  Parameters
 

argument-list

   One or more of the symbolic arguments listed in the following
   table:

   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 or the Itanium
                  compare-exchange (cmpxchg) instruction 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 Alpha Load-locked and Store-
                  conditional instruction sequences or the Itanium
                  compare-exchange (cmpxchg) instruction in code
                  it generates for VAX instructions with modify
                  operands.
 

4  Description
   The .PRESERVE and .NOPRESERVE directives cause the compiler to
   generate special Alpha assembly code for VAX MACRO instructions,
   within portions of the source module, that rely on VAX guarantees
   of operation atomicity or granularity.

   Use of .PRESERVE or .NOPRESERVE without specifying GRANULARITY
   or ATOMICITY will affect both options. 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.

   Alternatively, you can use the /PRESERVE and /NOPRESERVE compiler
   qualifiers to affect the atomicity and granularity in generated
   code throughout an entire MACRO source module, though this is not
   recommended, because the overhead of the extra code where it is
   not needed can slow the program down considerably.

   Atomicity is guaranteed for multiprocessing systems as well as
   uniprocessing systems when you specify .PRESERVE ATOMICITY.

   When the .PRESERVE directive is present, you can use the /RETRY_
   COUNT qualifier on the command line to control the number of
   times the compiler-generated code retries a granular or atomic
   update.

                                WARNING

      If .PRESERVE ATOMICITY is turned on, any unaligned data
      references will result in a fatal reserved operand fault.

      If .PRESERVE GRANULARITY is turned on, unaligned word
      references to addresses assumed aligned will also cause a
      fatal reserved operand fault.
 

4  Example

 INCW 1(R0)

     This instruction, when compiled with .PRESERVE GRANULARITY,
     retries the insertion of the new word value, if it is
     interrupted. However, when compiled with .PRESERVE ATOMICITY,
     it will also refetch the initial value and increment it, if
     interrupted. If both options are specified, it will do the
     latter.
 

3  .SET_REGISTERS
   This directive allows you to override the compiler's alignment
   assumptions, and also allows implicit reads/writes of registers
   to be declared.

   Format

     .SET_REGISTERS  argument-list
 

4  Parameters
 

argument-list

   One or more of the arguments listed in the following table. For
   each argument, you can specify one or more registers:

   Option       Description

   aligned=<>   Declares one or more registers to be aligned on
                longword boundaries.
   unaligned=<> Declares one or more registers to be unaligned.
                Because this is an explicit declaration, this
                unaligned condition will not produce a fault at
                run time.
   read=<>      Declares one or more registers, which otherwise the
                compiler could not detect as input registers, to be
                read.
   written=<>   Declares one or more registers, which otherwise the
                compiler could not detect as output registers, to be
                written to.
 

4  Description
   The aligned and unaligned qualifiers to this directive allow
   you to override the compiler's alignment assumptions. Using the
   directive for this purpose in certain cases can produce more
   efficient code.

   The read and written qualifiers to this directive allow implicit
   reads and writes of registers to be declared. They are generally
   used to declare the register usage of called routines and are
   useful for documenting your program.

   With one exception, the .SET_REGISTERS directive remains in
   effect (ensuring proper alignment processing) until the routine
   ends, unless you change the value in the register. The exception
   can occur under certain conditions when a flow path joins the
   code following a .SET_REGISTERS directive.

   The following example illustrates such an exception. R2 is
   declared aligned, and at a subsequent label, 10$, which is
   before the next write access to the register, a flow path joins
   the code. R2 will be treated as unaligned following the label,
   because it is unaligned from the other path.

           INCL R2          ; R2 is now unaligned
            .
            .
            .
           BLBC R0, 10$
            .
            .
            .
           MOVL R5, R2
           .SET_REGISTERS ALIGNED=R2
           MOVL R0, 4(R2)
     10$:  MOVL 4(R2), R3   ; R2 considered unaligned
                            ; due to BLBC branch


4  Examples

   1.DIVL R0,R1

     .SET_REGISTERS ALIGNED=R1
     MOVL     8(R1), R2          ; Compiler will use aligned load.

     In this example, the compiler would normally consider R1
     unaligned after the division. Any memory references using R1 as
     a base register (until it is changed again) would use unaligned
     load/stores. If it is known that the actual value will always
     be aligned, performance could be improved by adding a .SET_
     REGISTERS directive, as shown.

   2.MOV1     4(R0), R1          ;Stored memory addresses assumed

     .SET_REGISTERS UNALIGNED=R1 ;aligned so explicitly set it un-
     MOVL     4(R1), R2          ;aligned to avoid run-time fault.

     In this example, R1 would be considered longword aligned after
     the MOVL. If it is actually unaligned, an alignment fault would
     occur on memory reference that follows at run time. To prevent
     this, the .SET_REGISTERS directive can be used, as shown.

   3..SET_REGISTERS READ=<R3,R4>, WRITTEN=R5

     JSB     DO_SOMETHING_USEFUL

     In this example, the read/written attributes are used to
     explicitly declare register uses which the compiler cannot
     detect. R3 and R4 are input registers to the JSB target
     routine, and R5 is an output register. This is particularly
     useful if the routine containing this JSB does not use these
     registers itself, or if the SET_REGISTERS directive and JSB
     are embedded in a macro. When compiled with /FLAG=HINTS,
     routines which use the macro would then have R3 and R4 listed
     as possible input registers, even if they are not used in that
     routine.
 

3  .SYMBOL_ALIGNMENT
   This directive associates an alignment attribute with a symbol
   definition for a register offset. You can use this directive
   when you know the alignment of the base register. This attribute
   guarantees to the compiler that the base register has the same
   alignment, which enables the compiler to generate optimal code.

   Format

     .SYMBOL_ALIGNMENT  argument-list
 

4  Parameters
 

argument-list

   One of the arguments listed in the following table:

   Option  Description

   long    Declares longword alignment for any symbol that you
           declare after this directive.
   quad    Declares quadword alignment for any symbol that you
           declare after this directive.
   none    Turns off the alignment specified by the preceding
           .SYMBOL_ALIGNMENT directive.
 

4  Description
   The .SYMBOL_ALIGNMENT directive is used to associate an alignment
   attribute with the fields in a structure when you know the base
   alignment. It is used in pairs. The first .SYMBOL_ALIGNMENT
   directive associates either longword (long) or quadword (quad)
   alignment with the symbol or symbols that follow. The second
   directive, .SYMBOL_ALIGNMENT none, turns it off.

   Any time a reference is made with a symbol with an alignment
   attribute, the base register of that reference, in effect,
   inherits the symbol's alignment. The compiler also resets the
   base register's alignment to longword for subsequent alignment
   tracking. This alignment guarantee enables the compiler to
   produce more efficient code sequences.
 

4  Example

 OFFSET1 = 4
 .SYMBOL_ALIGNMENT LONG
 OFFSET2 = 8
 OFFSET3 = 12
 .SYMBOL_ALIGNMENT QUAD
 OFFSET4 = 16
 .SYMBOL_ALIGNMENT NONE
 OFFSET5 = 20
     .
     .
     .
 CLR1 OFFSET2(R8)
     .
     .
     .
 MOVL R2, OFFSET4(R6)

     For OFFSET1 and OFFSET5, the compiler will use only its
     tracking information for deciding if Rn in OFFSET1(Rn) is
     aligned or not. For the other references, the base register
     will be treated as longword (OFFSET2 and OFFSET3) or quadword
     (OFFSET4) aligned.

     After each use of OFFSET2 or OFFSET4, the base register in the
     reference is reset to longword alignment. In this example, the
     alignment of R8 and R6 will be reset to longword, although the
     reference to OFFSET4 will use the stronger quadword alignment.
 

3  .USE_LINKAGE
   OpenVMS I64 only.

   Establishes a temporary named or anonymous linkage that will
   be used by the compiler for the next CALLS, CALLG, JSB, BSBB,
   or BSBW instruction processed in lexical order. This directive
   is used when the target of the next CALLS, CALLG, JSB, BSBB,
   or BSBW instruction is not a name, but a run-time value (for
   example, CALLS #0, (R6)). When the compiler sees the next
   CALLS, CALLG, JSB, BSBB, or BSBW instruction, it will use the
   associated linkage to decide which registers need to be saved and
   restored around the call. After the instruction is processed, the
   temporary linkage is reset to null.

   Format

     .USE_LINKAGE  [linkage_name] [,input] [,output] [,scratch]

                   [,preserve]
 

4  Parameters
 

linkage_name

   The name of a linkage previously defined with the .DEFINE_LINKAGE
   directive. If you specify a linkage_name, you cannot specify an
   input, output, scratch or preserve clause.
 

input=<>

   Register set that indicates those registers from which the
   routine called by the next CALLS, CALLG, JSB, BSBB, or BSBW
   instruction receives input values.
 

output=<>

   Register set that indicates those registers to which the routine
   called by the next CALLS, CALLG, JSB, BSBB, or BSBW instruction
   assigns values that are returned to the routine's caller.
   Registers included in this register set are not saved and
   restored around the call.
 

scratch=<>

   Register set that indicates registers that are used within the
   routine called by the next CALLS, CALLG, JSB, BSBB, or BSBW
   instruction. This parameter is for documentation purposes only.
 

preserve=<>

   Register set that indicates those registers which the routine
   called by the next CALLS, CALLG, JSB, BSBB, or BSBW instruction
   will preserve. Registers included in this register set are not
   saved and restored around a call to the routine, since the called
   routine will perform that task.
 

2  MACRO_Compiler_Built-Ins
   On OpenVMS I64 systems, the compiler provides two sets of built-
   ins:

   o  Alpha instruction built-ins that are used to generate Itanium
      instructions for which there are no VAX equivalents.

   o  Itanium instruction built-ins that are used to access Itanium
      instructions for which there are no VAX equivalents.

   On OpenVMS I64 systems, all of the Alpha PALcode built-ins are
   emulated by means of macros provided by the system.

   Both sets of built-ins are presented in tables. The second column
   of each table specifies the operands the built-in expects, where:

      WL = write longword
      ML = modify longword
      AL = address of longword
      WQ = write quadword
      RQ = read quadword
      MQ = modify quadword
      AQ = address of quadword
      AB = address of byte
      AW = address of word
      WB = write byte
      WW = write word

                                  NOTE

      Be careful when mixing built-ins with VAX MACRO instructions
      on the same registers. The code generated by the compiler
      expects registers to contain 32-bit sign-extended values,
      but it is possible to create 64-bit register values that are
      not in this format. Subsequent longword operations on these
      registers could produce incorrect results.

      Therefore, make sure to return registers to 32-bit sign-
      extended format before using them in VAX MACRO instructions
      as source operands. Note that loading the register with
      a new value using a VAX MACRO instruction (such as MOVL)
      returns it to this format.
 

3  Alpha_Instruction_Built-Ins
   Ported VAX MACRO code sometimes requires access to Alpha
   native instructions to deal directly with a 64-bit quantity
   or to include an Alpha instruction that has no VAX equivalent.
   The compiler provides built-ins to allow you access to these
   instructions. On OpenVMS I64 systems, the compiler generates
   equivalent Itanium instructions.

   The following byte and word built-ins are included in the MACRO
   compiler:

   o  EVAX_LDBU

   o  EVAX_LDWU

   o  EVAX_STB

   o  EVAX_STW

   o  EVAX_SEXTB

   o  EVAX_SEXTW

   You use these built-ins in the same way that you use native VAX
   instructions, using any VAX operand mode. For example, EVAX_
   ADDQ 8(R0),(SP)+,R1 is legal. The only exception is that the
   first operand of any Alpha load/store built-in (EVAX_LD*, EVAX_
   ST*) must be a register.

   The following table summarizes the Alpha built-ins supported by
   the compiler. The built-ins that are Alpha-only (cannot be used
   to generate or access Itanium instructions) are noted in the
   table.

                                                    Functional on
   Built-in      Operands   Description             OpenVMS I64?

   EVAX_SEXTB    <RQ,WB>    Sign-extend byte        Yes
   EVAX_SEXTW    <RQ,WW>    Sign-extend word        Yes
   EVAX_SEXTL    <RQ,WL>    Sign-extend longword    Yes

   EVAX_LDBU     <WQ,AB>    Load zero-extended      Yes
                            byte from memory
   EVAX_LDWU     <WQ,AQ>    Load zero-extended      Yes
                            word from memory
   EVAX_LDLL     <WL,AL>    Load longword locked    Yes
   EVAX_LDAQ     <WQ,AQ>    Load address of         Yes
                            quadword
   EVAX_LDQ      <WQ,AQ>    Load quadword           Yes
   EVAX_LDQL     <WQ,AQ>    Load quadword locked    Yes
   EVAX_LDQU     <WQ,AQ>    Load unaligned          Yes
                            quadword

   EVAX_STB      <RQ,AB>    Store byte from         Yes
                            register to memory
   EVAX_STW      <RQ,AW>    Store word from         Yes
                            register to memory
   EVAX_STLC     <ML,AL>    Store longword          Yes
                            conditional
   EVAX_STQ      <RQ,AQ>    Store quadword          Yes
   EVAX_STQC     <MQ,AQ>    Store quadword          Yes
                            conditional
   EVAX_STQU     <RQ,AQ>    Store unaligned         Yes
                            quadword

   EVAX_ADDQ     <RQ,RQ,WQ> Quadword add            Yes
   EVAX_SUBQ     <RQ,RQ,WQ> Quadword subtract       Yes
   EVAX_MULQ     <RQ,RQ,WQ> Quadword multiply       Yes
   EVAX_UMULH    <RQ,RQ,WQ> Unsigned quadword       Yes
                            multiply high

   EVAX_AND      <RQ,RQ,WQ> Logical product         Yes
   EVAX_OR       <RQ,RQ,WQ> Logical sum             Yes
   EVAX_XOR      <RQ,RQ,WQ> Logical difference      Yes
   EVAX_BIC      <RQ,RQ,WQ> Bit clear               Yes
   EVAX_ORNOT    <RQ,RQ,WQ> Logical sum with        Yes
                            complement
   EVAX_EQV      <RQ,RQ,WQ> Logical equivalence     Yes
   EVAX_SLL      <RQ,RQ,WQ> Shift left logical      Yes
   EVAX_SRL      <RQ,RQ,WQ> Shift right logical     Yes
   EVAX_SRA      <RQ,RQ,WQ> Shift right             Yes
                            arithmetic

   EVAX_EXTBL    <RQ,RQ,WQ> Extract byte low        Yes
   EVAX_EXTWL    <RQ,RQ,WQ> Extract word low        Yes
   EVAX_EXTLL    <RQ,RQ,WQ> Extract longword low    Yes
   EVAX_EXTQL    <RQ,RQ,WQ> Extract quadword low    Yes
   EVAX_EXTBH    <RQ,RQ,WQ> Extract byte high       Yes
   EVAX_EXTWH    <RQ,RQ,WQ> Extract word high       Yes
   EVAX_EXTLH    <RQ,RQ,WQ> Extract longword high   Yes
   EVAX_EXTQH    <RQ,RQ,WQ> Extract quadword high   Yes

   EVAX_INSBL    <RQ,RQ,WQ> Insert byte low         Yes
   EVAX_INSWL    <RQ,RQ,WQ> Insert word low         Yes
   EVAX_INSLL    <RQ,RQ,WQ> Insert longword low     Yes
   EVAX_INSQL    <RQ,RQ,WQ> Insert quadword low     Yes
   EVAX_INSBH    <RQ,RQ,WQ> Insert byte high        Yes
   EVAX_INSWH    <RQ,RQ,WQ> Insert word high        Yes
   EVAX_INSLH    <RQ,RQ,WQ> Insert longword high    Yes
   EVAX_INSQH    <RQ,RQ,WQ> Insert quadword high    Yes

   EVAX_TRAPB    <>         Trap barrier            No
   EVAX_MB       <>         Memory barrier          Yes
   EVAX_RPCC     <WQ>       Read process cycle      No
                            counter

   EVAX_CMPEQ    <RQ,RQ,WQ> Integer signed          Yes
                            compare, equal
   EVAX_CMPLT    <RQ,RQ,WQ> Integer signed          Yes
                            compare, less than
   EVAX_CMPLE    <RQ,RQ,WQ> Integer signed          Yes
                            compare, less equal
   EVAX_CMPULT   <RQ,RQ,WQ> Integer unsigned        Yes
                            compare, less than
   EVAX_CMPULE   <RQ,RQ,WQ> Integer unsigned        Yes
                            compare, less equal

   EVAX_BEQ      <RQ,AQ>    Branch equal            Yes
   EVAX_BLT      <RQ,AQ>    Branch less than        Yes
   EVAX_BNE      <RQ,AQ>    Branch not equal        Yes

   EVAX_CMOVEQ   <RQ,RQ,WQ> Conditional             Yes
                            move/equal
   EVAX_CMOVNE   <RQ,RQ,WQ> Conditional move/not    Yes
                            equal
   EVAX_CMOVLT   <RQ,RQ,WQ> Conditional move/less   Yes
                            than
   EVAX_CMOVLE   <RQ,RQ,WQ> Conditional move/less   Yes
                            or equal
   EVAX_CMOVGT   <RQ,RQ,WQ> Conditional             Yes
                            move/greater than
   EVAX_CMOVGE   <RQ,RQ,WQ> Conditional             Yes
                            move/greater or equal
   EVAX_CMOVLBC  <RQ,RQ,WQ> Conditional move/low    Yes
                            bit clear
   EVAX_CMOVLBS  <RQ,RQ,WQ> Conditional move/low    Yes
                            bit set

   EVAX_MF_FPCR  <WQ>       Move from floating-     No
                            point control
                            register
   EVAX_MT_FPCR  <WQ,RQ>    Move to floating-       No
                            point control
                            register
   EVAX_ZAP      <RQ,RQ,WQ> Zero bytes              Yes
   EVAX_ZAPNOT   <RQ,RQ,WQ> Zero bytes with NOT     Yes
                            mask
 

3  Itanium[R]_Instruction_Built-Ins

   Built-in        Operands  Description

   IA64_BREAK      <RQ>      Generate a break instruction fault with
                             the immediate operand provided
   IA64_          <WQ,RQ,RQ> Generate a move-from-indirect-register
   GETINDREG                 instruction with the first operand as
                             the destination, the second operand
                             as a literal specifying which indirect
                             register file to access, and the third
                             operand as the index into the register
                             file
   IA64_GETREG     <WQ,RQ>   Generate a move-from-application-
                             register or move-from-control-register
                             instruction with the first operand
                             as the destination and the second
                             operand as a literal specifying which
                             application or control register to read

   IA64_LFETCH      <RQ,RQ>  Generate a line prefetch (LFETCH) or 
   IA64_LFETCH_EXCL <RQ,RQ>  exclusive line prefetch (LFETCH.EXCL)
                             instruction using the first operand as
                             the address to prefetch and the second
                             operand for either the reg-base-update-
                             form or the imm-base-update-form. If
                             the operand is the literal zero, the
                             no-base-update-form will be used

   IA64_PROBER    <WQ,RQ,RQ> Generate a probe.r instruction with the
                             first argument as the destination, the
                             second argument as the virtual address
                             to probe, and the third operand as the
                             privilege level
   IA64_PROBEW    <WQ,RQ,RQ> Generate a probe.w instruction with the
                             first argument as the destination, the
                             second argument as the virtual address
                             to probe, and the third operand as the
                             privilege level
   IA64_RSM        <RQ>      Generate a reset system mask ('RSM')
                             instruction with the specified mask
   IA64_RUM        <RQ>      Generate a reset user mask ('RUM')
                             instruction with the specified mask
   IA64_SETREG     <RQ,RQ>   Generate a move-to-application-register
                             or move-to-control-register instruction
                             with the first operand as a literal
                             specifying which application or control
                             register to write and the second
                             operand as the value to write into
                             the register
   IA64_SRLZD      <>        Generate a serialize data ('SRLZD')
                             instruction
   IA64_SRLZI      <>        Generate a serialize instruction
                             ('SRLZI') instruction
   IA64_SSM        <RQ>      Generate a set system mask ('SSM')
                             instruction with the specified mask
   IA64_SUM        <RQ>      Generate a set user mask ('SUM')
                             instruction with the specified mask
   IA64_TAK        <WK,RQ>   Generate a read translation access key
                             ('TAK') instruction
 

2  Macros_for_Porting_from_VAX_to_Alpha_or_I64
   The following macros facilitate the porting of VAX MACRO code to
   an OpenVMS Alpha or OpenVMS I64 system. The macros are grouped
   according to their function.
 

3  Calculating_Page-Size_Values
   The following macros provide a standard, architecture-independent
   means for calculating page-size dependent values:

   o  $BYTES_TO_PAGES

   o  $NEXT_PAGE

   o  $PAGES_TO_BYTES

   o  $PREVIOUS_PAGE

   o  $ROUND_RETADR

   o  $START_OF_PAGE

   These macros reside in the directory SYS$LIBRARY:STARLET.MLB and
   can be used by both application code and system code. Because
   application code does not have access to SYSTEM_DATA_CELLS, you
   must supply the relevant masks, shift values, and so on.

   The shift values are correlated with the page size of the
   processor. The rightshift values are negative; the leftshift
   values are positive, as shown in Shift Values.

   Table D-1 Shift Values

   Page size                 rightshift leftshift

   512 bytes (VAX)            -9         9
   8K (OpenVMS Alpha or      -13        13
   OpenVMS I64)
   16K                       -14        14
   32K                       -15        15
   64K                       -16        16

   Typically, the application issues a call to $GETSYI (specifying
   the SYI$_PAGESIZE item descriptor) to obtain the CPU-specific
   page size and then compute other values from the page size that
   is returned.

   The following conventions apply to the macros described in this
   section:

   o  If the destination operand is blank, the source operand is
      used as the destination.

   o  All macros conditionalize code on the symbols VAXPAGE and
      BIGPAGE.

   o  Several macros allow for page-size-independent code on VAX
      systems with the independent=YES argument. These macros
      generate code in which I-stream fetches are changed to memory
      accesses. Because this is inherently slower on a VAX system,
      the default value of the independent argument is NO.
 

4  $BYTES_TO_PAGES
   Converts a byte count to a page count.

   Format

     $BYTES_TO_PAGES  source_bytcnt, dest_pagcnt, rightshift,

                      roundup=YES, quad=YES
 

5  Parameters
 

source_bytcnt

   Source byte count.
 

dest_pagcnt

   Destination of page count.
 

rightshift

   Location of application-provided value to shift (in place of
   multiply). This value is a function of the page size, as shown in
   the table on shift values.
 

roundup=YES

   If YES, page-size-1 is added to byte count before shifting;
   if NO, page count is truncated. Any other value is treated as
   the user-specified address of the page-size-1 value. Note that
   roundup=YES is incompatible with the presence of the rightshift
   argument; invoking the macro with both these arguments generates
   a compile-time warning.
 

quad=YES

   If YES, the conversion supports 64-bit addressing. If NO, the
   conversion does not support 64-bit addressing.
 

4  $NEXT_PAGE
   Computes the virtual address of the first byte in the next page.

   Format

     $NEXT_PAGE  source_va, dest_va, clearbwp=NO,

                 user_pagesize_addr, user_mask_addr, quad=YES
 

5  Parameters
 

source_va

   Source virtual address.
 

dest_va

   Destination of virtual address within next page.
 

clearbwp=NO

   If YES, masks the byte-within-page portion of the source virtual
   address. The clearbwp=NO option is a performance enhancement,
   avoiding unnecessary instructions if you know you are starting
   on a page boundary or you are intending to divide by page-size
   anyway.
 

user_pagesize_addr

   Location of the page-size value (returned by a call to the
   $GETSYI system service specifying the SYI$_PAGESIZE item
   descriptor) in the application data area. If this argument is
   blank, the macro uses MMG$GL_PAGESIZE (bigpage) or MMG$C_VAX_
   PAGE_SIZE (vaxpage).
 

user_mask_addr

   Location of the application-provided byte-within-page mask. If
   this argument is blank, the macro uses MMG$GL_BWP_MASK if user_
   pagesize_addr is also blank. Otherwise, it subtracts 1 from the
   contents of the user_pagesize_addr and uses that value.
 

quad=YES

   If YES, the conversion supports 64-bit addressing. If NO, the
   conversion does not support 64-bit addressing.
 

4  $PAGES_TO_BYTES
   Converts a page count to a byte count.

   Format

     $PAGES_TO_BYTES  source_pagcnt, dest_bytcnt, leftshift,

                      quad=YES
 

5  Parameters
 

source_pagcnt

   Source page count.
 

dest_bytcnt

   Destination of byte count.
 

leftshift

   Location of application-provided value to shift (in place of
   multiply). This value is a function of the page size, as shown in
   the table on shift values.
 

quad=YES

   If YES, the conversion supports 64-bit addressing. If NO, the
   conversion does not support 64-bit addressing.
 

4  $PREVIOUS_PAGE
   Computes the virtual address of the first byte in the previous
   page.

   Format

     $PREVIOUS_PAGE  source_va, dest_va, clearbwp=NO,

                     user_pagesize_addr, user_mask_addr,

                     quad=YES
 

5  Parameters
 

source_va

   Source virtual address.
 

dest_va

   Destination of virtual address within previous page.
 

clearbwp=NO

   If YES, masks the byte-within-page portion of the source virtual
   address. The clearbwp=NO option is a performance enhancement,
   avoiding unnecessary instructions if you know you are starting
   on a page boundary or you are intending to divide by page-size
   anyway.
 

user_pagesize_addr

   Location of the page-size value (returned by a call to the
   $GETSYI system service specifying the SYI$_PAGESIZE item
   descriptor) in the application data area. If this argument is
   blank, the macro uses MMG$GL_PAGESIZE (bigpage) or MMG$C_VAX_
   PAGE_SIZE (vaxpage).
 

user_mask_addr

   Location of the application-provided byte-within-page mask. If
   this argument is blank, the macro uses MMG$GL_BWP_MASK if user_
   pagesize_addr is also blank. Otherwise, it subtracts 1 from the
   contents of the user_pagesize_addr and uses that value.
 

quad=YES

   If YES, the conversion supports 64-bit addressing. If NO, the
   conversion does not support 64-bit addressing.
 

4  $ROUND_RETADR
   Rounds the range implied by the virtual addresses in a retadr
   array returned from a memory management system service to a range
   that is the factor of CPU-specific pages. The return value can be
   supplied as an inadr array in a subsequent call to another memory
   management system service.

   Format

     $ROUND_RETADR  retadr, full_range, user_mask_addr,

                    direction=ASCENDING
 

5  Parameters
 

retadr

   Address of array of two 32-bit addresses, typically returned from
   $CRMPSC or a similar service. This value can be in the form of
   either "label" or "(Rx)".
 

full_range

   Output array of two longwords. FULL_RANGE[0] is retadr[0]
   rounded down to a CPU-specific page boundary, and FULL_RANGE[1]
   is retadr[1] rounded up to one less than a CPU-specific page
   boundary (that is, to the last byte in the page).
 

user_mask_addr

   Location of application-provided byte-within-page mask. If this
   argument is blank, the macro uses MMG$GL_BWP_MASK on an OpenVMS
   Alpha or OpenVMS I64 system and VA$M_BYTE on an OpenVMS VAX
   system.
 

direction=ASCENDING

   Direction of rounding. The keywords are defined in the following
   table:

   ASCENDING          retadr[0] < retadr[1]
   DESCENDING         retadr[1] < retadr[0]
   UNKNOWN            Values are compared at run time, then proper
                      rounding is performed
 

4  $START_OF_PAGE
   Converts a virtual address to the address of the first byte
   within that page.

   Format

     $START_OF_PAGE  source_va, dest_va, user_mask_addr, quad=YES
 

5  Parameters
 

source_va

   Source virtual address.
 

dest_va

   Destination of virtual address of first byte within page.
 

user_mask_addr

   Location of application-provided byte-within-page mask. If this
   argument is blank, the macro uses MMG$GL_BWP_MASK on an OpenVMS
   Alpha or OpenVMS I64 system and MMG$C_VAX_PAGE_SIZE - 1 (defined
   in $pagedef) on an OpenVMS VAX system.
 

quad=YES

   If YES, the conversion supports 64-bit addressing. If NO, the
   conversion does not support 64-bit addressing.
 

3  Saving_and_Restoring_64-Bit_Registers
   Frequently, VAX MACRO source code must save and restore register
   values, because that is part of the defined interface or because
   the code requires work registers.

   On OpenVMS VAX, code can invoke any number of macros to do
   this. On OpenVMS Alpha and OpenVMS I64, you cannot simply
   replace these macros with 64-bit pushes and pops to and from
   the stack, because there is no guarantee that the macro caller
   has a quadword-aligned stack. Instead, you should replace such
   macro invocations with $PUSH64 and $POP64 macros. These macros,
   located in STARLET.MLB, preserve all 64 bits of a register but
   use longword references to do so.
 

4  $POP64
   Pops the 64-bit value on the top of the stack into a register.

   Format

     $POP64  reg
 

5  Parameters
 

reg

   Register into which the macro places the 64-bit value from the
   top of the stack.
 

5  Description
   $POP64 takes the 64-bit value at the top of the stack and places
   it in a register using longword instructions. This is to avoid
   using quadword instructions when an alignment fault should be
   avoided, but restoring all 64 bits is necessary.
 

4  $PUSH64
   Pushes the contents of a 64-bit register onto the stack.

   Format

     $PUSH64  reg
 

5  Parameters
 

reg

   Register to be pushed onto the stack.
 

5  Description
   $PUSH64 takes a 64-bit register and puts it on the stack
   using longword instructions. This is to avoid using quadword
   instructions when an alignment fault should be avoided, but
   saving all 64 bits is necessary.
 

3  Locking_Pages_into_a_Working_Set
   Five macros are provided for locking pages into a working set.
   These macros reside in SYS$LIBRARY:LIB.MLB. For a description
   of how to use these macros, see the VSI OpenVMS MACRO Compiler
   Porting and User's Guide.

   Three macros are used for image initialization-time lockdown, and
   two macros are used for on-the-fly lockdown.

                                  NOTE

      If the code is being locked because the IPL will be raised
      above 2, where page faults cannot occur, make sure that
      the delimited code does not call run-time library or other
      procedures. The VAX MACRO compiler generates calls to
      routines to emulate certain VAX instructions. An image that
      uses these macros must link against the system base image so
      that references to these routines are resolved by code in a
      nonpageable executive image.

      For OpenVMS I64 systems, these macros are still under
      development and additional OpenVMS routines are being
      provided to lock working sets. See the OpenVMS I64 Release
      Notes for more information.
 

4  $LOCK_PAGE_INIT
   Required in the initialization routines of an image that is using
   $LOCKED_PAGE_START and $LOCKED_PAGE_END to delineate areas to be
   locked at initialization time.

   Format

     $LOCK_PAGE_INIT  [error]
 

5  Parameters
 

[error]

   Address to which to branch if one of the $LKWSET calls fail. If
   this address is reached, R0 reflects the status of the failed
   call, and R1 contains 0 if the call to lock the code failed, or 1
   if that call succeeded but the call to lock the linkage section
   failed.
 

5  Description
   $LOCK_PAGE_INIT creates the necessary psects and issues the
   $LWKSET calls to lock into the working set the code and linkage
   sections that were declared by $LOCKED_PAGE_START and $LOCKED_
   PAGE_END. R0 and R1 are destroyed by this macro.

   The psects locked by this macro are $LOCK_PAGE_2 and $LOCK_
   LINKAGE_2. If code sections in other modules, written in other
   languages, use these psects, they will be locked by an invocation
   of this macro in a VAX MACRO module.
 

4  $LOCKED_PAGE_END
   Marks the end of a section of code that may be locked at image
   initialization time by the $LOCK_PAGE_INIT macro.

   Format

     $LOCKED_PAGE_END  [link_sect]
 

5  Parameters
 

[link_sect]

   Psect to return to if the linkage psect in effect when the
   $LOCKED_PAGE_START macro was executed was not the default linkage
   psect, $LINKAGE.
 

5  Description
   $LOCKED_PAGE_END is used with $LOCKED_PAGE_START to delineate
   code that may be locked at image initialization time by the
   $LOCK_PAGE_INIT macro. The code delineated by these macros must
   contain complete routines-execution cannot fall through either
   macro, nor can you branch into or out of the locked code. Any
   attempt to branch into or out of the locked code section or to
   fall through the macros will be flagged by the compiler with an
   error.
 

4  $LOCKED_PAGE_START
   Marks the start of a section of code that may be locked at image
   initialization time by the $LOCK_PAGE_INIT macro.

   Format

     $LOCKED_PAGE_START

   There are no parameters for this macro.
 

5  Description
   $LOCKED_PAGE_START is used with $LOCKED_PAGE_END to delineate
   code that may be locked at image initialization time by the
   $LOCK_PAGE_INIT macro. The code delineated by these macros must
   contain complete routines-execution may not fall through either
   macro, nor may the locked code be branched into or out of. Any
   attempt to branch into or out of the locked code section or to
   fall through the macros will be flagged by the compiler with an
   error.
 

4  $LOCK_PAGE
   Marks the beginning of a section of code to be locked on-the-fly.

   Format

     $LOCK_PAGE  [error]
 

5  Parameters
 

[error]

   Address to branch to if one of the $LKWSET calls fail.
 

5  Description
   This macro is placed inline in executable code and must be
   followed by the $UNLOCK_PAGE macro. The $LOCK_PAGE/$UNLOCK_PAGE
   macro pair creates a separate routine in a separate psect. $LOCK_
   PAGE locks the pages and linkage section of this separate routine
   into the working set and JSRs to it. All code between this macro
   and the matching $UNLOCK_PAGE macro is included in the locked
   routine and is locked down.

   All registers are preserved by this macro unless the error
   address parameter is present and one of the calls fail. If that
   happens, R0 reflects the status of the failed call. R1 then
   contains 0 if the call to lock the code failed or 1 if that call
   succeeded but the call to lock the linkage section failed.

   If the ERROR parameter is used, the ERROR label must be placed
   outside the scope of the $LOCK_PAGE and $UNLOCK_PAGE pair. This
   is because the error routine is branched to before calling the
   subroutine that the $LOCK_PAGE and $UNLOCK_PAGE routines create.

   Note that since the locked code is made into a separate routine,
   any references to local stack storage within the routine will
   have to be changed, as the stack context is no longer the same.
   Also, you cannot branch into or out of the locked code from the
   rest of the routine.
 

4  $UNLOCK_PAGE
   Marks the end of a section of code to be locked on-the-fly.

   Format

     $UNLOCK_PAGE  [error][,LINK_SECT]
 

5  Parameters
 

[error]

   An error address to which to branch if one of the $ULKWSET calls
   fail.
 

[link_sect]

   Linkage psect to return to if the linkage psect in effect when
   the $LOCK_PAGE macro was executed was not the default linkage
   psect, $LINKAGE.
 

5  Description
   $UNLOCK_PAGE returns from the locked routine created by the
   $LOCK_PAGE and $UNLOCK_PAGE macro pair and then unlocks the pages
   and linkage section from the working set. This macro is placed
   inline in executable code after a $LOCK_PAGE macro.

   All registers are preserved by this macro unless the error
   address parameter is present and one of the calls fail. If that
   happens, R0 reflects the status of the failed call. R1 then
   contains 0 if the call to unlock the code failed or 1 if that
   call succeeded but the call to unlock the linkage section failed.

   If the error parameter is used, the error label must be placed
   outside the scope of the $LOCK_PAGE and $UNLOCK_PAGE pair. This
   is because the error routine is branched to after returning
   from the subroutine created by the $LOCK_PAGE and $UNLOCK_PAGE
   routines.
 

2  Macros_for_64-Bit_Addressing
   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.
 

3  $SETUP_CALL64
   Initializes the call sequence.

   Format

     $SETUP_CALL64  arg_count, inline=true | false
 

4  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.
 

4  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.
 

3  $PUSH_ARG64
   Does the equivalent of argument pushes for a call.

   Format

     $PUSH_ARG64  argument
 

4  Parameters
 

argument

   The argument to be pushed.
 

4  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
 

4  Parameters
 

call_target

   The routine to be invoked.
 

4  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.
 

3  $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  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  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  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$.
 

3  $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
 

4  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.
 

4  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.
 

4  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.