VMS Help  —  MACRO
    When used with the /ALPHA qualifier, the MACRO command invokes
    the MACRO-64 Assembler for OpenVMS Alpha Systems (provided it is
    installed).

    When used with the /MIGRATION qualifier, the MACRO command
    invokes the MACRO-32 Compiler for OpenVMS Alpha to compile one
    or more VAX MACRO assembly language source files into native
    OpenVMS Alpha object code.

1    /ALPHA

    Invokes the MACRO-64 Assembler for OpenVMS Alpha Systems. MACRO-64
    is an assembly language for programming Alpha computers.
    Source programs written in MACRO-64 are translated into object
    (or binary) code by the MACRO-64 Assembler, which produces an
    object module and, optionally, a listing file.

                                  NOTE

         The MACRO-64 product does not ship with the OpenVMS
         operating system. (Only this help file and the DCL
         command are included in the base system.) You must
         install MACRO-64 from the Freeware CD-ROM.

    To invoke MACRO-64, enter the MACRO command and the /ALPHA
    command-line qualifier, using the following syntax:

    MACRO/ALPHA  file-spec[, . . . ]

    You must specify the /ALPHA command-line qualifier
    before any other command-line parameters, qualifiers, or file
    specifications.

    If you do not specify a file type for an input file, the
    assembler uses the default file type of .M64.

    You can specify one or more source files to be assembled. To
    assemble files individually, separate the file specifications
    with commas. To concatenate and assemble the files as a single
    input file, separate the file specifications with plus signs
    (+).

    Command-line qualifiers control special assembler options.
    Assembler options can apply to the entire MACRO/ALPHA
    command-line, or to the individual file being assembled. When
    the qualifier follows the MACRO/ALPHA command, it applies
    to all files listed. For more information on qualifiers, see the
    Qualifiers on-line help section.

1.1  –  Qualifiers

1.1.1    /ALIGNMENT=option

    The full command-line option is /[NO]ALIGNMENT=option.

    Controls the alignment of code and data. Valid options are:

    Option   Function

    CODE     Alignment of certain branch target labels.
    DATA     Natural alignment of data items.

    If you omit the qualifier from the command line, the default
    options are /NOALIGNMENT=(CODE, DATA). If more than one option
    is specified, the options must be enclosed in parentheses and
    separated by a comma.

1.1.2    /ARCHITECTURE=option

    Determines which instructions are legal.

    Option      Function

    GENERIC     All instructions are allowed; equivalent to EV4.
    HOST        Instruction set is that of the host processor.
    EV4	       Instruction set is that of the EV4 base design processors
                (21064, 20164A, 21066, and 21068 chips).
    EV5         Instruction set is that of the EV5 processor
                (some 21164 chips).
    EV56        Instruction set is that of the EV56 processors
                (some 21164 chips).  Includes BWX extensions.
    PCA56       Instruction set is that of the PCA56 processor
                (21164PC chips).  Includes BWX and MAX extensions.
    EV6         Instruction set is that of the EV6 processor
                (21264 chips).  Includes BWX and MAX extensions and
                SQRT instructions.

1.1.3    /DEBUG[=(options)]

    The full command-line option is /[NO]DEBUG[=(options)].

    Specifies DEBUG support. Valid options are:

    Option   Function

    SYMBOL   Generates debug symbol information.
    TRACEBACKGenerates traceback information.
    ALL      Generates all previous debug information.
    NONE     Generates no debug information.

    The default qualifier is /NODEBUG. When you specify /DEBUG with
    no options, the default option is /DEBUG=ALL.

1.1.4    /DEFINE=(symbol_[=[=]value],...)

    The full command-line option is /[NO]DEFINE=(symbol [=
    [=]value],...).

    Performs the same function as direct symbol assignment in your
    source program. That is, the /DEFINE qualifier defines a numeric
    symbol.

    The Digital Command Language (DCL) converts all input to
    uppercase unless you enclose it within quotation marks.

    Use a single equal sign between the symbol and the value to
    define a local symbol. Use two equal signs between the symbol and
    the value to define a global symbol. The final value of a global
    symbol is output to the object module and is available during
    the linking process. A local symbol is only available during the
    assembly process.

    You cannot define a lexical string symbol with /DEFINE. The value
    you specify for a symbol must be an integer literal. You can
    specify this value using a binary, octal, decimal, or hexadecimal
    radix. The default radix is decimal. If you specify an alternate
    radix, you must use MACRO-64 radix syntax, not DCL radix syntax.

    If you do not specify a value for the symbol, it defaults to 1.

    The simplest form of a /DEFINE definition is as follows:

             /DEFINE=TRUE

    This definition is equivalent to the following definition:

             TRUE=1

    You can also specify more than one symbol definition as with the
    following command:

             /DEFINE=(CHIP==21064,UNROLL=4)

    This definition is equivalent to the following definitions:

             CHIP==21064
             UNROLL=4

    When more than one /DEFINE qualifier is present on the MACRO
    command line or in a single assembly unit, the assembler uses
    only the last one.

    The default qualifier is /NODEFINE.

1.1.5    /DIAGNOSTIC[=file-spec]

    The full command-line option is /[NO]DIAGNOSTIC[=file-spec].

    Controls whether diagnostics are created and stored in the
    specified optional file. If a file specification is not supplied,
    the assembler creates a diagnostic file using the same name
    as the source file. For example, if you use a source file
    named XXX.M64, the assembler creates a diagnostic file named
    XXX.DIA. You can use the diagnostic file with other Digital
    layered products including, but not limited to, the DEC Language-
    Sensitive Editor (LSE).

    The default qualifier is /NODIAGNOSTIC.

1.1.6    /ENVIRONMENT=[NO]FLOAT

    The full command-line option is /ENVIRONMENT=[NO]FLOAT.

    Controls whether the assembler generates floating-point
    instructions when optimizing code and performing code-label
    alignment.

    Currently, the only floating-point instruction generated by
    the assembler during optimization and alignment processing
    is FNOP, the floating-point no-operation instruction. If you
    specify /ENVIRONMENT=NOFLOAT, the assembler does not generate any
    floating-point instructions as part of optimization and alignment
    processing. Floating-point instructions that you specify in your
    source program are unaffected.

1.1.7    /LIBRARY

    The full command-line option is /LIBRARY[=file-spec].

    Searches macro libraries in the following order:

    1. The library designated by the /LIBRARY qualifier.

    2. The .LIBRARY directives.

    3. The MACRO64.MLB library. The assembler searches for the
       MACRO64.MLB macro library in the following locations:
       MACRO64$LIBRARY, ALPHA$LIBRARY, and finally SYS$LIBRARY.

    4. The STARLET.MLB library. The assembler searches for the
       STARLET.MLB macro library in the following locations:
       MACRO64$LIBRARY, ALPHA$LIBRARY, and finally SYS$LIBRARY.

    In addition, you can place the macro library definitions in the
    listing file by using the command-line qualifier /SHOW=LIBRARY.

1.1.8    /LIST[=file-spec]

    The full command-line option is /[NO]LIST[=file-spec].

    Controls whether a listing is created and optionally provides
    an output file specification for the listing file. Do not use
    wildcard characters in this file specification.

    If you enter the MACRO/ALPHA command interactively, the
    default qualifier is /NOLIST. The assembler sends output to
    the current output device rather than to a listing file. If you
    execute the MACRO/ALPHA command in a batch job, the default
    qualifier is /LIST.

    If you do not specify a file specification, the assembler creates
    a listing file using the same name as the source file. For
    example, if you use a source file named XXX.M64, the assembler
    creates a listing file named XXX.LIS.

1.1.9    /MACHINE_CODE

    The full command-line option is /[NO]MACHINE_CODE.

    Produces a binary machine code listing after the source text if a
    listing file is requested. The default qualifier is /NOMACHINE_
    CODE.

1.1.10    /NAMES=case_option

    The full command-line option is /NAMES=case_option.

    Specifies the alphabetic casing of identifiers in source code
    statements. Valid options are:

    Option   Function

    UPPER_   Converts all identifiers to upper alphabetic case.
    CASE
    LOWER_   Converts all identifiers to lower alphabetic case.
    CASE
    AS_IS    Causes all identifiers to remain in the case used in
             source statements.

    If you use the /NAMES qualifier in a command line, you must
    supply a case_option. If you omit the qualifier from the command
    line, the default option is /NAMES=UPPER_CASE.

1.1.11    /OBJECT[=file-spec]

    The full command-line option is /[NO]OBJECT[=file-spec].

    Controls whether an object file is created and optionally
    provides a file specification. Do not use wildcard characters
    in this file specification.

    If you do not specify a file specification, the assembler creates
    an object file using the same name as the source file. For
    example, if you use a source file named XXX.M64, the assembler
    creates an object file named XXX.OBJ.

    The default qualifier is /OBJECT.

1.1.12    /OPTIMIZE[=(option-list)]

    The full command-line option is /[NO]OPTIMIZE[=(option-list)].

    Specifies optional assembler optimizations. Valid items in the
    option-list are:

    Option   Function

    SCHEDULE Specifies instruction scheduling.
    PEEPHOLE Specifies peepholing.

    Specifying /OPTIMIZE with no options is the same as specifying
    /OPTIMIZE=(PEEPHOLE,SCHEDULE).

    The default qualifier is /NOOPTIMIZE.

1.1.13    /PREPROCESSOR_ONLY_[=filespec]

 \BK_ADDED_27)
    The full command-line option is /PREPROCESSOR_ONLY [=filespec]).

    Causes the assembler to output a source file that is the result
    of the input source file after preprocessing. Suppresses
    diagnostic messages and does not produce diagnostic (.ANA) or
    object (.OBJ) files.

    The default option, /NOPREPROCESSOR_ONLY-MACRO-64, assembles your
    source files normally.

    If you specify /PREPROCESSOR_ONLY without a file specification
    argument, the output file name defaults to the name of the
    primary source input file. The output file type defaults to .ASM.

    The following MACRO-64 directives are executed by the
    preprocessor and screened from the preprocessor output file:

       .DISABLE PREPROCESSOR_OUTPUT
       .ENABLE PREPROCESSOR_OUTPUT
       .IF
       .ELSE
       .ENDC
       .IIF
       .IF_FALSE
       .IF_TRUE
       .IF_TRUE_FALSE
       .INCLUDE
       .LIBRARY
       .IRP
       .IRPC
       .REPEAT
       .ENDR
       .MACRO
       .ENDM
       .MCALL
       .MDELETE
       .MEXIT
       .NARG
       .NCHR

    Include files are inserted in place of the .INCLUDE directive
    into the preprocessor output file.

    Macro definitions and repeat block definitions are screened from
    the preprocessor output file.

    Macro expansion lines and repeat block expansion lines are
    inserted in place of the macro invocation line or repeat block,
    respectively, into the preprocessor output file.

    Lexical string-symbol assignment statements are screened from the
    preprocessor output file.

    Lines containing lexical operators are replaced with their
    equivalents after lexical operator processing.

    Lexical line continuations are processed into a single,
    uncontinued line.

    All other language elements, including directives not previously
    listed, label definitions, direct numeric-symbol assignments, and
    so forth are passed through unchanged to the preprocessor output
    file.

1.1.14    /SHOW=(item,...)

    The full command-line option is /[NO]SHOW=(item,...).

    Modifies the output listing file. This qualifier is meaningful
    only when /LIST is specified. Valid items are:

    Option         Function

    BINARY         Lists macro expansions that generate binary code.
                   BINARY is a subset of EXPANSIONS.
    CONDITIONALS   Shows sections of code conditionally skipped.
    EXPANSIONS     Shows macro expansions.
    INCLUDE        Shows all .INCLUDE files.
    LIBRARY        Shows macro library modules.

    The default option is /SHOW=CONDITIONALS.

1.1.15    /WARNINGS=(option-list)

    The full command-line option is /[NO]WARNINGS=(option-list).

    Controls the severity level of messages and diagnostics. Valid
    options are:

    Option          Function

    WARNINGS        Display/suppress warnings.
    INFORMATIONALS  Display/suppress informationals.
    ALL             Display/suppress warnings and informationals.
    NONE            Display/suppress nothing.

    The default options are /WARNINGS=(WARNINGS,INFORMATIONALS). If
    more than one option is specified, options must be enclosed in
    parentheses separated by a comma.

1.2  –  Source Statement Format

    MACRO-64 source statements can have a maximum of four fields, as
    follows:

    o  Label field-Symbolically defines a location in a program.

    o  Operator field-Specifies the action to be performed by the
       statement; this can be an instruction, an assembler directive,
       or a macro call.

    o  Operand field-Contains the instruction operands or the
       assembler directive arguments or the macro arguments.

    o  Comment field-Contains a comment that explains the meaning of
       the statement; this does not affect program execution.

    You can separate statement fields by either a space or a tab
    stop, but Digital recommends that you format statements with the
    Tab key to ensure consistency and clarity.

    Table 1 Using Tab Stops in Statement Fields

              Column
              in
              Which
              Field
    Field     Begins   Tab Stops to Reach Column

    Label     1        0
    Operator  9        1
    Operand   17       2
    Comment   41       5

    The following example shows a typical source statement:

    EXP:    .BLKL   50           ; Table stores expected values
    Rules for Coding Source Statements
    The following rules apply for coding source statements:

    o  You can continue a single statement on several lines by
       using a hyphen (-)  as the last nonblank character before
       the comment field, or at the end of line (when there is no
       comment).

    o  In most cases, you can continue a statement at any point. If a
       symbol name is continued and the first character on the second
       line is a tab or a blank, the symbol name is terminated at
       that character.

    o  Blank lines are legal, but they have no significance in the
       source program except that they terminate a continued line.

    The following sections describe each of the statement fields in
    detail.

1.2.1  –  Label Field

    A label is a user-defined symbol that identifies a location in
    the program. The symbol is assigned a value equal to the location
    counter where the label occurs. The following rules apply when
    coding source statements with labels:

    o  If a statement contains a label, the label must be in the
       first field on the line.

    o  The user-defined symbol name can be up to 31 characters long
       and can contain any alphanumeric character, as well as the
       underscore (_),  dollar sign ($), and period (.)  characters.

    o  If a label extends past column 7, Digital recommends you place
       it on a line by itself so that the following operator field
       can start in column 9 of the next line.

    o  A label is terminated by a colon (:)  or a double colon (::).

    In the following source statement, EXP: is the label field:

    EXP:    .BLKL   50           ; Table stores expected values

    There are three types of labels:

    o  Global labels-Can be referenced by other object modules and
       are defined using a double colon (::).

    o  Local labels-Can be referenced only within the current module
       and are defined using a single colon (:).

    o  Temporary labels-Can be referenced only within the bounds
       of either two local labels, two global labels, two psects
       (program sections), or within the bounds of a temporary
       label scope, as defined by .ENABLE LOCAL_BLOCK and
       .DISABLE LOCAL_BLOCK. Temporary labels are defined using one
       to five digits followed by a dollar sign and a single colon
       ($:).

    The following example shows how these labels appear in use:

    EXP:    .BLKL   50           ; EXP is a local label used to
                                 ; identify a 50-word block of storage
    DATA::  .BLKW   25           ; DATA is a global label used to
                                 ; identify a 25-word block of storage
    10$:    .BLKW    5           ; 10$ is a temporary label used to
                                 ; identify a five word block of
                                 ; storage.

1.2.2  –  Operator Field

    The operator field specifies the action to be performed by the
    statement. This field can contain an instruction, an assembler
    directive, or a macro call. If the operator is:

    o  An instruction, MACRO-64 generates the binary code for that
       instruction in the object module.

    o  A directive, MACRO-64 performs certain control actions or
       processing operations during source program assembly.

    o  A macro call, MACRO-64 expands the macro.

    Use either a space or a tab stop to terminate the operator
    field; however, Digital recommends that you use the tab stop
    to terminate the operator field.

    In the following source statement, .BLKL is the operator field:

    EXP:    .BLKL   50           ; Table stores expected values

1.2.3  –  Operand Field

    The operand field can contain operands for instructions or
    arguments for either assembler directives or macro calls.

    Operands for instructions identify the memory locations or the
    registers that are used by the machine operation. The operand
    field for a specific instruction must contain the correct number
    and type of operands required by that instruction.

    Arguments for a directive must meet the format requirements of
    that directive.

    Operands for a macro must meet the requirements specified in the
    macro definition.

    Use a comma (,)  to separate operands for instructions and
    directives.

    The semicolon that starts the comment field terminates the
    operand field. If a line does not have a comment field, the
    operand field is terminated by the end of the line.

    In the following source statement example, 50 is the operand
    field supplied to the operator field, .BLKL:

    EXP:    .BLKL   50          ; Table stores expected values

1.2.4  –  Comment Field

    The comment field contains text that explains the function of the
    statement. You can use comments to describe algorithms, reasons
    for selecting particular methods, and parameters passed to
    routines. Comments do not affect assembly processing or program
    execution.

    The comment field must be preceded by a semicolon (;)  and can
    contain any printable ASCII character. It is terminated by the
    end of the line.

    A comment can appear on a line by itself. If a comment does
    not fit on one line, it can be continued on the next, but the
    continuation must be preceded by another semicolon.

    In the following source statement example, "Table stores expected
    values" is the comment field. Note that the comment field begins
    with a semicolon.

    EXP:    .BLKL   50          ; Table stores expected values

1.3  –  Character Set

    When coding source statements, you need to be aware of what
    characters are acceptable to the assembler, and how the assembler
    interprets them. The following numbers and characters are
    accepted by the assembler:

    o  The letters of the alphabet, A to Z, uppercase and lowercase.
       By default, the assembler converts all lowercase letters
       to uppercase. This means it considers lowercase letters
       equivalent to uppercase letters.

       The assembler can operate in a case-sensitive mode. In case-
       sensitive mode, the assembler does not convert lowercase
       letters to uppercase letters. On OpenVMS and OpenVMS Alpha
       systems, you can select case-sensitive mode from the command
       line with the /NAMES=AS_IS qualifier.

    o  The digits 0 to 9.

    o  The special characters listed in the Special Characters Table
       which follows.

    Table 2 Special Characters Used in MACRO-64 Statements

              Character
       CharactName       Function

       _      Underscore Character in symbol names.
       $      Dollar     Character in symbol names.
              sign
       .      Period     Character in symbol names, current location
                         counter, and decimal point.
       :      Colon      Local label terminator.
       ::     Double     Global label terminator.
              colon
              sign       keyword argument terminator.
              equal
              sign
       #      Number     Literal value indicator.
              sign
       @      At sign    Arithmetic shift operator.
       ;      Semicolon  Comment field indicator.
       +      Plus       Unary plus operator and arithmetic addition
              sign       operator.
       -      Minus      Unary minus operator, arithmetic subtraction
              sign or    operator, and line continuation indicator.
              hyphen
       *      Asterisk   Arithmetic multiplication operator.
       /      Slash      Arithmetic division operator.
       &      Ampersand  Logical AND operator.
       !      ExclamationLogical inclusive OR operator.
              point
       \      Backslash  Logical exclusive OR and numeric conversion
                         indicator in macro arguments.
       ^      Circumflex Unary operators and macro argument
                         delimiter.
       ( )    ParenthesesDisplacement and register field delimiter in
                         an instruction operand. Argument delimiter
                         to a lexical operator.
       <>     Angle      Argument or expression grouping delimiters.
              brackets
       ?      Question   Created local label indicator in macro
              mark       arguments.
       '      Apostrophe Macro argument concatenation indicator.
       "      Double     Quoted literal delimiter.
              quote
       %      Percent    Delimits the beginning of a lexical
              sign       operator.
       (space)Space or   Separates source statement fields. Spaces
              tab        within expressions are otherwise ignored.
       (tab)
       ,      Comma      Separates symbolic arguments within the
                         operand field. Multiple expressions in the
                         operand field must be separated by commas.

1.4  –  Numbers

    Numbers can be integers or floating-point numbers. The following
    sections describe these types of numbers.

1.4.1  –  Integers

    You can use integers in any expression, including expressions in
    operands and in direct assignment statements.
    FORMAT
    snn

 s

    An optional sign: plus sign (+)  for positive numbers (the
    default), or minus sign (-) for negative numbers.

 nn

    A string of numeric characters that is legal for the specified
    radix.

    MACRO-64 interprets all integers in the source program as decimal
    unless the number is preceded by a radix control operator.

    Integers must be in the range of -263 to +263 -1 for signed data

    or in the range of 0 to 264 -1 for unsigned data.

    Negative numbers must be preceded by a minus sign; MACRO-64
    translates such numbers into two's complement form. In positive
    numbers, the plus sign is optional.

1.4.2  –  Floating Point Number

    You can use a floating-point number in the .DOUBLE, .FLOAT,
    .F_FLOATING, .D_FLOATING, .G_FLOATING, .S_FLOATING, and
    .T_FLOATING directives. You cannot use a floating-point number
    in an expression or with a unary or binary operator except the
    unary plus and unary minus.

    You can specify a floating-point number with or without an
    exponent.
    FORMAT
    Floating-point number without exponent:

    snn
    snn.nn
    snn.

    Floating-point number with exponent (E):

    snnEsnn
    snn.nnEsnn
    snn.Esnn

 s

    An optional sign.

 nn

    A string of decimal digits in the range of 0 to 9.

    The decimal point can appear anywhere to the right of the first
    digit. A floating-point number cannot start with a decimal point
    because MACRO-64 treats the number as a user-defined symbol.

1.5  –  Quoted Literals

    A quoted literal is a string of characters enclosed in double
    quotes (" ").  Use the following guidelines when specifying
    characters in a quoted literal:

    o  Any character except null, carriage return, and form feed can
       appear within the string.

    o  To include a double quote or backslash in a string, you must
       precede it with a backslash (\).

    o  To specify an arbitrary character, you can specify "\xhh",
       where each h represents a single hexadecimal digit. For
       example:

       "AB\\CD\"EF\x47"

       This string contains the following characters:

       AB\CD"EFG

    Also note that the assembler does not convert the case of
    alphabetic characters within a quoted literal.

    Quoted literals can be continued over several lines. Use the
    hyphen (-)  as the line continuation character and delimit the
    string with double quotes. For example:

    .ASCII "Strings are delimited with double quotes."
    .ASCII "The backslash is an escape character."
    .ASCII "Strings can be continued onto multiple lines -
    just as any other line."
    .ASCII "Use two backslashes (\\) to represent -
    the back-slash itself."
    .ASCII "Hexidecimal escape sequences use -
    lower or upper X: \x00 or \X00"
    .ASCII "Precede a double quote with a backslash (\") -
    to embed the quote."

1.6  –  Symbols

    You use symbols in MACRO-64 source statements to represent an
    instruction, directive, register name, or value. You can use four
    types of symbols in MACRO-64 source programs: permanent symbols,
    predefined symbols, user-defined symbols, and macro names.

1.6.1  –  Permanent Symbols

    Permanent symbols consist of MACRO-64 directives and instruction
    mnemonics. You need not define directives before you use them in
    the operator field of a MACRO-64 source statement. It is also not
    necessary to define instruction mnemonics before using them in
    the instruction statements.

1.6.2  –  Predefined Symbols

    Predefined symbols are MACRO-64 register symbols that are not
    permanently reserved. You can delete the definition of any of
    these predefined register symbols. You can also define your own
    register symbols.

    You can express the 32 general registers and the 32 floating-
    point registers of the Alpha processor in a source program as
    follows:

    Register
    Name   Description

    R0     General register 0.
    R1     General register 1.
    .      .
    .      .
    .      .
    R29    General register 29 or frame pointer. If you use R29 as a
    or FP  frame pointer, Digital recommends you use the name FP. If
           you use R29 as a general register, Digital recommends you
           use the name R29.
    R30    General register 30 or stack pointer. If you use R30 as a
    or     stack pointer, the name SP is recommended; if you use R30
    SP     as a general register, the name R30 is recommended.
    R31    General register 31.
    F0     Floating-point register 0.
    .      .
    .      .
    .      .
    F31    Floating-point register 31.

                                   NOTE

       When MACRO-64 operates in /NAMES=AS_IS mode, all of the
       previous register symbols are defined in all uppercase and
       all lowercase.

    To define your own register symbols, use either the .DEFINE_
    FREG or .DEFINE_IREG directive for floating-point or integer
    registers, respectively. For more information about the .DEFINE_
    FREG or .DEFINE_IREG directives, see .DEFINE_FREG and .DEFINE_
    IREG, respectively.

    You can delete a register symbol definition with the .UNDEFINE_
    REG directive. For more information about the .UNDEFINE_REG
    directive, see .UNDEFINE_REG.

    While an identifier is defined as a register symbol, it can only
    be used in those contexts that allow a register.

1.6.3  –  User-Defined Symbols and Macro Names

    You can use symbols to define labels, or you can equate them to a
    specific value by a direct assignment statement. You can also use
    these symbols in expressions.

    Use the following rules to create user-defined symbols:

    o  Use alphanumeric characters, underscores (_),  dollar signs
       ($),  and periods (.). Any other character terminates the
       symbol.

    o  The first character of a symbol cannot be a number.

    o  The symbol must be no more than 31 characters long and must be
       unique.

    o  The symbol must not be a register name.

    o  The symbol cannot be one of the following conditional or macro
       directives:

       .ELSE          .ENDC          .ENDM
       .ENDR          .IF            .IF_FALSE (.IFF)
       .IF_TRUE       .IF_TRUE_      .IIF
       (.IFT)         FALSE
                      (.IFTF)
       .INCLUDE       .IRP           .IRPC
       .LIBRARY       .MACRO         .MCALL
       .MDELETE       .MEXIT         .NARG
       .NCHAR         .REPEAT

    In addition, by Digital convention:

    o  The dollar sign ($)  is reserved for names defined by Digital.
       This convention ensures that a user-defined name (that does
       not have a dollar sign) will not conflict with a Digital-
       defined name (that does have a dollar sign).

    o  Do not use the period (.)  in any global symbol name because
       many languages, such as Fortran, do not allow periods in
       symbol names.

    Macro names follow the same rules and conventions as user-defined
    symbols. User-defined symbols and macro names do not conflict;
    that is, you can use the same name for a user-defined symbol and
    a macro.

1.6.4  –  Determining Symbol Values

    The value of a symbol depends on its use in the program. MACRO-64
    uses a different method to determine the values of symbols in the
    operator field than it uses to determine the values of symbols in
    the operand field.

1.6.5  –  Using Symbols in the Operator Field

    A symbol in the operator field can be either a permanent symbol
    or a macro name. MACRO-64 searches for a symbol definition in the
    following order:

    1. Macro and conditional directives:

       .ELSE      .ENDC          .ENDM
       .ENDR      .IF            .IF_FALSE (.IFF)
       .IF_TRUE   .IF_TRUE_      .IIF
       (.IFT)     FALSE (.IFTF)
       .INCLUDE   .IRP           .IRPC
       .LIBRARY   .MACRO         .MCALL
       .MDELETE   .MEXIT         .NARG
       .NCHAR     .REPEAT

    2. Previously defined macro names

    3. Permanent symbols (instructions and other directives)

    This search order allows most permanent symbols, except
    conditional directives and macro directives, to be redefined
    as macro names. If a symbol in the operator field is not defined
    as a macro or a permanent symbol, the assembler displays an error
    message.

1.6.6  –  Using Symbols in the Operand Field

    A symbol in the operand field must be either a user-defined
    numeric symbol, a label, or a register name.

    User-defined numeric symbols and labels can be either local
    (internal) symbols or global (external) symbols. Whether numeric
    symbols and labels are local or global depends on their use in
    the source program.

    You can reference a local numeric symbol or label only in the
    module in which it is defined. If local numeric symbols or labels
    with the same names are defined in different modules, the symbols
    and labels are completely independent. The definition of a global
    numeric symbol or label, however, can be referenced from any
    module in the program.

    MACRO-64 treats all user-defined numeric symbols and labels as
    local unless you explicitly declare them to be global by doing
    one of the following:

    o  Use the double colon (::)  in defining a label.

    o  Use the double equal sign (==) in a direct assignment
       statement.

    o  Use the .WEAK directive.

    You can only use user-defined lexical string symbols with the
    lexical string operators. You can define a macro using the same
    name as a previously defined local numeric symbol, global numeric
    symbol, or a lexical string symbol. However, you cannot define a
    lexical string symbol and a numeric symbol using the same name.

    In addition, you cannot use the same name for both a local and
    global numeric symbol. You cannot use the same symbol name for
    both a numeric symbol (local or global) and a label (local or
    global).

1.7  –  Temporary Labels Within Source Code

    Use temporary labels to identify addresses within a block of
    source code.
    Format
    nnnnn$:

 nnnnn

    A decimal integer in the range of 1 to 65,535.

    In most cases, you can use temporary labels in the same way
    you use other labels that you define; however, there are some
    differences:

    o  Temporary labels cannot be referenced outside the temporary
       label block in which they are declared.

    o  Temporary labels can be redeclared in another block of source
       code.

    o  Temporary labels that occur within a psect with the MIX or
       NOMIX attribute do not appear in the debugger symbol table;
       thus, they cannot be accessed by the symbolic debugger.

    o  Temporary labels cannot be used in the .END or
       .PROCEDURE_DESCRIPTOR directives.

    By convention, temporary labels are positioned like statement
    labels: left-justified in the source text. Although temporary
    labels can appear in the program in any order, by convention,
    the temporary labels in any block of source code should be in
    increasing numeric order.

    Temporary labels are useful as branch addresses when you use
    the address only within the block. You can use temporary labels
    to distinguish between addresses that are referenced only in a
    small block of code and addresses that are referenced elsewhere
    in the module. A disadvantage of temporary labels is that their
    numeric names do not provide any indication of their purpose.
    Consequently, you should not use temporary labels to label
    sequences of statements that are logically unrelated; you should
    use user-defined symbols instead.

    Digital recommends that users create temporary labels only in
    the range of 0$ to 29999$ because the assembler automatically
    creates temporary labels in the range of 30000$ to 65535$ for use
    in macros.

    The temporary label block in which a temporary label is valid is
    delimited by the following statements:

    o  A user-defined label: global or local.

    o  A .PSECT directive.

       An example showing the correct and incorrect use of temporary
       labels follows:

       A:    ADDQ R1, R2, R3
             BEQ R3, 2$         ; correct use
             MULQ R2, R3, R4
       2$:   ADDQ R1, R4, R5    ; definition of temporary label
       B:    BNE R5, 2$         ; illegal
       C:    SUBQ R2, R4, R6

       In this example, 2$ is a temporary label defined in the
       block between A: and B:. The forward reference in the second
       instruction is properly resolved. The line labeled B: also
       references 2$, but the label B has already closed the range.
       The temporary label 2$ can be used later in the program, but
       its definition must appear within the same block as the label.

    o  The .ENABLE and .DISABLE directives, which can extend a local
       label block beyond user-defined labels and .PSECT directives.

    A temporary label block is usually delimited by two user-defined
    labels. However, the .ENABLE LOCAL_BLOCK directive starts a local
    block that is terminated by one of the following:

    o  A second .ENABLE LOCAL_BLOCK directive

    o  A .DISABLE LOCAL_BLOCK directive followed by a user-defined
       label or a .PSECT directive

    Temporary labels can be preserved with the context of the program
    section in which they are defined for future reference. See the
    descriptions of the .SAVE_PSECT [LOCAL_BLOCK] directive and the
    .RESTORE_PSECT directive.

1.8  –  Label Addresses

    In the absence of optimization and automatic data alignment,
    label addresses are defined to be the psect and offset of the
    current location counter at the point where the label is defined.
    When either optimization or automatic data alignment are enabled,
    the following additional considerations apply.

1.8.1  –  Label Addresses, Optimization, and Code Alignment

    Optimization and code alignment can affect the addresses
    assigned to labels defined in psects that have the EXE and NOMIX
    attributes. Optimization and code alignment are disabled by
    default, and can be enabled with the /OPTIMIZE and /ALIGNMENT
    command-line qualifiers and the .ENABLE directive In general, the
    assembler assigns the psect and offset of the current location
    counter before optimization or alignment of code labels. However,
    the assembler adjusts references to labels in branch instructions
    to the address of the label after optimization and code alignment
    processing. The assembler does not adjust references to labels
    where the label reference occurs in an expression with more than
    one term. The following example shows this:

            .PSECT CODE, EXE, NOMIX
            BSR     R0, 10$            ; R0 -> 10$ (postoptimization)
    10$:    LDA     R1, 20$-10$(R0)    ; R1 -> 20$ (preoptimization)
            JMP     (R1)
            [...]
    20$:

    In the previous example, the assembler adjusts the target
    address of the BSR instruction to be the location of 10$ after
    optimization and code alignment have taken place. Thus, the
    branch to 10$ functions as expected. However, when processing the
    LDA instruction, the assembler computes the offset between 20$
    and 10$ before optimization and code alignment. Thus, the address
    of 20$ that is stored in R1 is the address prior to optimization
    and code alignment. Depending on the sequence of instructions
    between 10$ and 20$, the address before optimization and code
    alignment may differ from the address after optimization and code
    alignment and the JMP instruction may not transfer control to the
    expected address.

    Note also that the assembler only performs postoptimization
    adjustment of label addresses when the label is the only term
    in the expression. For example:

            .PSECT CODE, EXE, NOMIX
            .BASE R27,LINKAGE
            LDQ     R26, ROUTINE1_ADDR
            JSR     R26, (R26)
            LDQ     R26, ROUTINE2_ADDR
            JSR     R26, (R26)
            RET     R28
            NOP
            NOP

    ROUTINE1:
            RET     (R26)
    ROUTINE2:
            RET     (R26)

            .PSECT LINKAGE, NOEXE
    LINKAGE:
    ROUTINE1_ADDR:
            .ADDRESS ROUTINE1
    ROUTINE2_ADDR:
            .ADDRESS ROUTINE2+0

    In the previous example, the assembler adjusts the address stored
    with the .ADDRESS ROUTINE1 directive to the address of label
    ROUTINE1 after optimization and code alignment. However, since
    the expression in the .ADDRESS ROUTINE2+0 directive is not a
    single term, the assembler adds the offset 0 and the address
    of ROUTINE2 before optimization and code alignment and stores
    the result. Since the address stored is the address before
    optimization and code alignment, the second JSR instruction may
    not transfer control to the address that is expected.

1.8.2  –  Label Addresses and Automatic Data Alignment

    Automatic data alignment can affect the addresses assigned to
    labels in psects that have the NOEXE or MIX attributes. Automatic
    data alignment is enabled with the .ENABLE ALIGN_DATA directive
    or the /ALIGNMENT=data command-line option.

    A label that occurs in a statement with a data-storage directive
    is assigned the psect and offset of the storage allocated by the
    data-storage directive. If the data-storage directive requires
    automatic alignment, the address is assigned to the label after
    automatic alignment.

    The same is true of labels that occur in statements by themselves
    and that are followed by a data directive in a subsequent
    statement. However, if a label occurs in a statement by itself
    and is followed by a statement that is not a data-storage
    directive, a macro directive, a conditional directive, or a
    lexical-string symbol assignment, the label is assigned the psect
    and offset of the current location counter before any automatic
    alignment.

    The assembler only assigns addresses to labels after alignment
    under the conditions previously described and only with automatic
    alignment. If you place a label before a .ALIGN directive that
    manually aligns the current location counter, the assembler
    assigns the address of the label before performing the manual
    alignment. The following example shows the interaction of label
    address assignment and automatic data alignment:

        .ENABLE ALIGN_DATA
        .PSECT DATA, NOEXE
        .BYTE   1       ; The byte is stored in psect data at offset 0
    A:  .PRINT "Not aligned" ; Any non-macro, nonconditional
                        ; statement, including this .PRINT directive
                 ; prevents A from being automatically aligned
                        ; -- A is assigned offset 1
    B:                  ; B is automatically aligned to offset 4
    C:  .LONG   2       ; C is automatically aligned to offset 4
    D:  .ALIGN 0        ; The .ALIGN global directive prevents D
                        ;  from being automatically aligned --
          ;  D is assigned offset 8
    E:  .OCTA 3         ; E is automatically aligned to offset 16

    Automatic data alignment and label-address assignment can be an
    important consideration when calculating the difference between
    two labels. For example, consider the following macro, which
    stores a string preceded by a word that contains the string's
    length:

            .MACRO VARYING_STRING STRING ?L1, ?L2
                    .WORD L2-L1
                L1: .ASCII "STRING"
                L2:
            .ENDM VARYING_STRING

    If an invocation of the VARYING_STRING macro is followed by a
    data-storage directive that requires automatic alignment, the
    VARYING_STRING macro will not store the correct string length.
    For example:

            .PSECT DATA, NOEXE, .OCTA
            .ENABLE ALIGN_DATA
            VARYING_STRING <Time for something sweet!> ; 25 bytes
    F:      .OCTA 4

    In this example, the intention is to make the L2 label generated
    by the VARYING_STRING macro be assigned the offset 27, 2 for
    the .WORD directive, plus 25 for the .ASCII directive. Instead,
    it is assigned the offset 32 along with the label F because
    the .OCTA directive requires automatic alignment to offset 32.
    Therefore, the string length is incorrectly stored as 30 rather
    25. To make this macro work as desired, you must include, in the
    macro definition, a macro directive that is not a data-storage,
    macro, or conditional directive after the generated label L2. In
    the following example, .ALIGN 0 is a good choice as it reflects
    the idea that the preceding label is not aligned:

     .MACRO VARYING_STRING STRING ?L1, ?L2
          .WORD L2-L1
         L1: .ASCII "STRING"
         L2: .ALIGN 0
     .ENDM VARYING_STRING

    With this change, the generated label L2 is assigned the offset
    27 before the assembler performs automatic data alignment for the
    .OCTA directive. As a result, the VARYING_STRING macro works as
    desired and stores the correct string length of 25.

1.9  –  Terms and Expressions

    A term can be any of the following:

    o  A number.

    o  A numeric symbol.

    o  A label.

    o  The current location counter.

    o  Any of the previously noted items preceded by a unary
       operator.

    MACRO-64 evaluates terms as quadword (8-byte) values. The current
    location counter (.)  has the value of the location counter at
    the start of the current operand.

    MACRO-64 considers unary operators part of a term and, thus,
    performs the action indicated by a unary operator before it
    performs the action indicated by a binary operator.

    Expressions are combinations of terms joined by binary operators
    and evaluated as quadword (8-byte) values. MACRO-64 evaluates
    expressions from left to right with no operator precedence rules.
    However, you can use angle brackets (<>)  to change the order
    of evaluation. Any part of an expression that is enclosed in
    angle brackets is first evaluated to a single value, which is
    then used in evaluating the complete expression. For example, the
    expressions A*B+C and A*<B+C> are different. In the first case, A
    and B are multiplied and then C is added to the product. In the
    second case, B and C are added and the sum is multiplied by A.
    You can also use angle brackets to apply a unary operator to an
    entire expression, such as -<A+B>.

    Expressions fall into four categories: relocatable, absolute,
    external (global), and complex. You can determine the type of
    expression by the following rules:

    o  An expression is relocatable if its value is fixed relative
       to the start of the psect in which it appears. The current
       location counter is relocatable in a relocatable psect.

    o  An expression is absolute if its value is an assembly-
       time constant. An expression whose terms are all numbers
       is absolute. An expression that consists of a relocatable
       term minus another relocatable term from the same psect is
       absolute, because such an expression reduces to an assembly-
       time constant.

    o  An expression is external if it is not complex, and it
       contains one or more symbols that are not defined in the
       current module.

    o  An expression is complex if it contains a relocatable or
       external term or subexpression that is operated upon by an
       operator other than the plus sign (+)  or the minus sign
       (-). An expression is also complex if it contains more than
       one term or subexpression that is relocatable or external.
       An exception to this rule is the difference between two
       relocatable subexpressions or terms where both relocatable
       values occur in the same psect. In this case, the expression
       is absolute.

    Complex expressions are constrained to use the following form:
    FORMAT
    term operator term

 term

    Term is a relocatable or external subexpression.

 operator

    Operator is any of the MACRO-64 operators.

    Neither term can itself be a complex subexpression. If you
    specify a complex expression that does not match the correct
    form, the assembler issues a diagnostic error message indicating
    that the expression is too complex. Note also that the assembler
    does not attempt to reorder expressions to make your expressions
    match the correct form. For example, the following expression is
    too complex:

     .external E1, E2
     .quad E1+5+E2+6  ; too complex

    Because the assembler has no precedence rules, it attempts to
    evaluate the previous expression as <<<E1+5>+E2>+6>. Since
    <<E1+5>+E2> is itself a complex term, <<<E1+5>+E2>+6> does not
    match the previous form and is too complex. However, you can
    regroup the expression using angle brackets (<>) to match the
    required form as follows:

     .external E1, E2
     .quad <E1+5>+<E2+6>  ; legal complex expression

    In this case, both <E1+5> and <E2+6> are simple, external terms.
    Since none of the terms are complex, the expression matches the
    correct form and the assembler accepts the complex expression.

    You can use any type of expression in most MACRO-64 statements,
    but restrictions are placed on expressions used in the following
    contexts:

    o  .BASE directive.

    o  .BLKx storage allocation directives.

    o  .IF conditional assembly block directives.

    o  .REPEAT repeat block directives.

    o  Direct assignment statements.

    o  Lexical string operator arguments.

    Expressions used in these contexts can contain only symbols or
    labels that have been previously defined in the current module.

    The .BASE directive accepts expressions that contain external
    symbols previously declared with the .EXTERNAL directive. The
    other contexts previously described cannot accept expressions
    that contain external symbols. Symbols defined later in the
    current module cannot be used in any of these contexts.

    Expressions in the .IF conditional directives, .REPEAT
    conditional directives, and lexical string operator arguments
    are relocatable. However, expressions in the .BLKx directives
    must be absolute.

    Expressions cannot contain floating-point numbers. The floating-
    point data-storage directives accept constant values. They do not
    accept floating-point expressions.

    The following example shows the use of expressions:

    A = 2*100                 ; 2*100 is an absolute expression
            .BLKB   A+50      ; A+50 is an absolute expression and
                              ;   contains no undefined symbols
    LAB:    .BLKW   A         ; LAB is relocatable
    HALF = LAB+<A/2>          ; LAB+<A/2> is a relocatable
                              ;   expression and contains no
                              ;   undefined symbols
    LAB2:   .BLKB   LAB2-LAB  ; LAB2-LAB is an absolute expression
                              ;   and contains no undefined symbols

1.10  –  Unary Operators

    A unary operator modifies a term or an expression and indicates
    the action to be performed on that term or expression.
    Expressions modified by unary operators must be enclosed in
    angle brackets. You can use unary operators to indicate whether
    a term or expression is positive or negative. If unary plus or
    minus is not specified, the default value is plus. In addition,
    unary operators perform radix conversion and numeric control
    operations, as described in the following sections.

    Table 3 Summary of Unary Operators

    Unary  Operator
    OperatoName       Example  Operation

    +      Plus       +A       Results in the positive value of A.
           sign
    -      Minus      -A       Results in the negative (two's
           sign                complement) value of A.
    \      Value of   \symbol  Indicates that the value of the symbol
           Escape              should be used. In a string literal,
                               indicates an escape sequence. For
                               example:
                               "Bob\X0A"
    ^A or  ASCII      ^A       Specifies an ASCII constant.
    ^a                /ABCD/
    ^B or  Binary     ^B1100011Specifies that 11000111 is a binary
    ^b                         number.
    ^D or  Decimal    ^D127    Specifies that 127 is a decimal
    ^d                         number.
    ^O or  Octal      ^O34     Specifies that 34 is an octal number.
    ^o
    ^X or  Hexadecimal^XFCF9   Specifies that FCF9 is a hexadecimal
    ^x                         number.
    ^C or  Complement ^C24     Produces the one's complement value of
    ^c                         24 (decimal).

1.10.1  –  Radix Control Operators

    Radix control operators determine the radix of a term or
    expression. MACRO-64 accepts terms or expressions in four
    different radixes: binary, decimal, octal, and hexadecimal. The
    default radix is decimal.
    FORMATS

    ^Bnn
    ^Dnn
    ^Onn
    ^Xnn

 nn

    A string of characters that is legal in the specified radix. The
    following are the legal characters for each radix:

           Radix
    Format Name       Legal Characters

    ^Bnn   Binary     0 and 1
    ^Dnn   Decimal    0 to 9
    ^Onn   Octal      0 to 7
    ^Xnn   Hexadecimal0 to 9 and A to F

    You can include radix control operators in the source program
    anywhere a numeric value is legal. A radix control operator
    affects only the term immediately following it, causing that
    term to be evaluated in the specified radix. For example:

    .WORD   ^B00001101              ; Binary radix
    .WORD   ^D123                   ; Decimal radix (default)
    .WORD   ^O47                    ; Octal radix

    Do not place spaces or tabs between the circumflex (^), the radix
    specifier (B, D, O, or X), or the numeric value.

1.10.2  –  Numeric Complement Operator

    The complement operator (^C)  produces the one's complement of
    the specified value.

    FORMAT
    ^Cterm

 term

    Any term or expression. If an expression is specified, it must be
    enclosed in angle brackets.

    MACRO-64 evaluates the term or expression as an 8-byte value
    before complementing it. For example:

    .LONG      ^C^XFF      ; Produces FFFFFF00 (hex)
    .LONG      ^C25        ; Produces complement of
                           ;   25 (dec) which is
                           ;   FFFFFFE6 (hex)

1.11  –  Binary Operators

    In contrast to unary operators, binary operators specify
    actions to be performed on two terms or expressions. You can
    enclose expressions in angle brackets to specify the order of
    evaluation.

    Table 4 Summary of Binary Operators

       BinaryOperator
       OperatName        ExampleOperation

       +     Plus sign   A+B     Addition
       -     Minus sign  A-B     Subtraction
       *     Asterisk    A*B     Multiplication
       /     Slash       A/B     Division
       @     At sign     A@B     Arithmetic shift
       &     Ampersand   A&B     Logical AND (product)
       !     Exclamation A!B     Logical OR (sum)
             point
       \     Backslash   A\B     Logical XOR (difference)

    All binary operators have equal priority. You can group terms or
    expressions for evaluation by enclosing them in angle brackets.
    The enclosed terms and expressions are evaluated first, and
    remaining operations are performed from left to right. For
    example:

    .LONG      1+2*3      ; Equals 9
    .LONG      1+<2*3>    ; Equals 7

    Note that a 64-bit result is returned from all binary operations.
    If you use the 64-bit result in a context requiring less than
    64 bits, only the lower-order bits of the result are used. If
    the truncation causes a loss of significance in a data-storage
    directive, the assembler displays an error message.

    The following sections describe the arithmetic shift, logical
    AND, logical inclusive OR, and logical exclusive OR operators.

1.11.1  –  Arithmetic Shift Operator

    Use the arithmetic shift operator (@)  to perform left and right
    arithmetic shifts of arithmetic quantities. The first argument
    is shifted left or right by the number of bit positions that
    you specify in the second argument. If the second argument is
    positive, the first argument is shifted left and the low-order
    bits are set to zero. If the second argument is negative, the
    first argument is shifted right and the high-order bits are set
    to the value of the original high-order bit (the sign bit). For
    example:

            .LONG   ^B101@4              ; Yields 1010000 (binary)
            .LONG   1@2                  ; Yields 100 (binary)
    A = 4
            .LONG   1@A                  ; Yields 10000 (binary)
            .LONG   ^X1234@-A            ; Yields 123(hex)

1.11.2  –  Logical AND Operator

    The logical AND operator (&)  takes the logical AND of two
    operands. For example:

    A = ^B1010
    B = ^B1100
            .LONG   A&B             ; Yields 1000 (binary)

1.11.3  –  Logical Inclusive OR Operator

    The logical inclusive OR operator (!)  takes the logical
    inclusive OR of two operands. For example:

    A = ^B1010
    B = ^B1100
            .LONG   A!B             ; Yields 1110 (binary)

1.11.4  –  Logical Exclusive OR Operator

    The logical exclusive OR operator (\)  takes the logical
    exclusive OR of two arguments. For example:

    A = ^B1010
    B = ^B1100
            .LONG   A\B             ; Yields 0110 (binary)

1.12  –  Direct Assignment Statements

    A direct assignment statement equates a symbol to a specific
    value. Unlike a symbol that you use as a label, you can redefine
    a symbol defined with a direct assignment statement as many times
    as you want.
    FORMATS

    symbol=expression

    symbol==expression

    symbol=quoted-literal

 symbol

    A user-defined symbol.

 expression

    An expression that does not contain any undefined symbols or
    forward references. The result must be either an absolute or
    relocatable value, whose value can be determined at the current
    point in the assembly. This form defines a numeric symbol.

    The format with a single equal sign (=)  defines a local symbol,
    and the format with a double equal sign (==) defines a global
    symbol.

    The following three syntactic rules apply to direct assignment
    statements:

    o  An equal sign (=)  or double equal sign (==) must separate
       the symbol from the expression that defines its value. Spaces
       preceding or following the direct assignment operators have no
       significance in the resulting value.

    o  Only one symbol can be defined in a single direct assignment
       statement.

    o  A direct assignment statement can be followed only by a
       comment field.

    For best results, Digital recommends you place the symbol in a
    direct assignment statement in the label field. For example:

    A == 1                  ; The symbol 'A' is globally
                            ;   equated to the value 1

    B = A@5                 ; The symbol 'B' is equated
                            ;   to 1@5 or 32(dec)

    C = 127*10              ; The symbol 'C' is equated
                            ;   to 1270(dec)

    D = ^X100/^X10          ; The symbol 'D' is equated
                            ;   to 10(hex)

 quoted-literal

    A literal within double quotes. This form defines a lexical
    string symbol. You can only use lexical string symbols with
    lexical string operators.

1.13  –  Current Location Counter

    The current location counter is a counter kept by an assembler to
    determine the address assigned to an instruction or constant that
    is being assembled. The symbol for the current location counter,
    the period (.),  represents the address of the current byte.
    MACRO-64 sets the current location counter to 0 at the beginning
    of the assembly and at the beginning of each new program section.

    Every MACRO-64 source statement that allocates memory in the
    object module increments the value of the current location
    counter by the number of bytes allocated. For example, the
    directive, .LONG 0 increments the current location counter by 4.
    However, with the exception of the special form described later
    in this section, a direct assignment statement does not increase
    the current location counter because no memory is allocated.

    The current location counter can be explicitly set by a special
    form of the direct assignment statement. The location counter can
    be either incremented or decremented. This method of setting the
    location counter is often useful when defining data structures.
    Data-storage areas should not be reserved by explicitly setting
    the location counter; use the .BLKx directives.
    FORMAT

    .=expression

 expression

    An expression that does not contain any undefined or external
    symbols.

    In a relocatable psect, the expression must be relocatable; that
    is, the expression must be relative to an address in the current
    psect. It also may be relative to the current location counter.
    For example:

    . = .+40        ; Moves location counter forward

    When a psect that you defined in the current module is continued,
    the current location counter is set to the last value of the
    current location counter in that psect.

    In a psect with the EXE and NOMIX attributes:

    o  The location counter cannot be changed.

    o  If optimization is enabled, the location counter represents
       the location before optimization.

    In a psect with either the EXE or NOMIX (or both) attributes:

    o  The location counter can be changed.

    o  If you store an initial data or instruction value in memory
       with a data directive such as .BYTE, .WORD, .LONG, or .QUAD
       or with an instruction statement, you can replace that initial
       value with a different initial value later in the assembly
       by assigning the appropriate address value to the current
       location counter and entering another data directive or
       instruction statement. However, the new value must be the
       same size and must start at exactly the same address as the
       value it replaces.

1.14  –  Lexical Operators

1.14.1  –  Processing with Lexical Operators

    Lexical operator processing is performed on all source lines
    and macro expansion lines before any other assembler processing.
    Thus, macro invocations, assembler directives, and instructions
    are subject to lexical operator processing before normal
    assembler processing.

    Lexical operators are recognized and processed within string
    literals. Lexical operator processing is suppressed during macro
    registration in order that lexical operator evaluation may occur
    during macro expansion. Lexical operator evaluation is also
    suppressed for a range of text that is conditionally excluded
    with one of the .IF directives. In addition, lexical operator
    processing is not performed within a comment.

1.14.2  –  Syntax

    You invoke a lexical string operator with a percent sign followed
    by the lexical operator name, a left parentheses, a list of
    arguments separated by commas, and a right parentheses. The
    following example shows the lexical operator syntax:

       .print "%EDIT(<Fred>,<upcase>)"

    Spaces are allowed between syntax elements in the general lexical
    operator syntax. For example, the following syntax, including
    spaces, is allowed:

    .print "%EDIT ( <Fred> , <upcase> )"

    Spaces are also allowed between the opening and closing percent
    signs in a lexical substitution operator.

    .print "% lexical_symbol_name %"

    Spaces are not allowed between the pair of percent signs
    indicating a lexical escape operator.

    You can specify lexical operator arguments in the same way as
    macro arguments:

    o  A numeric symbol name preceded by a backslash (\). This
       construct results in the decimal value of the numeric symbol,
       as shown in the following example:

          \N

    o  Any string of characters surrounded by left- and right-angle
       brackets, as shown in the following example:

       <Foo bar thud>

       You can nest angle brackets (<>).  For example:

       <<X+7>*17>

    o  Any string of characters surrounded by a delimiter specified
       after a caret character (^). You cannot nest delimiters. For
       example:

       ^%Foo bar thud%

    o  Any undelimited string of characters not separated by a space,
       tab, form feed, comma, equal sign, semicolon, or end of line.
       For example:

       A+B+C

    In addition to the formats allowed for a macro argument, you can
    also specify lexical operator arguments as follows:

    o  An undelimited string of characters may also contain a string
       of characters enclosed within left and right parentheses. The
       characters between the left and right parentheses may contain
       space, tab, or comma delimiters. For example:

       16( R27 )

    o  You can use a lexical operator as an argument to another
       lexical operator. For example:

       %EXTRACT( %LOCATE($,X), %LENGTH(X) - %LOCATE($,X) ,X)

    Except for the %TYPE lexical operator, a string symbol name
    supplied as a lexical operator argument is replaced with the
    value of the string symbol.

    Each lexical operator accepts a given number of arguments and
    each argument has a specific type. There are three different
    types of arguments-string, integer, and name:

    o  A string argument can be any arbitrary sequence of characters.

    o  An integer argument must be an absolute or relocatable
       expression that can be resolved at that point in the assembly.
       A relocatable expression represents a psect and an offset
       within that psect. If you specify a relocatable expression for
       an integer argument, the assembler uses only the value of the
       offset within the psect. The offset value is determined before
       optimization and code alignment, but after data alignment.

    o  The name argument type is used only by the %TYPE lexical
       operator. The %TYPE lexical operator accepts the name of a
       numeric symbol, string symbol, label, psect, or a permanent
       symbol as its argument. Unlike the other lexical operators, if
       a string symbol name is specified as an argument to %TYPE, the
       value of the string symbol is not substituted for its name.
       Instead, information about the name is returned.

    If you omit a string argument, the default is the empty string.
    An empty string is a string with no characters. If you omit an
    integer argument or specify an illegal expression, the default
    value is 0. The assembler does not issue diagnostic messages
    for illegal expressions used as arguments to lexical operators.
    If you omit the name argument or specify an illegal name to the
    %TYPE lexical operator, %TYPE returns a 0 value.

1.14.3  –  Numeric Symbols and Lexical String Symbols

    Lexical string symbols are similar in concept and syntax to
    numeric symbols. MACRO-64 supports numeric symbols using the
    following syntax:

    numeric_symbol_name = numeric_expression

    MACRO-64 supports lexical string symbols using the following
    syntax:

    string_symbol_name = "any string of characters"

    The assembler differentiates between numeric symbol assignment
    and lexical string symbol assignment as follows:

    o  In a lexical string symbol assignment, a quoted string literal
       must appear after the equal sign.

    o  A lexical string symbol value is specified by the quoted
       string literal.

    The quotes are not included in the value of the lexical string
    symbol. You cannot use the same name for a lexical string symbol,
    numeric symbol, or label.

    Like numeric symbols, lexical string symbols are assembly time
    variables. After you assign a string value to a lexical string
    symbol, you can reassign a different value to that symbol later
    in the assembly.

    You can use lexical string symbols as arguments to lexical
    operators. In particular, you can use a lexical string symbol
    as an argument to the lexical substitution operator (%)  or the
    %STRING lexical operator to substitute the value of the lexical
    string symbol at any point in the text of your program.

1.14.4  –  Lexical Substitution Operator

    You can use the lexical substitution operator at any point in
    your program to cause the assembler to substitute the value of
    a lexical string symbol for the name of the symbol. The lexical
    substitution operator is the percent sign (%). Place the lexical
    substitution operator to the left and right of the name of the
    lexical string symbol that you wish to subsitute, as follows:

    %lexsym_name%

    For example:

         HORSES    = "All the king's horses"
         MEN       = "all the king's men"
         .print "%HORSES% and %MEN%"

    This example defines two lexical string symbols: HORSES and MEN.
    The third statement displays a message at assembly time. The text
    of the message specifies that the value of the HORSES and MEN
    lexical string symbols be substituted as indicated. After lexical
    processing, the third statement appears as:

         .print "All the king's horses and all the king's men"

1.14.5  –  Lexical Escape Operator

    It is possible to defer the processing of a lexical string
    operator by using the lexical escape operator, which is the
    percent sign (%).  Since all lexical string operators begin with
    a percent sign, the effect of placing two percent signs before
    the name of the lexical string operator defers the evaluation of
    the lexical string operator. If you want to defer processing of
    a lexical substitution operator, place two percent signs to the
    left and two percent signs to the right of the lexical string
    symbol name.

    This can be useful when you want the evaluation of a lexical
    string operator that you have used in a default macro argument
    to occur during macro expansion, rather than during macro
    definition. Lexical operator processing is suppressed during
    macro registration. Therefore, lexical operator processing is
    automatically deferred within the body of a macro. However, the
    .MACRO directive line that begins the macro definition is subject
    to normal lexical operator processing. Sometimes you may need
    to use the value of a lexical string symbol as the default for
    a macro argument, but you need to use the value of the lexical
    string symbol that is current when the macro expands, not when
    the macro is defined. Lexical Processing Without the Escape
    Operator shows an example of this, but it does not use an escape
    operator.

    Example 1  Lexical Processing Without the Escape Operator

        CODE_PSECT_NAME = "CODE1"
        .MACRO CODE_PSECT PSECT_NAME=%string(CODE_PSECT_NAME)
         .PSECT PSECT_NAME
        .ENDM CODE_PSECT
        CODE_PSECT
        CODE_PSECT_NAME = "CODE2"
        CODE_PSECT

    Lexical Processing Without the Escape Operator does not process
    correctly for the following reasons:

    o  The lexical operator in the .MACRO directive line is processed
       when the macro is defined, not when the macro expands.

    o  The CODE_PSECT macro always defaults to setting the psect
       to the CODE1 psect because the default for the PSECT_NAME
       argument will be set to CODE1, not %string(CODE_PSECT_NAME).
       This is because %string(CODE_PSECT_NAME) is evaluated when the
       CODE_PSECT macro is defined, not when it expands.

    Lexical Processing with Escape Operator is similar to Lexical
    Processing Without the Escape Operator except it uses the lexical
    escape operator.

    Example 2  Lexical Processing with Escape Operator

        CODE_PSECT_NAME = "CODE1"
        .macro CODE_PSECT PSECT_NAME=%%string(CODE_PSECT_NAME)
       .psect PSECT_NAME
        .endm CODE_PSECT
        CODE_PSECT
        CODE_PSECT_NAME = "CODE2"
        CODE_PSECT

    Lexical Processing with Escape Operator processes correctly for
    the following reasons:

    o  Lexical operator processing of %%string(CODE_PSECT_NAME)
       is deferred when the CODE_PSECT macro is defined. The
       default value for the PSECT_NAME argument is stored as
       %string(CODE_PSECT_NAME).

    o  During macro expansion, %string(CODE_PSECT_NAME) is evaluated,
       which results in the current value of the CODE_PSECT_NAME
       lexical string symbol as desired.

1.14.6  –  %EDIT

    Lexical operator for editing text strings.

    Format

      %EDIT  (string1,string2)

1.14.6.1  –  Arguments

 string1

    The first argument, of type string, specifies the string to be
    edited.

 string2

    The second argument, of type string, specifies a list of edits to
    perform, which are separated by commas.

1.14.6.2  –  Description

    %EDIT is modeled after the OpenVMS DCL lexical function F$EDIT.
    It is used to perform one or more edits on a specified string.
    %EDIT processes the string of arguments from left to right. %EDIT
    gives precedence to the last argument. %EDIT gives precedence to
    uppercase over lowercase.

    The list of edits may contain any combination of the following
    elements:

    Element    Function

    COLLAPSE   Removes all tabs and spaces.
    COMPRESS   Replaces multiple, consecutive tabs or spaces with a
               single space.
    LOWERCASE  Changes uppercase characters to lowercase.
    TRIM       Removes leading and trailing spaces and tabs.
    UPCASE     Changes lowercase characters to uppercase.

1.14.6.3  –  Examples

      Example 1
             .PRINT "%EDIT(< Fred Smith >, <TRIM,COLLAPSE,UPCASE>)"

      After lexical processing, the statement apears as the
      following:

             .PRINT "FREDSMITH"
      Example 2
             .PRINT "%EDIT(<AbCdEfG>,<upcase,lowercase>)
             .PRINT "%EDIT(<AbCdEfG>,<lowercase,upcase>)

      The first source statement produces the string "abcdefg" and
      the second source statement produces the string "ABCDEFG". Each
      of the edits in the edit list is performed in sequence, from
      left to right.

1.14.7  –  %ELEMENT

    Lexical operator for extracting elements from a list of elements.

    Format

      %ELEMENT  (integer,string1,string2)

1.14.7.1  –  Arguments

 integer

    The first argument, of type integer, is the element number to
    extract. The first element is number 0.

 string1

    The second argument, of type string, is the delimiter or
    delimiters that separate elements.

 string2

    The third argument, of type string, is the list of elements.

1.14.7.2  –  Description

    %ELEMENT is modeled after the OpenVMS DCL lexical function
    F$ELEMENT. It is used to extract one element from a string of
    elements. Note that unlike F$ELEMENT, you may specify multiple
    delimiters. The result is the specified string element. If the
    specified element number is greater than the number of elements
    in the list, the delimiter argument is returned.

1.14.7.3  –  Example

             .PRINT "%ELEMENT (2, <+-*/>, JOE+FRED-TOM*BILL/ERIC)"

      After lexical processing, the statement appears as:

             .PRINT "TOM"

1.14.8  –  %EXTRACT

    Lexical operator for extracting a range of characters from a
    string of characters.

    Format

      %EXTRACT  (integer1,integer2,string)

1.14.8.1  –  Arguments

 integer1

    The first argument, of type integer, is the offset at which to
    begin the extraction. The first character is at offset 0.

 integer2

    The second argument, of type integer, is the number of characters
    to extract.

 string

    The third argument, of type string, is the string from which to
    extract the characters.

1.14.8.2  –  Description

    %EXTRACT is modeled after VAX MACRO's %EXTRACT macro string
    operator and the OpenVMS DCL lexical function F$EXTRACT. %EXTRACT
    is used to extract a specified range of characters from a string.

1.14.8.3  –  Example

             .PRINT "%EXTRACT(3,4,ABCDEFGHIJKLMNOP)"

      After lexical processing, the statement appears as:

             .PRINT "DEFG"

1.14.9  –  %FREG

    Lexical operator for obtaining the floating-point register number
    associated with a symbol.

    Format

      %FREG  (symbol)

1.14.9.1  –  Argument

 symbol

    The single argument, of type string, specifies a symbol that
    may or may not be currently defined as a floating-point register
    symbol.

1.14.9.2  –  Description

    %FREG returns the decimal number of the floating-point register
    when the specified symbol is defined as a floating-point register
    symbol. Otherwise, %FREG returns 32.

1.14.9.3  –  Example

            ; Is TARG_REG the same as F31?
            .IF EQ, <%FREG(TARG_REG)>, <%FREG(31)>

      If TARG_REG has been defined as floating-point register F5, the
      statements appear as follows after lexical processing:

            ; Is TARG_REG the same as F31?
            .IF EQ, <5>, <31>

1.14.10  –  %INTEGER

    Lexical operator for converting the value of an expression to a
    decimal value.

    Format

      %INTEGER  (integer)

1.14.10.1  –  Argument

 integer

    The single argument, of type integer, is the expression to be
    converted.

1.14.10.2  –  Description

    %INTEGER is modeled after the OpenVMS DCL lexical function
    F$INTEGER. It is used to convert the value of an expression to
    a decimal value. The result is its decimal value. You can also
    use %INTEGER to convert a relocatable expression to an absolute
    value.

1.14.10.3  –  Example

             .PRINT "%INTEGER (<<X+7>*17>)"

      After lexical processing, if X has the value 3, the statement
      will appear as:

             .PRINT "170"

1.14.11  –  %IREG

    Lexical operator for obtaining the integer register number
    associated with a symbol.

    Format

      %IREG  (symbol)

1.14.11.1  –  Argument

 symbol

    The single argument, of type string, specifies a symbol that may
    or may not be currently defined as an integer register symbol.

1.14.11.2  –  Description

    %IREG returns the decimal number of the integer register when
    the specified symbol is defined as an integer register symbol.
    Otherwise, %IREG returns 32.

1.14.11.3  –  Example

            ; Is SRC_REG the same as SP?
            .IF EQ, <%IREG(SRC_REG)>, <%IREG(SP)>

      If SRC_REG has been defined as integer register R16, the
      statements appear as follows after lexical processing:

            ; Is SRC_REG the same as SP?
            .IF EQ, <16>, <30>

1.14.12  –  %LENGTH

    Lexical operator for determining the length of a string.

    Format

      %LENGTH  (string)

1.14.12.1  –  Argument

 string

    The single argument, of type string, is the string from which the
    length is to be computed.

1.14.12.2  –  Description

    %LENGTH is modeled after VAX MACRO's %LENGTH macro string
    operator and the OpenVMS DCL lexical function F$LENGTH. %LENGTH
    is used to determine the length of a string. The result is the
    length of the string expressed as a decimal number.

1.14.12.3  –  Example

             .PRINT "%LENGTH(<The quick brown fox>)"

      After lexical processing, the statement appears as:

             .PRINT "19"

1.14.13  –  %LOCATE

    Lexical operator for locating a string of text within another
    string of text.

    Format

      %LOCATE  (string1,string2)

1.14.13.1  –  Arguments

 string1

    The first argument, of type string, is the string for which
    %LOCATE searches.

 string2

    The second argument, of type string, is the string in which the
    search is performed.

1.14.13.2  –  Description

    %LOCATE is modeled after VAX MACRO's %LOCATE macro string
    operator and the OpenVMS DCL lexical function F$LOCATE. %LOCATE
    is used to locate one string within another. The value returned
    is the decimal offset to the first occurrence of the first string
    within the second string. The offset to the first character is 0.
    If the first string cannot be found within the second string, the
    length of the second string is returned.

1.14.13.3  –  Example

             .PRINT "%LOCATE (DEF,ABCDEFGHIJKLMNOP)"

      After lexical processing, the statement appears as:

             .PRINT "3"

1.14.14  –  %REPEAT

    Lexical operator for repeating a specified string a specified
    number of times.

    Format

      %REPEAT  (integer,string)

1.14.14.1  –  Arguments

 integer

    The first argument, of type integer, is the number of times to
    repeat the string. If you specify a negative value, the string is
    repeated 0 times.

 string

    The second argument, of type string, is the string to be
    repeated.

1.14.14.2  –  Description

    %REPEAT is used to repeat the specified string a specified number
    of times.

1.14.14.3  –  Example

             .PRINT "Never, %REPEAT (3, <ever, >)touch that button!"

      After lexical processing, the statement appears as:

             .PRINT "Never, ever, ever, ever, touch that button!"

1.14.15  –  %STRING

    Lexical operator for obtaining the value of a lexical string
    symbol.

    Format

      %STRING  (string)

1.14.15.1  –  Argument

 string

    The single argument is of type string. If the argument is the
    name of the lexical string symbol, the value of the lexical
    string symbol is returned. Otherwise, the argument is returned
    unchanged.

1.14.15.2  –  Description

    %STRING is modeled after the OpenVMS DCL lexical function
    F$STRING. %STRING is generally used to obtain the value of
    a lexical string symbol, but you can use it with any string
    argument.

1.14.15.3  –  Example

             FOO = "All the king's horses"
             .PRINT "%STRING(FOO)"

      After lexical processing, the statement appears as:

             .PRINT "All the king's horses"

1.14.16  –  %TIME

    Lexical operator for obtaining the date and time of the assembly
    unit.

    Format

      %TIME  ()

1.14.16.1  –  Description

    %TIME is modeled after the OpenVMS DCL lexical function F$TIME.
    %TIME is used to obtain the time and date of the assembly unit.
    There are no arguments. The result is a string specifying the
    date and time of the assembly unit.

1.14.16.2  –  Example

             .PRINT "%TIME()"

      After lexical processing, the statement appears as:

             .PRINT " 8-OCT-1991 13:17:57"

1.14.17  –  %TYPE

    Lexical operator for obtaining information about a name.

    Format

      %TYPE  (name)

1.14.17.1  –  Argument

 name

    The single argument is of type name. Information is returned
    about the name specified in the argument.

1.14.17.2  –  Description

    %TYPE is modeled after the OpenVMS DCL lexical function
    F$TYPE. %TYPE is used to obtain information about a name. The
    value returned is a numeric value with certain bit positions,
    either 0 or 1, depending on whether the specified name has the
    corresponding attribute. As described elsewhere, the decimal
    digits of the numeric value are substituted for the %TYPE lexical
    operator. %TYPE Attributes shows the symbolic names that are
    predefined for each attribute.

    Table 5 %TYPE Attributes

    Symbolic Name          Attribute

    MACRO64$TYPE_SYMBOL    Name is a numeric symbol name.
    MACRO64$TYPE_PROC_     Name is a procedure descriptor name.
    DESC
    MACRO64$TYPE_LABEL     Name is a label.
    MACRO64$TYPE_EXTERN    Name is an external name.
    MACRO64$TYPE_WEAK      Name is a weak name.
    MACRO64$TYPE_PSECT     Name is a psect.
    MACRO64$TYPE_MACRO     Name is a macro name.
    MACRO64$TYPE_STRING    Name is a lexical string symbol name.
    MACRO64$TYPE_OPCODE    Name is an opcode.
    MACRO64$TYPE_DIR       Name is a directive.
    MACRO64$TYPE_GENREG    Name is a general register.
    MACRO64$TYPE_FLTREG    Name is a floating register.

    A given name may have zero, one, or several attributes.

1.14.17.3  –  Example

             .macro IS_GR ARG
               .IF equal, %TYPE(ARG) & <MACRO64$TYPE_GENREG>
                .PRINT "ARG is not a general register"
               .ENDC
             .endm IS_GR
             IS_GR F11

      Initially, the first line of the IS_GR macro expands as the
      following:

             .IF equal, <%TYPE(F11) & MACRO64$TYPE_GENREG>

      After lexical processing, the statement appears as:

             .IF equal, <8192 & MACRO64$TYPE_GENREG>

      In this example, 8192 is the attribute value for a floating-
      point register. This value could change in subsequent releases.
      Use only the predefined attribute masks described in %TYPE
      Attributes. Since the attribute for a general register
      MACRO64$TYPE_GENREG is 4096, the expression evaluates as 0.

             <8192 & MACRO64$TYPE_GENREG>

1.15  –  Macros

    By using macros, you can use a single source statement to insert
    a sequence of source statements into a program.

    A macro definition contains the source statements of the macro.
    The macro definition may have formal arguments. You can use these
    formal arguments throughout the sequence of source statements
    within the definition. When the macro is called, the formal
    arguments are replaced by the actual arguments within the macro
    call.

    The macro call is a single source statement consisting of the
    macro name, optionally followed by arguments. When the macro
    is called, the assembler replaces the line containing the macro
    call with the source statements in the macro definition. The
    assembler replaces any occurrences of formal arguments in the
    macro definition with the actual arguments specified in the macro
    call. This process is called the macro expansion.

    By default, macro expansions are not printed in the assembly
    listing. To print the macro expansions, you must specify the
    /SHOW=EXPANSIONS qualifier and argument in the command line. Note
    that the examples of macro expansions used in this chapter are
    listed as they would appear using the /SHOW=EXPANSIONS qualifier
    and argument.

    Use .SHOW with a symbolic argument of EXPANSIONS in the source
    text of a program to specify the listing of expansions.

1.15.1  –  Arguments

    Macros have two types of arguments: actual and formal. Actual
    arguments are the text given in the macro call after the name
    of the macro. Formal arguments are specified by name in the
    macro definition; that is, after the macro name in the .MACRO
    directive. Actual arguments in macro calls and formal arguments
    in macro definitions can be separated by commas (,),  tabs, or
    spaces.

    The number of actual arguments in the macro call can be less
    than or equal to the number of formal arguments in the macro
    definition. If the number of actual arguments is greater than
    the number of formal arguments, the assembler displays an error
    message.

    Formal and actual arguments normally maintain a strict positional
    relationship. That is, the first actual argument in a macro call
    replaces all occurrences of the first formal argument in the
    macro definition. This strict positional relationship can be
    overridden by using keyword arguments. See the section on keyword
    arguments.

    An example of a macro definition using formal arguments follows:

    .MACRO  STORE  ARG1,ARG2,ARG3
    .LONG   ARG1                     ; ARG1 is first argument
    .WORD   ARG3                     ; ARG3 is third argument
    .BYTE   ARG2                     ; ARG2 is second argument
    .ENDM   STORE

    The following two examples show possible calls and expansions of
    the macro previously defined:

    STORE   3,2,1                    ; Macro call
    .LONG   3                        ; 3 is first argument
    .WORD   1                        ; 1 is third argument
    .BYTE   2                        ; 2 is second argument

    STORE   X,X-Y,Z                  ; Macro call
    .LONG   X                        ; X is first argument
    .WORD   Z                        ; Z is third argument
    .BYTE   X-Y                      ; X-Y is second argument

1.15.2  –  Default Values

    Default values are values that are defined in the macro
    definition. They are used when no value for a formal argument
    is specified in the macro call.

    Default values are specified in the .MACRO directive as follows:

    formal-argument-name = default-value

    An example of a macro definition specifying default values
    follows:

    .MACRO  STORE   ARG1=12,ARG2=0,ARG3=1000
    .LONG   ARG1
    .WORD   ARG3
    .BYTE   ARG2
    .ENDM   STORE

    The following three examples show possible calls and expansions
    of the macro defined previously:

    STORE                   ; No arguments supplied
    .LONG   12
    .WORD   1000
    .BYTE   0

    STORE   ,5,X            ; Last two arguments supplied
    .LONG   12
    .WORD   X
    .BYTE   5

    STORE   1               ; First argument supplied
    .LONG   1
    .WORD   1000
    .BYTE   0

1.15.3  –  Keyword Arguments

    Keyword arguments allow a macro call to specify the arguments
    in any order. In this case, the macro call must specify the
    same formal argument names that appear in the macro definition.
    Keyword arguments are useful when a macro definition has more
    formal arguments than necessary in the call.

    In any one macro call, it is good practice to specify the
    arguments as either all positional arguments or all keyword
    arguments. For example, the following macro definition specifies
    three arguments:

    .MACRO  STORE   ARG1,ARG2,ARG3
    .LONG   ARG1
    .WORD   ARG3
    .BYTE   ARG2
    .ENDM   STORE

    The following macro call specifies keyword arguments:

    STORE   ARG3=27+5/4,ARG2=5,ARG1=SYMBL
    .LONG   SYMBL
    .WORD   27+5/4
    .BYTE   5

    Because the keywords are specified in the macro call, the
    arguments in the macro call need not be given in the order they
    were listed in the macro definition.

    Positional and keyword arguments may be mixed. Usually,
    positional arguments are placed before keyword arguments. For
    example:

    .MACRO  STORE   ARG1,ARG2,ARG3=27+5/4
    .LONG   ARG1
    .BYTE   ARG2
    .WORD   27+5/4
    .ENDM   STORE

                                   NOTE

       Keyword arguments are not counted when positional arguments
       are parsed. This means that when positional and keyword
       arguments are used in the same macro, one argument can be
       specified twice. The last value specified for the argument
       is used.

1.15.4  –  String Arguments

    If an actual argument is a string containing characters that
    the assembler interprets as separators (such as a tab, space,
    or comma), the string must be enclosed by delimiters. String
    delimiters for macro arguments are usually paired angle brackets
    (<>). A quoted literal enclosed in double quotes ("")  is also a
    valid string argument.

    The assembler also interprets any character
    (except A, B, C, D, O, or X) after an initial circumflex (^)
    as a delimiter. Note that ^B, ^D, ^O, and ^X are used as radix
    control operators rather than argument delimiters. ^A is used
    as the ASCII operator and ^C is used as the complement operator.
    To pass an angle bracket as part of a string, you can use the
    circumflex form of the delimiter.

    The following are examples of delimited macro arguments:

    <HAVE THE SUPPLIES RUN OUT?>
    <LAB:    CLR     R4>

    "A quoted literal is taken as a single parameter value."

    ^%ARGUMENT IS <LAST,FIRST> FOR CALL%
    ^?EXPRESSION IS <5+3>*<4+2>?

    In the last two examples, the initial circumflex indicates
    that the percent sign (%)  and question mark (?) are the
    delimiters. Note that only the left-hand delimiter is preceded
    by a circumflex.

    The assembler interprets a string argument enclosed by delimiters
    as one actual argument and associates it with one formal
    argument. If a string argument that contains separator characters
    is not enclosed by delimiters, the assembler interprets it as
    successive actual arguments and associates it with successive
    formal arguments.

    For example, the following macro definition has one formal
    argument:

    .MACRO DOUBLE_ASCII STRNG
    .ASCII  "STRNG"
    .ASCII  "STRNG"
    .ENDM   DOUBLE_ASCII

    The following two macro calls demonstrate actual arguments with
    and without delimiters:

    DOUBLE_ASCII <A B C D E>
    .ASCII  "A B C D E"
    .ASCII  "A B C D E"

    DOUBLE_ASCII  A B C D E
    %MACRO64-E-TOOMNYARGS, Too many arguments in macro call

    Note that the assembler interprets the second macro call as
    having five actual arguments instead of one actual argument with
    spaces.

    When a macro is called, the assembler removes normal delimiters
    around a string before associating it with the formal arguments.
    However, a quoted literal within double quotes is treated as a
    single token and retains its double quote delimiters.

    If a string contains a semicolon (;),  the string must be
    enclosed by delimiters; otherwise, the semicolon will mark the
    start of the comment field. Further, if the string contains a
    semicolon, you cannot continue the line unless the string is a
    quoted literal.

    You can nest macro invocations, that is, a macro definition can
    contain a call to another macro. If, within a macro definition,
    another macro is called and is passed a string argument, you must
    delimit the argument so that the entire string is passed to the
    second macro as one argument.

    The following macro definition contains a call to the DOUBLE_
    ASCII macro defined earlier:

            .MACRO     CNTDA LAB1,LAB2,STR_ARG
    LAB1:   .BYTE      LAB2-LAB1-1            ; Length of 2*string
              DOUBLE_ASCII   <STR_ARG>
       ; Call DOUBLE_ASCII macro
    LAB2:
            .ENDM    CNTDA

    Note that the argument in the call to DOUBLE_ASCII is enclosed in
    angle brackets even though it does not contain any separator
    characters. The argument is thus delimited because it is a
    formal argument in the definition of the macro CNTDA and will
    be replaced with an actual argument that may contain separator
    characters.

    The following example calls the macro CNTDA, which in turn calls
    the macro DOUBLE_ASCII:

    CNTDA  ST,FIN,<LEARN YOUR ABC'S>
    ST:     .BYTE   FIN-ST-1
            DOUBLE_ASCII <LEARN YOUR ABC'S>
            .ASCII  "LEARN YOUR ABC'S"
            .ASCII  "LEARN YOUR ABC'S"
    FIN:

    In addition to nested macro invocations, you can
    also nest macro definitions. That is, you can define
    one macro within another. In this example, the
    INNER_MACRO_DEF macro is not defined until the OUTER_MACRO_DEF
    macro is invoked and expanded:

            .macro OUTER_MACRO_DEF
                .macro INNER_MACRO_DEF
                    ...
                .endm INNER_MACRO_DEF
            .endm OUTER_MACRO_DEF

    You can use this capability to define a macro that redefines
    itself:

            .macro SETUP
                A = 75
                B = 92
                C = 87
                D = 0
                E = -12
                F = 42
                .macro SETUP
                    ; Setup is done - do nothing
                .endm SETUP
            .endm SETUP

    In this example, the SETUP macro defines a number of assembly
    constants. After the SETUP macro has been expanded once, its
    work is done. Subsequent expansions of the setup macro need not
    take any action. Therefore, the SETUP macro redefines itself
    to a macro whose expansion includes only a comment statement.
    As described elsewhere, when you redefine a macro, the original
    version of the macro is automatically deleted. If that macro is
    currently expanding (as would be the case with the previous SETUP
    macro), the new definition is immediately associated with the
    macro name. However, the old definition is retained until all
    pending expansions complete normally. When all pending expansions
    complete, the old version of the macro is deleted. Thus, the
    SETUP macro may be invoked any number of times in the assembly
    unit. Since the first expansion redefines itself, the expansion
    of the SETUP macro has no effect other than the first time it is
    invoked.

    Another way to pass string arguments in nested macros is to
    enclose the macro argument in nested delimiters.

                                   NOTE

       Each time you use the delimited argument in a macro call,
       the assembler removes the outermost pair of delimiters
       before associating it with the formal argument. This method
       is not recommended because it requires that you know how
       deeply a macro is nested.

    The following macro definition also contains a call to the
    DOUBLE_ASCII macro:

           .MACRO  CNTDA2 LAB1,LAB2,STR_ARG
    LAB1:  .BYTE   LAB2-LAB1-1             ; Length of 2*string
           DOUBLE_ASCII  STR_ARG           ; Call DOUBLE_ASCII macro
    LAB2:
           .ENDM   CNTDA2

    Note that the argument in the call to DOUBLE_ASCII is not
    enclosed in angle brackets.

    The following example calls the macro CNTDA2:

           CNTDA2 BEG,TERM,<<MIND YOUR P'S AND Q'S>>
    BEG:   .BYTE   TERM-BEG-1              ; Length of 2*string
           DOUBLE_ASCII  <MIND YOUR P'S AND Q'S>
           ; Call DOUBLE_ASCII macro
           .ASCII  "MIND YOUR P'S AND Q'S"
           .ASCII  "MIND YOUR P'S AND Q'S"
    TERM:

    Note that even though the call to DOUBLE_ASCII in the macro
    definition is not enclosed in delimiters, the call in the
    expansion is enclosed because the call to CNTDA2 contains nested
    delimiters around the string argument.

1.15.5  –  Argument Concatentation

    The argument concatenation operator, the apostrophe ('),
    concatenates a macro argument with constant text or another
    argument. Apostrophes can either precede or follow a formal
    argument name in the macro source.

    If an apostrophe precedes the argument name, the text before
    the apostrophe is concatenated with the actual argument when
    the macro is expanded. For example, if ARG1 is a formal argument
    associated with the actual argument TEST, then ABCDE'ARG1 is
    expanded to ABCDETEST.

    If an apostrophe follows the formal argument name, the actual
    argument is concatenated with the text that follows the
    apostrophe when the macro is expanded. The apostrophe itself
    does not appear in the macro expansion.

    To concatenate two arguments, separate the two formal arguments
    with two successive apostrophes. Two apostrophes are needed
    because each concatenation operation discards an apostrophe from
    the expansion.

    An example of a macro definition that uses concatenation follows:

            .MACRO CONCAT   A,B
    A''B:   .WORD 0
            .ENDM CONCAT

    Note that two successive apostrophes are used when concatenating
    the two formal arguments A and B.

    An example of a macro call and expansion follows:

            CONCAT  X,Y
    XY:     .WORD 0

1.15.6  –  Passing Numeric Values of Symbols

    When a symbol is specified as an actual argument, the name of
    the symbol, not the numeric value of the symbol, is passed to
    the macro. You can pass the value of the symbol by inserting a
    backslash (\) before the symbol in the macro call. The assembler
    passes the characters representing the decimal value of the
    symbol to the macro. For example, if the symbol COUNT has a value
    of 2 and the actual argument specified is \COUNT, the assembler
    passes the string 2 to the macro; it does not pass the name of
    the symbol, COUNT.

    Passing numeric values of symbols is especially useful with the
    apostrophe (')  concatenation operator for creating new symbols.

    An example of a macro definition for passing numeric values of
    symbols follows:

            .MACRO WORD n
    WORD'n: .WORD n
            .ENDM WORD

    The following example shows a possible call and expansion of the
    macro previously defined:

           X = 1       ; Start counting at 1
           WORD \X
    WORD1: .WORD 1

1.15.7  –  Created Temporary Labels

    Temporary labels are often very useful in macros. You can create
    a macro definition that specifies temporary labels within it,
    but these temporary labels might be duplicated elsewhere in the
    temporary label block, possibly causing errors. However, the
    assembler can create temporary labels in the macro expansion that
    will not conflict with other temporary labels. These labels are
    called created temporary labels.

    Created temporary labels range from 30000$ to 65535$. Each time
    the assembler creates a new temporary label, it increments the
    numeric part of the label name by 1. Consequently, no user-
    defined temporary labels should be in the range of 30000$ to
    65535$.

    A created temporary label is specified by a question mark (?)  in
    front of the formal argument name. When the macro is expanded,
    the assembler creates a new temporary label if the corresponding
    actual argument is blank. If the corresponding actual argument is
    specified, the assembler substitutes the actual argument for the
    formal argument.

    The following example is a macro definition specifying a created
    temporary label:

            .MACRO  POSITIVE        ARG1,?L1
            BGE     ARG1,L1
            NEGQ    ARG1,ARG1
    L1:    .ENDM    POSITIVE

    The following three calls and expansions of the macro defined
    previously show both created temporary labels and a user-defined
    temporary label:

            POSITIVE  R0
            BGE     R0,30000$
            NEGQ    R0,R0
    30000$:

            POSITIVE  R5
            BGE     R5,30001$
            NEGQ    R5,R5
    30001$:

            POSITIVE  R7,10$
            BGE     R7,10$
            NEGQ    R7,R7
    10$:

1.16  –  Program Sections

    MACRO-64 allows you to divide your program into sections called
    psects using the .PSECT directive. Psects are useful for
    organizing your program, and for low-level control over the
    linking process. More importantly, each psect falls into one
    of the following three categories:

    o  CODE psects can contain only instructions. They contain no
       data. Psects in this category have the EXE and NOMIX psect
       attributes.

    o  DATA psects can contain only data. They contain no
       instructions. Psects in this category have the NOEXE and NOMIX
       attributes.

    o  MIXED psects can contain instructions, data, or both. Psects
       in this category have the MIX attribute. In addition, they may
       have either the EXE or NOEXE attribute.

    MACRO-64 categorizes psects because:

    o  There is a significant performance compromise associated
       with mixing instructions and data in the same program section
       within the Alpha architecture. This is because the Alpha
       architecture typically maintains separate memory caches
       for instructions and data.

    o  If you mix instructions and data, it is likely that
       instructions will migrate into the data cache and that
       data will migrate into the instruction cache. While this
       situation still yields correct results, the benefits of the
       instruction and data caches are diminished. Placing data in
       the instruction stream can also have detrimental effects on
       the instruction pipeline and the multiple instruction-issue
       capabilities that most Alpha systems employ.

    Since a code psect can contain only instructions and cannot
    contain arbitrary data, instructions you place in a CODE psect
    can be analyzed by the assembler optimizer and by the symbolic
    debugger. Since a mixed psect can contain arbitrary data as well
    as instructions, instructions you place in a mixed psect are not
    analyzed by the assembler optimizer or by the symbolic debugger.
    Instead, the assembler internally converts instructions in a
    mixed psect to an equivalent data representation.

    Because of the compromises associated with mixed psects, by
    default the assembler creates psects with the NOMIX psect
    attribute. If you need to place data in a psect that has the
    EXE attribute, or if you need to place instructions in a psect
    that has the NOEXE attribute, you must also specify the MIX
    attribute in the psect's definition. Note that unlike the other
    psect attributes, the MIX psect attribute is an assembly-time
    attribute. The MIX psect attribute does not appear in the psect
    definitions in your object module and it does not affect the
    linking process.

    You can use all assembler directives and instructions within
    mixed psects. While many assembler directives can be used
    within both code and data psects, data-storage directives
    cannot be used in code psects and instructions and instruction-
    storage directives cannot be used in data psects. If you place
    instructions or instruction-storage directives in a data psect,
    or if you place data-storage directives in a code psect, the
    assembler issues a diagnostic message.

    In summary, code psects may contain only storage for instructions
    and storage created by instruction directives. Data psects may
    contain only storage created by data directives. Mixed psects may
    contain either storage for instructions or data or both. There
    are no restrictions on the use of data directives in a mixed
    psect. However, the assembler converts instructions you place in
    a mixed psect to a data representation. Therefore, instructions
    in a mixed psect are not analyzed as instructions by either the
    assembler optimizer or the symbolic debugger.

1.17  –  Automatic Data Alignment

    The assembler can optionally align your data on natural
    boundaries. While disabled by default, this feature is
    enabled with the /ALIGNMENT=DATA command-line qualifier or the
    .ENABLE ALIGN_DATA directive. A natural boundary is an address
    that is evenly divisibly by the size of the scalar data type
    being accessed. The MACRO-64 automatic data alignment feature can
    automatically align word, longword, quadword, and octaword data
    to a natural boundary. Accessing data on a natural boundary can
    be significantly faster than an unaligned access.

    When the MACRO-64 automatic data alignment feature is enabled,
    the assembler automatically aligns all data-storage directives to
    a natural boundary. To achieve alignment, the assembler pads
    with 0 bytes as necessary before allocating the storage for
    the data directive. Labels that occur before the data-storage
    directive are defined to be the address of the data storage after
    alignment.

1.18  –  Directives

    The general assembler directives provide facilities for
    performing eleven types of functions. Some directives are only
    applicable within data psects (psects with the NOEXE and NOMIX
    attributes). Other directives are only applicable within code
    psects (psects with the EXE and NOMIX attributes). All directives
    are applicable within psects that contain either data and code,
    or both (psects with the MIX attribute). For information on the
    MIX assembly-time psect and any associated restrictions, see the
    description of the .PSECT directive in this chapter.

    The following table discusses these types of functions and their
    directives.

1.18.1  –  .ADDRESS

    Address storage directive

    Format

      .ADDRESS  address-list

1.18.1.1  –  Parameter

 address-list

    A list of symbols or expressions, separated by commas (,),  which
    MACRO-64 interprets as addresses.

1.18.1.2  –  Description

    .ADDRESS stores successive quadwords (8 bytes) containing
    addresses in the object module. Digital recommends that you use
    .ADDRESS rather than .QUAD for storing address data to provide
    additional information to the linker.

1.18.1.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current (64-bit) boundary before allocating storage.

    o  You can define a 32-bit address item using macros and the
       .LONG directive. For example:

       .macro address_32 item
           .long item
       .endm address_32

1.18.1.4  –  Example

        .ADDRESS A,B,C

1.18.2  –  .ALIGN

    Location counter alignment directive

    Format

      .ALIGN  integer [,fill-specifier]

      .ALIGN  keyword [,fill-specifier]

1.18.2.1  –  Parameters

 integer

    An integer in the range 0 to 9. The location counter is aligned
    at an address that is the value of 2 raised to the power of the
    integer.

 keyword

    One of five keywords that specify the alignment boundary. The
    location counter is aligned to an address that is the next
    multiple of the following values:

    Keyword  Size (in Bytes)

    BYTE     20= 1
    WORD     21= 2
    LONG     22= 4
    QUAD     23= 8
    OCTA     24= 16

 [,fill-specifier]

    Any expression that resolves to an assembly-time integer value
    containing no forward references. The filling is done per byte,
    regardless of the alignment. If the value you specify is not in
    the range of 0 to 255, the assembler issues a diagnostic message
    and truncates the value.

1.18.2.2  –  Description

    .ALIGN aligns the location counter to the boundary specified by
    either an integer or a keyword.

1.18.2.3  –  Notes

    o  If .ALIGN is specified in a psect with the EXE and NOMIX
       attributes, the fill-specifier is ignored. The assembler
       aligns the psect to the requested boundary padding with NOP
       or FNOP instructions.

    o  If .ALIGN is specified in a psect that does not have the EXE
       attribute and a fill-specifier is specified, the assembler
       aligns the psect to the requested boundary padding, with byte
       locations using the fill-specifier as the initial value for
       the generated byte padding.

    o  If the fill-specifier expression encounters a value that is
       too large to fit in a boundary specified by the keyword, the
       data is truncated and an informational message is displayed.

    o  The alignment that you specify in .ALIGN cannot exceed the
       alignment of the psect in which the alignment is attempted
       (see the description of .PSECT). For example, if you are using
       the BYTE psect alignment and you specify .ALIGN with a word or
       larger alignment, the assembler displays an error message.

1.18.2.4  –  Examples

      Example 1

           .PSECT A,QUAD  ; Begin at quadword
        B::.BYTE 4        ; Data is byte
           .ALIGN QUAD    ; Next data is
        C::.WORD 6        ; also quadword aligned
      Example 2

           .PSECT A,EXE,NOMIX,OCTA
        L1::TRAPB:        ; offset 0
           .ALIGN OCTA    ; NOP padding bytes 4..15
            TRAPB:         ; offset 16
      Example 3

           .PSECT A,NOEXE,NOMIX,OCTA
        L1:.WORD 5        ; byte offset 0..1
           .ALIGN QUAD,2  ; fill specifier initial value
                          ; of 2 for bytes 2..7
           .WORD 6        ; byte offsets 8..9

1.18.3  –  .ASCIC

    Counted ASCII string storage directive

    Format

      .ASCIC  quoted-literal

1.18.3.1  –  Parameter

 quoted-literal

    An ASCII string delimited with double quotes.

1.18.3.2  –  Description

    .ASCIC performs the same function as .ASCII, except that .ASCIC
    inserts a count byte before the string data. The count byte
    contains the length of the string in bytes. The length given
    includes any bytes of nonprintable characters specified using the
    backslash (\) operator, but excludes the count byte.

    .ASCIC is useful in copying text because the count indicates the
    length of the text to be copied.

1.18.3.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  This directive also accepts VAX MACRO syntax.

1.18.3.4  –  Example

        .ASCIC "MY STRING"  ; In the listing, this becomes:
                            ; .BYTE 9
                            ; .ASCII \MY STRING\

1.18.4  –  .ASCID

    String-descriptor ASCII string storage directive

    Format

      .ASCID  quoted-literal

1.18.4.1  –  Parameter

 quoted-literal

    An ASCII string delimited with double quotes.

1.18.4.2  –  Description

    .ASCID performs the same function as the .ASCII directive, except
    that .ASCID inserts a string descriptor before the string data.
    The descriptor format is identical to that defined for OpenVMS
    Alpha and OpenVMS VAX. The string descriptor has the following
    format:

1.18.4.3  –  Notes

    o  String descriptors are used in calling certain system
       routines.

    o  The string-length field is two bytes in size.

    o  Descriptor information (2 bytes) is always set to ^X010E.

    o  The pointer field is a 32-bit pointer to the string (4 bytes).

    o  If natural alignment is enabled (using .ENABLE ALIGN_DATA),
       the descriptor is quadword aligned. This allows you to access
       the entire descriptor (2 data words and a longword address) on
       a quadword boundary.

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  This directive also accepts VAX MACRO syntax. See the
       VAX MACRO and Instruction Set Reference Manual for details.

1.18.4.4  –  Examples

      Example 1
        .DESCR1:   .ASCID "ARGUMENT FOR CALL"     ; String descriptor
      Example 2
        .DESCR2:   .ASCID "SECOND ARGUMENT"  ; Another string descriptor

1.18.5  –  .ASCII

    ASCII string storage directive

    Format

      .ASCII  quoted-literal

1.18.5.1  –  Parameters

 quoted-literal

    An ASCII string delimited with double quotes.

1.18.5.2  –  Description

    .ASCII stores the ASCII value of each character in the ASCII
    string or the value of each byte expression in the next available
    byte.

1.18.5.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  This directive also accepts VAX MACRO syntax. See the
       VAX MACRO and Instruction Set Reference Manual for details.

1.18.5.4  –  Examples

        .ASCII "MY STRING"

1.18.6  –  .ASCIZ

    Zero-terminated ASCII string storage directive

    Format

      .ASCIZ  quoted-literal

1.18.6.1  –  Parameter

 quoted-literal

    An ASCII string delimited with double quotes.

1.18.6.2  –  Description

    .ASCIZ performs the same function as .ASCII, except that .ASCIZ
    appends a null byte as the final character of the string. When a
    list or text string is created with an .ASCIZ directive, you need
    only perform a search for the null character in the last byte to
    determine the end of the string.

1.18.6.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  This directive also accepts VAX MACRO syntax. See the
       VAX MACRO and Instruction Set Reference Manual for details.

1.18.6.4  –  Example

        .ASCIZ "MY STRING"    ; Equivalent to
                              ; .ASCII "MY STRING \x00"

1.18.7  –  .BASE

    Base register directive

    Format

      .BASE  Rn [,base_expression]

1.18.7.1  –  Parameters

 Rn

    One of the base registers, R0 through R30, FP, and SP.

 base_expression

    The base address, which is optional, and can be one of the
    following:

    o  An absolute expression

    o  A relocatable expression

    o  An external expression

    An expression must not contain forward references or implicit
    external symbols. An implicitly defined external symbol is a
    symbol that the assembler defaults to an external symbol. This
    occurs when the assembler encounters references to a symbol, but
    does not encounter a definition for the symbol or an .EXTERNAL
    directive that declares the symbol.

1.18.7.2  –  Description

    The .BASE directive is used to inform the assembler that a
    specified base register contains a specified base address. Later
    in your program, the assembler allows you to implicitly reference
    the specified base register. When the assembler knows which
    base addresses are stored in one or more base registers, it can
    convert an expression to an offset from one of the base registers
    previously specified in a .BASE directive. .BASE provides a
    convenient and more readable shorthand for accessing memory and
    constant values using base registers. .BASE also makes it easier
    for you to change your register assignments if you later modify
    your code.

    The base expression is optional. If the base expression is
    specified, this base address value is assumed by the assembler
    to be in the specified register, Rn. If the base expression is
    omitted, the contents of the specified base register, Rn, is
    considered undefined until a new base expression is associated
    with the base register.

    R31 is defined to always contain 0, according to the architecture
    definition. Therefore, R31 is known to be a predefined base
    register containing 0. For every assembly, the assembler assumes
    the following statement:

        .BASE R31, 0

    Because the contents of R31 cannot change, you cannot specify a
    base address for R31.

    You can use the .BASE directive to implicitly reference base
    registers. You can also automatically compute offsets from a base
    address known to be in a register to a base address you use in an
    instruction argument.

    Most of the memory format Alpha instructions are defined
    such that one of their arguments must have a base register and
    an offset. If the assembler encounters only an expression with
    no base register, the assembler attempts to find a base register
    that contains a base address or constant within a 16-bit signed
    offset of the value of the expression. If it finds such a base
    register, the assembler computes an offset that, when added to
    the value of the base register, results in a value equal to the
    expression specified in the instruction argument.

1.18.7.3  –  Examples

      Example 1
        .EXTERNAL COMM_AREA       1
        .BASE R1, COMM_AREA       2
        CURR_LINE       = COMM_AREA + 0
        CURR_COLUMN     = COMM_AREA + 4
        CURR_MODE       = COMM_AREA + 8
        LDA     R4, 17                  ; LDA R4, 17(R31)  3
        LDL     R2, CURR_LINE           ; LDL R2, 0(R1)    4
        LDL     R3, CURR_COLUMN         ; LDL R3, 4(R1)
        STL     R4, CURR_MODE           ; STL R4, 8(R1)

      1  This statement declares an external symbol, COMM_AREA.
         COMM_AREA is a global symbol that represents the base
         address of a three-longword communication area that is used
         by different routines in the program.

      2  This statement informs the assembler that base register R1
         contains the base address, COMM_AREA, of this communication
         area. The next three statements define variables within the
         communication area.

      3  The first instruction shows how you can load registers
         with constant values in the range -32,768 to +32,767 by
         implicitly using R31 as the base register.

      4  The last three statements show how the .BASE directive
         allows you to implicitly reference base registers
         and automatically compute offsets. In each of these
         instructions, the second argument is defined to require
         an offset and a base register.

         Since no base register is specified, the assembler attempts
         to imply the base register and compute the offset based upon
         information given in previous .BASE directives.

         In the last three instructions, the address argument is
         within -32,768 to +32,767 of the base address known to
         be in R1 (that is, COMM_AREA). Therefore, R1 is selected
         as the base register. The assembler also computes the
         correct offset from the base address known to be in R1 to
         the address specified in the instruction argument.

      Example 2
      The assembler performs a sequential search through the list
      of possible base registers, R0 through R31. It uses the first
      definition possible if multiple base registers are valid. For
      example:

             .BASE R5, 300
             :
             LDQ  R10, 100

      The assembler outputs the LDQ instruction as follows:

             LDQ  R10, -200(R5)

      Both R31 and R5 are defined as base registers that can be used
      in constructing the instruction argument. R31 always contains
      0. In this example, R5 is also known to contain the constant
      300. The assembler uses the first base register, starting at
      R0 and progressing to R31, which provides a known value within
      -32,768 to +32,767 of the specified argument value. Since the
      assembler considers R5 before it considers R31, R5 is used
      rather than R31.

1.18.8  –  .BEGIN EXACT

    Exact instruction block directive

    Format

      .BEGIN_EXACT

1.18.8.1  –  Description

    An exact instruction block suppresses code optimizations
    (SCHEDULE and PEEPHOLE) regardless if these optimizations are
    enabled for the assembly unit. Unlike .ENABLE and .DISABLE, which
    can be used to enable or disable specific optimizations for the
    entire assembly unit, .BEGIN_EXACT and .END_EXACT allow you to
    suppress optimization for a specified range of instructions.
    Instructions outside the specified range remain subject to any
    optimizations you have enabled.

1.18.8.2  –  Notes

    o  This directive cannot appear in a psect with the NOEXE and
       NOMIX attributes.

    o  Although this directive is accepted by the assembler in a
       psect with the MIX attribute, it has no effect in these psects
       since no code optimizations are in affect for MIX psects.

    o  .BEGIN_EXACT must be paired with a matching .END_EXACT to
       close the exact instruction block.

    o  .BEGIN_EXACT and .END_EXACT instruction blocks can be
       nested. The outermost level of the .BEGIN_EXACT and matching
       .END_EXACT directives delimit the actual exact instruction
       block from which code optimizations are suppressed. Nesting
       .BEGIN_EXACT and .END_EXACT instruction blocks can be useful
       in macro definitions where the macro expansion requires an
       exact instruction sequence. Nested .BEGIN_EXACT and .END_EXACT
       instruction blocks allow a macro to be invoked both from
       within and without the exact instruction block.

    o  .BEGIN_EXACT does not affect automatic alignment. Automatic
       alignment is enabled with the .ENABLE ALIGN_CODE and .ENABLE
       ALIGN_DATA directives or with the /ALIGN=(CODE,DATA) command-
       line qualifier.

1.18.8.3  –  Examples

      The following example shows an instruction sequence prior to
      optimization:

             addf f7, f8, f9     ; 1
             addf f2, f3, f4     ; 2
             addl r5, r6, r7     ; 3
             addl r8, r9, r10    ; 4

      The assembler optimizes the previous example to a sequence
      similar to the following instruction sequence:

                     :
             addf f7, f8, f9     ; 1
             addl r5, r6, r7     ; 3
             addf f2, f3, f4     ; 2
             addl r8, r9, r10    ; 4
                     :

      If you choose to suppress optimization in the previous example,
      enclose the four instructions with the .BEGIN_EXACT and
      .END_EXACT directives, as shown in the following example:

             .BEGIN_EXACT
             addf f7, f8, f9     ; 1
             addf f2, f3, f4     ; 2
             addl r5, r6, r7     ; 3
             addl r8, r9, r10    ; 4
             .END_EXACT

1.18.9  –  .BLKx

    Block storage allocation directives

    Format

      .BLKA  [expression]

      .BLKB  [expression]

      .BLKD  [expression]

      .BLKF  [expression]

      .BLKG  [expression]

      .BLKL  [expression]

      .BLKO  [expression]

      .BLKQ  [expression]

      .BLKS  [expression]

      .BLKT  [expression]

      .BLKW  [expression]

1.18.9.1  –  Parameter

 expression

    An integer expression specifying the amount of storage to be
    allocated. All the symbols in the expression must be defined
    at the current point in the assembly and the expression must be
    an absolute expression. If the expression is omitted, a default
    value of 1 is assumed.

1.18.9.2  –  Description

    MACRO-64 has the following 11 block storage directives:

    DirectivReserves Storage for:  Bytes Allocated

    .BLKA   Addresses (quadwords)  8 * value of expression
    .BLKB   Byte data              Value of expression
    .BLKD   Double-precision       8 * value of expression
            floating-point data
            (quadwords)
    .BLKF   Single-precision       4 * value of expression
            floating-point data
            (longwords)
    .BLKG   G_floating data        8 * value of expression
            (quadwords)
    .BLKL   Longword data          4 * value of expression
    .BLKO   Octaword data          16 * value of expression
    .BLKQ   Quadword data          8 * value of expression
    .BLKS   S_floating data        4 * value of expression
            (longwords)
    .BLKT   T_floating data        8 * value of expression
            (quadwords)
    .BLKW   Word data              2 * value of expression

    Each directive reserves storage for a different data type. The
    value of the expression determines the number of data items for
    which MACRO-64 reserves storage. For example, .BLKL 4 reserves
    storage for 4 longwords of data and .BLKB 2 reserves storage for
    2 bytes of data. The total number of bytes reserved is equal to
    the length of the data type times the value of the expression.

1.18.9.3  –  Notes

    o  If automatic data alignment is enabled, the .BLKx directives
       align the current location counter to one of the alignments
       listed in the following table:

       DirectiAlignment

       .BLKA  Quadword (64-bit) boundary
       .BLKB  None
       .BLKD  Quadword (64-bit) boundary
       .BLKF  Longword (32-bit) boundary
       .BLKG  Quadword (64-bit) boundary
       .BLKL  Longword (32-bit) boundary
       .BLKO  Octaword (128-bit) boundary
       .BLKQ  Quadword (64-bit) boundary
       .BLKS  Longword (32-bit) boundary
       .BLKT  Quadword (64-bit) boundary
       .BLKW  Word (16-bit) boundary

    o  You can only use these directives within psects having either
       the NOEXE or MIX attributes.

1.18.9.4  –  Example

            .PSECT A,NOEXE
        B:: .BLKW  10             ; 10 words (20 bytes) of storage
            .BLKQ   5             ; 5 quadwords (40 bytes) of storage

            .BLKW                 ; 1 word (2 bytes) of storage

1.18.10  –  .BYTE

    Byte storage directive

    Format

      .BYTE  expression-list

1.18.10.1  –  Parameter

 expression-list

    One or more expressions separated by commas. Each expression
    is first evaluated as a quadword expression; then the value of
    the expression is truncated to fit in a byte. The value of each
    expression should be in the range 0 to 255 for unsigned data or
    in the range -128 to +127 for signed data.

1.18.10.2  –  Description

    .BYTE generates successive bytes of binary data in the object
    module.

1.18.10.3  –  Notes

    o  The assembler displays a warning message if the expression is
       outside the range -128 to -255.

    o  The assembler will truncate the most significant bits of an
       integer or external value that is too large to store in eight
       bits.

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

1.18.10.4  –  Example

        A:      .BYTE   5       ; Stores 5 in a byte

1.18.11  –  .CODE ADDRESS

    Code address storage directive

    Format

      .CODE_ADDRESS  name-list

1.18.11.1  –  Parameter

 name-list

    A list of symbols separated by commas. These symbols should
    reference either a procedure descriptor name, such as a routine
    name, or an externally defined procedure descriptor.

1.18.11.2  –  Description

    .CODE_ADDRESS causes the code addresses of the specified
    identifiers to be placed at the current psect and current
    location counter. The specified identifier should reference a
    procedure descriptor defined in the image.

1.18.11.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a quadword (64-bit) boundary
       before allocating storage.

1.18.11.4  –  Example

        .CODE_ADDRESS A

1.18.12  –  .D FLOATING

    Floating-point storage directive

    Format

      .D_FLOATING  floating-point-number-list

      .DOUBLE  floating-point-number-list

1.18.12.1  –  Parameter

 floating-point-number-list

    A comma-separated list of floating-point constants. The constants
    cannot contain any operators except unary plus or unary minus.

1.18.12.2  –  Description

    .D_FLOATING evaluates the specified floating-point constants and
    stores the results in the object module. .D_FLOATING generates
    64-bit, double-precision floating-point data (1 bit of sign, 8
    bits of exponent, and 55 bits of fraction). See the description
    of .F_FLOATING for information on storing single-precision
    floating-point numbers and the descriptions of .G_FLOATING, .S_
    FLOATING, and .T_FLOATING for descriptions of other floating-
    point constants.

1.18.12.3  –  Notes

    o  Double-precision floating-point numbers are always rounded.

    o  The alternate form of .D_FLOATING is .DOUBLE.

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a quadword (64-bit) boundary
       before allocating storage.

    o  The Alpha architecture supports only conversion operations
       for the
       D floating-point data type.

1.18.12.4  –  Example

        .D_FLOATING  3.1E+02

1.18.13  –  .DEFINE FREG

    Define floating-point register symbol directive

    Format

      .DEFINE_FREG  regsym regnum

1.18.13.1  –  Parameters

 regsym

    A MACRO-64 identifier.

 regnum

    An assembly-time expression or a currently defined register
    symbol.

1.18.13.2  –  Description

    The identifier you specify as the first argument to .DEFINE_FREG
    becomes a floating-point register symbol. Thereafter, it cannot
    be used as a MACRO-64 identifier. Specifically, the user-defined
    register symbol is only allowed where a register is allowed. In
    this sense, the user-defined register symbol is reserved until
    the end of the assembly unit or until you delete its definition
    (see .UNDEFINE_REG), whichever occurs first.

    The second argument to .DEFINE_FREG can be either an integer
    expression or a currently defined floating-point register symbol.
    An integer expression indicates the register number to assign
    to the register symbol. The expression can contain no forward
    or external references and must be in the range of 0 to 31.
    Alternatively, you can define a register symbol in terms of
    another currently defined register symbol. A currently defined
    register symbol is a predefined register symbol or a register
    symbol that you have previously defined. In this case, the new
    register symbol you specify with the first argument receives the
    current value of the register symbol you specify with the second
    argument.

1.18.13.3  –  Notes

    o  You cannot define a floating-point register in terms of an
       integer register and vice versa.

    o  You cannot redefine a currently defined register symbol with a
       different register number. To redefine a register symbol, you
       must first delete the old definition with the .UNDEFINE_REG
       directive.

1.18.13.4  –  Example

            .DEFINE_IREG A0     16      ; A0 is integer register 16
            .DEFINE_IREG A1     R17     ; A1 is integer register 17,
                                        ;  defined in terms of the
                                        ;  predefined R17 register symbol
            .DEFINE_IREG PTR    A0      ; PTR is integer register 16,
                                        ;  defined in terms of the
                                        ;  previously-defined A0 register
                                        ;  symbol
            .DEFINE_FREG $F0    0       ; $F0 is floating register 0
            .DEFINE_FREG $F1    F1      ; $F1 is floating register 1,
                                        ;  defined in terms of the
                                        ;  predefined F1 register symbol
            .DEFINE_FREG RADIUS $F1     ; RADIUS is floating register 1,
                                        ;  defined in terms of the
                                        ;  previously defined $F1
                                        ;  register symbol
            .DEFINE_IREG X1     R5      ; X1 is integer register 5,
                                        ;  defined in terms of the
                                        ;  predefined R5 register symbol
            .DEFINE_IREG X1     5       ; 2nd definition is the same
                                        ;  value, so no diagnostic
                                        ;  results
            .DEFINE_IREG X1     7       ; Warning: redefinition with a
                                        ;  different value
            .DEFINE_IREG X2     F5      ; Error: cannot define an integer
                                        ;  register in terms of a
                                        ;  floating register

            LDQ         R1, (PTR)       ; LDQ R1, (R16)
            LDG         RADIUS, (A1)    ; LDG F1, (R17)

1.18.14  –  .DEFINE IREG

    Define integer register symbol directive

    Format

      .DEFINE_IREG  regsym regnum

1.18.14.1  –  Parameters

 regsym

    A MACRO-64 identifier.

 regnum

    An assembly-time expression or a currently defined register
    symbol.

1.18.14.2  –  Description

    The identifier you specify as the first argument to .DEFINE_IREG
    becomes an integer register symbol. Thereafter, it cannot be
    used as a MACRO-64 identifier. Specifically, the user-defined
    register symbol is only allowed where a register is allowed. In
    this sense, the user-defined register symbol is reserved until
    the end of the assembly unit or until you delete its definition
    (see .UNDEFINE_REG), whichever occurs first.

    The second argument to .DEFINE_IREG can be either an integer
    expression or a currently defined integer register symbol.
    An integer expression indicates the register number to assign
    to the register symbol. The expression can contain no forward
    or external references and must be in the range of 0 to 31.
    Alternatively, you can define a register symbol in terms of
    another, currently defined register symbol. A currently defined
    register symbol is a predefined register symbol or a register
    symbol that you have previously defined. In this case, the new
    register symbol you specify with the first argument receives the
    current value of the register symbol you specify with the second
    argument.

1.18.14.3  –  Notes

    o  You cannot define an integer register in terms of a floating-
       point register and vice versa.

    o  You cannot redefine a currently defined register symbol with a
       different register number. To redefine a register symbol, you
       must first delete the old definition with the .UNDEFINE_REG
       directive.

1.18.14.4  –  Example

      Refer to the example in .DEFINE_FREG.

1.18.15  –  .DISABLE

    Disable assembler functions directive

    Format

      .DISABLE  argument-list

      .DSABL  argument-list

1.18.15.1  –  Parameter

 argument-list

    One or more of the symbolic arguments listed in the description
    of .ENABLE. You can use either the long or the short form of the
    symbolic arguments. If you specify multiple arguments, separate
    them by commas, spaces, or tabs.

1.18.15.2  –  Description

    .DISABLE disables the specified assembler function. See the
    description of .ENABLE for more information.

    The alternate form of .DISABLE is .DSABL.

1.18.16  –  .ELSE

    Conditional assembly block directive

    Format

      .ELSE

1.18.16.1  –  Description

    A conditional assembly block is a series of source statements
    that is assembled only if a certain condition is met. .IF starts
    the conditional block and .ENDC ends the conditional block; each
    .IF must have a corresponding .ENDC. The .IF directive contains
    a condition test and one or two arguments. The condition test
    specified is applied to the arguments. If the test is met, all
    MACRO-64 statements between .IF and .ELSE are assembled. If
    the test is not met, the statements between .ELSE and .ENDC are
    assembled.

    Conditional blocks can be nested; that is, a conditional block
    can be inside another conditional block. In this case, the
    statements in the inner conditional block are assembled only
    if the condition is met for both the outer and inner block. For
    more information, see the description of the .IF directive.

1.18.16.2  –  Notes

    o  You cannot use the .ELSE directive in the same conditional
       block as the .IF_x directive.

    o  The .ELSE directive is similar to the .IF_FALSE directive.
       However, you can only use .ELSE once within a conditional
       block. .IF_FALSE can be used any number of times in a
       conditional block.

1.18.16.3  –  Example

      Here is an example of a conditional assembly directive:

        .IF EQUAL  ALPHA+1        ; Assemble block if ALPHA+1=0.
          .
          .
        .ELSE                     ; Assemble when .IF=false.
          .
          .
        .ENDC

1.18.17  –  .ENABLE

    Enable assembler functions directive

    Format

      .ENABLE  argument-list

      .ENABL  argument-list

1.18.17.1  –  Parameter

 argument-list

    One or more of the symbolic arguments You can use either the long
    form or the short form of the symbolic arguments.

    If you specify multiple arguments, separate them with commas,
    spaces, or tabs.

    Table 6 .ENABLE and .DISABLE Symbolic Arguments

                Short  Default
    Long Form   Form   Condition  Function

    ALIGN_CODE         Disabled The code alignment option aligns
                              certain branch target labels. The
                              ALIGN_CODE option is disabled for
                              the assembly unit if any one of the
                              following is true:

                              o  /NOALIGNMENT=CODE is specified on
                                 the command line.

                              o  .DISABLE ALIGN_CODE is specified in
                                 the source program.

                              o  The /ALIGNMENT=CODE option is
                                 defaulted.

    ALIGN_DATA         Disabled When ALIGN_DATA is disabled, the data-
                              storage directives put each succeeding
                              item on the next byte boundary.

                              When ALIGN_DATA is enabled, the data-
                              storage directives put each succeeding
                              item on natural boundaries (such as
                              words on word boundaries, longwords on
                              longword boundaries) and add pad bytes
                              as necessary.

                              Accessing data on anything other than
                              natural boundaries usually incurs a
                              significant performance penalty.

                              You can enable or disable the
                              ALIGN_DATA option for specific ranges
                              within your program.

    FLOAT              Enabled Controls whether the assembler
                              generates floating-point instructions
                              when optimizing code and performing
                              code-label alignment.

                              Currently, the only floating-point
                              instruction generated by the assembler
                              during optimization and alignment
                              processing is FNOP, the floating-
                              point no-operation instruction. If you
                              specify .DISABLE FLOAT, the assembler
                              does not generate any floating-point
                              instructions as part of optimization
                              and alignment processing.

                              The initial value of this option is
                              specified by the /ENVIRONMENT=[NO]FLOAT
                              command-line option. The last value of
                              the FLOAT option at the end of assembly
                              determines whether FLOAT is enabled or
                              DISABLED.

    GLOBAL      GBL    Enabled When GLOBAL is enabled, the assembler
                              implicitly treats any undefined symbol
                              as an external reference defined in
                              another module. If the GLOBAL option
                              is disabled, the assembler issues
                              a warning and implicitly treats
                              the undefined symbol as an external
                              reference assumed to be defined in
                              another module. The last value of the
                              GLOBAL option at the end of assembly
                              determines whether the GLOBAL option is
                              enabled or disabled.

    LOCAL_BLOCK LSB    Disabled Used to override the default assembler
                              behavior to define a temporary label
                              block. (A temporary label is of the
                              form n$ where n represents a number.)
                              A temporary label block is usually
                              delimited by two user-defined local
                              or global labels. However, the .ENABLE
                              LOCAL_BLOCK directive defines the start
                              of a block that is terminated by one of
                              the following:

                              o  A second .ENABLE LOCAL_BLOCK
                                 directive.

                              o  A .DISABLE LOCAL_BLOCK directive
                                 followed by a user-defined local or
                                 global label, or a .PSECT directive.

    PEEPHOLE           Disabled Peephole optimization reduces the
                              strength of certain instructions and
                              eliminates instructions where possible.
                              The PEEPHOLE option is disabled for
                              the assembly unit if any one of the
                              following is true:

                              o  /NOOPTIMIZE=PEEPHOLE is specified on
                                 the command line.

                              o  .DISABLE PEEPHOLE is specified in
                                 the source program.

                              o  The PEEPHOLE option is defaulted.

    PREPROCESSOR_      Enabled When PREPROCESSOR_OUTPUT is enabled,
    OUTPUT                    the MACRO-64 preprocessor processes
                              your source statements and outputs to
                              the preprocessor-output file. If the
                              PREPROCESSOR_OUTPUT option is disabled,
                              your source statements are processed
                              as before. However, output of these
                              statements to the preprocessor-output
                              file is suppressed.

                              Neither .ENABLE PREPROCESSOR_OUTPUT
                              nor .DISABLE PREPROCESSOR_OUTPUT is
                              passed through to the preprocessor-
                              output file. These two directives
                              have no effect unless you specify
                              /PREPROCESSOR_ONLY on the command line.

    SCHEDULE           Disabled Instruction scheduling optimization
                              reorders instructions to more optimally
                              utilize the instruction pipeline.
                              The SCHEDULE option is disabled for
                              the assembly unit if any one of the
                              following is true:

                              o  /NOOPTIMIZE=SCHEDULE is specified on
                                 the command line.

                              o  .DISABLE SCHEDULE is specified in
                                 the source program.

                              o  The SCHEDULE option is defaulted.

1.18.17.2  –  Description

    .ENABLE enables the specified assembly function. .ENABLE and
    its negative form, .DISABLE, control the following assembler
    functions:

    o  Creating local label blocks

    o  Specifying that undefined symbol references are external
       references

    o  Enabling or disabling specific optimizations for the assembly
       unit

    You can enable one or more specific optimization options with
    either the .ENABLE directive or the /OPTIMIZE command-line
    qualifier, or both. If you explicitly disable one or more
    specific optimization options with the .DISABLE directive, those
    optimization options are disabled regardless of the command-line
    options you specify.

1.18.17.3  –  Notes

    o  The alternate form of .ENABLE is .ENABL.

1.18.17.4  –  Examples

      Example 1
      The following example shows the ALIGN_DATA option:

        .PSECT A, NOEXE
        .ENABLE ALIGN_DATA  ; Align on natural
                            ; natural boundaries
        A: .BYTE 1          ;
        B: .QUAD 1000       ; B is allocated at
                            ; a natural boundary -
                            ; specifically at A + 7
        .DISABLE ALIGN_DATA ;
        C: .BYTE 2          ;
        D: .QUAD 1001       ; D is allocated at
                            ; an unaligned boundary -
                            ; specifically C + 1
      Example 2
      The following example shows the GLOBAL option disabled:

        .DISABLE GLOBAL
        .ADDRESS X         ; Assembler issues a warning
        .END
      Example 3
      The following example shows the LOCAL_BLOCK option enabled:

              .ENABLE LOCAL_BLOCK

              .PSECT A,NOEXE
        A1::
        5$:   .PROCEDURE_DESCRIPTOR PROC_1   ; Temporary label 5$
              .blkb 32
        A2::
              .address 5$         ; By default the declaration
                                  ; of A2 would have ended the
                                  ; temporary label block and
                                  ; made this reference to 5$
                                  ; illegal.  However, this default
                                  ; behavior has been overridden
                                  ; by the use of .ENABLE LOCAL_BLOCK.

              .DISABLE LOCAL_BLOCK
              .END
      Example 4
      The following example shows an unoptimized and optimized list
      of instructions with the SCHEDULE and PEEPHOLE options enabled:

        .ENABLE PEEPHOLE,SCHEDULE
        .psect A,EXE,QUAD     ; unoptimized
        TRAPB
        A::ADDF F1,F2,F3
           ADDF F4,F5,F6
           ADDL R1,R2,R3
           ADDL R4,R5,R6

      This example shows the optimized list of instructions:

        .ENABLE PEEPHOLE,SCHEDULE
        .psect A,EXE,QUAD     ; optimized
        A::ADDF F1,F2,F3
           ADDL R1,R2,R3
           ADDF F4,F5,F6
           ADDL R4,R5,R6

      The following example shows a repeat block that initializes
      a block of 1000 longwords to the values of 0 through 999. The
      .DISABLE PREPROCESSOR_OUTPUT directive suppresses from the
      preprocessor output file those statements that are incompatible
      with the OSF/1 Assembler.

        .DISABLE PREPROCESSOR_OUTPUT
         I=0
        .REPEAT 1000
           .ENABLE PREPROCESSOR_OUTPUT
           .LONG %INTEGER(I)
           .DISABLE PREPROCESSOR_OUTPUT
           I = I + 1
        .ENDR

1.18.18  –  .END

    Assembly termination directive

    Format

      .END  [label]

1.18.18.1  –  Parameter

 label

    The procedure descriptor name that specifies the routine (called
    the transfer address) where program execution begins. This
    argument is optional.

1.18.18.2  –  Description

    .END terminates the source program. No additional text should
    occur beyond this point in the current source file, or in any
    additional source files specified in the command line for this
    assembly. If any additional text does occur, the assembler
    ignores it. The additional text does not appear in the listing
    file nor does it affect the object file.

1.18.18.3  –  Notes

    o  When an executable image consisting of several object modules
       is linked, only one object module should be terminated by an
       .END directive that specifies a transfer address. All other
       object modules should be terminated by .END directives that
       do not specify a transfer address. If an executable image
       contains either no transfer address or more than one transfer
       address, the linker displays an error message.

    o  For more information, see the .PROCEDURE_DESCRIPTOR directive.

1.18.18.4  –  Example

          .
          .
          .
        .PROCEDURE_DESCRIPTOR TRANSFER1,code_address_T1
          .
          .
          .
        .END TRANSFER1        ; TRANSFER1 is module transfer address

1.18.19  –  .ENDC

    End conditional directive

    Format

      .ENDC

1.18.19.1  –  Description

    .ENDC terminates the conditional range started by the .IF
    directive. See the description of .IF for more information and
    examples.

1.18.20  –  .ENDM

    End macro definition directive

    Format

      .ENDM  [macro-name]

1.18.20.1  –  Parameter

 macro-name

    The name of the macro whose definition is to be terminated. The
    macro name is optional; if specified, it must match the name
    defined in the matching .MACRO directive. The macro name should
    be specified so that the assembler can detect any improperly
    nested macro definitions.

1.18.20.2  –  Description

    .ENDM terminates the macro definition. See the description of
    .MACRO for an example that uses an .ENDM directive.

1.18.20.3  –  Notes

    o  If .ENDM is encountered outside a macro definition, the
       assembler displays an error message.

1.18.21  –  .ENDR

    End repeat range directive

    Format

      .ENDR

1.18.21.1  –  Description

    .ENDR indicates the end of a repeat range. It must be the final
    statement of every repeat block. A repeat block consists of
    any range of text beginning with the .IRP, .IRPC, or .REPEAT
    directive. For more information, see the description for the
    .IRP, .IRPC, or .REPEAT directives for examples of how to use the
    .ENDR directive.

1.18.21.2  –  Notes

    o  If .ENDR is encountered outside a repeat block, the assembler
       displays an error message.

1.18.22  –  .END EXACT

    End exact instruction block directive

    Format

      .END_EXACT

1.18.22.1  –  Description

    .END_EXACT delimits the end of an exact instruction block. An
    exact instruction block suppresses the SCHEDULE and PEEPHOLE
    optimizations for the specified range of instructions regardless
    if code optimizations are enabled for the assembly unit.

    For more information on the .END_EXACT directive, see the
    description of the .BEGIN_EXACT directive in this chapter.

1.18.23  –  .ERROR

    Error directive

    Format

      .ERROR  quoted-literal

1.18.23.1  –  Parameter

 quoted-literal

    A string of characters, between a pair of double quotes,
    displayed during assembly.

1.18.23.2  –  Description

    .ERROR causes the assembler to display an error message on the
    terminal or batch log file and in the listing file (if there is
    one).

    Using .ERROR prevents an output object file from being produced.

1.18.23.3  –  Notes

    o  .PRINT, .WARN, and .ERROR are directives used to display
       messages. You can use them to display information indicating
       unexpected or important conditions within the assembly.

    o  This directive also accepts VAX MACRO syntax. See the
       VAX MACRO and Instruction Set Reference Manual for details.

1.18.23.4  –  Example

        .ERROR "Illegal Arguments"
        ^
        %MACRO64-E-GENERROR, Generated ERROR: Illegal Arguments
        at line number 3 in file DISK$:[TEST]ERROR.M64;2

1.18.24  –  .EVEN

    Even location counter alignment directive

    Format

      .EVEN

1.18.24.1  –  Description

    .EVEN ensures that the current value of the location counter
    is even by adding 1 if the current value is odd. If the current
    value is already even, no action is taken.

1.18.24.2  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

1.18.25  –  .EXTERNAL

    External symbol attribute directive

    Format

      .EXTERNAL  symbol-list

      .EXTRN  symbol-list

1.18.25.1  –  Parameter

 symbol-list

    A list of symbol names separated by commas.

1.18.25.2  –  Description

    .EXTERNAL indicates that the specified symbols are external; that
    is, the symbols are defined in another object module.

1.18.25.3  –  Notes

    o  The alternate form of .EXTERNAL is .EXTRN.

1.18.25.4  –  Example

             .EXTERNAL B    ; B is defined in another module
                .
                .
                .
        A::  .ADDRESS B    ; Its address is stored here

1.18.26  –  .F FLOATING

    Floating-point storage directive

    Format

      .F_FLOATING  floating-point-number-list

      .FLOAT  floating-point-number-list

1.18.26.1  –  Parameter

 floating-point-number-list

    A list of one or more floating-point constants separated by
    commas. The constants cannot contain any operators except unary
    plus or unary minus.

1.18.26.2  –  Description

    .F_FLOATING evaluates the specified floating-point constant(s)
    and stores the results in the object module. .F_FLOATING
    generates 32-bit, single-precision, floating-point data (1
    bit of sign, 8 bits of exponent, and 23 bits of fractional
    significance). See the description of .D_FLOATING for information
    on storing double-precision floating-point constants and the
    descriptions of .G_FLOATING, S_FLOATING, and T_FLOATING for
    descriptions of other floating-point constants.

1.18.26.3  –  Notes

    o  The alternate form of .F_FLOATING is .FLOAT.

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a longword (32-bit) boundary
       before allocating storage.

1.18.26.4  –  Example

        .F_FLOATING 1.0,3.0E+2

1.18.27  –  .G FLOATING

    G_floating-point storage directive

    Format

      .G_FLOATING  floating-point-number-list

1.18.27.1  –  Parameter

 floating-point-number-list

    A comma-separated list of one or more floating-point constants.
    The constants cannot contain any operators except unary plus or
    unary minus.

1.18.27.2  –  Description

    .G_FLOATING evaluates the specified floating-point constants and
    stores the results in the object module. .G_FLOATING generates
    64-bit data (1 bit of sign, 11 bits of exponent, and 52 bits of
    fraction). See the description of .D_FLOATING for information
    on storing double-precision floating-point constants and the
    descriptions of .F_FLOATING, S_FLOATING, and T_FLOATING for
    descriptions of other floating-point constants.

1.18.27.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a quadword (64-bit) boundary
       before allocating storage.

1.18.27.4  –  Example

        .G_FLOATING  2.0E-3

1.18.28  –  .IDENT

    Identification directive

    Format

      .IDENT  quoted-literal

1.18.28.1  –  Parameter

 quoted-literal

    A 1- to 31-character string, within double quotes, that
    identifies the module, such as a string that specifies a version
    number.

1.18.28.2  –  Description

    .IDENT provides a means of identifying the object module. This
    identification is in addition to the name assigned to the object
    module with .TITLE. You can specify a character string in .IDENT
    to label the object module. This string is printed in the header
    of the listing file and also appears in the object module.

1.18.28.3  –  Notes

    o  If a source module contains more than one .IDENT, the last
       directive given establishes the character string that forms
       part of the object module identification.

    o  This directive also accepts VAX MACRO syntax. See the
       VAX MACRO and Instruction Set Reference Manual for details.

1.18.28.4  –  Example

        .IDENT "Module Name"

1.18.29  –  .IF

    Conditional assembly block directive

    Format

      .IF  condition argument(s)
         .

         .

         .

      range
         .

         .

         .

      .ENDC

1.18.29.1  –  Parameters

 condition

    A specified condition that must be met if the block is to be
    included in the assembly. The condition must be separated from
    the argument by a comma, space, or tab.

 argument(s)

    One or more symbolic arguments or expressions of the specified
    conditional test. If the argument is an expression, it cannot
    contain any undefined symbols. The assembler converts relocatable
    arguments to absolute arguments by discarding the relocatable
    portion of the expression and using only the offset from the
    beginning of the psect. Arguments must be separated by a comma.

 range

    The block of source code that is conditionally included in the
    assembly.

    Table 7 Condition Tests for Conditional Assembly Directives

                                                             Condition
    Condition       Complement                     Number    That
    Test            Condition           Argument   of        Assembles
                    Test                Type       Arguments Block

    Long      Short               Short
    Form      Form  Long Form     Form

    EQUAL     EQ    NOT_EQUAL     NE    Expression 1 or 2    Expression-
                                                             1 is
                                                             equal to
                                                             expression-
                                                             2 or not
                                                             equal to
                                                             expression-
                                                             2.
    GREATER   GT    LESS_EQUAL    LE    Expression 1 or 2    Expression-
                                                             1 is
                                                             greater
                                                             than
                                                             expression-
                                                             2 or
                                                             less
                                                             than or
                                                             equal to
                                                             expression-
                                                             2.
    LESS_     LT    GREATER_      GE    Expression 1 or 2    Expression-
    THAN            EQUAL                                    1 is
                                                             less
                                                             than
                                                             expression-
                                                             2 or
                                                             greater
                                                             than or
                                                             equal to
                                                             expression-
                                                             2.
    DEFINED   DF    NOT_DEFINED   NDF   Symbolic   1         Symbol
                                                             is
                                                             defined
                                                             or not
                                                             defined.
    BLANK     B     NOT_BLANK     NB    Macro      1         Argument
                                                             is blank
                                                             or not
                                                             blank.
    IDENTICAL IDN   DIFFERENT     DIF   Macro      2         Arguments
                                                             are
                                                             identi-
                                                             cal or
                                                             differ-
                                                             ent.

1.18.29.2  –  Description

    A conditional assembly block is a series of source statements
    that are assembled only if a certain condition is met. A .IF
    starts the conditional block and a .ENDC ends the conditional
    block; each .IF must have a corresponding .ENDC. The .IF
    directive contains a condition test and one or two arguments.
    The condition test specified is applied to the arguments. If
    the test is met, all MACRO-64 statements between .IF and .ENDC
    are assembled. If the test is not met, the statements are not
    assembled. Optionally, you can use the .ELSE directive (or a
    combination of the .IFF, .IFT, and .IFTF directives) to specify
    an alternate series of statements to assemble if the test is not
    met.

    You can nest conditional blocks; that is, a conditional block
    can be inside another conditional block. In this case, the
    statements in the inner conditional block are assembled only
    if the condition is met for both the outer and inner block.

1.18.29.3  –  Notes

    o  The assembler displays an error message if the following
       directives occur outside a conditional assembly block: .ENDC,
       .ELSE, .IF_FALSE, .IF_TRUE, .IF_TRUE_FALSE.

    o  MACRO-64 permits a nesting depth of 100 conditional assembly
       levels. If a statement attempts to exceed this nesting level
       depth, the assembler displays an error message.

    o  The effect of logical expressions can only be achieved by
       using several levels of .IF directives. See Example 5.

    o  Lowercase string arguments are converted to uppercase before
       being compared, unless the string is surrounded by double
       quotes or /NAMES=AS_IS is specified on the command line.

    o  The assembler displays an error message if .IF specifies any
       of the following: a condition test other than those which are
       valid, an illegal argument, or a null argument specified in an
       .IF directive.

1.18.29.4  –  Examples

      Example 1
      Here is an example of a conditional assembly directive:

        .IF EQUAL  ALPHA+1        ; Assemble block if ALPHA+1=0. Do
          .                       ;   not assemble if ALPHA+1 not=0
          .
          .
        .ENDC
      Example 2
      Nested conditional directives take the following form:

        .IF   condition argument(s)
        .IF   condition argument(s)
          .
          .
          .
        .ENDC
        .ENDC
      Example 3
      The following conditional directives can govern whether
      assembly of the specified range is to occur:

        .IF DEFINED  SYM1
        .IF DEFINED  SYM2
          .
          .
          .
        .ENDC
        .ENDC

      In this example, if the outermost condition is not satisfied,
      no deeper level of evaluation of nested conditional statements
      within the program occurs. Therefore, both SYM1 and SYM2 must
      be defined for the specified range to be assembled.
      Example 4
      An alternate series of statements can be specified using .ELSE.

        .IF EQUAL A,B        ; Assemble if A is equal to B
        .ELSE                ; Assemble if A is not equal to B
        .ENDC

      Example 5
      The following example demonstrates the use of .ELSE and
      nesting:

        .IF LESS_THAN X,Y  ; Assemble if X is less than Y
           .IF DEFINED Z   ; Assemble if Z is defined and
                           ;  X is less than Y
           .ELSE           ; Assemble if Z is not defined and
                           ;  X is less than Y
           .ENDC
        .ELSE              ; Assemble if X is greater than or equal to Y
           .IF DEFINED Z   ; Assemble if Z is defined and X is
                           ;  greater than or equal to Y
           .ENDC
        .ENDC

1.18.30  –  .IF x

    Subconditional assembly block directives

    Format

      .IF_FALSE

      .IF_TRUE

      .IF_TRUE_FALSE

1.18.30.1  –  Description

    For compatibility with VAX MACRO, MACRO-64 provides three
    directives for use within .IF blocks:

    Directive     Function

    .IF_FALSE     If the condition of the assembly block tests false,
                  the program includes the source code following
                  the .IF_FALSE directive and continuing up to the
                  next subconditional directive or to the end of the
                  conditional assembly block.
    .IF_TRUE      If the condition of the assembly block tests true,
                  the program includes the source code following
                  the .IF_TRUE directive and continuing up to the
                  next subconditional directive or to the end of the
                  conditional assembly block.
    .IF_TRUE_     Regardless of whether the condition of the
    FALSE         assembly block tests true or false, the source
                  code following the .IF TRUE_FALSE directive (and
                  continuing up to the next subconditional directive
                  or to the end of the assembly block) is always
                  included.

    The implied argument of a subconditional directive is the
    condition test specified when the conditional assembly block was
    entered. A conditional or subconditional directive in a nested
    conditional assembly block is not evaluated if the preceding (or
    outer) condition in the block is not satisfied (see Example 3 and
    Example 4).

    A conditional block with a subconditional directive is different
    from a nested conditional block. If the condition in the .IF is
    not met, the inner conditional blocks are not assembled, but a
    subconditional directive can cause a block to be assembled.

1.18.30.2  –  Notes

    o  If a subconditional directive appears outside a conditional
       assembly block, the assembler displays an error message.

    o  The alternate forms of .IF_FALSE, .IF_TRUE, and .IF_TRUE_FALSE
       are .IFF, .IFT, and .IFTF.

    o  You cannot use .ELSE in the same conditional block as .IF_x.

1.18.30.3  –  Examples

      Example 1
      Assume that symbol SYM is defined:

           .IF DEFINED   SYM     ; Tests TRUE since SYM is defined.
             .                   ;   Assembles the following code.
             .
             .
           .IF_FALSE             ; Tests FALSE since previous
             .                   ;   .IF was TRUE.  Does not
             .                   ;   assemble the following code.
             .
           .IF_TRUE              ; Tests TRUE since SYM is defined.
             .                   ;   Assembles the following code.
             .
             .
           .IF_TRUE_FALSE        ; Assembles following code
             .                   ;   unconditionally.
             .
             .
           .IF_TRUE              ; Tests TRUE since SYM is defined.
             .                   ;   Assembles remainder of
             .                   ;   conditional assembly block.
             .
           .ENDC
      Example 2
      Assume that symbol X is defined and that symbol Y is not
      defined:

           .IF DEFINED  X        ; Tests TRUE since X is defined.
           .IF DEFINED  Y        ; Tests FALSE since Y is not defined.
           .IF_FALSE             ; Tests TRUE since Y is not defined.
             .                   ;   Assembles the following code.
             .
             .
           .IF_TRUE              ; Tests FALSE since Y is not defined.
             .                   ;   Does not assemble the following
             .                   ;   code.
             .
           .ENDC
           .ENDC
      Example 3
      Assume that symbol A is defined and that symbol B is not
      defined:

           .IF DEFINED  A       ; Tests TRUE since A is defined.
             .                  ;   Assembles the following code.
             .
             .
           .IF_FALSE            ; Tests FALSE since A is defined.
             .                  ;   Does not assemble the following
             .                  ;   code.
             .
           .IF NOT_DEFINED B    ; Nested conditional directive
             .                  ;   is not evaluated.
             .
             .
           .ENDC
           .ENDC
      Example 4
      Assume that symbol X is not defined but symbol Y is defined:

           .IF DEFINED  X       ; Tests FALSE since X is not defined.
             .                  ;   Does not assemble the following
             .                  ;   code.
             .
           .IF DEFINED  Y       ; Nested conditional directive
             .                  ;   is not evaluated.
             .
             .
           .IF_FALSE            ; Nested subconditional
             .                  ;   directive is not evaluated.
             .
             .
           .IF_TRUE             ; Nested subconditional
             .                  ;   directive is not evaluated.
             .
             .
           .ENDC
           .ENDC

1.18.31  –  .IIF

    Immediate conditional assembly block directive

    Format

      .IIF  condition [,]argument(s), statement

1.18.31.1  –  Parameters

 condition

    One of the legal condition tests defined for conditional assembly
    blocks (see the description of .IF). The condition must be
    separated from the arguments by a comma, space, or tab. If the
    first argument can be a blank, the condition must be separated
    from the arguments with a comma.

 argument(s)

    An expression or symbolic argument associated with the immediate
    conditional assembly block directive. If the argument is an
    expression, it cannot contain any undefined symbols. The
    assembler converts relocatable arguments to absolute arguments
    by discarding the relocatable portion of the expression and using
    only the offset from the beginning of the psect. The arguments
    must be separated from the statement by a comma.

 statement

    The statement to be assembled if the condition is satisfied.

1.18.31.2  –  Description

    .IIF provides a means of writing a one-line conditional assembly
    block. The condition to be tested and the conditional assembly
    block are expressed completely within the line containing the
    .IIF directive. No terminating .ENDC statement is required or
    allowed.

1.18.31.3  –  Notes

    o  The assembler displays an error message if .IIF specifies a
       condition test other than those which the assembler considers
       valid, an illegal argument, or a null argument.

1.18.31.4  –  Example

      In the following example, the symbol EXAM is defined within the
      source program:

        .IIF DEFINED EXAM, BR ALPHA

      This directive generates the following code:

        BR    ALPHA

1.18.32  –  .INCLUDE

    Include source file directive

    Format

      .INCLUDE  quoted-literal

1.18.32.1  –  Parameter

 quoted-literal

    The name of the source file to be included within double quotes.
    If a logical name exists that is the same as the source file
    name, specify the .M64 file extension to override the logical
    name.

1.18.32.2  –  Description

    .INCLUDE indicates that the current input source file should be
    suspended and that the specified file should be used. When that
    file ends, the original source stream resumes, starting at the
    line after .INCLUDE.

1.18.32.3  –  Notes

    o  The assembler issues an error message if the file nesting
       level exceeds 50.

1.18.32.4  –  Example

        .INCLUDE "file1.m64"

1.18.33  –  .INSTRUCTION

    Instruction directive

    Format

      .INSTRUCTION  expression

1.18.33.1  –  Parameter

 expression

    An absolute expression in the range of -2147483648 to 2147483647.
    The expression cannot be relocatable, external, or complex.

1.18.33.2  –  Description

    The specified value is stored at the current location as an
    instruction. You can use .INSTRUCTION to specify arbitrary
    instructions. Similar to .LONG, .INSTRUCTION stores a longword
    (32 bits) of data. Unlike .LONG, the assembler considers
    .INSTRUCTION an instruction and allows its use in code psects.

1.18.33.3  –  Notes

    o  You can only use this directive within code or mixed psects
       (psects that have either the EXE or MIX attributes).

    o  If automatic data alignment is enabled within a mixed psect,
       this directive aligns the current location counter to a
       longword (32-bit) boundary before allocating storage.

    o  You can use this directive to store arbitrary, longword,
       assembly-time constant data in a code section.

1.18.33.4  –  Example

        .INSTRUCTION 7

1.18.34  –  .IRP

    Indefinite repeat argument directive

    Format

      .IRP  symbol,<argument list>

         .

         .

         .

      range

         .

         .

         .

      .ENDR

1.18.34.1  –  Parameters

 symbol

    A formal argument that is successively replaced with the
    specified actual arguments enclosed in angle brackets (<>).  If
    no formal argument is specified, the assembler displays an error
    message.

 <argument list>

    A list of actual arguments enclosed in angle brackets and used
    in expanding the indefinite repeat range. An actual argument
    can consist of one or more characters. Multiple arguments must
    be separated by a legal separator (comma, space, or tab). If no
    actual arguments are specified, no action is taken.

 range

    The block of source text to be repeated once for each occurrence
    of an actual argument in the list. The range can contain macro
    definitions and repeat ranges. .MEXIT is legal within the range
    and causes the current and remaining repetitions to be aborted.

1.18.34.2  –  Description

    .IRP replaces a formal argument with successive actual arguments
    specified in an argument list. This replacement process occurs
    during the expansion of the indefinite repeat block range. The
    .ENDR directive specifies the end of the range.

    .IRP is similar to a macro definition with only one formal
    argument. At each successive expansion of the repeat block, this
    formal argument is replaced with successive elements from the
    argument list. The directive and its range are coded in line
    within the source program. This type of macro definition and
    its range do not require calling the macro by name, as do other
    macros described in this section.

    .IRP can appear either inside or outside another macro
    definition, indefinite repeat block, or repeat block (see the
    description of .REPEAT). The rules for specifying .IRP arguments
    are the same as those for specifying macro arguments.

1.18.34.3  –  Example

      The macro definition is as follows:

        .macro CHECK_PROCEDURE_KIND PROCEDURE_KIND
            OK = 0      ; Assume procedure_kind is unknown
            .irp REFERENCE_KIND,BOUND,NULL, REGISTER,STACK
                .if identical, <PROCEDURE_KIND>, <REFERENCE_KIND>
                    OK = 1 ; Procedure_kind is known
                    .mexit ; No need to look further
                .endc
            .endr
            .if eq, OK  ; If unknown procedure kind
                .error "Unknown procedure kind: PROCEDURE_KIND"
            .endc
        .endm CHECK_PROCEDURE_KIND

        CHECK_PROCEDURE_KIND REGISTER
        CHECK_PROCEDURE_KIND FOOZLE

      The macro call and expansion of the previously defined macro is
      as follows:

        CHECK_PROCEDURE_KIND REGISTER
            OK = 0      ; Assume procedure kind is unknown
            .if identical,<REGISTER>,<BOUND>
            .endc
            .if identical,<REGISTER>,<NULL>
            .endc
            .if identical,<REGISTER>,<REGISTER>
                OK = 1 ; Procedure kind is known
                .mexit ; No need to look further
            .if eq, OK  ; If unknown procedure kind
            .endc

        CHECK_PROCEDURE_KIND FOOZLE
            OK = 0      ; Assume procedure kind is unknown
            .if identical,<FOOZLE>,<BOUND>
            .endc
            .if identical,<FOOZLE>,<NULL>
            .endc
            .if identical,<FOOZLE>,<REGISTER>
            .endc
            .if identical,<FOOZLE>,<STACK>
            .endc
            .if eq, OK  ; If unknown procedure kind
                .error "Unknown procedure kind: FOOZLE"
            .endc

      In this example the CHECK_PROCEDURE_KIND macro uses the
      .IRP directive to iterate over a list of reference keywords
      to determine if its argument matches one of the reference
      keywords. If a match is not found, the macro displays an error
      message.

1.18.35  –  .IRPC

    Indefinite repeat character directive

    Format

      .IRPC  symbol,<STRING>

         .

         .

         .

      range

         .

         .

         .

      .ENDR

1.18.35.1  –  Parameters

 symbol

    A formal argument that is successively replaced with the
    specified characters enclosed in angle brackets (<>).  If no
    formal argument is specified, the assembler displays an error
    message.

 <STRING>

    A sequence of characters enclosed in angle brackets and used in
    the expansion of the indefinite repeat range. Although the angle
    brackets are required only when the string contains separating
    characters, their use is recommended for legibility.

 range

    The block of source text to be repeated once for each occurrence
    of a character in the list. The range can contain macro
    definitions and repeat ranges. .MEXIT is legal within the range.

1.18.35.2  –  Description

    .IRPC is similar to .IRP except that .IRPC permits single-
    character substitution rather than argument substitution. On each
    iteration of the indefinite repeat range, the formal argument is
    replaced with each successive character in the specified string.
    The .ENDR directive specifies the end of the range.

    .IRPC is similar to a macro definition with only one formal
    argument. At each expansion of the repeat block, this formal
    argument is replaced with successive characters from the actual
    argument string. The directive and its range are coded in line
    within the source program and do not require calling the macro by
    name.

    .IRPC can appear either inside or outside another macro
    definition, indefinite repeat block, or repeat block (see
    description of .REPEAT).

1.18.35.3  –  Example

      The macro definition is as follows:

            .macro X_COUNT ARG
                COUNT = 0
                .irpc CH,<ARG>
                    .iif identical,<CH>,<X>, COUNT = COUNT + 1
                .endr
            .endm X_COUNT

      The macro call and expansion of the macro defined previously is
      as follows:

            X_COUNT XXFOOXBARXX
                COUNT = 0
                .irpc CH,<XXFOOXBARXX>
                    .iif identical,<CH>,<X>, COUNT = COUNT + 1
                .endr
                    .iif identical,<X>,<X>, COUNT = COUNT + 1
                    .iif identical,<X>,<X>, COUNT = COUNT + 1
                    .iif identical,<F>,<X>, COUNT = COUNT + 1
                    .iif identical,<O>,<X>, COUNT = COUNT + 1
                    .iif identical,<O>,<X>, COUNT = COUNT + 1
                    .iif identical,<X>,<X>, COUNT = COUNT + 1
                    .iif identical,<B>,<X>, COUNT = COUNT + 1
                    .iif identical,<A>,<X>, COUNT = COUNT + 1
                    .iif identical,<R>,<X>, COUNT = COUNT + 1
                    .iif identical,<X>,<X>, COUNT = COUNT + 1
                    .iif identical,<X>,<X>, COUNT = COUNT + 1

                .print "%integer(COUNT)"
        %MACRO64-I-GENPRINT, Generated PRINT: 5

      This example uses the .IRPC directive to iterate over the
      characters in the argument to the X_COUNT macro. Each time
      an argument character is X, the variable COUNT is incremented.
      After the X_COUNT macro has expanded, the example uses the
      %INTEGER() lexical operator to display the value of COUNT.

1.18.36  –  .LIBRARY

    Macro library directive

    Format

      .LIBRARY  quoted-literal1 [quoted-literal2]

1.18.36.1  –  Parameters

 quoted-literal1

    A string enclosed within double quotes that is the file
    specification of a macro library. If a logical name exists and
    it is the same as the macro library name, specify the .MLB file
    extension to override the logical name.

 quoted-literal2

    An optional string enclosed within double quotes that specifies
    a search list of file specifications where the assembler should
    look for the specified macro library. The assembler successively
    processes the search list in left-to-right order and attempts to
    locate the specified macro library in each location specified in
    the search list until the macro library is found. If the macro
    library is not found, the assembler issues a diagnostic message.
    If you omit the second argument to the .LIBRARY directive, the
    assembler uses the following search list by default:

    o  The current device and directory

    o  The device and directory specified by the logical name
       MACRO64$LIBRARY (if defined)

    o  The device and directory specified by the logical name
       ALPHA$LIBRARY (if defined)

    o  The device and directory specified by the logical name
       SYS$LIBRARY

    Logical names may be defined as OpenVMS search lists.

1.18.36.2  –  Description

    .LIBRARY adds a name to the macro library list that is searched
    whenever a .MCALL or an undefined opcode is encountered. The
    libraries are searched in the reverse order in which they were
    specified to the assembler.

    If you omit any information from the macro-library-name file
    description, default values are assumed. The device defaults to
    your current default disk; the directory defaults to your current
    default directory; the file type defaults to MLB.

1.18.36.3  –  Example

        .LIBRARY "MY_MACROS" 1
        .LIBRARY "PROJ_MACROS" "PROJ:[MACRO],PROJ:[DEVELOPMENT]" 2

      1  The first statement adds the macro library MY_MACROS.MLB
         to the macro library list. The assembler first looks for
         MY_MACROS.MLB in the current directory. If not found there,
         the assembler next looks in the directory or directories
         indicated by the MACRO64$LIBRARY logical name if it is
         defined. If not found there or if MACRO64$LIBRARY is not
         defined, the assembler next looks in the directory or
         directories indicated by the ALPHA$LIBRARY logical name
         if it is defined. If not found there or if ALPHA$LIBRARY is
         not defined, the assembler next looks in the directory or
         directories indicated by the SYS$LIBRARY logical name. If
         not found there, the assembler issues a diagnostic message.

      2  The second statement adds the macro library PROJ_MACROS.MLB
         to the macro library list. The assembler first looks for
         PROJ_MACROS.MLB in the PROJ:[MACRO] directory. If not found
         there, the assembler next looks in the PROJ:[DEVELOPMENT]
         directory. If not found there, the assembler issues a
         diagnostic message.

1.18.37  –  .LINKAGE PAIR

    Linkage directive

    Format

      .LINKAGE_PAIR  name

1.18.37.1  –  Parameter

 name

    The name of the procedure descriptor, possibly defined in a
    different module of the routine to which linkage is required.

1.18.37.2  –  Description

    .LINKAGE_PAIR causes a linkage pair to be stored at the current
    location counter. A linkage pair consists of two quadwords. The
    first quadword is the code entry point of the routine indicated
    by the specified identifier. The second quadword is the address
    of the procedure descriptor of the routine indicated by the
    specified identifier. The second quadword is also called the
    procedure value. The specified name should reference a procedure
    descriptor that is either defined within the assembly unit or
    that becomes defined at the time the program is linked.

1.18.37.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to an octaword (128-bit) boundary
       before allocating storage.

1.18.37.4  –  Example

        .LINKAGE_PAIR A     ; Code address A followed by address of
                            ; procedure descriptor A

1.18.38  –  .LIST

    Listing directive

    Format

      .LIST  [argument-list]

1.18.38.1  –  Parameter

 argument-list

    One or more of the symbolic arguments You can use either the long
    form or the short form of the arguments. If multiple arguments
    are specified, separate them with commas, spaces, or tabs.

1.18.38.2  –  Description

    .LIST is equivalent to .SHOW. See the description of .SHOW for
    more information.

1.18.39  –  .LOCAL CODE ADDRESS

    Local code address storage directive

    Format

      .LOCAL_CODE_ADDRESS  name-list

1.18.39.1  –  Parameter

 name-list

    A list of symbols separated by commas. Each symbol references a
    procedure descriptor defined in the current module.

1.18.39.2  –  Description

    .LOCAL_CODE_ADDRESS causes the code addresses of the specified
    identifiers to be placed at the current psect and current
    location counter. The specified identifier must reference a
    procedure descriptor defined within the module. The .LOCAL_
    CODE_ADDRESS directive, rather than the .CODE_ADDRESS directive,
    must be used with procedure descriptor names that are local (as
    opposed to global) to the assembly unit.

1.18.39.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a quadword (64-bit) boundary
       before allocating storage.

1.18.39.4  –  Example

        .PROCEDURE_DESCRIPTOR P1,C1
        .BLKQ 1
        .LOCAL_CODE_ADDRESS P1       ; Code address
                                     ; of P1...address of C1...
                                     ; is stored here.

1.18.40  –  .LOCAL LINKAGE PAIR

    Local linkage directive

    Format

      .LOCAL_LINKAGE_PAIR  name

1.18.40.1  –  Parameter

 name

    The name of a procedure descriptor of the routine to which
    linkage is required. The specified procedure descriptor must
    be defined in the current module.

1.18.40.2  –  Description

    .LOCAL_LINKAGE_PAIR causes a linkage pair to be stored at
    the current location counter. A linkage pair consists of a
    code address and the address of the specified identifier. The
    specified name must reference a procedure descriptor that is
    defined within the assembly unit.

1.18.40.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to an octaword (128-bit) boundary
       before allocating storage.

1.18.40.4  –  Example

        .PROCEDURE_DESCRIPTOR P1,CA1
         .
         .
         .
        .LOCAL_LINKAGE_PAIR P1        ; Code address CA1 followed by
                                      ; procedure descriptor address P1.

1.18.41  –  .LOCAL PROCEDURE DESCRIPTOR

    Procedure descriptor labeling directive

    Format

      .LOCAL_PROCEDURE_DESCRIPTOR  pd-name, ca-name

1.18.41.1  –  Parameters

 pd-name

    The name of the procedure descriptor. This name can be up to 31
    characters long. It cannot be a temporary label.

 ca-name

    The name of the code address that corresponds to the procedure
    descriptor. This name must be defined later in the program as
    a label in a psect that has either the EXE or MIX attribute, or
    both. This name can be up to 31 characters long. It cannot be a
    temporary label.

1.18.41.2  –  Description

    .LOCAL_PROCEDURE_DESCRIPTOR defines a bivalued local identifier
    that is used to represent a local routine. The first value
    is the procedure value, which is the address of the procedure
    descriptor. This value is defined as the current location counter
    at the point where you use the .LOCAL_PROCEDURE_DESCRIPTOR
    directive. The second value is the code address, which is
    the code entry-point address of the procedure. This value is
    defined by the second argument to the .LOCAL_PROCEDURE_DESCRIPTOR
    directive. No storage is allocated.

1.18.41.3  –  Notes

    o  See the OpenVMS Calling Standard for a full description of
       procedure descriptors.

    o  You must specify .LOCAL_PROCEDURE_DESCRIPTOR before the code
       of the routine it describes.

    o  See the description for the $PROCEDURE_DESCRIPTOR and $ROUTINE
       library macros. These macros define the procedure identifier
       and define the storage for the procedure descriptor.

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a quadword (64-bit) boundary
       before defining the procedure identifier.

1.18.41.4  –  Example

        .LOCAL_PROCEDURE_DESCRIPTOR LP1,C1

1.18.42  –  .LONG

    Longword storage directive

    Format

      .LONG  expression-list

1.18.42.1  –  Parameter

 expression-list

    One or more expressions separated by commas.

1.18.42.2  –  Description

    .LONG generates successive longwords (4 bytes) of data in the
    object module. The assembler truncates on the left of an integer
    or external value.

1.18.42.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a longword (32-bit) boundary
       before allocating storage.

    o  You can define a 32-bit address item using macros and the
       .LONG directive. For example:

       .macro address_32 item
       .long item
       .endm address_32

1.18.42.4  –  Example

        .LONG 4     ; Places 4 in 4 bytes of storage.

1.18.43  –  .MACRO

    Macro definition directive

    Format

      .MACRO  macro-name [formal-argument-list]
         .

         .

         .

      range
         .

         .

         .

      .ENDM  [macro-name]

1.18.43.1  –  Parameters

 macro-name

    The name of the macro to be defined; this name can be any legal
    symbol up to 31 characters long.

 formal-argument-list

    The symbols, separated by commas, to be replaced by the actual
    arguments in the macro call.

 range

    The source text to be included in the macro expansion.

1.18.43.2  –  Description

    .MACRO begins the definition of a macro. It gives the macro name
    and a list of formal arguments. The .MACRO directive is followed
    by the source text to be included in the macro expansion. The
    .ENDM directive specifies the end of the range.

    Macro names do not conflict with user-defined symbols. Both a
    macro and a user-defined symbol can have the same name.

    When the assembler encounters a .MACRO directive, it adds the
    macro name to its macro name table and stores the source text
    of the macro (up to the matching .ENDM directive). No other
    processing occurs until the macro is expanded.

    The symbols in the formal argument list are associated with the
    macro name and are limited to the scope of the definition of that
    macro. For this reason, the symbols that appear in the formal
    argument list can also appear elsewhere in the program.

1.18.43.3  –  Notes

    o  If a macro has the same name as an Alpha opcode, the macro
       is used instead of the instruction. This feature allows you to
       temporarily redefine an opcode.

    o  You can redefine a macro by using a .MACRO directive with the
       same name as in a previous macro definition. Therefore, the
       previous macro definition is implicitly deleted and the new
       macro definition supersedes the previous definition. See the
       .MDELETE directive for more information on macro deletion.

    o  You can nest a macro definition within another macro
       definition. The inner macro is not defined until the outer
       macro is invoked.

    o  You can nest a macro invocation so that one macro can invoke
       another. The assembler supports nested macro invocations to a
       depth of 1000. If a macro invokes itself, either directly or
       indirectly, it is recursive. Recursive macros must specify a
       basis-step in order to avoid infinite recursion. A basis-step
       is a macro exit condition that will eventually cause the macro
       to exit, which ends the recursion (see Example 3).

1.18.43.4  –  Examples

      Example 1
      This example shows how macro definitions and invocations may
      be nested. It also shows examples of the various forms of
      parameter passing.

        .MACRO OP1 A,B=R4,?C
        C:      ADDL R2, B, R3
        .MACRO OP'B
                TRAPB
        .ENDM OP'B
                ADDL A, R2, R3
                OP'B
                .MDELETE OP'B
        .ENDM OP1

      When OP1 is invoked "OP1 R0", the text expands to:

        33000$: ADDL R2, R4, R3
        .MACRO OPR4
                TRAPB
        .ENDM
                ADDL R0, R2, R3
                OPR4
                .MDELETE OPR4

      Processing this text will cause OPR4 to be expanded to TRAPB;
      the final text will be:

        33000$: ADDL R2, R4 R3
                ADDL R0, R2, R3
                TRAPB

      Example 2
      The following example shows macro redefinition:

        .MACRO INITIALIZE
           .MACRO INITIALIZE   ;Redefine to nothing
           .ENDM INITIALIZE
           X=0
           Y=1
           Z=-1
        .ENDM INITIALIZE

      Note that while the redefined version of the macro immediately
      supersedes the previous definition in any subsequent
      invocation, the invocation of the original definition expands
      to completion.
      Example 3
      This example shows a recursive macro:

        .MACRO FACTORIAL N
           .IF EQUAL <N>,0      ;Basis step; stop at zero
              F=1
           .ELSE
              FACTORIAL <N-1>
              F = F * <N>
           .ENDC
        .ENDM FACTORIAL

1.18.44  –  .MCALL

    Macro call directive

    Format

      .MCALL  macro-name-list

1.18.44.1  –  Parameter

 macro-name-list

    A list of macros to be defined for this assembly. Separate the
    macro names with commas.

1.18.44.2  –  Description

    .MCALL specifies the names of the system and user-defined macros
    that are required to assemble the source program but are not
    defined in the source file.

    If any named macro is not found upon completion of the search
    (that is, if the macro is not defined in any of the macro
    libraries), the assembler displays an error message.

1.18.44.3  –  Notes

    o  Using the .MCALL directive is optional unless the macro name
       is the same as an opcode or assembler directive. The assembler
       automatically searches for a library macro when it encounters
       an identifier that is not an opcode or directive in the
       opcode field. If your macro name is the same as an opcode or
       directive, you must use the .MCALL directive. You can also use
       the .MCALL directive in your program to document which macros
       are used by your program.

1.18.44.4  –  Example

        .MCALL TRAPB       ; Substitute macro in library for
                           ; TRAPB instruction

1.18.45  –  .MDELETE

    Macro deletion directive

    Format

      .MDELETE  macro-name-list

1.18.45.1  –  Parameter

 macro-name-list

    A list of macros whose definitions are to be deleted. You can
    separate the macros with commas or spaces.

1.18.45.2  –  Description

    .MDELETE deletes the definitions of specified macros.

    .MDELETE completely deletes the macro. If you delete a macro that
    is currently expanding (such as a macro that deletes itself),
    the macro name is immediately removed from the macro name table
    and the macro is marked for deletion. When the macro finishes
    expanding, it is deleted.

1.18.45.3  –  Example

        .MACRO FOO
        .PRINT "In macro FOO"
        .ENDM FOO
        FOO
        .MDELETE FOO

1.18.46  –  .MEXIT

    Macro exit directive

    Format

      .MEXIT

1.18.46.1  –  Description

    .MEXIT terminates a macro expansion before the end of the macro.
    Termination is the same as if .ENDM were encountered. You can
    also use the directive within repeat blocks. .MEXIT is useful
    in conditional expansion of macros and repeat blocks because it
    bypasses the complexities of nested conditional directives and
    alternate assembly paths.

1.18.46.2  –  Notes

    o  When .MEXIT occurs in a repeat block, the assembler terminates
       the current repetition of the range and suppresses further
       expansion of the repeat range.

    o  When macros or repeat blocks are nested, .MEXIT exits to the
       next higher level of expansion.

    o  If .MEXIT occurs outside a macro definition or a repeat block,
       the assembler displays an error message.

1.18.46.3  –  Examples

      Example 1
      The following macro definition uses the .MEXIT directive
      to exit the current macro when it has finished processing a
      particular kind of argument:

                .macro STORE REG, LOCATION
                    .if identical,<REG>,<FP>
                        STQ REG, LOCATION
                        .mexit
                    .endc
                    .if identical,<REG>,<SP>
                        STQ REG, LOCATION
                        .mexit
                    .endc
                    .if identical,<%extract(0,1,<REG>)>,<R>
                        STQ REG, LOCATION
                        .mexit
                    .endc
                    .if identical,<%extract(0,1,<REG>)>,<F>
                        STT REG, LOCATION
                        .mexit
                    .endc
                    .error "Register argument is not a register"
                .endm STORE

      Example 2
      In this example, the STORE macro (as defined in Example 1)
      attempts to recognize its REG argument as either FP, SP, an
      integer register (a register with R as its first letter),
      or a floating-point register (a register with F as its first
      letter). The following example show two expansions of the STORE
      macro:

                STORE R1, 0(SP)
                    .if identical,<R1>,<FP>
                    .endc
                    .if identical,<R1>,<SP>
                    .endc
                    .if identical,<%extract(0,1,<R1>)>, <R>
                    .if identical,<R>,<R>
                        STQ R1, 0(SP)
                        .mexit

                STORE 24(SP), 16(SP)
                    .if identical,<24(SP)>,<FP>
                    .endc
                    .if identical,<24(SP)>,<SP>
                    .endc
                    .if identical,<%extract(0,1,<24(SP)>)>,<R>
                    .if identical,<2>,<R>
                    .endc
                    .if identical, <%extract(0,1<24(SP)>)>,<F>
                    .if identical,<2>,<F>
                    .endc
                    .error "Register argument is not a register"

      The first call of the STORE macro stores R1 at 0(SP). The
      STORE macro determines to do an integer store by recognizing
      the letter R as the first letter of the register name. After
      it has done so, it abandons further expansion of the macro
      using the .MEXIT directive. The second invocation attempts to
      store 24(SP) at 16(SP). Since the STORE macro cannot identify
      24(SP) as a legitimate register in any of the four forms it
      recognizes, the STORE macro does not attempt to store the
      REG argument, and does not abandon expansion with the .MEXIT
      directive. Instead, the STORE macro expands and issues a
      diagnostic message.

1.18.47  –  .NARG

    Number of arguments directive

    Format

      .NARG  symbol

1.18.47.1  –  Parameter

 symbol

    A symbol that is assigned a value equal to the number of
    positional arguments in the macro call.

1.18.47.2  –  Description

    .NARG determines the number of arguments in the current macro
    call.

    .NARG counts all the positional arguments specified in the macro
    call, including null arguments (specified by adjacent commas).
    The value assigned to the specified symbol does not include
    any keyword arguments or any formal arguments that have default
    values.

1.18.47.3  –  Notes

    o  If .NARG appears outside a macro, the assembler displays an
       error message.

1.18.47.4  –  Examples

      Example 1
      The macro definition is as follows:

        .MACRO  CNT_ARG A1,A2,A3,A4,A5,A6,A7,A8,A9=DEF9,A10=DEF10
        .NARG   COUNTER         ; COUNTER is set to no. of ARGS
        .WORD   COUNTER         ; Store value of COUNTER
        .ENDM   CNT_ARG
      Example 2
      The macro calls and expansions of the macro previously defined
      are as follows:

        CNT_ARG TEST,FIND,ANS   ; COUNTER will = 3
        .NARG   COUNTER         ; COUNTER is set to no. of ARGS
        .WORD   COUNTER         ; Store value of COUNTER

        CNT_ARG                 ; COUNTER will = 0
        .NARG   COUNTER         ; COUNTER is set to no. of ARGS
        .WORD   COUNTER         ; Store value of COUNTER

        CNT_ARG TEST,A2=SYMB2,A3=SY3      ; COUNTER will = 1
        .NARG   COUNTER         ; COUNTER is set to no. of ARGS
        .WORD   COUNTER         ; Store value of COUNTER
                                ; Keyword arguments are not counted

        CNT_ARG ,SYMBL,,        ; COUNTER will = 4
        .NARG   COUNTER         ; COUNTER is set to no. of ARGS
        .WORD   COUNTER         ; Store value of COUNTER
                                ; Null arguments are counted

1.18.48  –  .NCHR

    Number of characters directive

    Format

      .NCHR  symbol,<string>

1.18.48.1  –  Parameters

 symbol

    A symbol that is assigned a value equal to the number of
    characters in the specified character string.

 <string>

    A sequence of printable characters. Delimit the character
    string with angle brackets (<>)  (or a character preceded by a
    circumflex (^))  only if the specified character string contains
    a legal separator (comma, space, or tab) or a
    semicolon (;).

1.18.48.2  –  Description

    .NCHR determines the number of characters in a specified
    character string. It can appear anywhere in an MACRO-64 program
    and is useful in calculating the length of macro arguments.

1.18.48.3  –  Notes

    o  You can use the %LENGTH lexical operator instead of the .NCHR
       directive.

1.18.48.4  –  Examples

      Example 1
      The macro definition is as follows:

        .MACRO   CHAR    MESS                  ; Define MACRO
        .NCHR    CHRCNT,<MESS>      ; Assign value to CHRCNT
        .WORD    CHRCNT                        ; Store value
        .ASCII   "MESS"                        ; Store characters
        .ENDM    CHAR                          ; Finish
      Example 2
      The macro calls and expansions of the macro previously defined
      are as follows:

        CHAR     <HELLO>                        ; CHRCNT will = 5
        .NCHR    CHRCNT,<HELLO>                 ; Assign value to CHRCNT
        .WORD    CHRCNT                          ; Store value
        .ASCII   "HELLO"                         ; Store characters

        CHAR     <14, 75.39  4>                 ; CHRCNT will = 12(dec)
        .NCHR    CHRCNT,<14, 75.39  4>          ; Assign value to CHRCNT
        .WORD    CHRCNT                          ; Store value
        .ASCII   "14, 75.39  4"                  ; Store characters

1.18.49  –  .NLIST

    Listing exclusion directive

    Format

      .NLIST  [argument-list]

1.18.49.1  –  Parameter

 argument-list

    One or more of the symbolic arguments Use either the long form
    or the short form of the arguments. If you specify multiple
    arguments, separate them with commas, spaces, or tabs.

1.18.49.2  –  Description

    .NLIST is equivalent to .NOSHOW. See the description of .SHOW for
    more information.

1.18.50  –  .NOSHOW

    Listing exclusion directive

    Format

      .NOSHOW  [argument-list]

1.18.50.1  –  Parameter

 argument-list

    One or more of the symbolic arguments listed in the description
    of .SHOW. Use either the long form or the short form of the
    arguments. If you specify multiple arguments, separate them with
    commas, spaces, or tabs.

1.18.50.2  –  Description

    .NOSHOW specifies listing control options. See the description of
    .SHOW for more information.

1.18.51  –  .OCTA

    Octaword storage directive

    Format

      .OCTA  expression-list

1.18.51.1  –  Parameter

 expression-list

    A list of constant values separated by commas. Each value results
    in a 64-bit value being sign-extended to 128 bits and stored in
    an octaword.

1.18.51.2  –  Description

    .OCTA generates 128 bits (16 bytes) of binary data.

1.18.51.3  –  Notes

    o  The low quadword contains the specified constant value.

    o  The high quadword contains the sign extension of the specified
       constant value. That is, the high quadword contains 0 if the
       specified value is positive, and it contains all bits set to 1
       if the specified value is negative.

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to an octaword (128-bit) boundary
       before allocating storage.

1.18.51.4  –  Example

        .OCTA  0                         ; OCTA 0
        .OCTA  ^X01234ABCD5678F9         ; OCTA hex value specified

        .OCTA  VINTERVAL                 ; VINTERVAL has 64-
 bit value,

                                         ;   sign-extended

1.18.52  –  .ODD

    Odd location counter alignment directive

    Format

      .ODD

1.18.52.1  –  Description

    .ODD ensures that the current value of the location counter is
    odd by adding 1 if the current value is even. If the current
    value is already odd, no action is taken.

1.18.52.2  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

1.18.53  –  .PACKED

    Packed decimal string storage directive

    Format

      .PACKED  decimal-string[,symbol]

1.18.53.1  –  Description

    .PACKED is supplied as a library macro with MACRO-64.

1.18.54  –  .PAGE

    Page ejection directive

    Format

      .PAGE

1.18.54.1  –  Description

    .PAGE forces a new page in the listing. The directive itself is
    also printed in the listing and begins the new page.

    .PAGE in a macro definition is ignored. The paging operation is
    performed only during macro expansion. If the .PAGE directive
    occurs during macro expansion, text beginning with the original
    macro invocation line appears at the top of a new page.

1.18.54.2  –  Example

        .MACRO SKIP    ; macro definition with .PAGE
        .PAGE          ;
        .ENDM SKIP     ;
        .PSECT A,NOEXE ;
        .BLKW 10       ;
        SKIP           ; In the listing file, a form feed
                       ;  will be inserted here

1.18.55  –  .PRINT

    Assembly message directive

    Format

      .PRINT  quoted-literal

1.18.55.1  –  Parameter

 quoted-literal

    The string of characters enclosed in quotes are displayed when
    encountered during assembly.

1.18.55.2  –  Description

    .PRINT causes the assembler to display an informational message.
    The message consists of the string.

1.18.55.3  –  Notes

    o  .PRINT, .WARN, and .ERROR are directives that display
       messages. You can use these to display information indicating
       unexpected or important conditions within the assembly.

    o  This directive also accepts VAX MACRO syntax. See the
       VAX MACRO and Instruction Set Reference Manual for details.

1.18.55.4  –  Example

        .PRINT "Questionable usage"
        ^
        %MACRO64-I-GENPRINT, Generated PRINT: Questionable usage
        at line number 3 in file DISK$:[TEST]PRINT.M64;2

1.18.56  –  .PROCEDURE DESCRIPTOR

    Procedure descriptor labeling directive

    Format

      .PROCEDURE_DESCRIPTOR  pd-name, ca-name

1.18.56.1  –  Parameters

 pd-name

    The name of the procedure descriptor. This name can be up to 31
    characters long. It cannot be a temporary label.

 ca-name

    The name of the code address that corresponds to the procedure
    descriptor. This name must be defined later in the program as
    a label in a psect that has either the EXE or MIX attribute, or
    both. This name can be up to 31 characters long. It cannot be a
    temporary label.

1.18.56.2  –  Description

    .PROCEDURE_DESCRIPTOR defines a bivalued global identifier
    that is used to represent a global routine. The first value
    is the procedure value, which is the address of the procedure
    descriptor. This value is defined as the current location counter
    at the point where you use the .PROCEDURE_DESCRIPTOR directive.
    The second value is the code address, which is the code entry-
    point address of the procedure. This value is defined by the
    second argument to the .PROCEDURE_DESCRIPTOR directive. No
    storage is allocated.

1.18.56.3  –  Notes

    o  See the OpenVMS Calling Standard for a full description of
       procedure descriptors.

    o  You must specify .PROCEDURE_DESCRIPTOR before the code of the
       routine it describes.

    o  See the descriptions for the $PROCEDURE_DESCRIPTOR and
       $ROUTINE library macros. These macros define the procedure
       identifier and define the storage for the procedure
       descriptor.

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a quadword (64-bit) boundary
       before defining the procedure identifier.

1.18.57  –  .PSECT

    Program sectioning directive

    Format

      .PSECT  program-section-name[,argument-list]

1.18.57.1  –  Parameters

 program-section-name

    The name of the program section (psect).

 argument-list

    A list containing the program section attributes and the program
    section alignment. Program sections are aligned when you specify
    an integer in the range of 0 to 16 or one of the five keywords
    listed in the following table. If you specify an integer, the
    program section is linked to begin at the next virtual address
    that is a multiple of two raised to the power of the integer. If
    you specify a keyword, the program section is linked to begin at
    the next virtual address that is a multiple of the corresponding
    value listed in the following table:

    KeywordSize (in Bytes)

    BYTE   20 = 1
    WORD   21 = 2
    LONG   22 = 4
    QUAD   23 = 8
    OCTA   24 = 16

    QUAD is the default.

    Table 8 Program Section Attributes

    AttribuFunction

    ABS    Absolute-The program section has an absolute address. An
           absolute program section contributes no binary code to
           the image, so its byte allocation request to the linker
           is 0. You cannot store initial values in an absolute
           program section with directives such as .BYTE, .WORD,
           .LONG, .QUAD. Usually the .BLKx directives are used in
           conjunction with label definitions within an absolute
           program section to define symbolic offsets within a
           structure. Compare this attribute with its opposite, REL.

    CON    Concatenate-Program sections with the same name and
           attributes (including CON) from other modules are
           concatenated into one program section at link time. Their
           contents are concatenated in the order in which the linker
           acquires them. The allocated virtual address space is the
           sum of the individual requested allocations. Compare this
           attribute with its opposite, OVL.

    EXE    Executable-The program section contains instructions.
           This attribute provides the capability of separating
           instructions from read-only and read/write data. The
           linker uses this attribute in gathering program sections
           and in verifying that the transfer address is in an
           executable program section. The assembler only allows
           you to place instructions in a program section that has
           either or both the EXE or MIX attributes. Compare this
           attribute with its opposite, NOEXE.

    GBL    Global-Program sections that have the same name and
           attributes will be combined at link time into a single
           program section even when the individual program sections
           are in different clusters. This attribute is specified
           for Fortran COMMON block program sections. Compare this
           attribute with its opposite, LCL.

    LCL    Local-The program section is restricted to its cluster.
           Compare this attribute with its opposite, GBL.

    MIX    Mix-The program section can contain both data and
           instructions. The MIX and NOMIX attributes are assembly-
           time attributes that only affect assembler processing.
           The MIX and NOMIX attributes do not appear in the object
           module and do not affect linker processing. To mix
           instructions and data in the same psect, you must specify
           the MIX attribute. The NOMIX attribute is the default. If
           you choose to use instructions in a NOEXE psect, or use
           data directives in an EXE psect, you must specify the MIX
           attribute. The following limitations apply when using the
           MIX attribute:

           o  Optimizations and alignment of code labels are not
              performed. Optimizations and code-label alignment are
              not performed on instructions placed in a MIX psect,
              regardless of whether the .ENABLE/.DISABLE options have
              been set, or if the command-line /OPTIMIZATION and
              /ALIGNMENT=CODE options have been specified.

           o  Limited debugging information is provided. No PC-line
              (program counter) correlation information is generated
              for the instructions placed in a MIX psect.

           o  The listing file includes only binary encoded
              instructions. All instructions that are placed in a
              MIX psect appear in the machine-code portion of the
              listing file, in their binary encoded instruction form
              as a data initializer to the .LONG data directive.

           There are no restrictions on data directives. Compare this
           attribute with its opposite, NOMIX.

    NOEXE  Not Executable-The program section contains data only; it
           does not contain instructions. The assembler only allows
           you to place data allocations in a program section that
           has either or both the NOEXE and MIX attributes. Compare
           this attribute with its opposite, EXE.

    NOMIX  The default attribute when you use the .PSECT directive.
           Compare this attribute with its opposite, MIX.

    NOPIC  Non-Position-Independent Content-The program section is
           assigned to a fixed location in virtual memory (when it
           is in a shareable image). Compare this attribute with its
           opposite, PIC.

    NORD   Nonreadable-Reserved for future use. Compare this
           attribute with its opposite, RD.

    NOSHR  No Share-The program section is reserved for private use
           at execution time by the initiating process. Compare this
           attribute with its opposite, SHR.

    NOWRT  Nonwritable-The contents of the program section cannot
           be altered (written into) at execution time. Compare this
           attribute with its opposite, WRT.

    OVR    Overlay-Program sections with the same name and attributes
           (including OVR) from other modules receive the same
           relocatable base address in memory at link time. The
           allocated virtual address space is the requested
           allocation of the largest overlaying program section.
           Compare this attribute with its opposite, CON.

    PIC    Position-Independent Content-The program section can be
           relocated; that is, it can be assigned to any memory area
           (when it is in a shareable image). Compare this attribute
           with its opposite, NOPIC.

    RD     Readable-Reserved for future use. Compare this attribute
           with its opposite, NORD.

    REL    Relocatable-The linker assigns the program section a
           relocatable base address. The contents of the program
           section can be code or data. Compare this attribute with
           its opposite, ABS.

    SHR    Share-The program section can be shared at execution time
           by multiple processes. This attribute is assigned to a
           program section that can be linked into a shareable image.
           Compare this attribute with its opposite, NOSHR.

    WRT    Write-The contents of the program section can be altered
           (written into) at execution time. Compare this attribute
           with its opposite, NOWRT.

    Table 9 Default Program Section Attributes

    Default
    Attribute   Opposite Attribute

    CON         OVR
    EXE         NOEXE
    LCL         GBL
    NOMIX       MIX
    NOPIC       PIC
    NOSHR       SHR
    RD          NORD
    REL         ABS
    WRT         NOWRT

1.18.57.2  –  Description

    .PSECT defines a program section and its attributes and refers to
    a program section after it is defined. Use program sections to do
    the following:

    o  Develop modular programs.

    o  Separate instructions from data.

    o  Allow different modules to access the same data.

    o  Protect read-only data and instructions from being modified.

    o  Identify sections of the object module to the linker and the
       debugger.

    o  Control the order in which program sections are stored in
       virtual memory.

    When the assembler encounters a .PSECT directive that specifies
    a new program section name, it creates a new program section
    and stores the name, attributes, and alignment of the program
    section. The assembler includes all data or instructions that
    follow the .PSECT directive in that program section until it
    encounters another .PSECT directive. The assembler starts all
    program sections at a relative location counter of 0.

    The assembler does not automatically define program sections.
    Any code or data placed before the first .PSECT directive in the
    source code produces an assembly error.

    If the assembler encounters a .PSECT directive that specifies
    the name of a previously defined program section, it stores the
    new data or instructions after the last entry in the previously
    defined program section, even with program sections that have
    the OVR attribute. (OVR program sections from separate modules
    are overlaid by the linker. The OVR attribute does not affect
    how multiple contributions to a psect are processed within a
    single assembly unit.) You need not relist the attributes when
    continuing a program section, but any attributes that are listed
    must be the same as those previously in effect for the program
    section. A continuation of a program section cannot contain
    attributes conflicting with those specified, or defaulted, in
    the original .PSECT directive.

    The attributes listed in the .PSECT directive describe the
    contents of the program section. Except for the EXE and NOEXE
    attributes, the assembler does not check to ensure that the
    contents of the program section actually adhere to the attributes
    listed. However, the assembler and the linker do check that
    all program sections with the same name have exactly the same
    attributes. The assembler and linker display an error message if
    the program section attributes are not consistent.

    Program section names are independent of local symbol, global
    symbol, and macro names. You can use the same symbolic name
    for a program section and for a local symbol, global symbol,
    or macro name. You may want to use unique names for clarity and
    maintainability.

1.18.57.3  –  Notes

    o  The .ALIGN directive cannot specify an alignment greater than
       that of the current program section; consequently, .PSECT
       should specify the largest alignment needed in the program
       section.

    o  For efficiency of execution and ease of programming, an
       alignment of quadword or larger is recommended for all program
       sections that have quadword data.

1.18.57.4  –  Example

        .PSECT A,QUAD,EXE     ; Code psect

1.18.58  –  .QUAD

    Quadword storage directive

    Format

      .QUAD  expression-list

1.18.58.1  –  Parameter

 expression-list

    One or more expressions separated by commas.

1.18.58.2  –  Description

    .QUAD generates 64 bits (8 bytes) of binary data.

1.18.58.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a quadword (64-bit) boundary
       before allocating storage.

1.18.58.4  –  Example

        A:: .QUAD 4

1.18.59  –  .REPEAT

    Repeat block directive

    Format

      .REPEAT expression
         .

         .

         .

      range
         .

         .

         .

      .ENDR

1.18.59.1  –  Parameters

 expression

    An expression whose value controls the number of times the range
    is to be assembled within the program. When the expression is
    less than or equal to 0, the repeat block is not assembled. The
    expression must be absolute or relocatable and must not contain
    any undefined symbols. The assembler converts a relocatable value
    to the relative offset within the psect.

 range

    The source text to be repeated the number of times specified by
    the value of the expression. The repeat block can contain macro
    definitions or other repeat blocks. .MEXIT is legal within the
    range and causes the current and all succeeding repetitions to be
    aborted.

1.18.59.2  –  Description

    .REPEAT repeats a block of code a specified number of times in
    line with other source code. The .ENDR directive specifies the
    end of the range.

1.18.59.3  –  Notes

    The alternate form of .REPEAT is .REPT.

1.18.59.4  –  Examples

      Example 1
      The following macro definition uses the .REPEAT directive to
      store an ASCII string a specified number of times, followed by
      a 0 byte:

        .MACRO  COPIES  STRING,NUM
        .REPEAT NUM
        .ASCII  "STRING"
        .ENDR
        .BYTE   0
        .ENDM   COPIES
      Example 2
      The following macro call stores five copies of the string
      ABCDEF. This example is divided into four parts:

      Macro invocation:

        COPIES  <ABCDEF>,5

      Macro expansion of .REPEAT invocation:

          .REPEAT 5
          .ASCII  "ABCDEF"
          .ENDR

      .REPEAT expansion:

          .ASCII  "ABCDEF"
          .ASCII  "ABCDEF"
          .ASCII  "ABCDEF"
          .ASCII  "ABCDEF"
          .ASCII  "ABCDEF"

      End of macro expansion:

          .BYTE   0
      Example 3
      The following macro call stores three copies of the string How
      Many Times. This example is divided into four parts:

      Macro invocation:

          VARB = 3
          COPIES  <How Many Times>,VARB

      Macro expansion of .REPEAT invocation:

          .REPEAT VARB
          .ASCII  "How Many Times"
          .ENDR

      .REPEAT expansion:

          .ASCII  "How Many Times"
          .ASCII  "How Many Times"
          .ASCII  "How Many Times"

      End of macro expansion:

          .BYTE   0

1.18.60  –  .RESTORE PSECT

    Restore previous program section context directive

    Format

      .RESTORE_PSECT

      .RESTORE

1.18.60.1  –  Description

    .RESTORE_PSECT retrieves the program section from the top of
    the program section context stack, an internal stack in the
    assembler. If the stack is empty when .RESTORE_PSECT is issued,
    the assembler displays an error message. When .RESTORE_PSECT
    retrieves a program section, it restores the current location
    counter to the value it had when the program section was saved.
    The maximum stack level is 50. See the description of .SAVE_PSECT
    for more information.

1.18.60.2  –  Notes

    o  The alternate form of .RESTORE_PSECT is .RESTORE.

    o  You cannot use .RESTORE_PSECT to overwrite previous data-
       storage initializations. In the following example, MACRO-
       64 attempts to store 42 over 43 and fails, resulting in a
       diagnostic:

       .PSECT A
       .SAVE PSECT
       .PSECT A
       .QUAD 43
       .RESTORE PSECT
       .QUAD 42

1.18.60.3  –  Example

            .PSECT A,QUAD,NOEXE
        A1: .WORD 5
        A2: .QUAD 6
            .SAVE_PSECT        ; Saves psect A context
            .PSECT B,QUAD,NOEXE
        B1: .WORD 6
            .RESTORE_PSECT     ; Return A location counter
        A3: .WORD 5

            .PSECT B,QUAD,NOEXE
        1$: .WORD 5
            .SAVE LOCAL_BLOCK  ; Saves psect B context and temporary
                               ; label context

            .PSECT C,NOEXE
        1$: .WORD 6
            .RESTORE_PSECT     ; Restores psect B and saves
                               ; label context
            .ADDRESS 1$        ; References the address of
                               ; psect B temporary label 1$

1.18.61  –  .SAVE PSECT

    Save current program section context directive

    Format

      .SAVE_PSECT  [LOCAL_BLOCK]

      .SAVE  [LOCAL_BLOCK]

1.18.61.1  –  Description

    .SAVE_PSECT stores the current program section context on the
    top of the program section context stack, an internal assembler
    stack. It leaves the current program section context in effect.
    The program section context stack can hold up to 50 entries.
    Each entry includes the value of the current location counter
    and the maximum value assigned to the location counter in the
    current program section. If the stack is full when .SAVE_PSECT is
    encountered, an error occurs.

    If the LOCAL_BLOCK option is specified, the current temporary
    label block is saved with the current program section context.

    .SAVE_PSECT and .RESTORE_PSECT are especially useful in macros
    that define program sections. See the description of .RESTORE_
    PSECT for an example using .SAVE_PSECT.

1.18.61.2  –  Notes

    o  The alternate form of .SAVE_PSECT is .SAVE.

1.18.62  –  .S FLOATING

    Single-precision IEEE floating-point arithmetic directive

    Format

      .S_FLOATING  floating-point-number-list

1.18.62.1  –  Parameter

 floating-point-number-list

    A list of IEEE single-precision floating-point constants
    separated by commas.

1.18.62.2  –  Description

    .S_FLOATING evaluates the specified floating-point constants and
    stores the results in the object module. .S_FLOATING generates
    32-bit, single-precision, floating-point data (1 bit of sign, 8
    bits of exponent, and 23 bits of fractional significance). See
    the description of .T_FLOATING for information on storing double-
    precision floating-point IEEE numbers and the descriptions of
    .D_FLOATING, .F_FLOATING, and .G_FLOATING for descriptions of
    other floating-point numbers.

1.18.62.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a longword (32-bit) boundary
       before allocating storage.

1.18.62.4  –  Example

        .S_FLOATING 2.0,3.0,4.405

1.18.63  –  .SHOW

    Listing inclusion and exclusion directives

    Format

      .SHOW  [argument-list]

      .NOSHOW  [argument-list]

1.18.63.1  –  Parameter

 [argument-list]

    You can use either the long form or the short form of the
    arguments. If you specify multiple arguments, you must separate
    them by commas. If any argument is not specifically included in
    a listing control statement, the assembler assumes its default
    value (show or noshow) throughout the source program.

    Table 10 .SHOW and .NOSHOW Symbolic Arguments

                  Short
    Long Form     Form     Default  Function

    BINARY        MEB      Noshow   Lists macro and repeat block
                                    expansions that generate binary
                                    code. BINARY is a subset of
                                    EXPANSIONS.
    CONDITIONALS  CND      Noshow   Lists unsatisfied conditional
                                    code associated with the
                                    conditional assembly directives.
    EXPANSIONS    ME       Noshow   Lists macro and repeat range
                                    expansions.
    LIBRARY       None     Noshow   Includes the macro definitions in
                                    a library in the listing.
    INCLUDE       None     Noshow   Lists include file text in the
                                    listing file.

1.18.63.2  –  Description

    .SHOW and .NOSHOW specify listing control options in the source
    text of a program. You can use .SHOW and .NOSHOW with or without
    an argument list.

    .SHOW and .NOSHOW control the listing of the source lines that
    are in conditional assembly blocks (see the description of .IF),
    macros, and repeat blocks. When you use them without arguments,
    these directives alter the listing level count. The listing level
    count is initialized to 0. Each time .SHOW appears in a program,
    the listing level count is incremented; Each time .NOSHOW appears
    in a program, the listing level count is decremented.

    When the listing level count is negative, the listing is
    suppressed unless the line contains an error. Conversely, when
    the listing level count is positive, the listing is generated.
    When the count is 0, the line is either listed or suppressed,
    depending on the value of the listing control symbolic arguments.

1.18.63.3  –  Notes

    o  The listing level count allows macros to be listed
       selectively; a macro definition can specify .NOSHOW at the
       beginning to decrement the listing count and can specify .SHOW
       at the end to restore the listing count to its original value.

    o  The alternate forms of .SHOW and .NOSHOW are .LIST and .NLIST.

    o  The initial setting for each .LIST/.SHOW option (except
       BINARY) is obtained from the command-line setting using the
       /SHOW qualifier.

    o  The /[NO]SHOW=BINARY option overrides the .[NO]SHOW BINARY
       directive.

1.18.63.4  –  Example

        .NOSHOW   ; Turn off listing file display.  Counter < 0.
           .
           .
           .
        .SHOW     ; Turn on listing file display.  Counter = 0.
                  ; Value of .SHOW options are used.
           .
           .
           .
        .SHOW     ; Counter > 0.  Listing file display is
                  ; on for all options regardless of setting.
           .
           .
           .

1.18.64  –  .SIGNED BYTE

    Signed byte storage directive

    Format

      .SIGNED_BYTE  expression-list

1.18.64.1  –  Parameters

 expression-list

    An expression or list of expressions separated by commas. Each
    expression specifies a value to be stored. The value must be in
    the range of -128 through +127.

1.18.64.2  –  Description

    .SIGNED_BYTE generates successive bytes of binary data in the
    object module and performs signed range checking. Apart from
    the range check, .SIGNED_BYTE is equivalent to .BYTE for storage
    allocation.

1.18.64.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

1.18.64.4  –  Example

        .PSECTA,NOEXE
        .SIGNED_BYTE   LABEL1-LABEL2  ;  Data must fit
        .SIGNED_BYTE   -126           ;     in a byte

1.18.65  –  .SIGNED WORD

    Signed word storage directive

    Format

      .SIGNED_WORD  expression-list

1.18.65.1  –  Parameter

 expression-list

    An expression or list of expressions separated by commas. Each
    expression specifies a value to be stored. The value must be in
    the range of -32,768 through +32,767.

1.18.65.2  –  Description

    .SIGNED_WORD generates successive words of binary data in the
    object module and performs signed range checking. Apart from
    the range check, .SIGNED_WORD is equivalent to .WORD in terms of
    storage allocation.

1.18.65.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a word (16-bit) boundary
       before allocating storage.

1.18.65.4  –  Example

        .PSECT $DATA,NOEXE
        .SIGNED_WORD -32766;
        .SIGNED_WORD 32769 ;causes assembly error

1.18.66  –  .SUBTITLE

    Listing subtitle directive

    Format

      .SUBTITLE  quoted-literal

      .SBTTL  quoted-literal

1.18.66.1  –  Parameter

 quoted-literal

    An ASCII string enclosed in quotes from 1 to 31 characters long;
    excess characters are truncated.

1.18.66.2  –  Description

    .SUBTITLE causes the assembler to print the line of text as
    the subtitle on the second line of each assembly listing page.
    This subtitle text is printed on each page until altered by a
    subsequent .SUBTITLE directive in the program.

1.18.66.3  –  Notes

    o  The alternate form of .SUBTITLE is .SBTTL.

    o  This directive also accepts VAX MACRO syntax. See the
       VAX MACRO and Instruction Set Reference Manual for details.

1.18.66.4  –  Example

        .SUBTITLE "Terminal Display Routines"

1.18.67  –  .T FLOATING

    Double-precision IEEE floating-point arithmetic directive

    Format

      .T_FLOATING  floating-point-number-list

1.18.67.1  –  Parameter

 floating-point-number-list

    A list of IEEE double-precision floating-point constants
    separated by commas.

1.18.67.2  –  Description

    .T_FLOATING evaluates the specified floating-point constants and
    stores the results in the object module. .T_FLOATING generates
    64-bit, double-precision, floating-point data (1 bit of sign, 11
    bits of exponent, and 52 bits of fractional significance). See
    the description of .S_FLOATING for information on storing single-
    precision floating-point IEEE numbers and the descriptions of .D_
    FLOATING, .F_FLOATING, and .G_FLOATING for descriptions of other
    floating-point numbers.

1.18.67.3  –  Notes

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a quadword (64-bit) boundary
       before allocating storage.

1.18.67.4  –  Example

        .T_FLOATING 4.5036,6.034

1.18.68  –  .TITLE

    Listing title directive

    Format

      .TITLE  module-name ["listing-title"]

1.18.68.1  –  Parameters

 module-name

    Either a quoted literal or an identifier that specifies the
    module's title.

 "listing-title"

    Optional quoted literal that specifies a title to appear within
    the first line of each listing output file.

1.18.68.2  –  Description

    .TITLE assigns a name to the object module.

1.18.68.3  –  Notes

    o  The module name specified with .TITLE bears no relationship
       to the file specification of the object module, as specified
       in the MACRO-64 command line. The object module name appears
       in the linker load map and is also the module name that the
       debugger and librarian recognize.

    o  If .TITLE is not specified, MACRO-64 assigns the default
       name (.MAIN.) to the object module. If more than one .TITLE
       directive is specified in the source program, the last .TITLE
       directive encountered establishes the name for the entire
       object module.

    o  This directive also accepts VAX MACRO syntax. See the
       VAX MACRO and Instruction Set Reference Manual for details.

1.18.68.4  –  Example

        .TITLE "MAIN" "Main Entry Point"

1.18.69  –  .UNDEFINE REG

    Undefine register symbol directive

    Format

      .UNDEFINE_REG  regsym

1.18.69.1  –  Parameter

 regsym

    A currently defined floating-point or integer register symbol.

1.18.69.2  –  Description

    The register symbol that you specify as the argument to the
    .UNDEFINED_REG directive is no longer a register symbol. Starting
    with the statement that follows the .UNDEFINE_REG directive, you
    can use the symbol as a MACRO-64 identifier.

1.18.69.3  –  Notes

    o  If you specify a MACRO-64 identifier that is not currently
       defined as a register symbol, the .UNDEFINE_REG directive has
       no effect.

1.18.69.4  –  Example

           .DEFINE_IREG  X1    R5      ; X1 is integer register 5
           .UNDEFINE_REG X1            ; X1 is an identifier again
           .DEFINE_IREG  X1    7       ; X1 is integer register 7 -
 no
                                        ;  redefinition and no warning

            $ROUTINE F0                 ; Error: F0 is a register and
                                        ;  cannot be used as an
                                        ;  identifier
            .UNDEFINE_REG F0            ; F0 is no longer a register
            $ROUTINE F0                 ; Ok now

1.18.70  –  .WARN

    Warning directive

    Format

      .WARN  quoted-literal

1.18.70.1  –  Parameter

 quoted-literal

    The string of characters enclosed in quotes are displayed during
    assembly.

1.18.70.2  –  Description

    .WARN causes the assembler to display a warning message on the
    terminal or in the batch log file, and in the listing file (if
    there is one).

1.18.70.3  –  Notes

    o  .PRINT, .WARN, and .ERROR are directives that display
       messages. You can use them to display information indicating
       an unexpected or important assembly condition.

    o  This directive also accepts VAX MACRO syntax. See the
       VAX MACRO and Instruction Set Reference Manual for details.

1.18.70.4  –  Example

        .WARN "Illegal parameter value; 0 assumed"
        ^
        %MACRO64-W-
 GENWARN, Generated WARNING: Illegal parameter value; 0 assumed
        at line number 3 in file DISK$:[TEST]WARN.M64;2

1.18.71  –  .WEAK

    Weak symbol attribute directive

    Format

      .WEAK  symbol-list

1.18.71.1  –  Parameter

 symbol-list

    A list of identifiers separated by commas.

1.18.71.2  –  Description

    .WEAK specifies symbols that are either defined externally in
    another module or defined globally in the current module. .WEAK
    suppresses any object library search for the symbol.

    When .WEAK specifies a symbol that is not defined in the current
    module, the symbol is externally defined. If the linker finds the
    symbol's definition in another module, it uses that definition.
    If the linker does not find an external definition, the symbol
    has a value of 0 and the linker does not report an error. The
    linker does not search a library for the symbol, but if a module
    brought in from a library for another reason contains the symbol
    definition, the linker uses it.

    When .WEAK specifies a symbol that is defined in the current
    module, the symbol is considered to be globally defined. However,
    if this module is inserted in an object library, this symbol
    is not inserted in the library's symbol table. Consequently,
    searching the library at link time to resolve this symbol does
    not cause the module to be included.

1.18.71.3  –  Example

            .WEAK A,B,C
        A:: .WORD 5     ; A and B are weak global definitions
        B:: .QUAD 6
            .ADDRESS C  ; C is a weak external reference

1.18.72  –  .WORD

    Word storage directive

    Format

      .WORD  expression-list

1.18.72.1  –  Parameter

 expression-list

    One or more expressions separated by commas.

1.18.72.2  –  Description

    .WORD generates successive words (2 bytes) of data in the object
    module.

1.18.72.3  –  Notes

    o  The expression is first evaluated as a quadword and then
       truncated to a word. The value of the expression should be
       in the range of -32,768 to +32,767 for signed data or 0 to
       65,535 for unsigned data. The assembler displays an error if
       the high-order 6 bytes of the quadword expression have a value
       other than zero or ^XFFFFFFFFFFFF.

    o  The assembler truncates on the left of an integer or external
       value.

    o  Addresses are not allowed with .WORD.

    o  You can only use this directive within data or mixed psects
       (psects that have either the NOEXE or MIX attributes).

    o  If automatic data alignment is enabled, this directive aligns
       the current location counter to a word (16-bit) boundary
       before allocating storage.

1.18.72.4  –  Example

        .WORD 5,6,7

1.19  –  Supplied Library Macros

    The MACRO-64 assembler provides a library of macros that help you
    to program in conformance with the OpenVMS Calling Standard. This
    library also allows you to define your own opcodes and packed
    decimal data. The library, called MACRO64.MLB, is installed on
    your system with the MACRO-64 assembler.

    The MACRO-64 assembler automatically adds the MACRO64.MLB library
    to the library list before it begins processing your source
    program. Consequently, you do not need to add it manually using
    the .LIBRARY directive.

    The following macros are supplied by the MACRO-64 Assembler:

       $BEGIN_EPILOGUE
       $CALL
       $CODE_SECTION
       $DATA_SECTION
       $END_EPILOGUE
       $END_PROLOGUE
       $END_ROUTINE
       $LINKAGE_PAIR
       $LINKAGE_SECTION
       $OPDEF
       .PACKED
       $PROCEDURE_DESCRIPTOR
       $RESET_LP_LIST
       $RETURN
       $ROUTINE

1.19.1  –  Routines and Lexical Scope

    The calling-standard macros use the concept of a single, current,
    active routine. A routine is a programming entity that is
    associated with a procedure descriptor that may be called, or
    is a main routine specified as the transfer address of a linked
    image.

    Only one routine can be active or current at any given time
    during assembly. If more than one routine is defined in a single
    assembler source file, all items associated with the current
    routine, that is, within the lexical scope of the routine, must
    be completed before making a different routine current. The
    lexical scope of one routine cannot overlap the lexical scope
    of another routine.

    A routine becomes current or comes into scope by invoking the
    $ROUTINE macro with the appropriate arguments. $ROUTINE marks the
    beginning of the lexical scope of a routine. The complementary
    macro, $END_ROUTINE, marks the end of the current routine's
    lexical scope.

1.19.1.1  –  Routines and Program Sections

    Routines have three types of associated program sections:

    o  Code section-Contains the executable instructions of the
       routine. This section is typically read-only and executable.

    o  Data section-Contains data accessed by a routine. Typically,
       this is where variable data is stored. This section is
       typically nonexecutable, readable, and writeable.

    o  Linkage section-Contains a routine's procedure descriptor and
       the necessary linkage information for calling other routines,
       and for linkage to data not in the linkage section, if any.
       Also, constant data may be placed here. Typically, this
       section is read-only and not executable.

       The linkage section is considered a type of data section with
       the following function:

       -  Provides linkage information for calls made from a routine
          associated with the linkage section.

       -  Provides linkage information for data outside of the
          linkage section.

       -  Defines the associated routine's procedure descriptor so
          that calls can be made to the routine.

       -  Defines constant or static data.

1.19.2  –  Using Macros to Control Program Sections

    The following section explains how to use the MACRO-64 supplied
    macros to define and control the various program sections during
    assembly.

1.19.2.1  –  Defining Program Sections

    Each of the three program section types can be referenced by a
    corresponding macro. The following three macros are used to refer
    to and define these three psects associated within a routine:

    o  $CODE_SECTION-makes the routine's code psect current.

    o  $DATA_SECTION-makes the routine's data psect current.

    o  $LINKAGE_SECTION-makes the routine's linkage psect current.

    To switch to one of the current routine's sections, you invoke
    the corresponding macro. For example, after invoking $ROUTINE,
    to place instructions into the current routine's code psect,
    you invoke the $CODE_SECTION macro. This makes the code psect
    associated with the current routine the current psect. Similarly,
    invoking $LINKAGE_SECTION makes the linkage psect associated with
    the current routine the current psect.

    You can also control the psect name and attributes for each of
    the program sections by defining arguments to the $ROUTINE macro.

1.19.2.2  –  Using Macro Defined Symbols

    When you use any of the supplied macros described in this
    chapter, with the exception of $OPDEF, the following register
    symbols are defined for you:

       .DEFINE_IREG $IA0 R16 ; Integer argument 0
       .DEFINE_IREG $IA1 R17 ; Integer argument 1
       .DEFINE_IREG $IA2 R18 ; Integer argument 2
       .DEFINE_IREG $IA3 R19 ; Integer argument 3
       .DEFINE_IREG $IA4 R20 ; Integer argument 4
       .DEFINE_IREG $IA5 R21 ; Integer argument 5
       .DEFINE_FREG $FA0 F16 ; Floating-point argument 0
       .DEFINE_FREG $FA1 F17 ; Floating-point argument 1
       .DEFINE_FREG $FA2 F18 ; Floating-point argument 2
       .DEFINE_FREG $FA3 F19 ; Floating-point argument 3
       .DEFINE_FREG $FA4 F20 ; Floating-point argument 4
       .DEFINE_FREG $FA5 F21 ; Floating-point argument 5
       .DEFINE_IREG $AI R25 ; Argument-information register
       .DEFINE_IREG $RA R26 ; Return-address register
       .DEFINE_IREG $PV R27 ; Procedure-value register
       .DEFINE_IREG $FP R29 ; Frame pointer
       .DEFINE_IREG $SP R30 ; Stack pointer

                                   NOTE

       SP and FP remain predefined by MACRO-64 whether or not
       you use the OpenVMS Calling Standard macros. $SP and
       $FP are defined by the OpenVMS Calling Standard macros
       for consistency with the other register definitions that
       correspond to OpenVMS Calling Standard register conventions.

    The following symbols are defined by the $ROUTINE macro. These
    symbols are useful while programming with the calling-standard
    macros to refer to particular data and linkage section items.

    o  $CS-The address of the beginning of the current routine's code
       section.

    o  $LS-The address of the beginning of the current routine's
       linkage section.

    o  $DS-The address of the beginning of the current routine's data
       section.

    o  $DP-The linkage section address where the $ROUTINE macro
       places the .ADDRESS $DS to enable access to the data section
       from the linkage section (this variable is optional).

    o  $SIZE-The size of the fixed-stack area in bytes. $SIZE is
       defined using the value specified with the SIZE argument.

    o  $RSA_OFFSET-The offset within the fixed-stack area to the
       register save area. $RSA_OFFSET is defined using the value
       specified with the RSA_OFFSET argument.

    o  $RSA_END-The offset within the fixed-stack area to the first
       byte beyond the end of the register save area.

    For more information, see the description for the $ROUTINE macro
    in this chapter.

    The $CALL macro also defines the $STACK_ARG_SIZE symbol. This
    symbol specifies the number of bytes used to store arguments
    on the stack. This value is useful after calling a routine that
    returns a value on the stack. In this case, $CALL cannot remove
    the arguments from the stack because you must first retrieve the
    returned value from the stack. Subsequently, you can remove the
    arguments from the stack using the $STACK_ARG_SIZE symbol. For
    more information, see the description of $CALL in this chapter.

1.19.2.3  –  Defining Procedure Type

    The OpenVMS Calling Standard defines four types of routines;
    stack, register, null, and bound.

    You can define the routine type by using the KIND keyword
    argument with $ROUTINE or $PROCEDURE_DESCRIPTOR macros. The
    validity and values of other $ROUTINE and $PROCEDURE_DESCRIPTOR
    macro parameters are determined by the type of routine being
    declared. For example, a null procedure type has no stack size;
    therefore, the SIZE parameter is invalid and cannot be specified
    for a null procedure type. When using the KIND keyword with the
    $ROUTINE or $PROCEDURE_DESCRIPTOR macros, note the following
    exceptions:

    o  The $SIZE symbol defined by $ROUTINE is only valid for stack
       and register routines.

    o  The $RSA_OFFSET symbol defined by $ROUTINE is only valid for a
       stack routine.

1.19.2.4  –  Using Macros in Prologue Sections

    With stack and register routines, $ROUTINE generates a standard
    prologue sequence if you specify the STANDARD_PROLOGUE=TRUE
    keyword argument. STANDARD_PROLOGUE=TRUE is the default for
    register and stack routines.

    Alternatively, you can code your own prologue sequence by
    specifying the STANDARD_PROLOGUE argument as FALSE and using the
    $END_PROLOGUE macro to mark the end of your prologue sequence. In
    this case, you may wish to use the $SIZE and $RSA_OFFSET symbols
    to symbolically specify the fixed-stack size and register save
    area offset, respectively.

    For more information on the prologue sequence of instructions
    that must occur at the beginning of all stack and register
    routines, see the OpenVMS Calling Standard.

1.19.2.5  –  Using Macros in Epilogue Sections

    With stack and register routines, you can use the $RETURN
    macro to generate an epilogue sequence. Alternatively, you
    can code your own epilogue sequence using the $BEGIN_EPILOGUE
    and $END_EPILOGUE macros to mark the beginning and end of your
    epilogue sequences.

    The OpenVMS Calling Standard also describes the epilogue sequence
    of instructions that must be executed every time a stack or
    register routine returns to its caller.

1.19.3  –  Programming Examples Using Supplied Macros

    Examples Program Using Supplied Macros and Program Using $CALL
    show how to use the calling-standard macros to define a routine,
    switch control between psects, generate an epilogue sequence, and
    end the routine.

    Example 3  Program Using Supplied Macros

            $ROUTINE MAIN, KIND=STACK, - ; Stack routine kind 1
                SAVED_REGS=<FP>, - ; Saves FP           2
                SIZE=48               ; Stack size is 48   3

            $LINKAGE_SECTION          ; Switch to the linkage psect. 4

    X:      .long 6                   ; X is a constant
    FP1_ADDR:                         ; FP1_ADDR -> FP1
            .address FP1

            $DATA_SECTION             ; Switch to the data section 5

    A::     .blkw 5                   ; $DS points here
    B::     .blkw

            $CODE_SECTION             ; Switch to the code section 6
                                      ; ($CS points here)
                   .
                   .
                   .
            $RETURN                   ; Perform epilogue and return 7

            $END_ROUTINE MAIN         ; Mark the end of the routine 8

    1  $ROUTINE defines the routine MAIN. The routine type is defined
       as a stack routine using the KIND=STACK keyword argument.

    2  The keyword argument SAVED_REGS=<FP> adds the frame pointer
       register to the list of registers saved on the stack by the
       prologue code. The SAVED_REGS keyword is valid only for stack
       procedures. If you do not specify the FP register (R29) with
       this argument, it is assumed.

    3  The keyword argument SIZE=48 defines the stack area in bytes.
       This argument is valid only for register and stack routines.
       If you do not specify a stack size for a stack or register
       routine, $ROUTINE computes the minimum stack size required to
       accommodate the other arguments you specify or leave as the
       default.

    4  The $LINKAGE_SECTION macro switches to the linkage section.
       You can use the $LS symbol created by the $ROUTINE macro
       to point to the address of the current routine's linkage
       section. $ROUTINE creates the procedure descriptor and leaves
       the current location counter within the linkage section just
       beyond the procedure descriptor.

    5  The $DATA_SECTION macro switches to the data section. You can
       use the $DS symbol created by the $ROUTINE macro to point to
       the address of the current routine's data section.

    6  The $CODE_SECTION macro switches to the code section. The $CS
       symbol created by the $ROUTINE macro is used to point to the
       address of the current routine's code section.

    7  The $RETURN macro generates a standard epilogue instruction
       sequence. You can use this macro only with stack or register
       routine defined with the $ROUTINE macro.

    8  The $END_ROUTINE macro marks the end of the routine.

1.19.4  –  Using the $CALL Macro

    $CALL calls local or external routines previously defined by the
    $ROUTINE macro or defined in another language.

    To call a routine using standard linkage, use the $CALL macro.
    You invoke this macro from within the routine's code section.
    $CALL performs the following actions:

    o  Searches a list of linkage pairs referenced in previous
       invocations of the $CALL and $LINKAGE_PAIR macros within
       the calling routine. If a linkage pair is already found to
       exist on the list, $CALL uses the linkage pair stored from the
       previous invocation. Otherwise, $CALL stores the linkage pair
       of the called routine in the caller's linkage section and adds
       the linkage pair to the caller's list.

    o  Allocates stack space for arguments, if necessary.

    o  Loads arguments specified with the ARGS argument into argument
       registers and onto the stack, as appropriate.

    o  Sets the arguments information register, R25, according to the
       arguments specified with ARGS argument.

    o  Generates the following instruction sequence to perform
       the actual call based on the location of the linkage pair
       generated from above, and the value of Rls, linkage register,
       which is assumed to point to the base of the linkage section:

             LDQ R26, code_addr_offset(Rls)      ; load code address
             LDQ R27, proc_desc_addr_offset(Rls) ; load procedure
                                                 ; descriptor address
                                                 ;
             JSR R26, R26                        ; Jump to the routine
                                                 ;  saving the return
                                                 ;  address in R26

    o  Frees argument stack space, if any, and if the called routine
       does not return a value on the stack.

       Like $ROUTINE, the $CALL macro invokes other macros to perform
       the previous tasks.

       If you do not specify the Rls argument in your invocation of
       $CALL, $CALL assumes that you have used the .BASE directive
       to define a register that points to the base address of your
       linkage section. That is, it assumes that you have included a
       statement similar to the following:

       .BASE R27, $LS

       This source statement defines the base address of the linkage
       section to be R27, and to be associated with the macro symbol
       $LS. This source statement should be placed in your source
       code before the $CALL macro call.

1.19.4.1  –  Using $CALL in Source Code

    This example uses the same source code from the previous example,
    except it uses the $CALL macro to show how to call a local and
    external routine.

    Example 4  Program Using $CALL

                .
                .
                .
            $CODE_SECTION             ; Switch to the code section
                                      ; ($CS points here)
                .
                .
                .
            MOV     R27,R2    1
            .base   R2, $LS   2
                .
                .
                .
            $CALL SUB1                ; Call external routine SUB1  3
            $CALL SUB2, LOCAL=TRUE    ; Call local routine SUB2     4
                .
                .
                .
            $RETURN                   ; Perform epilogue and return
            $END_ROUTINE MAIN         ; Mark the end of the routine

    1  The $LS symbol is defined to be the address of the procedure
       that is defined within the linkage section. The calling
       routine places the address of the procedure descriptor in
       R27 before making the call. This guarantees that the address
       associated with the symbol $LS is stored in R27 upon routine
       entry. Since the information in R27 is erased during a
       standard call, a copy is preserved in register R2.

    2  Register R2 now contains the address of our procedure
       descriptor, which is the base address of our linkage section.
       Since $LS is defined to point to the base address of the
       linkage section, the assembler computes the offsets within
       the linkage section using the .BASE directive.

    3  The $CALL macro calls the external routine SUB1.

    4  The $CALL macro calls the local routine SUB2. This call uses
       the LOCAL=TRUE keyword argument to indicate that routine SUB2
       is defined within the module.

1.19.5  –  Programming Considerations

    This section discusses some programming considerations you need
    to be aware of when using the calling-standard macros.

1.19.5.1  –  Making Multiple Calls From the Same Routine

    The $CALL macro generates the following instruction sequence:

     LDQ R26, code_address_offset(Rls)              ; load code address
     LDQ R27, procedure_descriptor_address_offset(Rls) ; load procedure
                                                       ;    descriptor
                                                       ;    address
     JSR R26, R26                                      ;

    The contents of R26 and R27 are erased as a result of using the
    $CALL macro. This is important since Rls in the previous sequence
    is typically R27. Thus, if you require subsequent access to your
    linkage section, such as when making subsequent calls, you need
    to make a working copy of R27 to use after the first call.

    Note that $CALL also overwrites the values in the argument
    registers, and the scratch registers specified or the default
    set by the SCRATCH_REGS argument, when you pass arguments to the
    called routine.

1.19.5.2  –  Nonstandard Linkage

    Under certain circumstances, there may be advantages in using a
    nonstandard routine linkage.

1.19.5.3  –  Routine Restrictions

    Different routine types have different capabilities and
    restrictions. For example, only a stack routine that specifies
    BASE_REG_IS_FP=TRUE can make standard calls.

1.19.5.4  –  Syntax Rules

    You can use either positional or keyword argument association
    or a combination of the two with these macros. For positional
    association, the order of formal arguments is shown with
    the format of each macro. The following syntax rules apply
    when invoking the assembler using the command-line qualifier
    /NAMES=AS_IS:

    o  When specifying macro names, you must use all uppercase or all
       lowercase characters. You cannot mix uppercase and lowercase
       characters.

    o  When specifying keyword arguments, you must use the same
       alphabetic case as the macro name it is associated with. If
       you use lowercase characters with the macro name, you must
       use lowercase characters with the keyword argument. If you
       use uppercase characters with the macro name, you must use
       uppercase characters with the keyword argument.

1.19.6  –  $BEGIN EPILOGUE

    Marks the beginning of an epilogue instruction sequence.

    Format

      $BEGIN_EPILOGUE

1.19.6.1  –  Description

    $BEGIN_EPILOGUE marks the beginning of an epilogue instruction
    sequence that you code within a stack or register routine defined
    with the $ROUTINE macro.

    At each point where a stack or register routine returns to
    its caller, the routine must perform a sequence of operations
    to restore any saved registers and to perform stack frame
    management. This sequence is called the epilogue and is described
    in detail in the OpenVMS Calling Standard.

    You can use the $RETURN macro to generate a standard epilogue
    instruction sequence for you, or you can code your own sequence.
    If you code your own epilogue sequence, you must mark the
    beginning and end of the epilogue sequence with the $BEGIN_
    EPILOGUE and $END_EPILOGUE macros.

1.19.6.2  –  Notes

    o  You must not use $BEGIN_EPILOGUE for an epilogue instruction
       sequence generated by $RETURN. $RETURN automatically invokes
       $BEGIN_EPILOGUE and $END_EPILOGUE.

1.19.6.3  –  Example

                $ROUTINE MUMBLE, KIND=REGISTER, SAVE_FP=R1
                    :
                    :
                    :
                $BEGIN_EPILOGUE
                MOV     R1,FP               ; Restore caller's frame
                RET     (R26)               ; Return to caller
                $END_EPILOGUE
                    :
                    :
                    :
                $END_ROUTINE MUMBLE

1.19.7  –  $CALL

    Issues a call to another routine.

    Format

      $CALL  NAME=routine-being-called -

             [Rls=linkage-section-register] -

             [LS=linkage-section-address] -

             [LOCAL=boolean] -

             [ARGS=argument-list] -

             [SET_ARG_INFO=boolean-value] -

             [STACK_RETURN_VALUE=boolean-value] -

             [SCRATCH_REGS=scratch_reg-list] -

             [TIE=boolean-value] -

             [FUNC_RETURN=

             {I64,D64,I32,U32,FF,FD,FG,FS,FT,FDC,FGC,FSC,FTC}]

             -

             [USES_VAX_ARGLIST=boolean-value] -

             [SIGNATURE_BLOCK=signature_address] -

             [NONSTANDARD=boolean-value] -

1.19.7.1  –  Parameters

 NAME

    The name of the routine to call. This argument is required.

 Rls

    Linkage section register to use when generating the LDQ, LDQ, JSR
    instruction sequence. This argument is optional.

    If Rls is omitted, $CALL assumes that you entered a .BASE
    directive before invoking $CALL that establishes the value of a
    base register pointing into the linkage section. If you omit the
    Rls argument and you do not enter such a .BASE directive before
    invoking $CALL, the assembler issues the following error message
    during the $CALL macro expansion:

        "Argument 2 invalid"  The assembler failed to find a
         base register specified with a previous .BASE directive
         to form a register expression of the form offset(Rn)"

 LS

    LS is the address of the linkage section. If you use $CALL within
    a routine defined by the $ROUTINE macro, the LS argument defaults
    to the $LS symbol defined by $ROUTINE. If you use $CALL outside
    of a routine defined by the $ROUTINE macro, there are two ways
    that you can indicate the location of the linkage section to
    $CALL. First, you can specify the LS argument to $CALL as a
    relocatable address expression that indicates the base of the
    linkage section. In this case you must also specify the Rls
    argument. Second, you can specify both the linkage-section base
    register and the linkage-section address in a .BASE directive
    before invoking $CALL. In this case, you must omit both the Rls
    and LS arguments to $CALL.

    Digital recommends that you omit this argument if you use $CALL
    within a routine defined by the $ROUTINE macro.

 LOCAL

    A Boolean value (TRUE or FALSE) that specifies whether the
    routine to be called is local to the module or globally visible.
    By default, $CALL generates a call to a globally visible routine.
    To generate a call to a routine that is not globally visible, you
    must specify LOCAL=TRUE.

 ARGS

    An optional list of arguments to pass to the called routine.
    Enclose the argument list within angle brackets (<>)  and
    separate the arguments with commas (,).  You can use the
    following qualifiers with each argument you specify with the
    ARGS argument. These qualifiers are described in the following
    table.

    Each argument is an address expression (which may include a
    register) followed by a qualifier. The table also contains
    the argument type, the instruction used to load the argument
    into a register, the instruction used to store the argument on
    the stack, and the encodings used in the Argument Information
    Register (R25) in the call signature block when you specify
    TIE=TRUE. See the OpenVMS Calling Standard for more information
    on these encodings. Note that arguments are only stored on
    the stack if there are more than six arguments provided to the
    routine.

                                    ARGS Arguments
 _________________________________________________________________________
 Argument
           Argument   LOAD        STORE       AI       Reg Arg   Mem Arg
 Qualifier Type       Instruction Instruction Encoding Signature Signature
 _________________________________________________________________________

1.19.7.1.1    /A Address LDA STQ I64 I32 I32

1.19.7.1.2    /D D-floating LDG STG FD FD Q

1.19.7.1.3    /F F-floating LDF STF FF FF I32

1.19.7.1.4    /G G-floating LDG STG FG FG Q

1.19.7.1.5    /L Longword LDL STQ I64 I32 I32

1.19.7.1.6    /Q Quadword LDQ STQ I64 Q Q

1.19.7.1.7    /S S-floating LDS STS FS FS I32

1.19.7.1.8    /T T-floating LDT STT FT FT Q

1.19.7.1.9    /UL(1) Unsigned LDL STQ I64 U32 I32

           Longword   /ZAP
                      #^xF0
 _______________________________________________________________________
 (1)--Unsigned 32-bit integers are normally passed using the /L argument
 qualifier. Therefore, Digital does not recommend that you use the /UL
 argument qualifier.
 _______________________________________________________________________

 SET_ARG_INFO

    An optional argument to indicate whether $CALL should
    set the Argument Information (AI) register (R25) with
    the appropriate argument information or not. By default,
    or if you specify SET_ARG_INFO=TRUE, $CALL stores the
    appropriate argument information in R25. If you specify
    SET_ARG_INFO=FALSE, $CALL does not affect R25.

    If you want to conform to the OpenVMS Calling Standard, you
    must store the appropriate information in R25 yourself before
    invoking $CALL. If you do not need to conform to the OpenVMS
    Calling Standard, and if the called routine does not need
    argument information in R25, you can specify SET_ARG_INFO=FALSE
    and make no change in R25. By making no change in R25, you
    avoid the overhead involved when either you or $CALL load
    argument information into R25 at the expense of calling standard
    conformance.

 STACK_RETURN_VALUE

    An optional argument to indicate that the called routine returns
    a value on the stack. By default, $CALL assumes that the called
    routine does not return a value on the stack. In this case, $CALL
    removes any arguments passed to the called routine from the stack
    when the called routine returns.

    If the called routine returns a value on the stack, the returned
    value is placed at a lower address than the arguments on the
    stack. In this case, you must specify STACK_RETURN_VALUE=TRUE
    to prevent $CALL from removing the arguments to the called
    routine from the stack and erasing the value returned by the
    called routine. You must retrieve the return value and remove it
    from the stack. Then you can remove the arguments to the called
    routine using the $STACK_ARG_SIZE symbol defined by $CALL.

 SCRATCH_REGS

    An optional list of scratch registers for $CALL to use when
    processing arguments passed to the called routine with the ARGS
    argument. If you pass more than six arguments to the called
    routine, $CALL may need to use scratch registers to process the
    call.

    By default, $CALL uses R0, R1, F0, and F1. You can cause $CALL to
    use different scratch registers with the SCRATCH_REGS argument.

    If you are passing integer arguments, you should specify at
    least one integer register. If you are passing floating-point
    arguments, you should specify at least one floating-point
    register.

    $CALL can process arguments to the called routine more
    efficiently if you specify two or more scratch registers of the
    type or types appropriate to the arguments you are passsing.

 TIE

    A Boolean value (TRUE or FALSE) that specifies whether $CALL
    should generate a call sequence that is compatible with both
    native routines and the Translated Image Environment (TIE). By
    default, $CALL generates a faster call sequence that is only
    compatible with native routines. If you specify TIE=TRUE, $CALL
    generates a call sequence that works with both native routines
    and translated routines. If you are calling a VAX routine in a
    shareable image that has been translated with the DECmigrate
    image translator, specify TIE=TRUE. If you are calling a native
    routine, Digital recommends you default the TIE argument or
    specify TIE=FALSE. While $CALL generates a call sequence that
    is compatible with native routines when you specify TIE=TRUE,
    that call sequence is slower than when you specify or default
    TIE=FALSE.

 FUNC_RETURN

    An optional argument used to indicate the type of function return
    when you also specify TIE=TRUE. This argument is ignored unless
    you also specify TIE=TRUE. Specify one of I64, D64, I32, U32,
    FF, FD, FG, FS, FT, FFC, FDC, FGC, FSC, or FTC. These values
    correspond to the RASE$K_FR_* signature encodings described
    in Table 3-7 in the OpenVMS Calling Standard. If you specify
    TIE=TRUE and do not specify a function return type with FUNC_
    RETURN, the default function return type is I64.

                                   NOTE

       Specification of the FUNC_RETURN argument does not in itself
       cause $ROUTINE to generate a procedure signature block.
       However, if you specify either or both the ARGLIST or USES_
       VAX_ARGLIST arguments, any value you specify with the FUNC_
       RETURN argument is recorded in both the procedure descriptor
       and the procedure signature block.

 USES_VAX_ARGLIST

    An optional argument to indicate whether the called routine uses
    a VAX argument list. This argument is ignored unless you also
    specify TIE=TRUE. By default, $CALL assumes the called routine
    does not use a VAX argument list. Specify USES_VAX_ARGLIST=TRUE
    to indicate that the called routine uses a VAX argument list.

 SIGNATURE_BLOCK

    An optional argument that you can use to supply the address of
    the call signature block. This argument is ignored unless you
    also specify TIE=TRUE. Note that you cannot specify a SIGNATURE_
    BLOCK argument in combination with either of the FUNC_RETURN
    or USES_VAX_ARGLIST arguments. By default, $CALL generates a
    call signature block for you when you specify TIE=TRUE, and you
    can in part control the contents of that signature block with
    the FUNC_RETURN and USES_VAX_ARGLIST arguments. If you wish to
    define your own call signature block, do not specify either of
    the FUNC_RETURN or USES_VAX_ARGLIST arguments and supply the
    address of your call signature block with the SIGNATURE_BLOCK
    argument.

 NONSTANDARD

    A Boolean value (TRUE or FALSE) that specifies whether $CALL
    should suppress warning and informational messages concerning
    nonstandard usage. By default, $CALL issues warning and
    informational messages to indicate you are using $CALL in a
    way that violates the OpenVMS Calling Standard or in a way
    that requires special programming considerations. Specify
    NONSTANDARD=TRUE if you wish to suppress these messages.

1.19.7.2  –  Description

    $CALL issues a call to another routine and performs the following
    actions:

    1. Searches a list of linkage pairs referenced in previous
       invocations of the $CALL and $LINKAGE_PAIR macros. If a
       linkage pair is already in the list, $CALL uses the linkage
       pair from the previous invocation. Otherwise, $CALL stores
       the linkage pair of the called routine in the caller's linkage
       section and adds the linkage pair to the caller's list. If you
       use $CALL within a routine defined with the $ROUTINE macro,
       $CALL and $LINKAGE_PAIR reset the list of linkage pairs for
       each routine.

    2. Allocates stack space for arguments if necessary.

    3. Generates instructions to load the arguments to the called
       routine.

    4. Sets the value in the argument information register, R25.

    5. Generates the following instruction sequence to perform
       the actual call based on the location of the linkage pair
       generated from step 1 and the address specified or defaulted
       with the LS argument. The register specified with the Rls
       argument is assumed to point to the base of the linkage
       section as shown in the following example:

       LDQ R26, code_address_offset(Rls)         ; load code address
       LDQ R27, procedure_descriptor_address_offset(Rls) ; load
                                                         ;  procedure
                                                         ;  descriptor
                                                         ;  address
           JSR R26, R26

    6. Frees argument stack space, if any, and if the called routine
       does not return a value on the stack.

1.19.7.3  –  Examples

      Example 1
            $CALL SUB1, Rls=R13, LS=MY_LINKAGE_SECTION
            .BASE R13, MY_LINKAGE_SECTION
            $CALL SUB2

            $ROUTINE SUB3, KIND=STACK, SAVED_REGS=<R2,FP>
            $LINKAGE_SECTION
            .QUAD 1
        XX:
            $CODE_SECTION
            MOV R27, R2
            $CALL SUB4, R2
            .BASE R2, $LS
            $CALL SUB5
            $CALL SUB6, -
               ARGS=<XX/A, R0/Q>, -
               SCRATCH_REGS=<R22,R23>
            $CALL SUB7, -
               ARGS=<1/A,2/A,3/A>
            $RETURN
            $END_ROUTINE SUB3
      Example 2
        $CALL FOO, ARGS=<A,B,C,D,E,F,G,H>, STACK_RETURN_VALUE=TRUE
                                ; Fetch octaword return value from stack
        LDQ R4, 0(SP)           ; low quadword
        LDQ R5, 8(SP)           ; high quadword
        LDA SP, $STACK_ARG_SIZE+16(SP)  ; RESET STACK

1.19.8  –  $CODE SECTION

    Switches control to the current routine's code section psect.

    Format

      $CODE_SECTION

1.19.8.1  –  Description

    $CODE_SECTION switches control to the current routine's code
    section psect.

1.19.8.2  –  Example

          $CODE_SECTION

1.19.9  –  $DATA SECTION

    Switches control to the current routine's data section psect.

    Format

      $DATA_SECTION

1.19.9.1  –  Description

    $DATA_SECTION switches control to the current routine's data
    section psect.

1.19.9.2  –  Example

        $DATA_SECTION

1.19.10  –  $END EPILOGUE

    Marks the end of an epilogue instruction sequence.

    Format

      $END_EPILOGUE

1.19.10.1  –  Description

    You can use the $END_EPILOGUE macro to mark the end of an
    epilogue instruction sequence that you code yourself within
    a stack or register routine defined with the $ROUTINE macro.
    At each point where a STACK or REGISTER routine returns to
    its caller, the routine must perform a sequence of operations
    to restore any saved registers and to perform stack-frame
    management. This sequence is called the epilogue and is described
    in detail in the OpenVMS Calling Standard.

    You can use the $RETURN macro to generate a standard epilogue
    instruction sequence for you. Alternatively, you can code your
    own sequence. If you code your own epilogue sequence, you must
    mark the beginning and end of the epilogue sequence with the
    $BEGIN_EPILOGUE and $END_EPILOGUE macros, respectively.

    Note that you must not use $END_EPILOGUE for an epilogue
    instruction sequence generated by $RETURN. $RETURN invokes
    $BEGIN_EPILOGUE and $END_EPILOGUE for you.

    You may omit the invocation of $END_EPILOGUE if your epilogue
    sequence occurs at the end of the routine. The $END_ROUTINE macro
    invokes $END_EPILOGUE for you if you invoke the $BEGIN_EPILOGUE
    macro without a matching invocation of the $END_EPILOGUE macro.
    You must invoke $END_EPILOGUE with epilogue sequences that occur
    in the middle of your routine.

1.19.10.2  –  Example

                $ROUTINE MUMBLE, KIND=REGISTER, SAVE_FP=R1
                    :
                    :
                    :
                $BEGIN_EPILOGUE
                MOV     R1,FP               ; Restore caller's frame
                RET     (R26)               ; Return to caller
                $END_EPILOGUE
                    :
                    :
                    :
                $END_ROUTINE MUMBLE

1.19.11  –  $END PROLOGUE

    Marks the end of a prologue instruction sequence.

    Format

      $END_PROLOGUE

1.19.11.1  –  Description

    $END_PROLOGUE marks the end of a routine prologue instruction
    sequence that you code yourself. The prologue instruction
    sequence begins with the first instruction of the routine. There
    can only be one prologue instruction sequence in a routine. The
    prologue is described in detail in the OpenVMS Calling Standard.

    You invoke $END_PROLOGUE after the last instruction in the
    routine prologue code. The last instruction in the routine
    prologue is the one that updates FP (R29, the frame pointer)
    and makes the frame become current. You must use this macro
    when the routine type is stack or register and you specify
    STANDARD_PROLOGUE=FALSE to the $ROUTINE macro.

1.19.11.2  –  Notes

    o  Do not use this macro when the $ROUTINE macro generates a
       standard prologue or when the routine type is null or bound.
       For example, a standard prologue is generated for you when you
       specify or leave the default of $ROUTINE's STANDARD_PROLOGUE
       argument to TRUE.

1.19.11.3  –  Example

                MOV     SP, FP
                $END_PROLOGUE

1.19.12  –  $END ROUTINE

    Marks the end of a routine.

    Format

      $END_ROUTINE  [name=routine-name]

1.19.12.1  –  Parameter

 name

    The name of the routine that is ended. This argument is optional.
    If you specify a name, $END_ROUTINE verifies that the name
    matches that which was specified with $ROUTINE to begin the
    routine. If the name does not match, $END_ROUTINE issues a
    diagnostic message. There is no default. If you omit the name,
    $END_ROUTINE does not verify a matching name.

1.19.12.2  –  Description

    You must use this macro at the end of a routine that is defined
    with the $ROUTINE macro to delimit the end the current routine
    and to perform final macro processing of the routine.

1.19.12.3  –  Example

            $END_ROUTINE NAME=FOOZLE

1.19.13  –  $LINKAGE PAIR

    Locates or defines a linkage pair in the linkage psect.

    Format

      $LINKAGE_PAIR  name=routine-name, local=boolean

1.19.13.1  –  Parameters

 name

    Name of the linkage pair to define. This argument is required.

 local

    A Boolean value (TRUE or FALSE) that specifies whether the
    routine is defined within the module for not. The default is
    to store a linkage pair for a global routine. You must specify
    LOCAL=TRUE to store a linkage pair for a routine that is not
    globally visible.

1.19.13.2  –  Description

    You can invoke this macro to locate or define a linkage pair
    in the linkage psect. The linkage pair is added to a list for
    later use and retrieval by the $CALL and $LINKAGE_PAIR macros.
    Thus, only the first invocation of $LINKAGE_PAIR (or $CALL) for
    a given routine to be called results in a linkage pair being
    stored. $LINKAGE_PAIR and $CALL use the same list of linkage
    pairs. $LINKAGE_PAIR restores the current psect when it is done.

    $LINKAGE_PAIR defines the symbol $LP. This symbol value is the
    address within the linkage section of the linkage pair for the
    specified routine to call.

1.19.13.3  –  Notes

    o  Because the $CALL macro invokes the $LINKAGE_PAIR macro
       for you, you do not need to use $LINKAGE_PAIR when you are
       using $CALL. You may wish to use $LINKAGE_PAIR when you are
       not using $CALL or when you require a specific ordering or
       placement of linkage pairs within the linkage section.

1.19.13.4  –  Example

    $LINKAGE_PAIR SUB1  ; define linkage pair in linkage section
    LDQ R26, $LP
    LDQ R27, $LP+8
    JSR R26, R26

1.19.14  –  $LINKAGE SECTION

    $LINKAGE_SECTION switches control to the current routine's
    linkage section psect.

    Format

      $LINKAGE_SECTION

1.19.14.1  –  Description

    $LINKAGE_SECTION switches control to the current routine's
    linkage section psect.

1.19.14.2  –  Example

        $LINKAGE_SECTION

1.19.15  –  $OPDEF

    Used to define opcodes.

    Format

      $OPDEF  MNEMONIC, FORMAT, ENCODING [,DEFAULTS]

1.19.15.1  –  Parameters

 MNEMONIC

    MNEMONIC is the mnemonic name by which the instruction is called.
    You may optionally specify a qualifier list separated from the
    name by a slash (/).  A qualifier list is a sequence of one or
    more letters or digits with no intervening spaces or separators.

 FORMAT

    FORMAT is one of the following arguments:

    Format                      Description

    MEMORY                      Standard memory format instructions.
    MEMORY_FUNCTION             Memory format instructions with a
                                function code.
    JUMP                        Memory format instructions formatted
                                like jump instructions.
    BRANCH                      Standard branch format instructions.
    OPERATE                     Standard operate instructions.
    FLOATING_OPERATE            Standard floating-point operate
                                instructions.
    PAL                         Standard PALcode instructions.
    <CUSTOM=operand_type_list>  Custom format.

    With the CUSTOM format, you may optionally specify a list of the
    types of operands the instruction is to accept. If you specify
    a list of operand types, you must enclose the entire FORMAT
    argument within angle brackets, and you must specify the operand
    types in the order they are to be used with the instruction.
    $OPDEF supports the following operand types:

    IREGISTER      Integer register, such as R5 or SP.
    FREGISTER      Floating-point register, such as F7.
    LITERAL        Integer literal, such as #123 or 32767.
    LIT_IREG       Integer literal, such as #123 or 32767, or integer
                   register, such as R5 or SP.
    INDIRECT       Indirect integer register notation such as (R7).
    DISPLACEMENT   Indirect integer register notation with an integer
                   literal displacement, such as FOO(R12).
    BRANCH_OFFSET  Label or address expression, such as L1.

    For example:

    FORMAT=<CUSTOM=IREGISTER,DISPLACEMENT>

    The following example shows the definition of the ADDQ
    instruction, which takes either an integer register or literal
    as its second argument:

        $OPDEF ADDQ,                                      -
            FORMAT=<CUSTOM=IREGISTER,LIT_IREG,IREGISTER>, -
            ENCODING=<26:31=^x10,                         -
                21:25=%OP1,                               -
                12:20=%OP2,                               -
                5:11=^x20,                                -
                0:4=%OP3>

    For a detailed description of instruction formats, see the Alpha
    Architecture Reference Manual.

 ENCODING

    ENCODING is the numeric encoding for the instruction opcode.
    The default radix is decimal, as is the case for all assembler
    constants. Prefix the value with ^X for hexadecimal. Certain
    instruction formats allow multipart encoding:

    Format             Encoding Description

    MEMORY_FUNCTION    Specify the base opcode, followed by a dot,
                       followed by the function code. For example:

                       ENCODING=^X10.F000
    JUMP               Specify the base opcode, optionally followed
                       by a dot, and the hardware-hint bits
                       optionally followed by a dot and the software-
                       hint bits. For example:

                       ENCODING=^X1A.2.1
    OPERATE            Specify the base opcode, followed by a dot,
                       followed by the function code. For example:

                       ENCODING=^X12.3C
    FLOATING_OPERATE   Specify the base opcode, followed by a dot and
                       the function code. For example:

                       ENCODING=^X17.02B
    PAL                Specify the base opcode, optionally followed
                       by a dot and the function code. Omit the
                       function code for a generic PAL instruction
                       that accepts an integer-expression argument.
                       For example:

                       ENCODING=^X0.0080
                       ENCODING=^X19
    CUSTOM             Specify a comma-separated list of bit ranges
                       and values to place in those bit ranges. For
                       example:

                       ENCODING = < 26:31=^X14, 21:25=%OP1, -
                                    16:20=%OP2.REG, 0:15=%OP2.DISP >

    For CUSTOM format instructions, specify the ENCODING argument as
    a comma-separated list of bit ranges and values to place in those
    bit ranges. Enclose the list within angle brackets.

    Specify a bit range as start:end where start and end are integer
    constant expressions. For a 1-bit bit range, start and end are
    equal. Bit positions range from 0 to 31. Place an equal sign (=)
    after the bit-range specifier followed by the value you wish to
    put in the bit range. You can place either a constant integer
    expression or an operand into the bit range. Start and end
    expressions and integer constant expressions must not reference
    any external symbols or symbols not yet defined in the assembly.
    $OPDEF evaluates these expressions at the time that it defines
    the instruction as opposed to when the defined instruction is
    referenced.

    Operand names are of the form %OPn, where n is the ordinal number
    of the operand as specified from left to right with the FORMAT
    argument.

    For the IREGISTER, FREGISTER, and INDIRECT operands, $OPDEF
    places the 5-bit register number into the bit positions you
    specify.

    For LITERAL operands, $OPDEF places the literal value of the
    operand into the bit positions you specify. Operand literal
    values can be up to 32 bits long. The most significant bits
    are truncated if the size of the operand literal value exceeds
    the bit range you specify. Forward and external references are
    allowed.

    For LIT_IREG operands, $OPDEF places either a literal value or
    a 5-bit register number into the bit positions you specify. If a
    literal, the low bit is 1, and the literal value is placed in the
    upper bits. If an integer register, the low four bits are 0, and
    the high five bits contain the register number.

    For DISPLACEMENT operands, $OPDEF defines two parts: a 5-bit
    register number and a displacement value that can be up to 32
    bits long. The most significant bits are truncated from the
    displacement value if the size of the displacement value exceeds
    the bit range you specify. You can reference the register number
    by placing .REG after the operand name. For example: %OP2.REG.
    Similarly, you can reference the displacement value by placing
    .DISP after the operand name. For example: %OP2.DISP. Forward
    references are allowed. Relocatable expressions are not allowed.

    For BRANCH_OFFSET operands, $OPDEF stores the signed longword
    offset between the next instruction and the specified address in
    the bit positions you specify. The address expression specified
    for a BRANCH_OFFSET operand can be a backward or forward
    reference to a location within the current psect. It cannot
    be an external address or an address in a different psect. The
    resulting offset can be up to 32 bits in size. If the size of the
    offset exceeds the bit range you specify, the most significant
    bits are truncated.

    $OPDEF fills any bit positions you leave unspecified with zeros.

 DEFAULTS

    DEFAULTS is an optional list of operand defaults of the form
    <%OPn=value, ...>, where n is the number of the operand to which
    the value is to apply as a default. Operand defaults may be
    specified in any order. If you specify a default for one or more
    operands, you need not specify a default for all operands.

    The following example specifies a default of R31 for the first
    instruction argument:

        $OPDEF RET, FORMAT=<CUSTOM=IREGISTER,INDIRECT>,   -
            ENCODING=<26:31=^x1A,                         -
                21:25=%OP1,                               -
                16:20:%OP2,                               -
                14;14=^x2,0:13=0>,                        -
            DEFAULTS=<%OP1=R31>

1.19.15.2  –  Description

    You can use the $OPDEF macro to define your own opcodes.

    $OPDEF defines a macro using an unqualified version of the
    mnemonic name you specify. When this macro is invoked with the
    instruction qualifiers you specify when you define it with $OPDEF
    (if any), it expands to the instruction representation you have
    defined with $OPDEF. You can specify the qualifiers in any order
    as long as the combination of qualifiers you use is the same.

    Other uses of the mnemonic name remain valid provided you do not
    use the mnemonic name as a macro name in a .MACRO directive. For
    instance, you can use the same mnemonic name in the opcode field
    with different or no qualifiers. If the qualifiers (or absence
    thereof) do not match those specified in your $OPDEF instruction
    definition, the macro defined by $OPDEF processes as though you
    had not defined an instruction by that mnemonic name. To do
    so, it expands to a single statement. This expansion statement
    is identical to the mnemonic-name macro invocation statement,
    except it is processed in a context that prevents the mnemonic-
    name macro from expanding recursively. Instead, the statement
    is processed as a normal, MACRO-64 instruction statement. In
    this case, you may notice references to the mnemonic-name macro
    expansion in a MACAUXMSG diagnostic message if the instruction
    statement contains errors.

    For instance, if you define a STQ/P instruction using $OPDEF,
    you can still use the STQ instruction without the /P qualifier.
    If you do, and your STQ instruction statement contains an error,
    the assembler generates a MACAUXMSG message indicating that the
    error occurred during the expansion of macro STQ. Aside from
    the fact that the STQ instruction is processed in the context of
    the expansion of the STQ macro, $OPDEF's definition of the STQ/P
    instruction has no effect on your use of the STQ instruction.

1.19.15.3  –  Example

        $OPDEF MNEMONIC=BANG, FORMAT=PAL, -
               ENCODING=^X0.0099

1.19.16  –  .PACKED

    Packed decimal string storage macro.

    Format

      .PACKED  decimal-string[,symbol]

1.19.16.1  –  Parameters

 decimal-string

    A decimal number from 0 to 31 digits long with an optional sign.
    Digits can be in the range 0 to 9.

 symbol

    An optional symbol that is assigned a value equivalent to the
    number of decimal digits in the string. The sign is not counted
    as a digit.

1.19.16.2  –  Description

    .PACKED generates packed decimal data with two digits per byte.
    Packed decimal data is useful in calculations requiring exact
    accuracy. It is operated on by the decimal string instructions.

    A packed decimal string is a contiguous sequence of bytes in
    memory. It is specified by two attributes: the address A of
    the first byte and a length L, which is the number of digits in
    the string and not the length of the string in bytes. The bytes
    of a packed decimal string are divided into two, 4-bit fields
    (nibbles). Each nibble except the low nibble (bits 3:0) of the
    last (highest-addressed) byte must contain a decimal digit. The
    low nibble of the highest-addressed byte must contain a sign. The
    representation for the digits and sign is indicated as follows:

    Digit
    or
    Sign  Decimal        Hexadecimal

    0     0              0
    1     1              1
    2     2              2
    3     3              3
    4     4              4
    5     5              5
    6     6              6
    7     7              7
    8     8              8
    9     9              9
    +     10,12,14, or   A,C,E, or F
    -     15             B or D
          11 or 13

    The preferred sign representation is 12 for plus (+)  and 13 for
    minus (-). The length L is the number of digits in the packed
    decimal string (not counting the sign); L must be in the range
    0 to 31. When the number of digits is odd, the digits and the
    sign fit into a string of bytes whose length is defined by the
    following equation: L/2(integer part only) + 1. When the number
    of digits is even, it is required that an extra 0 appear in the
    high nibble (bits 7:4) of the first byte of the string. Again,
    the length in bytes of the string is L/2 + 1.

    The address A of the string specifies the byte of the string
    containing the most-significant digit in its high nibble. Digits
    of decreasing significance are assigned to increasing byte
    addresses and from high nibble to low nibble within a byte.
    Thus, +123 has a length of 3. The packed decimal number -12
    has a length of 2.

1.19.16.3  –  Example

        .PACKED -12,PACKED_SIZED        ; PACKED_SIZE gets value of 2
        .PACKED +500
        .PACKED 0
        .PACKED -0,SUM_SIZE             ; SUM_SIZE gets value of 1

1.19.17  –  $PROCEDURE DESCRIPTOR

    Defines a procedure descriptor structure at the current psect and
    offset.

    Format

      $PROCEDURE_DESCRIPTOR

1.19.17.1  –  Description

    The arguments for the $PROCEDURE_DESCRIPTOR macro are the same as
    the $ROUTINE macro, with the following exceptions:

    o  The ENTRY argument is required.

    o  There are no CODE_SECTION, LINKAGE_SECTION, DATA_SECTION,
       DATA_SECTION_POINTER, or STANDARD_PROLOGUE arguments.

    o  There is an additional END_PROLOGUE argument. This argument
       must be a label that you define at the end of the routine's
       prologue sequence. This argument is required for stack and
       register procedure types.

1.19.17.2  –  Notes

    o  Because the $ROUTINE macro invokes the $PROCEDURE_DESCRIPTOR
       macro for you, you do not need to use the
       $PROCEDURE_DESCRIPTOR macro if you use $ROUTINE. You may wish
       to use $PROCEDURE_DESCRIPTOR when you are not using $ROUTINE.

1.19.17.3  –  Example

            $PROCEDURE_DESCRIPTOR p1,           -
                              KIND=NULL,        -
                              ENTRY=p1_entry

1.19.18  –  $RESET LP LIST

    Clears the list of linkage pairs maintained by the $LINKAGE_PAIR
    and $CALL macros.

    Format

      $RESET_LP_LIST

1.19.18.1  –  Description

    The $LINKAGE_PAIR and $CALL macros maintain an assembly-time
    list of linkage pairs that the $LINKAGE_PAIR macro has stored in
    the linkage section. This list enables $LINKAGE_PAIR and $CALL
    to use the same linkage pair for multiple routine calls to the
    same routine. You can clear this list of linkage pairs with the
    $RESET_LP_LIST macro.

    Under normal circumstances, you do not need to clear the linkage-
    pair list. Some of the times when you do are as follows:

    o  When you change the psect assigned to the linkage section.

    o  If distance from the linkage section of your current routine
       falls more than 32K bytes beyond where the linkage pair has
       been stored.

1.19.18.2  –  Example

         ; Define the linkage section psect for routines A & B
         $LINK$ = "AB_LINK,NOEXE,OCTA"

         $ROUTINE A, KIND=STACK
         .BASE  R27, $LS
         $CALL D ; Linkage pair is stored in A's linkage
           ;  section and put on the assembly-time list
         $RETURN
         $END_ROUTINE A

         $ROUTINE B, KIND=STACK
         .BASE  R27, $LS
         $CALL D ; Linkage pair is found on the list,
           ;  and used from A's linkage section
         $RETURN
         $END_ROUTINE B

         ; Define a different linkage section for routine C
         $LINK$ = "C_LINK,NOEXE,OCTA"

         ; Linkage pairs that are on the list are in A & B's linkage
         ; section, which is not easily accessible by C.  Therefore,
         ; clear the list.
         $RESET_LP_LIST

         $ROUTINE C, KIND=STACK
         .BASE  R27, $LS
         $CALL D ; Linkage pair is stored in C's linkage
           ;  section and put on the assembly-time list
         $RETURN
         $END_ROUTINE B

1.19.19  –  $RETURN

    Generates a standard epilogue instruction sequence.

    Format

      $RETURN

1.19.19.1  –  Description

    Generates a standard epilogue instruction sequence when used
    within a stack or register routine defined with the $ROUTINE
    macro. The epilogue sequence generated by $RETURN restores any
    registers you specify with the SAVED_REGS argument to $ROUTINE
    and performs stack frame management as necessary. You can use
    $RETURN whether or not you specify STANDARD_PROLOGUE as TRUE or
    accept the default.

    You can use $RETURN any number of times within a given stack or
    register routine to affect a return to the calling routine.

    You must not use the $BEGIN_EPILOGUE or $END_EPILOGUE macros
    for an epilogue sequence generated by $RETURN. $RETURN invokes
    $BEGIN_EPILOGUE and $END_EPILOGUE for you.

1.19.19.2  –  Example

        $ROUTINE FOOZLE, KIND=REGISTER, SAVE_FP=R1
            :
            :
            :
        $RETURN
        $END_ROUTINE FOOZLE

1.19.20  –  $ROUTINE

    Defines the current routine and creates a context for the
    routine.

    Format

      $ROUTINE  NAME=routine name -

                ALIASES=alias names -

                LOCAL=boolean value -

                STANDARD_PROLOGUE=boolean value -

                ENTRY=code entry point -

                CODE_SECTION=code section psect name -

                DATA_SECTION=data section psect name -

                DATA_SECTION_POINTER=boolean value -

                LINKAGE_SECTION=linkage section psect name -

                KIND=routine type-

                HANDLER_REINVOKABLE=boolean value -

                BASE_REG_IS_FP=boolean value-

                REI_RETURN=boolean value -

                STACK_RETURN_VALUE=boolean value -

                RSA_OFFSET=integer value -

                SAVE_FP=register name -

                SAVE_RA=return address register name -

                SIZE=numeric value -

                SAVED_REGS=list of registers -

                HANDLER=exception handler address -

                HANDLER_DATA=data address for exception handler -

                SYNCH_EXCEPTIONS=boolean value-

                PROC_VALUE=procedure value -

                ENVIRONMENT=environment value -

                FUNC_RETURN=function return type -

                ARGLIST=argument type list -

                USES_VAX_ARGLIST=boolean value -

                OVERRIDE_FLAGS=procedure descriptor flags -

                DEFAULT_SIGNATURE=boolean value -

                COMMON_BASE=list of registers -

                TARGET_INVO=boolean value -

                EXCEPTION_MODE=mode -

1.19.20.1  –  Parameters

 NAME

    The name of the routine. This argument is required for all
    procedure kinds. There is no default. For example:

    NAME=FOOZLE

 ALIASES

    List of alias names for the routine. This argument is optional
    for all procedure types. There is no default. For example:

    ALIASES=<FOO,BAR,FOOBAR,foo,bar,foobar,Foo,Bar,FooBar>

 LOCAL

    Boolean value indicating whether the routine is local (TRUE) or
    externally visible (FALSE). This argument is optional for all
    procedure kinds. The default is FALSE. For example:

    LOCAL=TRUE

 STANDARD_PROLOGUE

    Specifies a Boolean value to indicate whether $ROUTINE should
    generate a standard instruction prologue sequence at the
    beginning of the routine's code section. This argument is
    optional and valid only with REGISTER and STACK procedures. If
    the procedure type is stack or register, the default is TRUE and
    $ROUTINE generates a standard prologue sequence. The prologue
    sequence generated by $ROUTINE saves the registers you specify
    with the SAVED_REGS argument and performs stack-frame management
    as necessary.

    If you also specify BASE_REG_IS_FP=FALSE, the standard prologue
    sequence generated by $ROUTINE makes a copy of the procedure
    descriptor address that is in R27 upon entry into R29 (FP). While
    you cannot change the value in R29 before the epilogue, you can
    use R29 as a working, linkage-section register. If you specify
    the STANDARD_PROLOGUE argument as FALSE, you must code your own
    prologue sequence and mark the end of the prologue with the $END_
    PROLOGUE macro. Whether or not you specify STANDARD_PROLOGUE as
    TRUE or accept the default, you can generate a standard epilogue
    sequence for stack and register procedures with the $RETURN
    macro. For example:

    STANDARD_PROLOGUE=FALSE

 ENTRY

    The name of the code-entry point. This argument is the code
    entry-point label that $ROUTINE defines for you at the beginning
    of the code section for the routine. If this argument is omitted,
    $ROUTINE generates a label. For example:

    ENTRY=FOOZLE_ENTRY

 CODE_SECTION

    The psect name and attributes of the code section. This argument
    is optional for all procedure kinds. If omitted, the default
    is the name and attributes defined by the $CODE$ lexical string
    symbol. If you specify a name and attributes for the CODE_SECTION
    argument, $ROUTINE redefines the $CODE$ lexical string symbol
    such that the specified values become the new default. Initially,
    $CODE$ is defined as follows:

    $CODE$ = "$CODE$,OCTA,PIC,CON,REL,LCL,SHR,EXE,NORD,NOWRT"

    Since you must delimit the psect name and attributes using
    commas, be sure to enclose this argument within angle brackets
    to avoid having the assembler interpret the name and attributes
    as different arguments to $ROUTINE. For example:

    CODE_SECTION=<MY_CODE,EXE,QUAD,NOWRT>

 DATA_SECTION

    The psect name and attributes of the data section. This argument
    is optional for all procedure kinds. If omitted, the default
    is the name and attributes defined by the $DATA$ lexical string
    symbol. If you specify a name and attributes for the DATA_SECTION
    argument, $ROUTINE redefines the $DATA$ lexical string symbol
    such that the specified values become the new default. Initially,
    $DATA$ is defined as follows:

    $DATA$ = "$DATA$,OCTA,NOPIC,CON,REL,LCL,NOSHR,NOEXE,RD,WRT"

    Since you must delimit the psect name and attributes using
    commas, be sure to enclose this argument within angle brackets
    to avoid having the assembler interpret the name and attributes
    as different arguments to $ROUTINE. For example:

    DATA_SECTION=<MY_DATA,NOEXE,QUAD,RD,WRT>

 DATA_SECTION_POINTER

    Boolean value indicating whether $ROUTINE should store a pointer
    to the data section in the linkage section and define $DP as
    the address of that pointer. This argument is optional for all
    procedure kinds. The default is FALSE. For example:

    DATA_SECTION_POINTER=TRUE

    You can use the DATA_SECTION_POINTER argument as follows:

             $ROUTINE TALLY_HO, DATA_SECTION_POINTER=TRUE
             $DATA_SECTION
     TALLY:  .QUAD 0
             $CODE_SECTION
             .BASe       R27, $LS  ; Inform assembler that R27->$LS
             LDQ         R1, $DP   ; R1->$DS
             .BASE R1,$DS          ;Inform assembler that R1-$DS
             LDQ         R0, TALLY ; R0<-TALLY
             LDA         R0, 1(R0) ; R0<-R0++
             STQ         R0, TALLY ; TALLY<-R0
             RET         (R26)     ; Return
             $END_ROUTINE TALLY_HO

    In this example, the DATA_SECTION_POINTER argument is specified
    in order to obtain linkage to the data section. The first LDQ
    instruction loads R1 with the pointer to the data section
    that $ROUTINE stores in the linkage section. The next three
    instructions increment the value in the TALLY variable in the
    data section. Finally, the routine returns the incremented value
    to its caller in R0.

 LINKAGE_SECTION

    The psect name and attributes of the linkage section. This
    argument is optional for all procedure kinds. If omitted, the
    default is the name and attributes defined by the $LINK$ lexical
    string symbol. If you specify a name and attributes for the
    LINKAGE_SECTION argument, $ROUTINE redefines the $LINK$ lexical
    string symbol such that the specified values become the new
    default. Initially, $LINK$ is defined as follows:

    $LINK$ = "$LINK$,OCTA,NOPIC,CON,REL,LCL,NOSHR,NOEXE,RD,NOWRT"

    Since you must delimit the psect name and attributes using
    commas, be sure to enclose this argument within angle brackets
    to avoid having the assembler interpret the name and attributes
    as different arguments to $ROUTINE. For example:

    LINKAGE_SECTION=<MY_LINK,NOEXE,QUAD,RD,NOWRT>

 KIND

    Specifies the kind of routine being defined. This must be one
    of the following: STACK, REGISTER, NULL, or BOUND. This is an
    optional argument. The default is NULL. For example:

    KIND=STACK

 HANDLER_REINVOKABLE

    Specifies a Boolean value to indicate whether the condition
    handler can be re-invoked. This argument is optional and valid
    only with STACK and REGISTER procedures. It defaults to FALSE
    if no value is specified and the procedure kind is STACK or
    REGISTER. Note that this argument is only valid if a value is
    also specified for the HANDLER argument. For example:

    HANDLER_REINVOKABLE=TRUE

 BASE_REG_IS_FP

    Specifies a Boolean value to indicate whether register R29
    (FP) is used as the frame-pointer base register (TRUE) or not
    (FALSE). If specified as FALSE, R29 must be used to hold the
    address of the procedure descriptor (or the address of the
    address of the procedure descriptor-see the OpenVMS Calling
    Standard. You can use R29 to hold a working copy of the linkage-
    section address passed in R27. In addition, your prologue and
    epilogue instruction sequences can be shorter and more efficient.
    However, you cannot make standard calls to other routines if
    BASE_REG_IS_FP is specified as FALSE. This argument is optional
    and valid only with stack and register procedure kinds. It
    defaults to TRUE if the procedure type is stack or register.
    For example:

    BASE_REG_IS_FP=FALSE

 REI_RETURN

    Specifies a Boolean value to indicate whether this routine
    returns using an REI instruction. This argument is optional and
    valid only with STACK, REGISTER, and NULL procedure kinds. It
    defaults to FALSE if the procedure kind is STACK, REGISTER, or
    NULL. For example:

    REI_RETURN=TRUE

 STACK_RETURN_VALUE

    This argument is obsolete. Do not specify this argument.

 RSA_OFFSET

    An integer value specifying the stack offset (in bytes) of the
    register save area. This argument is optional and valid only
    for STACK procedures. If you specify BASE_REG_IS_FP as TRUE,
    the value you specify with RSA_OFFSET must be at least 8. RSA_
    OFFSET defaults to 8 if BASE_REG_IS_FP is specified as TRUE, 0
    otherwise. For example:

    RSA_OFFSET=32

 SAVE_FP

    The register that contains a copy of the value of FP (R29) upon
    entry to this routine. The prologue instruction sequence must
    copy FP to the register specified by SAVE_FP and the epilogue
    instruction sequence(s) must restore FP from the register
    specified by SAVE_FP. This argument is required and only valid
    for REGISTER procedures. There is no default. For example:

    SAVE_FP=R1

 SAVE_RA

    The register that contains the return address. This argument
    is optional and only valid for REGISTER procedures. If SAVE_RA
    is not R26, the prologue instruction sequence must copy R26 to
    the register specified by SAVE_RA and the epilogue instruction
    sequence(s) must use the return address stored in the register
    specified by SAVE_FP to affect its return to caller. SAVE_RA
    defaults to R26 if the procedure kind is REGISTER. For example:

    SAVE_RA=R22

 SIZE

    A numeric value that must be a multiple of 16 specifying the
    size of the fixed-stack area in bytes. This parameter is valid
    only for REGISTER and STACK procedure kinds. It defaults to the
    minimum value possible given the other arguments you specify or
    default. $ROUTINE computes the amount of stack storage needed for
    the register save area (if any) and defines the $RSA_END symbol
    to be the offset of the first byte beyond the register save area.
    If you wish to allocate a fixed area of stack beyond the register
    save area, you can specify an expression with the SIZE argument
    that includes the term $RSA_END plus the amount of fixed-stack
    storage you need for your application. For example:

    SIZE=$RSA_END+32

 SAVED_REGS

    A list of registers saved on the stack by the prologue code of
    this routine. It is valid only for STACK procedures and you must
    specify at least FP (R29) with this argument. It defaults to FP
    (R29) for STACK procedures. For example:

    SAVED_REGS=<R5,FP,F2,F3,F4>

    The OpenVMS Calling Standard specifies that registers R0, R1,
    R28, R30 (SP), and R31 must never be saved and restored. If
    you specify these registers with the SAVED_REGS argument, the
    $ROUTINE macro issues a diagnostic warning message.

 HANDLER

    The address of an exception handler. It is optional and valid
    only for STACK and REGISTER procedure kinds. By default, the
    procedure is defined not to have an exception handler. For
    example:

    HANDLER=MY_HANDLER

 HANDLER_DATA

    The address of data for the specified handler, if any. This
    argument is optional and valid only for stack and register
    procedure kinds and has no default value. You cannot specify a
    HANDLER_DATA argument if you do not specify the HANDLER argument.
    For example:

    HANDLER_DATA=MY_HANDLER_DATA

 SYNCH_EXCEPTIONS

    An argument to indicate whether exceptions must be synchronized
    or not. This argument is optional with STACK and REGISTER
    routines and is not allowed with other kinds of routines. This
    argument defaults to TRUE if you specify an exception handler
    with the HANDLER argument. Otherwise, it defaults to FALSE.
    When this argument is TRUE and you specify or accept the default
    STANDARD_PROLOGUE=TRUE, $ROUTINE generates a TRAPB instruction
    as part of the standard prologue sequence. In addition, when this
    argument is true, the $RETURN macro generates a TRAPB instruction
    as part of the standard epilogue sequence. When this argument is
    FALSE, neither $ROUTINE nor $RETURN generate TRAPB instructions.

 PROC_VALUE

    The procedure value of a bound procedure's parent. This argument
    is required for BOUND procedures and is invalid for all other
    procedure kinds. For example:

    PROC_VALUE=PARENT_PROC

 ENVIRONMENT

    Specifies an environment value. This parameter is optional and
    valid only for BOUND procedures. It has no default value. For
    example:

    ENVIRONMENT=0

 FUNC_RETURN

    Specifies the function return type. This argument is optional
    and valid for all procedure kinds. If specified, it must be one
    of the following: I64, D64, I32, U32, FF, FD, FG, FS, FT, FFC,
    FDC, FGC, FSC, or FTC. These values correspond to those listed in
    Table 3-7 of the OpenVMS Calling Standard that have an additional
    "RASE$K_FR_" prefix. There is no default. For example:

    FUNC_RETURN=U32

 ARGLIST

    Argument type list. This argument is optional and valid for
    all procedure kinds. If the argument list contains one or more
    elements, each of the first six elements must be one of the
    following: Q, I32, U32, FF, FD, FG, FS, or FT. The seventh and
    subsequent arguments (if any) must be either I32 or Q.

    These values correspond to the PSIG$K_RA_* and MASE$K_MA_*
    signature encodings in Table 3-6 of the OpenVMS Calling Standard.
    There is no default. If you specify this argument, $ROUTINE
    generates a procedure signature block. For example:

    ARGLIST=<Q,I32,FF,FF,U32>.

 USES_VAX_ARGLIST

    Specifies a Boolean value indicating whether the routine uses a
    VAX argument list. This argument is optional for all procedure
    kinds and defaults to FALSE. If you specify this argument,
    $ROUTINE generates a procedure signature block. For example:

    USES_VAX_ARGLIST=TRUE

 OVERRIDE_FLAGS

    Specifies overriding flags for the PDSC$W_FLAGS field in the
    procedure descriptor. This argument is optional and valid for
    all procedure kinds. However, it is required for BOUND procedures
    when the parameter specified with the PROC_VALUE argument is an
    external or forward reference. There is no default. For example:

    OVERRIDE_FLAGS=PARENT_FLAGS

 DEFAULT_SIGNATURE

    Specifies a Boolean value to indicate whether the standard
    procedure signature is used. TRUE means to use the standard
    signature. It is optional and valid for all procedure kinds.
    The default is FALSE if you specify either the ARGLIST or USES_
    VAX_ARGLIST arguments. Otherwise, the default is TRUE. Note that
    this argument must be FALSE or blank if you specify either the
    ARGLIST or USES_VAX_ARGLIST arguments. For example:

    DEFAULT_SIGNATURE=TRUE

 COMMON_BASE

    An argument to specify one or more base registers that are used
    in common with other routines. This argument is optional for
    all routine kinds. By default, $ROUTINE invalidates any previous
    .BASE directives that may be in effect when you invoke $ROUTINE.
    In this way, you are prevented from inadvertently processing the
    second or subsequent routines in a module with .BASE directives
    in effect that apply only to a previous routine. However, you
    may wish to share a common base register assignment between a
    number of routines. To do so, you can reissue the appropriate
    .BASE directive or directives after each invocation of $ROUTINE.
    Alternatively, you can specify one or more common base registers
    with the COMMON_BASE argument, and enter the appropriate .BASE
    directive or directives only once at the beginning of the module.
    Specify the value for the COMMON_BASE argument as a list of
    integer registers. For example:

    COMMON_BASE=<R5,R13>

    In this example, $ROUTINE invalidates any previous .BASE
    directives except those for registers R5 and R13. Previous .BASE
    directives for registers R5 and R13 are unaffected.

 TARGET_INVO

    Specifies a Boolean value indicating whether or not the exception
    handler for this procedure is invoked when this procedure is the
    target of an invocation unwind. (TARGET_INVO=TRUE) causes the
    exception handler to be invoked during an unwind. The default is
    TARGET_INVO=FALSE.

 EXCEPTION_MODE

    An argument to specify one of the following exception modes with
    STACK and REGISTER procedures:

    o  SIGNAL-raise all exceptions except underflow.

    o  SIGNAL_ALL-raise all exceptions.

    o  SILENT-raise no exceptions.

    o  FULL_IEEE-only raise exceptions as per IEEE control bits.

    The default is EXCEPTION_MODE=SIGNAL.

1.19.20.2  –  Description

    $ROUTINE defines a routine, makes it the current routine, and
    performs the following actions:

    o  Creates and associates a linkage section, code section, and
       data section with the routine.

    o  Defines a procedure descriptor and optional signature block in
       accordance with the values of macro arguments.

    o  Optionally stores a pointer to the data section within the
       linkage section.

    o  Creates the following numeric and lexical symbols:

       Symbol      Description

       $CS         Address at start of the current routine's code
                   section.
       $DS         Address at start of the current routine's data
                   section.
       $DP         Optional address of a pointer to the current
                   routine's data section. This symbol has a value
                   that is an address in the current routine's
                   linkage section at which the $ROUTINE macro has
                   placed the address of the data section ($DS) as
                   follows:

                   $DP = .
                   .ADDRESS $DS

                   $DP enables you to access the data area of the
                   current routine from its linkage section.
       $LS         Address of the current routine's linkage section.
       $SIZE       Size of fixed area of stack frame of the current
                   routine. This symbol is valid only with STACK and
                   REGISTER routines.
       $RSA_       The offset within the fixed-stack area to the
       OFFSET      register save area. This symbol is valid only with
                   STACK routines.
       $RSA_END    The offset within the fixed-stack area to the the
                   first byte beyond the end of the register save
                   area (if any).
       $CODE$      A lexical string symbol that defines the routine's
                   code psect name and attributes.
       $DATA$      A lexical symbol that defines the routine's data
                   psect name and attributes.
       $LINK$      A lexical string symbol that defines the routine's
                   linkage psect name and attributes.

    o  Optionally generates a standard instruction prologue sequence
       at the beginning of the code section.

       If you specify /NAMES=AS_IS on the command line, all but
       the last three of these symbols are defined in both complete
       uppercase and complete lowercase. These symbols are intended
       for your use outside of the macros themselves. For example,
       the values of these numeric symbols may be useful as a
       mnemonic when coding an instruction with a register as in
       the following example:

        lda   SP,-$SIZE(SP)

       The last three symbols, $CODE$, $DATA$, and $LINK$, are only
       defined in uppercase. They are used by the $ROUTINE macro
       for the default code, data, and linkage section psect names
       and attributes. You can define these symbols before invoking
       $ROUTINE to alter the default program sections as follows:

       -  $CODE$ = "MY_CODE,EXE,OCTA,SHR,NORD,NOWRT,GBL"

       -  $DATA$ = "MY_DATA,NOEXE,OCTA,NOSHR,RD,WRT,GBL"

       -  $LINK$ = "MY_LINK,NOEXE,OCTA,SHR,RD,NOWRT,GBL"

       These statements cause $ROUTINE to use the previous psect
       names and attributes by default. If you specify any of the
       CODE_SECTION, DATA_SECTION, or LINKAGE_SECTION arguments in
       your invocation of $ROUTINE, $ROUTINE uses the psect name and
       attributes specified with the argument.

       In addition, $ROUTINE redefines the corresponding $CODE$,
       $DATA$, or $LINK$ lexical string symbol to the value
       you specify when you specify any of the CODE_SECTION,
       DATA_SECTION, or LINKAGE_SECTION arguments with $ROUTINE.

1.19.20.3  –  Example

                $ROUTINE MAIN1, KIND=NULL

                $ROUTINE MAIN1,         -
                    KIND=STACK,         -
                    SIZE=48,            -
                    SAVED_REGS=<R2,FP,F5>

1.20  –  MACRO-64 Alpha Architecture Quick Reference

    This topic provides figures and tables showing the data types
    and addressing capabilities of the Alpha architecture. The
    information is derived from the Alpha Architecture Quick
    Reference Guide. Minor changes have been made to reflect the
    usage of the Alpha architecture that is specific to MACRO-64.

    For more information, see the Alpha Architecture Reference Manual
    and the OpenVMS Calling Standard.

1.20.1  –  Register Usage Conventions

    Register Usage Conventions for OpenVMS Alpha lists the register
    usage conventions for OpenVMS Alpha. MACRO-64 recognizes FP and
    SP as register synonyms, but does not recognize AI, RA, or PV as
    register synonyms.

    Table 11 Register Usage Conventions for OpenVMS Alpha

    R0             Int func ret value
    R1             Scratch
    R2-R15         Saved
    R16-           Argument
    R21
    R22-           Scratch
    R24
    R25     AI     Argument information
    R26     RA     Return address
    R27     PV     Procedure value
    R28            Volatile scratch
    R29     FP     Stack frame base
    R30     SP     Stack pointer
    R31            Zero
    F0             F-P function ret value
    F1             F-P complex func ret value
    F2-F9          Saved
    F10-           Scratch
    F15
    F16-           Argument
    F22
    F23-           Scratch
    F30
    F31            Zero

1.20.2  –  Instruction Operand Notation

    Instruction Operand Notation shows the notation for instruction
    operands. The notation format is as follows:

    <name>.<access type><data type>

    Table 12 Instruction Operand Notation

    <name>:
    disp Displacement field
    fnc  PALcode function field
    Ra   Integer register operand in the Ra field
    Rb   Integer register operand in the Rb field
    #b   Integer literal operand in the Rb field
    Rc   Integer register operand in the Rc field
    Fa   Floating-point register operand in the Ra field
    Fb   Floating-point register operand in the Rb field
    Fc   Floating-point register operand in the Rc field

    <access type>:
    a    The operand is used in an address calculation to form an
         effective address. The data-type code that follows indicates
         the units of addressability (or scale factor) applied to
         this operand when the instruction is decoded.
    i    The operand is an immediate literal.
    m    The operand is both read and written.
    r    The operand is read only.
    w    The operand is write only.

    <data type>:
    b    Byte
    f    F_floating
    g    G_floating
    l    Longword
    q    Quadword
    s    IEEE single floating (S_floating)
    t    IEEE double floating (T_floating)
    w    Word
    x    The data type is specified by the instruction.

1.20.3  –  Instruction Qualifier Notation

    Instruction Qualifier Notation shows the notation for instruction
    qualifiers.

    Table 13 Instruction Qualifier Notation

    /QualifierMeaning

    C         Chopped rounding
    D         Dynamic rounding
              (mode determined by FPCR<DYN>)
    I         Inexact result enable
    M         Minus infinity rounding
    S         Software completion enable
    U         Floating underflow enable
    V         Integer overflow enable

1.20.4  –  F-P Control Register (FPCR) Format

    F-P Control Register (FPCR) Format shows the format for the F-P
    control register.

    Table 14 F-P Control Register (FPCR) Format

    Bits   Symbol  Meaning

    63     SUM     Bitwise OR of <57:52>
    62:60  RAZ     Read as zero; ignored when written
           /IGN
    59:58  DYN     IEEE rounding mode selected:
                   00   Chopped
                   01   Minus infinity
                   10   Normal rounding
                   11   Plus infinity
    57     IOV     Integer overflow of destination precision
    56     INE     Floating mathematically inexact result
    55     UNF     Floating underflow of destination exponent
    54     OVF     Floating overflow of destination exponent
    53     DZE     Floating divide with divisor of zero
    52     INV     Floating invalid operand value
    51:0   RAZ     Read as zero; ignored when written
           /IGN

1.20.5  –  Decodable Pseudo-Operations

    Decodable Pseudo-Operations lists the decodable pseudo-operations
    and their associated actual instructions.

    Table 15 Decodable Pseudo-Operations

    Pseudo-              Actual
    Operation            Instruction

    BR       target      BR         R31,target
    CLR      Rx          BIS        R31,R31,Rx
    FABS     Fx,Fy       CPYS       F31,Fx,Fy
    FCLR     Fx          CPYS       F31,F31,Fx
    FMOV     Fx,Fy       CPYS       Fx,Fx,Fy
    FNEG     Fx,Fy       CPYSN      Fx,Fx,Fy
    FNOP                 CPYS       F31,F31,F31
    MOV      Lit,Rx      LDA        Rx,lit(R31)
    MOV      {Rx         BIS        R31,{Rx/Lit8},Ry
             /Lit8},Ry
    MF_FPCR  Fx          MF_FPCR    Fx,Fx,Fx
    MT_FPCR  Fx          MT_FPCR    Fx,Fx,Fx
    NEGF     Fx,Fy       SUBF       F31,Fx,Fy
    NEGF/S   Fx,Fy       SUBF/S     F31,Fx,Fy
    NEGG     Fx,Fy       SUBG       F31,Fx,Fy
    NEGG/S   Fx,Fy       SUBG/S     F31,Fx,Fy
    NEGL     {Rx         SUBL       R31,{Rx/Lit},Ry
             /Lit8},Ry
    NEGL/V   {Rx         SUBL/V     R31,{Rx/Lit},Ry
             /Lit8},Ry
    NEGQ     {Rx         SUBQ       R31,{Rx/Lit},Ry
             /Lit8},Ry
    NEGQ/V   {Rx         SUBQ/V     R31,{Rx/Lit},Ry
             /Lit8},Ry
    NEGS     Fx,Fy       SUBS       F31,Fx,Fy
    NEGS/SU  Fx,Fy       SUBS/SU    F31,Fx,Fy
    NEGS/SUI Fx,FY       SUBS/SUI   F31,Fx,Fy
    NEGT     Fx,Fy       SUBT       F31,Fx,Fy
    NEGT/SU  Fx,Fy       SUBT/SU    F31,Fx,Fy
    NEGT/SUI Fx,FY       SUBT/SUI   F31,Fx,Fy
    NOP                  BIS        R31,R31,R31
    NOT      {Rx         ORNOT      R31,{Rx/Lit},Ry
             /Lit8},Ry
    SEXTL    {Rx         ADDL       R31,{Rx/Lit},Ry
             /Lit},Ry
    UNOP                 LDQ_U      R31,0(Rx)

1.20.6  –  Common Architecture Opcodes in Numerical Order

    This table lists the common architecture opcodes in numerical
    order.

    MACRO-64 Alpha Architecture Quick Reference

    A.6 Common Architecture Opcodes in Numerical Order

    Table_A-6_Common_Architecture_Opcodes_in_Numerical_Order

    Opcode________________Opcode________________Opcode___

    00      CALL_PAL      11.26   CMOVNE        15.01E    CVTDG/C
    01      OPC01         11.28   ORNOT         15.020    ADDG/C
    02      OPC02         11.40   XOR           15.021    SUBG/C
    03      OPC03         11.44   CMOVLT        15.022    MULG/C
    04      OPC04         11.46   CMOVGE        15.023    DIVG/C
    05      OPC05         11.48   EQV           15.02C    CVTGF/C
    06      OPC06         11.64   CMOVLE        15.02D    CVTGD/C
    07      OPC07         11.66   CMOVGT        15.02F    CVTGQ/C
    08      LDA           12.02   MSKBL         15.03C    CVTQF/C
    09      LDAH          12.06   EXTBL         15.03E    CVTQG/C
    0A      OPC0A         12.0B   INSBL         15.080    ADDF
    0B      LDQ_U         12.12   MSKWL         15.081    SUBF
    0C      OPC0C         12.16   EXTWL         15.082    MULF
    0D      OPC0D         12.1B   INSWL         15.083    DIVF
    0E      OPC0E         12.22   MSKLL         15.09E    CVTDG
    0F      STQ_U         12.26   EXTLL         15.0A0    ADDG
    10.00   ADDL          12.2B   INSLL         15.0A1    SUBG
    10.02   S4ADDL        12.30   ZAP           15.0A2    MULG
    10.09   SUBL          12.31   ZAPNOT        15.0A3    DIVG
    10.0B   S4SUBL        12.32   MSKQL         15.0A5    CMPGEQ
    10.0F   CMPBGE        12.34   SRL           15.0A6    CMPGLT
    10.12   S8ADDL        12.36   EXTQL         15.0A7    CMPGLE
    10.1B   S8SUBL        12.39   SLL           15.0AC    CVTGF
    10.1D   CMPULT        12.3B   INSQL         15.0AD    CVTGD
    10.20   ADDQ          12.3C   SRA           15.0AF    CVTGQ
    10.22   S4ADDQ        12.52   MSKWH         15.0BC    CVTQF
    10.29   SUBQ          12.57   INSWH         15.0BE    CVTQG
    10.2B   S4SUBQ        12.5A   EXTWH         15.100    ADDF/UC
    10.2D   CMPEQ         12.62   MSKLH         15.101    SUBF/UC
    10.32   S8ADDQ        12.67   INSLH         15.102    MULF/UC
    10.3B   S8SUBQ        12.6A   EXTLH         15.103    DIVF/UC
    10.3D   CMPULE        12.72   MSKQH         15.11E    CVTDG
                                                          /UC
    10.40   ADDL/V        12.77   INSQH         15.120    ADDG
                                                          /UC
    10.49   SUBL/V        12.7A   EXTQH         15.121    SUBG
                                                          /UC
    10.4D   CMPLT         13.00   MULL          15.122    MULG
                                                          /UC
    10.60   ADDQ/V        13.20   MULQ          15.123    DIVG
                                                          /UC
    10.69   SUBQ/V        13.30   UMULH         15.12C    CVTGF
                                                          /UC
    10.6D   CMPLE         13.40   MULL/V        15.12D    CVTGD
                                                          /UC
    11.00   AND           13.60   MULQ/V        15.12F    CVTGQ
                                                          /VC
    11.08   BIC           14      OPC14         15.180    ADDF
                                                          /U
    11.14   CMOVLBS       15.000  ADDF/C        15.181    SUBF
                                                          /U
    11.16   CMOVLBC       15.001  SUBF/C        15.182    MULF
                                                          /U
    11.20   BIS           15.002  MULF/C        15.183    DIVF
                                                          /U
    11.24   CMOVEQ        15.003  DIVF/C        15.19E    CVTDG
                                                          /U
    15.1A0  ADDG/U        15.580  ADDF/SU       16.0A6    CMPTLT
    15.1A1  SUBG/U        15.581  SUBF/SU       16.0A7    CMPTLE
    15.1A2  MULG/U        15.582  MULF/SU       16.0AC    CVTTS
    15.1A3  DIVG/U        15.583  DIVF/SU       16.0AF    CVTTQ
    15.1AC  CVTGF/U       15.59E  CVTDG/SU      16.0BC    CVTQS
    15.1AD  CVTGD/U       15.5A0  ADDG/SU       16.0BE    CVTQT
    15.1AF  CVTGQ/V       15.5A1  SUBG/SU       16.0C0    ADDS
                                                          /D
    15.400  ADDF/SC       15.5A2  MULG/SU       16.0C1    SUBS
                                                          /D
    15.401  SUBF/SC       15.5A3  DIVG/SU       16.0C2    MULS
                                                          /D
    15.402  MULF/SC       15.5AC  CVTGF/SU      16.0C3    DIVS
                                                          /D
    15.403  DIVF/SC       15.5AD  CVTGD/SU      16.0E0    ADDT
                                                          /D
    15.41E  CVTDG/SC      15.5AF  CVTGQ/SV      16.0E1    SUBT
                                                          /D
    15.420  ADDG/SC       16.000  ADDS/C        16.0E2    MULT
                                                          /D
    15.421  SUBG/SC       16.001  SUBS/C        16.0E3    DIVT
                                                          /D
    15.422  MULG/SC       16.002  MULS/C        16.0EC    CVTTS
                                                          /D
    15.423  DIVG/SC       16.003  DIVS/C        16.0EF    CVTTQ
                                                          /D
    15.42C  CVTGF/SC      16.020  ADDT/C        16.0FC    CVTQS
                                                          /D
    15.42D  CVTGD/SC      16.021  SUBT/C        16.0FE    CVTQT
                                                          /D
    15.42F  CVTGQ/SC      16.022  MULT/C        16.100    ADDS
                                                          /UC
    15.480  ADDF/S        16.023  DIVT/C        16.101    SUBS
                                                          /UC
    15.481  SUBF/S        16.02C  CVTTS/C       16.102    MULS
                                                          /UC
    15.482  MULF/S        16.02F  CVTTQ/C       16.103    DIVS
                                                          /UC
    15.483  DIVF/S        16.03C  CVTQS/C       16.120    ADDT
                                                          /UC
    15.49E  CVTDG/S       16.03E  CVTQT/C       16.121    SUBT
                                                          /UC
    15.4A0  ADDG/S        16.040  ADDS/M        16.122    MULT
                                                          /UC
    15.4A1  SUBG/S        16.041  SUBS/M        16.123    DIVT
                                                          /UC
    15.4A2  MULG/S        16.042  MULS/M        16.12C    CVTTS
                                                          /UC
    15.4A3  DIVG/S        16.043  DIVS/M        16.12F    CVTTQ
                                                          /VC
    15.4A5  CMPGEQ/S      16.060  ADDT/M        16.140    ADDS
                                                          /UM
    15.4A6  CMPGLT/S      16.061  SUBT/M        16.141    SUBS
                                                          /UM
    15.4A7  CMPGLE/S      16.062  MULT/M        16.142    MULS
                                                          /UM
    15.4AC  CVTGF/S       16.063  DIVT/M        16.143    DIVS
                                                          /UM
    15.4AD  CVTGD/S       16.06C  CVTTS/M       16.160    ADDT
                                                          /UM
    15.4AF  CVTGQ/S       16.06F  CVTTQ/M       16.161    SUBT
                                                          /UM
    15.500  ADDF/SUC      16.07C  CVTQS/M       16.162    MULT
                                                          /UM
    15.501  SUBF/SUC      16.07E  CVTQT/M       16.163    DIVT
                                                          /UM
    15.502  MULF/SUC      16.080  ADDS          16.16C    CVTTS
                                                          /UM
    15.503  DIVF/SUC      16.081  SUBS          16.16F    CVTTQ
                                                          /VM
    15.51E  CVTDG/SUC     16.082  MULS          16.180    ADDS
                                                          /U
    15.520  ADDG/SUC      16.083  DIVS          16.181    SUBS
                                                          /U
    15.521  SUBG/SUC      16.0A0  ADDT          16.182    MULS
                                                          /U
    15.522  MULG/SUC      16.0A1  SUBT          16.183    DIVS
                                                          /U
    15.523  DIVG/SUC      16.0A2  MULT          16.1A0    ADDT
                                                          /U
    15.52C  CVTGF/SUC     16.0A3  DIVT          16.1A1    SUBT
                                                          /U
    15.52D  CVTGD/SUC     16.0A4  CMPTUN        16.1A2    MULT
                                                          /U
    15.52F  CVTGQ/SVC     16.0A5  CMPTEQ        16.1A3    DIVT
                                                          /U
    16.1AC  CVTTS/U       16.5AF  CVTTQ/SV      16.7BC    CVTQS
                                                          /SUI
    16.1AF  CVTTQ/V       16.5C0  ADDS/SUD      16.7BE    CVTQT
                                                          /SUI
    16.1C0  ADDS/UD       16.5C1  SUBS/SUD      16.7C0    ADDS
                                                          /SUID
    16.1C1  SUBS/UD       16.5C2  MULS/SUD      16.7C1    SUBS
                                                          /SUID
    16.1C2  MULS/UD       16.5C3  DIVS/SUD      16.7C2    MULS
                                                          /SUID
    16.1C3  DIVS/UD       16.5E0  ADDT/SUD      16.7C3    DIVS
                                                          /SUID
    16.1E0  ADDT/UD       16.5E1  SUBT/SUD      16.7E0    ADDT
                                                          /SUID
    16.1E1  SUBT/UD       16.5E2  MULT/SUD      16.7E1    SUBT
                                                          /SUID
    16.1E2  MULT/UD       16.5E3  DIVT/SUD      16.7E2    MULT
                                                          /SUID
    16.1E3  DIVT/UD       16.5EC  CVTTS/SUD     16.7E3    DIVT
                                                          /SUID
    16.1EC  CVTTS/UD      16.5EF  CVTTQ/SVD     16.7EC    CVTTS
                                                          /SUID
    16.1EF  CVTTQ/VD      16.6AC  CVTST/S       16.7EF    CVTTQ
                                                          /SVID
    16.2AC  CVTST         16.700  ADDS/SUIC     16.7FC    CVTQS
                                                          /SUID
    16.500  ADDS/SUC      16.701  SUBS/SUIC     16.7FE    CVTQT
                                                          /SUID
    16.501  SUBS/SUC      16.702  MULS/SUIC     17.010    CVTLQ
    16.502  MULS/SUC      16.703  DIVS/SUIC     17.020    CPYS
    16.503  DIVS/SUC      16.720  ADDT/SUIC     17.021    CPYSN
    16.520  ADDT/SUC      16.721  SUBT/SUIC     17.022    CPYSE
    16.521  SUBT/SUC      16.722  MULT/SUIC     17.024    MT_
                                                          FPCR
    16.522  MULT/SUC      16.723  DIVT/SUIC     17.025    MF_
                                                          FPCR
    16.523  DIVT/SUC      16.72C  CVTTS/SUIC    17.02A   FCMOVEQ
    16.52C  CVTTS/SUC     16.72F  CVTTQ/SVIC    17.02B   FCMOVNE
    16.52F  CVTTQ/SVC     16.73C  CVTQS/SUIC    17.02C   FCMOVLT
    16.540  ADDS/SUM      16.73E  CVTQT/SUIC    17.02D   FCMOVGE
    16.541  SUBS/SUM      16.740  ADDS/SUIM     17.02E   FCMOVLE
    16.542  MULS/SUM      16.741  SUBS/SUIM     17.02F   FCMOVGT
    16.543  DIVS/SUM      16.742  MULS/SUIM     17.030    CVTQL
    16.560  ADDT/SUM      16.743  DIVS/SUIM     17.130    CVTQL/V
    16.561  SUBT/SUM      16.760  ADDT/SUIM     17.530    CVTQL/SV
    16.562  MULT/SUM      16.761  SUBT/SUIM     18.0000   TRAPB
    16.563  DIVT/SUM      16.762  MULT/SUIM     18.0400   EXCB
    16.56C  CVTTS/SUM     16.763  DIVT/SUIM     18.4000   MB
    16.56F  CVTTQ/SVM     16.76C  CVTTS/SUIM    18.4400   WMB
    16.580  ADDS/SU       16.76F  CVTTQ/SVIM    18.8000   FETCH
    16.581  SUBS/SU       16.77C  CVTQS/SUIM    18.A000   FETCH_M
    16.582  MULS/SU       16.77E  CVTQT/SUIM    18.C000   RPCC
    16.583  DIVS/SU       16.780  ADDS/SUI      18.E000   RC
    16.5A0  ADDT/SU       16.781  SUBS/SUI      18.F000   RS
    16.5A1  SUBT/SU       16.782  MULS/SUI      19        PAL19
    16.5A2  MULT/SU       16.783  DIVS/SUI      1A.0      JMP
    16.5A3  DIVT/SU       16.7A0  ADDT/SUI      1A.1      JSR
    16.5A4  CMPTUN/SU     16.7A1  SUBT/SUI      1A.2      RET
    16.5A5  CMPTEQ/SU     16.7A2  MULT/SUI      1A.3      JSR_
                                                       COROUTINE
    16.5A6  CMPTLT/SU     16.7A3  DIVT/SUI      1B        PAL1B
    16.5A7  CMPTLE/SU     16.7AC  CVTTS/SUI     1C        OPC1C
    16.5AC  CVTTS/SU      16.7AF  CVTTQ/SVI     1D        PAL1D
    1E      PAL1E         2A      LDL_L         36        FBGE
    1F      PAL1F         2B      LDQ_L         37        FBGT
    20      LDF           2C      STL           38        BLBC
    21      LDG           2D      STQ           39        BEQ
    22      LDS           2E      STL_C         3A        BLT
    23      LDT           2F      STQ_C         3B        BLE
    24      STF           30      BR            3C        BLBS
    25      STG           31      FBEQ          3D        BNE
    26      STS           32      FBLT          3E        BGE
    27      STT           33      FBLE          3F        BGT
    28      LDL           34      BSR
    29      LDQ           35      FBNE

1.20.7  –  OpenVMS PALcode Instruction Summary

    OpenVMS Unprivileged PALcode Instructions lists the OpenVMS
    unprivileged PALcode instructions and OpenVMS Privileged PALcode
    Instructions lists the OpenVMS privileged PALcode instructions.

    Table 16 OpenVMS Unprivileged PALcode Instructions

    Mnemonic    Opcode   Description

    AMOVRM      00.00A1  Atomic move from register to memory
    AMOVRR      00.00A0  Atomic move from register to register
    BPT         00.0080  Breakpoint
    BUGCHK      00.0081  Bugcheck
    CHMK        00.0083  Change mode to kernel
    CHME        00.0082  Change mode to executive
    CHMS        00.0084  Change mode to supervisor
    CHMU        00.0085  Change mode to user
    GENTRAP     00.00AA  Generate software trap
    IMB         00.0086  I-stream memory barrier
    INSQHIL     00.0087  Insert into longword queue at head
                         interlocked
    INSQHILR    00.00A2  Insert into longword queue at head
                         interlocked resident
    INSQHIQ     00.0089  Insert into quadword queue at head
                         interlocked
    INSQHIQR    00.00A4  Insert into quadword queue at head
                         interlocked resident
    INSQTIL     00.0088  Insert into longword queue at tail
                         interlocked
    INSQTILR    00.00A3  Insert into longword queue at tail
                         interlocked resident
    INSQTIQ     00.008A  Insert into quadword queue at tail
                         interlocked
    INSQTIQR    00.00A5  Insert into quadword queue at tail
                         interlocked resident
    INSQUEL     00.008B  Insert entry into longword queue
    INSQUEL/D   00.008D  Insert entry into longword queue deferred
    INSQUEQ     00.008C  Insert entry into quadword queue
    INSQUEQ/D   00.008E  Insert entry into quadword queue deferred
    PROBER      00.008F  Probe for read access
    PROBEW      00.0090  Probe for write access
    RD_PS       00.0091  Move processor status
    READ_UNQ    00.009E  Read unique context
    REI         00.0092  Return from exception or interrupt
    REMQHIL     00.0093  Remove from longword queue at head
                         interlocked
    REMQHILR    00.00A6  Remove from longword queue at head
                         interlocked resident
    REMQHIQ     00.0095  Remove from quadword queue at head
                         interlocked
    REMQHIQR    00.00A8  Remove from quadword queue at head
                         interlocked resident
    REMQTIL     00.0094  Remove from longword queue at tail
                         interlocked
    REMQTILR    00.00A7  Remove from longword queue at tail
                         interlocked resident
    REMQTIQ     00.0096  Remove from quadword queue at tail
                         interlocked
    REMQTIQR    00.00A9  Remove from quadword queue at tail
                         interlocked resident
    REMQUEL     00.0097  Remove entry from longword queue
    REMQUEL/D   00.0099  Remove entry from longword queue deferred
    REMQUEQ     00.0098  Remove entry from quadword queue
    REMQUEQ/D   00.009A  Remove entry from quadword queue deferred
    RSCC        00.009D  Read system cycle counter
    SWASTEN     00.009B  Swap AST enable for current mode
    WRITE_UNQ   00.009F  Write unique context
    WR_PS_SW    00.009C  Write processor status software field

    Table 17 OpenVMS Privileged PALcode Instructions

    Mnemonic       Opcode   Description

    CFLUSH         00.0001  Cache flush
    CSERVE         00.0009  Console service
    DRAINA         00.0002  Drain aborts
    HALT           00.0000  Halt processor
    LDQP           00.0003  Load quadword physical
    MFPR_ASN       00.0006  Move from processor register ASN
    MFPR_ESP       00.001E  Move from processor register ESP
    MFPR_FEN       00.000B  Move from processor register FEN
    MFPR_IPL       00.000E  Move from processor register IPL
    MFPR_MCES      00.0010  Move from processor register MCES
    MFPR_PCBB      00.0012  Move from processor register PCBB
    MFPR_PRBR      00.0013  Move from processor register PRBR
    MFPR_PTBR      00.0015  Move from processor register PTBR
    MFPR_SCBB      00.0016  Move from processor register SCBB
    MFPR_SISR      00.0019  Move from processor register SISR
    MFPR_SSP       00.0020  Move from processor register SSP
    MFPR_TBCHK     00.001A  Move from processor register TBCHK
    MFPR_USP       00.0022  Move from processor register USP
    MFPR_VPTB      00.0029  Move from processor register VPTB
    MFPR_WHAMI     00.003F  Move from processor register WHAMI
    MTPR_ASTEN     00.0026  Move to processor register ASTEN
    MTPR_ASTSR     00.0027  Move to processor register ASTSR
    MTPR_DATFX     00.002E  Move to processor register DATFX
    MTPR_ESP       00.001F  Move to processor register ESP
    MTPR_FEN       00.000B  Move to processor register FEN
    MTPR_IPIR      00.000D  Move to processor register IPRI
    MTPR_IPL       00.000E  Move to processor register IPL
    MTPR_MCES      00.0011  Move to processor register MCES
    MTPR_PERFMON   00.002B  Move to processor register PERFMON
    MTPR_PRBR      00.0014  Move to processor register PRBR
    MTPR_SCBB      00.0017  Move to processor register SCBB
    MTPR_SIRR      00.0018  Move to processor register SIRR
    MTPR_SSP       00.0021  Move to processor register SSP
    MTPR_TBIA      00.001B  Move to processor register TBIA
    MTPR_TBIAP     00.001C  Move to processor register TBIAP
    MTPR_TBIS      00.001D  Move to processor register TBIS
    MTPR_TBISD     00.0024  Move to processor register TBISD
    MTPR_TBISI     00.0025  Move to processor register TBISI
    MTPR_USP       00.0023  Move to processor register USP
    MTPR_VPTB      00.002A  Move to processor register VPTB
    STQP           00.0004  Store quadword physical
    SWPCTX         00.0005  Swap privileged context
    SWPPAL         00.000A  Swap PALcode image

1.20.8  –  PALcode Opcodes in Numerical Order

    PALcode Opcodes in Numerical Order lists the PALcode opcodes in
    numerical order.

    Table 18 PALcode Opcodes in Numerical Order

    Opcode(16Opcode(10)penVMS

    00.0000  00.0000  HALT
    00.0001  00.0001  CFLUSH
    00.0002  00.0002  DRAINA
    00.0003  00.0003  LDQP
    00.0004  00.0004  STQP
    00.0005  00.0005  SWPCTX
    00.0006  00.0006  MFPR_ASN
    00.0007  00.0007  MTPR_ASTEN
    00.0008  00.0008  MTPR_ASTSR
    00.0009  00.0009  CSERVE
    00.000A  00.0010  SWPPAL
    00.000B  00.0011  MFPR_FEN
    00.000C  00.0012  MTPR_FEN
    00.000D  00.0013  MTPR_IPIR
    00.000E  00.0014  MFPR_IPL
    00.000F  00.0015  MTPR_IPL
    00.0010  00.0016  MFPR_MCES
    00.0011  00.0017  MTPR_MCES
    00.0012  00.0018  MFPR_PCBB
    00.0013  00.0019  MFPR_PRBR
    00.0014  00.0020  MTPR_PRBR
    00.0015  00.0021  MFPR_PTBR
    00.0016  00.0022  MFPR_SCBB
    00.0017  00.0023  MTPR_SCBB
    00.0018  00.0024  MTPR_SIRR
    00.0019  00.0025  MFPR_SISR
    00.001A  00.0026  MFPR_TBCHK
    00.001B  00.0027  MTPR_TBIA
    00.001C  00.0028  MTPR_TBIAP
    00.001D  00.0029  MTPR_TBIS
    00.001E  00.0030  MFPR_ESP
    00.001F  00.0031  MTPR_ESP
    00.0020  00.0032  MFPR_SSP
    00.0021  00.0033  MTPR_SSP
    00.0022  00.0034  MFPR_USP
    00.0023  00.0035  MTPR_USP
    00.0024  00.0036  MTPR_TBISD
    00.0025  00.0037  MTPR_TBISI
    00.0026  00.0038  MFPR_ASTEN
    00.0027  00.0039  MFPR_ASTSR
    00.0029  00.0040  MFPR_VPTB
    00.002A  00.0041  MTPR_VPTB
    00.002B  00.0042  MTPR_PERFMON
    00.002E  00.0043  MTPR_DATFX
    00.003F  00.0063  MFPR_WHAMI
    00.0080  00.0128  BPT
    00.0081  00.0129  BUGCHK
    00.0082  00.0130  CHME
    00.0083  00.0131  CHMK
    00.0084  00.0132  CHMS
    00.0085  00.0133  CHMU
    00.0086  00.0134  IMB
    00.0087  00.0135  INSQHIL
    00.0088  00.0136  INSQTIL
    00.0089  00.0137  INSQHIQ
    00.008A  00.0138  INSQTIQ
    00.008B  00.0139  INSQUEL
    00.008C  00.0140  INSQUEQ
    00.008D  00.0141  INSQUEL/D
    00.008E  00.0142  INSQUEQ/D
    00.008F  00.0143  PROBER
    00.0090  00.0144  PROBEW
    00.0091  00.0145  RD_PS
    00.0092  00.0146  REI
    00.0093  00.0147  REMQHIL
    00.0094  00.0148  REMQTIL
    00.0095  00.0149  REMQHIQ
    00.0096  00.0150  REMQTIQ
    00.0097  00.0151  REMQUEL
    00.0098  00.0152  REMQUEQ
    00.0099  00.0153  REMQUEL/D
    00.009A  00.0154  REMQUEQ/D
    00.009B  00.0155  SWASTEN
    00.009C  00.0156  WR_PS_SW
    00.009D  00.0157  RSCC
    00.009E  00.0158  READ_UNQ
    00.009F  00.0159  WRITE_UNQ
    00.00A0  00.0160  AMOVRR
    00.00A1  00.0161  AMOVRM
    00.00A2  00.0162  INSQHILR
    00.00A3  00.0163  INSQTILR
    00.00A4  00.0164  INSQHIQR
    00.00A5  00.0165  INSQTIQR
    00.00A6  00.0166  REMQHILR
    00.00A7  00.0167  REMQTILR
    00.00A8  00.0168  REMQHIQR
    00.00A9  00.0169  REMQTIQR
    00.00AA  00.0170  GENTRAP

1.20.9  –  Common Architecture Instructions

1.21  –  Using LSE with MACRO-64

    This topic explains how to use the Language-Sensitive Editor
    (LSE) with the MACRO-64 language. For LSE to function correctly,
    LSE must be installed prior to the MACRO-64 assembler.

1.21.1  –  Invoking LSE

    To use LSE with the MACRO-64 language, you must name your program
    source file with a .M64 file extension. For example, to edit a
    file named TEST.M64, enter the following command:

    $ LSE TEST.M64

    Using the .M64 file extension invokes the LSE editor and places
    you in the MACRO-64 language environment.

    If you choose to use a different file extension, you can still
    use LSE in the MACRO-64 language environment. For example, to
    edit a file named TEST.ASM, enter the following command:

    $ LSE/LANGUAGE=MACRO64 TEST.ASM

    If you use LSE with MACRO-64, and you want the same behavior on
    the OpenVMS Alpha operating system as on the OpenVMS VAX operating
    system, enter the following LSE command:

    $ SET COMMAND LANGUAGE VMS

1.21.2  –  Running Diagnostics

    You can run diagnostics in LSE to debug programs without leaving
    the LSE editor. For more information, see the Guide to Language-
    Sensitive Editor for VMS Systems and the MACRO-64 release notes.

    When running diagnostics in an LSE editing session, MACRO-64
    displays error messages of different severity levels.

1.22  –  Error Messages

    The description of each message gives the severity, followed by
    additional explanatory text and suggested action.

1.22.1  –  ADDTRUNC

 Storing an address expression into a storage allocation less than
 the size of an address results in data truncation.

    Informational: The assembler stored a value that is too large for
    the allocated space, resulting in data truncation.

    User Action: Allocate more storage.

1.22.2  –  ALIGNFILLIGN

 The optional .ALIGN fill pattern argument is ignored in psects with
 the EXE and NOMIX attributes.

    Warning: The optional fill pattern is ignored because it is
    only valid for psects that do not possess the EXE and NOMIX
    attributes.

    User Action: Omit the fill pattern or specify the MIX psect
    attribute.

1.22.3  –  ALIGNFILLTRUNC

 The value you specify for the .ALIGN optional fill pattern must be
 an integer in the range of 0 . . . 255. Data truncation occurs with
 the currently specified fill pattern in a byte storage location.

    Warning: The value you specify as the fill pattern for the .ALIGN
    directive must be within the range of 0 . . . 255. Data truncation
    occurs whenever you specify a value that is outside of this
    range.

    User Action: Specify a smaller value for the fill pattern.

1.22.4  –  ALIGNLABELIGN

 The ALIGN_LABEL option has been replaced by the ALIGN_CODE option.

    Error: The ALIGN_LABEL option has been replaced by the ALIGN_CODE
    option.

    User Action: Use the recommended new option.

1.22.5  –  ALIGNTOBIG

 Specified alignment is too large for PSECT.

    Error: The alignment you specified is too large for the current
    psect.

    User Action: Check the psect attributes to insure that the psect
    alignment is greater than or equal to the alignment you are
    requesting.

1.22.6  –  ASCIITRUNC

 ASCII constant contains too many characters; value is truncated.

    Error: Your ASCII constant contains more than eight characters
    with the ^A or ^a radix specifier. The assembler deletes the
    extra characters.

    User Action: Check your source code. Use eight or less
    characters.

1.22.7  –  BADALIGN

 Alignment specifier is out of range.

    Error: The alignment specifier used with the .PSECT or .ALIGN
    directive is out of range.

    User Action: See the descriptions of the .PSECT and .ALIGN
    directives.

1.22.8  –  BADENDARG

 Bad argument to .END directive.

    Error: The optional argument to the .END directive is invalid.

    User Action: If you specify the argument, it must reference a
    procedure descriptor within the module. Specify a valid procedure
    descriptor name or omit the argument.

1.22.9  –  BADINSARG

 Argument N is invalid for this instruction.

    Error: The argument number shown is invalid for the instruction.

    User Action: Check the argument and required format as specified
    in the documentation.

1.22.10  –  BADLIB

 Error opening library file XXXXX.

    Error: The assembler encountered an error when attempting to open
    the indicated library file.

    User Action: Check the file format and file protections.

1.22.11  –  BADMACPARAMNAME

 Illegal macro parameter name.

    Error: The indicated macro parameter name is illegal.

    User Action: Examine your source code and see Chapter 1 in the
    Reference Manual for information about valid parameter names.

1.22.12  –  BADMACRONAME

 Illegal macro name.

    Error: The indicated macro name is illegal.

    User Action: Check your source code and see Chapter 2 in the
    Reference Manual for information about valid macro names.

1.22.13  –  BADOPERAND

 Invalid operand type for operator.

    Error: The resolved operand type is invalid for the specified
    operator.

    User Action: See Chapter 2 in the Reference Manual for
    descriptions of operators, operands, and expressions.

1.22.14  –  BADPARAMSTR

 Illegal parameter string.

    Error: The string specified as a macro parameter is invalid.

    User Action: Examine your source code and see Chapter 1 in the
    Reference Manual for information about valid parameter names.

1.22.15  –  BADSYSCALL

 Internal error. Bad system call.

    Error: The assembler encountered an unexpected internal error
    when performing a system call.

    User Action: Report the problem to Digital.

1.22.16  –  BASEFAIL

 Argument N is invalid. The assembler failed to find a base register
 specified with a previous .BASE directive to form a register
 expression of the form offset(Rn).

    Error: The assembler could not find a base register, which
    you specified with a previous .BASE directive, to form a valid
    register expression of the form offset(Rn).

    User Action: Check the instruction in the source code and see the
    description of the .BASE directive.

1.22.17  –  BASERANGE

 Argument N invalid. The assembler attempted to use base register Rn
 to form a register expression of the form offset(Rn). However, the
 argument offset exceeds the allowable range of -32,768 to +32,767.

    Error: The assembler attempted to use a base register, which
    you specified with a previous .BASE directive, to form a valid
    register expression of the form offset(Rn). This attempt failed
    because the specified argument offset exceeded the valid range of
    the base register offset (_32,768 to +32,767). The register cited
    in the message represents the register that produced an offset
    closest to the range of -32,768 to +32,767.

    User Action: Check the instruction in the source code and see
    description of the .BASE directive.

1.22.18  –  BEGEXPSC

 .BEGIN_EXACT is invalid in a psect with the NOEXE and NOMIX
 attributes.

    Error: A .BEGIN_EXACT directive is not valid in a psect with the
    NOEXE and NOMIX attributes.

    User Action: Check your source code.

1.22.19  –  BYTEALIGNIGN

 The BYTE_ALIGN option has been replaced by the ALIGN_DATA option.

    Error: The BYTE_ALIGN option has been replaced by the ALIGN_DATA
    option.

    User Action: Use the recommended new option.

1.22.20  –  CONPSECTATTR

 Contradictory PSECT attribute.

    Error: A previously specified psect attribute conflicts with the
    flagged psect attribute.

    User Action: See the description of the .PSECT directive and
    psect attributes.

1.22.21  –  CONTEOF

 Assembler encountered end of file after line continuation.

    Error: The assembler encountered end of file after a line that
    specified a continuation.

    User Action: Check your source code.

1.22.22  –  DATAALIGNTOBIG

 Data requires alignment too large for PSECT.

    Error: The alignment required for a specified data item is too
    large for the psect.

    User Action: Check the psect attributes to insure that the psect
    alignment is greater than or equal to the required alignment of
    the data items. See the description of the .PSECT directive and
    psect attributes.

1.22.23  –  DATANOTINNOEXE

 Data declarations must be in a psect with the MIX or NOEXE
 attribute.

    Error: A data declaration, such as a data-storage directive, has
    been specified in a psect with incorrect psect attributes.

    User Action: Make sure the psect has the MIX or NOEXE attribute
    set. See the description of the .PSECT directive and psect
    attributes.

1.22.24  –  DIRNOTINNOEXE

 Directive must be in a psect with the MIX or NOEXE attribute.

    Error: The directive you specify must appear in a psect with the
    MIX or NOEXE attribute set.

    User Action: Make sure you specify a psect with the MIX or NOEXE
    attribute set. See the description of the .PSECT directive and
    psect attributes.

1.22.25  –  DISPTOOLGE

 Branch offset is too large for this instruction.

    Error: The offset you specified is too large for this
    instruction.

    User Action: Check the range of the specified target to insure it
    falls between -1048576 . . . +1048575, inclusive.

1.22.26  –  DUPLEXTERN

 External item has multiple definitions.

    Error: The item you declared as externally defined with the
    .EXTERNAL attribute has another conflicting definition within
    this assembly unit.

    User Action: Check the definitions for the specified item.

1.22.27  –  DUPLGLOBAL

 Duplicate global name.

    Warning: The assember detected a duplicate global name.

    User Action: Check all references in your source code to this
    name.

1.22.28  –  DUPMACPARAMNAME

 Duplicate macro parameter name.

    Error: The assembler detected a duplicate macro parameter name.

    User Action: Check your source code.

1.22.29  –  ENDEXPSC

 .END_EXACT is invalid in a psect with the NOEXE and NOMIX
 attributes.

    Error: A .END_EXACT directive is not valid in a psect with the
    NOEXE and NOMIX attributes.

    User Action: Check your source code.

1.22.30  –  EOLEXP

 Assembler expected an end of line.

    Error: The assembler expected no more input from the current
    line.

    User Action: Check your source code.

1.22.31  –  ESCAPE

 Illegal escape sequence in string literal; assembler expected \, ",
 x, or X.

    Error: The escape sequence you specified in the string literal is
    illegal.

    User Action: Check your source code.

1.22.32  –  EXP32BITTRUNC

 Assembler expected an integer in the range 0 . . . (2^32)-1 for
 an unsigned expression OR -(2^31) . . . +(2^31)-1 for a signed
 expression. Data truncation to 32 bits.

    Warning: The assembler found an integer that was not within the
    expected range.

    User Action: Check your source code. The literal must be within
    the range of 0 . . . (2^32)-1 for an unsigned expression OR
    -(2^31) . . . +(2^31)-1 for a signed expression. Data truncation
    to 32 bits occurs.

1.22.33  –  EXP32BITTYPE

 Assembler expected an integer in the range 0 . . . (2^32)-1 for
 unsigned expression OR -(2^31) . . . +(2^31)-1 for signed expression.

    Error: The assembler expected an unsigned integer value within
    the range of 0 . . . (2^32)-1 or a signed integer value within in
    the range of -(2^31) . . . +(2^31)-1.

    User Action: Check your source code.

1.22.34  –  EXPBINEXPTERM

 Assembler found XXXXX when expecting a binary operator or expression
 terminator.

    Error: The assembler expected a binary operator, such as the plus
    sign (+)  for binary addition, or an item to end the expression,
    such as the right-angle bracket (>).

    User Action: Check the flagged item in the source statement.

1.22.35  –  EXPFPREG

 Argument N is invalid. Assembler expected a floating point register.

    Error: The instruction argument cited is invalid. The assembler
    expected a floating-point register.

    User Action: Check your source code and the instruction
    documentation.

1.22.36  –  EXPGENREG

 Argument N is invalid. Assembler expected a general register.

    Error: The instruction argument cited is invalid. The assembler
    expected a general register.

    User Action: Check your source code and the instruction
    documentation.

1.22.37  –  EXPIDPROC

 Argument N is invalid. Assembler expected an identifier representing
 a procedure value.

    Error: The argument cited is invalid. The assembler expected a
    user identifier that represents a procedure value.

    User Action: Check your source code and the instruction
    documentation.

1.22.38  –  EXPINTPAL

 Assembler expected an integer expression or PAL opcode.

    Error: Integer expession or PAL opcode missing.

    User Action: Replace the flagged item with an integer or PAL
    opcode.

1.22.39  –  EXPLAB

 Argument N is invalid. Assembler expected a label defined in the
 same psect.

    Error: The cited argument is invalid. The assembler expected a
    label definition to occur in the same psect as its reference.

    User Action: Check your source code and the instruction
    documentation.

1.22.40  –  EXPLITVAL

 Argument N is invalid. Assembler expected an integer literal value
 in the inclusive range 0 . . . 255.

    Error: The instruction argument cited is invalid. The assembler
    expected an integer literal within the range of 0 . . . 255.

    User Action: Check your source code and the instruction
    documentation.

1.22.41  –  EXPMACRONAME

 Assembler expected a valid macro name.

    Error: The assembler expected a valid macro name in this context.

    User Action: Check your source code to insure that the item
    flagged is a user identifier, opcode, or nonmacro directive.

1.22.42  –  EXPPALOPLIT

 Argument N is invalid. Assembler expected an integer literal value
 in the inclusive range 0 . . . 67108863.

    Error: The instruction argument cited is invalid. The assembler
    expected an integer literal.

    User Action: Check your source code and the instruction
    documentation.

1.22.43  –  EXPREGOFF

 Argument N is invalid. Assembler expected a general register
 expression of the form offset(Rn).

    Error: The cited argument is invalid. The assembler expected a
    general register expression of the form integer_offset(Rn) for
    this argument.

    User Action: Check the source code and the instruction
    documentation.

1.22.44  –  EXPRESEXP

 Argument N is invalid. Assembler expected an expression with no
 forward references resolvable to psect +/- offset.

    Error: The argument cited is invalid. The assembler expected an
    expression with no forward references.

    User Action: Check your source code and the instruction
    documentation.

1.22.45  –  EXPSTACKOVER

 Internal SEM expression stack overflow.

    Fatal: An internal error has occurred.

    User Action: Gather as much information as possible about the
    circumstances under which the error occurred and report the
    problem to Digital.

1.22.46  –  EXPTOOCMPLX

 Expression is too complex to evaluate.

    Error: The expression is too complex for the assembler to
    evaluate.

    User Action: Try grouping the expression components using angle
    brackets (< >). The most complex expression form handled by
    the assembler resolves to the form: <psect/symbol +/- offset>
    OPERATOR <psect/symbol +/- offset>, where OPERATOR is one of: +,
    -, *, /, @, \, &, or !. See Chapter 2 in the Reference Manual for
    further descriptions of the assembler evaluation of expressions.

1.22.47  –  EXPZEROFF

 Argument N is invalid. Assembler expected a general register
 expression of the form 0(Rn) or (Rn).

    Error: The cited argument is invalid. The assembler expected a
    general register expression of the form 0(Rn).

    User Action: Check your source code and see Chapter 2 in
    the Reference Manual for information about general register
    expressions.

1.22.48  –  FOUNDEXP

 Assembler found XXXXX when expecting one of the following: XXXXX.

    Error: The assembler found an unexpected item in a location where
    it expected something else.

    User Action: Check the unexpected item found in the source
    statement. Examine those items cited as expected as alternatives
    for the unexpected item.

1.22.49  –  FREGDEF

 You cannot define a floating-point register in terms of an integer
 register.

    Warning: You are attempting to define a floating-point register
    symbol in terms of an integer register.

    User Action: Specify either a floating-point register or an
    expression within the range of 0 to 31 with the .DEFINE_FREG
    directive. See the description of the .DEFINE_FREG directive.

1.22.50  –  GENERROR

 Generated ERROR:

    Error: This statement was generated using the .ERROR directive.

    User Action: Examine your source code.

1.22.51  –  GENPRINT

 Generated PRINT:

    Informational: This statement was generated using the .PRINT
    directive.

    User Action: Examine your source code.

1.22.52  –  GENWARN

 Generated WARNING:

    Warning: This statement was generated using the .WARNING
    directive.

    User Action: Examine your source code.

1.22.53  –  HEXSTR

 Illegal hexadecimal escape sequence in string literal.

    Error: The specified hexadecimal escape sequence is invalid.

    User Action: Check your source code and the documentation.

1.22.54  –  IDENTTRUNC

 The string length of the module IDENT is greater than 31 characters.
 It is truncated to 31 characters.

    Warning: The string argument you specified with the .IDENT
    directive is too long.

    User Action: Specify a shorter string argument. See the
    description of the .IDENT directive.

1.22.55  –  IDFOUND

 Assembler found identifier in the opcode field when expecting one
 of the following: opcode, directive, macro invocation, or symbol
 definition.

    Error: The identifier cited was unexpected. The assembler
    expected either an opcode, a directive, a macro invocation, or
    a symbol definition.

    User Action: Check your source code.

1.22.56  –  IDTOOLONG

 Identifier is longer than 31 characters.

    Error: The identifier exceeds the 31 character maximum size.

    User Action: Check your source code and either rename or truncate
    the identifier.

1.22.57  –  ILLASCII

 Illegal ASCII constant.

    Error: The assembler found an illegal ASCII constant with the 6A
    or ^a radix specifier.

    User Action: Check your source code.

1.22.58  –  ILLBIN

 Illegal binary constant.

    Error: The assembler found an illegal binary constant with the ^B
    or ^b radix specifier.

    User Action: Check your source code.

1.22.59  –  ILLDEC

 Illegal decimal constant.

    Error: The assembler found an illegal binary constant with the ^D
    or ^d radix specifier.

    User Action: Check your source code.

1.22.60  –  ILLEXPON

 Illegal exponent in floating-point constant.

    Error: The specified exponent of the floating-point constant is
    illegal.

    User Action: Check your source code and see Chapter 5 in the
    Reference Manual for information about floating-point constants.

1.22.61  –  ILLFLOAT

 Illegal floating-point constant.

    Error: The specified floating-point constant is illegal.

    User Action: Check your source code and see Chapter 5 in the
    Reference Manual for information about floating-point constants.

1.22.62  –  ILLHEX

 Illegal hexadecimal constant.

    Error: The assembler found an illegal binary constant with the ^X
    or ^x radix specifier.

    User Action: Check your source code.

1.22.63  –  ILLIFOP

 Illegal .IF operator.

    Error: An illegal operator was encountered as an .IF operator.

    User Action: Check your source code and see the description of
    the .IF directive.

1.22.64  –  ILLINCL

 Illegal .INCLUDE file specification.

    Error: The assembler encountered an illegal .INCLUDE directive.

    User Action: Check your source code and see the description of
    the .INCLUDE directive.

1.22.65  –  ILLOCT

 Illegal octal constant.

    Error: The assembler found an illegal binary constant with the ^O
    or ^o radix specifier.

    User Action: Check your source code.

1.22.66  –  ILLOPERANDMIX

 Illegal operand mixing for operator.

    Error: The resolved operand types are invalid when used together
    with the specified operator.

    User Action: See Chapter 2 in the Reference Manual for
    descriptions of operators, operands, and expressions.

1.22.67  –  ILLPROCRET

 Illegal procedure return; linkage register (argument 1) must be R31
 when software hint (argument 3) is 1.

    Error: Illegal procedure return.

    User Action: Check the instruction arguments. When argument 3,
    software hint, is 1, the first argument specifying the linkage
    register must be R31.

1.22.68  –  ILLRADIX

 Illegal radix specifier in numeric constant; specify A, B, C, D, O,
 or X.

    Error: The assembler found an illegal radix specifier.

    User Action: Check your source code and use one of A, B, C, D, O,
    or X.

1.22.69  –  INCLDEPTH

 .INCLUDE nest depth exceeds N - check for circular .INCLUDE.

    Error: The assembler attempted to exceed the maximum level of
    include file depth.

    User Action: Check your source code for circular file inclusion.

1.22.70  –  INCLOPEN

 .INCLUDE file open error.

    Error: The assembler could not open the included file.

    User Action: Check the file attributes and so forth of the
    specified .INCLUDE file.

1.22.71  –  INSNOTINPSC

 Instructions must be in a MIX, NOEXE; MIX, EXE; or NOMIX, EXE PSECT.

    Error: You specified an instruction in a psect with incorrect
    psect attributes.

    User Action: Make sure the psect has MIX or EXE and NOMIX
    attributes set.

1.22.72  –  INTERNAL

 Internal assembler error. Please report the problem to Digital.

    Fatal: An internal error has occurred.

    User Action: Gather as much information as possible about the
    circumstances under which the error occurred and report the
    problem to Digital.

1.22.73  –  INTERR

 Internal processing error in the SYN facility. Please report the
 problem to Digital.

    Fatal: An internal error has occurred.

    User Action: Gather as much information as possible about the
    circumstances under which the error occurred and report the
    problem to Digital.

1.22.74  –  INVALIGNFILL

 You specified an invalid optional fill pattern with the .ALIGN
 directive.

    Error: You specified an invalid optional fill pattern.

    User Action: Check your source code, in particular the second
    argument to the .ALIGN directive, the alignment fill specifier,
    to insure that it resolves to an integer. See the description of
    the .ALIGN directive.

1.22.75  –  INVBASEEXP

 Invalid expression for .BASE directive.

    Error: The expression is not valid for .BASE directive.

    User Action: The expression you specified for a base register
    with the .BASE directive should contain no forward references and
    resolve to one of the following at this point in assembly: psect
    +/- offset, external symbol reference +/- offset, integer, label
    +/- offset, where the label is defined in a psect with the EXE
    and NOMIX attributes. See Chapter 5 in the Reference Manual for
    more information about the assembler evaluation of expressions.

1.22.76  –  INVBASEREG

 Invalid base register. Base register must be one of R0 through R30.

    Error: You specified an invalid base register.

    User Action: Specify a base register as a general register from
    the range of R0 . . . R30. R31 cannot be specified as a base
    register and is implicitly defined as .BASE R31, 0.

1.22.77  –  INVBRTGT

 Invalid branch target. Branch target label must be defined in same
 psect as the branch instruction which references the label.

    Error: The specified label you reference as the target of a
    branch instruction must be defined in the same psect in which
    it is referenced.

    User Action: See Chapter 4 in the Reference Manual for more
    information about labels.

1.22.78  –  INVCA

 You specified an invalid code address with the procedure descriptor.
 The code address must be a nontemporary label defined in a psect
 with the EXE or MIX attribute after its use with .PROCEDURE_
 DESCRIPTOR.

    Error: The code address you specified as the second argument to
    the .PROCEDURE_DESCRIPTOR directive is invalid.

    User Action: The code address must be a non-temporary label
    defined in a psect with the EXE or NOMIX attribute. Check your
    source code.

1.22.79  –  INVEXP

 Assembler found XXXXX when expecting a valid expression.

    Error: The assembler expected one of the following: integer,
    floating-point constant, identifier, register, period (.),  left-
    angle bracket (<),  or unary operator.

    User Action: Check the unexpected item found in the source
    statement.

1.22.80  –  INVEXPRFORDIR

 Invalid expression type for directive.

    Error: The assembler resolved value for the expression in the
    cited directive is invalid.

    User Action: See Chapters 1 and 5 in the Reference Manual for
    more information about the directive arguments and types.

1.22.81  –  INVEXPRFORSYM

 Invalid expression type for symbol.

    Error: The assembler resolved value for the expression that is
    assigned to a local or global symbol is invalid.

    User Action: Expressions assigned to a symbol must contain no
    forward references and must resolve to an integer or psect
    /label +/- offset. See Chapter 2 in the Reference Manual for
    more information about how the assembler determines symbol and
    expression values.

1.22.82  –  INVFPCONST

 Invalid floating-point value. Check value range for floating-point
 data type.

    Error: The assembler detected an invalid floating-point value.

    User Action: Check the specified range for the directive type.

1.22.83  –  INVINSQUAL

 You specified an invalid instruction qualifier list for the opcode.

    Error: The instruction qualifier you specified with the opcode is
    invalid.

    User Action: See Appendix A in the Reference Manual for a
    complete list of opcodes and valid instruction qualifiers.

1.22.84  –  INVLCA

 Assembler found an invalid or undefined code address for the
 procedure descriptor.

    Error: An invalid or undefined code address corresponds to the
    specified procedure descriptor.

    User Action: Check your source code for the specified code
    address.

1.22.85  –  INVLISTOPT

 You specified an invalid option with the .LIST or .SHOW directive.

    Error: You specified an invalid option with the .LIST or .SHOW
    directive.

    User Action: See the descriptions of the .LIST and .SHOW
    directives for valid .LIST and .SHOW options.

1.22.86  –  INVLPD

 Invalid procedure descriptor.

    Error: You specified an invalid procedure descriptor. There was
    no definition of a procedure descriptor by the specified name.

    User Action: Check your source code.

1.22.87  –  INVNLISTOPT

 You specified an invalid option with the .NLIST or .NOSHOW
 directive.

    Error: You specified an invalid option with the .NLIST or .NO_
    SHOW directive.

    User Action: See the descriptions of the .NLIST and .NO_SHOW
    directives for valid .NLIST and .NO_SHOW options.

1.22.88  –  INVOFF

 You attempted to specify data intialization with a current psect
 offset that is outside the range of 0 to 2147483647.

    Error: The current psect offset is invalid for specifying a data
    initialization.

    User Action: Check your source code and the value of the current
    psect offset.

1.22.89  –  INVREGNUMEXP

 Invalid register-number expression. Specify an integer expression
 between 0 and 31 or a previously defined or predefined register.

    Error: You specified an illegal expression for a register symbol
    definition.

    User Action: Specify a value between 0 and 31. You can also
    define a register in terms of a previously-defined or predefined
    register.

1.22.90  –  INVREPCOUNT

 The integer value of the .REPEAT expression is not within the
 inclusive range of 0 . . . 65535. A 0 value is assumed.

    Warning: The value of the .REPEAT expression must be within the
    range of 0 . . . 65,535, inclusive. Therefore, a 0 expression
    value is assumed.

    User Action: Specify a repetition count between 0 and 65,535,
    inclusive.

1.22.91  –  INVSAVEOPT

 You specified an invalid option with the .SAVE_PSECT directive.

    Error: You specified an invalid option with the .SAVE_PSECT
    directive.

    User Action: See the description of the .SAVE_PSECT directive for
    valid .SAVE_PSECT options.

1.22.92  –  INVTEMPLAB

 Invalid use of temporary label.

    Error: A temporary label reference is not allowed in this
    context.

    User Action: See Chapter 2 in the Reference Manual for
    information about using temporary labels.

1.22.93  –  INVTERM

 Assembler found N when expecting a valid expression term.

    Error: The assembler found an unexpected item where it expected
    one of the following expressions: floating-point number, integer,
    register, decimal point (.),  identifier, or left-angle bracket
    (<).

    User Action: Check the item flagged by the assembler.

1.22.94  –  IREGDEF

 You cannot define an integer register in terms of a floating-point
 register.

    Warning: You are attempting to define an integer register symbol
    in terms of a floating-point register. IREGDEF

    User Action: Specify either an integer register or an expression
    within the range of 0 to 31 with the .DEFINE_IREG directive.

1.22.95  –  LABELNOTDEF

 Undefined label.

    Error: The label you specified is undefined.

    User Action: See Chapters 2 and 4 for descriptions of the valid
    labels.

1.22.96  –  LABELREDECL

 Illegal redefinition of label.

    Error: You have illegally defined this label in multiple places
    in this assembly unit.

    User Action: Check all references to this label in your source
    code.

1.22.97  –  LABNOTINPSECT

 Label must be declared in a PSECT.

    Error: You are attempting to declare a temporary, local, or
    global label without first establishing a psect.

    User Action: Make sure you enter the appropriate .PSECT directive
    before declaring the label in your source stream.

1.22.98  –  LEXOPEDITSPEC

 Unrecognized edit specifier.

    Error: The assembler does not recognize the edit specifier for
    the %EDIT lexical operator.

    User Action: Check your source code and see the description of
    the %EDIT lexical operator.

1.22.99  –  LEXOPENDM

 Illegal modification of .ENDM directive keyword by lexical
 operation.

    Error: While your macro definition contains a .ENDM directive
    that ends the macro definition, the .ENDM directive is modified
    by a lexical operator so that it can no longer be recognized as a
    .ENDM directive keyword after lexical processing.

    User Action: Change the statement to avoid modifying the .ENDM
    directive keyword with lexical operator processing. See Chapter
    3 in the Reference Manual for information about using lexical
    operators.

1.22.100  –  LEXOPENDR

 Illegal modification of .ENDR directive keyword by lexical
 operation.

    Error: While your repeat range contains a .ENDR directive that
    ends the repeat block, the .ENDR directive is modified by a
    lexical operator so that it can no longer be recognized as a
    .ENDR directive keyword after lexical processing.

    User Action: Change the statement to avoid modifying the .ENDR
    directive keyword with lexical operator processing. See Chapter
    3 in the Reference Manual for information about using lexical
    operators.

1.22.101  –  LEXOPSYNTAX

 Illegal lexical operator syntax (missing left or right parenthesis,
 missing comma, or other lexical operator syntax error).

    Error: The indicated lexical operator has a syntax error.

    User Action: Check the source code to insure correct syntax.

1.22.102  –  LEXSYM

 XXXXX is already a lexical string symbol name; it cannot also be a
 numeric symbol name.

    Error: You cannot define a lexical string symbol and a numeric
    symbol by the same name.

    User Action: Check your source code and remove either the lexical
    string or the numeric symbol definition.

1.22.103  –  LIBMOD_BADFORMAT

 Library module XXXXX contains illegal syntax (missing .MACRO or
 label preceding .MACRO, missing or not matching .ENDM, or other
 macro syntax error).

    Error: The assembler encountered illegal syntax.

    User Action: Check the syntax of the macro.

1.22.104  –  LIBMOD_EMPTY

 Library module XXXXX is empty.

    Warning: The assembler encountered an empty library module.

    User Action: Replace the library module.

1.22.105  –  LIBMOD_EXTRA

 Library module XXXXX contains extraneous text after .ENDM; the
 assembler ignores the extra text.

    Warning: The assembler encountered extraneous text after an .ENDM
    directive in a library module. The assembler ignores this text.

    User Action: Correct the library module.

1.22.106  –  LIBMOD_NOT_FOUND

 Library module XXXXX not found.

    Error: The assembler could not find the indicated library module.

    User Action: Check the spelling of the macro library and module
    names.

1.22.107  –  LOCCTRNOTDATA

 Location counter cannot be set in a psect with the EXE and NOMIX
 attributes.

    Error: You cannot modify the location counter in a psect with the
    EXE and NOMIX attributes.

    User Action: If you need to modify the location counter, specify
    the MIX psect attribute. See Chapter 5 iin the Reference Manual
    for a description of the MIX psect attribute.

1.22.108  –  MACCASEMATCH

 Library macro name is spelled using different alphabetic case than
 in .MCALL directive or macro invocation.

    Error: There is an alphabetic case difference between that
    specified in the macro library and what you specified for the
    macro name.

    User Action: Check the case of the macro name in your source code
    and the case of the macro in the specified macro library.

1.22.109  –  MACEXPNEST

 Macro expansion exceeds maximum nesting depth (macro recursion not
 detected).

    Error: The macro is not recursive but exceeds the maximum
    allowable expansion depth.

    User Action: Check your source code for possible restructuring.

1.22.110  –  MACPARAMGENDEF

 You can specify a generated label default value or a default string
 value, but not both.

    Error: You specified both a default string value and a generated
    label default value when you can only specify one.

    User Action: Examine your source code.

1.22.111  –  MACPARAMSYNTAX

 Illegal macro parameter syntax. Assembler found XXXXX when expecting
 one of XXXXX.

    Error: Macro parameter syntax is invalid.

    User Action: Try replacing the unexpected argument with one of
    those items cited as expected.

1.22.112  –  MACRECURSE

 Recursive macro exceeds maximum macro expansion nesting depth.

    Error: The macro is recursive and exceeds the maximum expansion
    nesting depth.

    User Action: Check your source code for a missing basis step in
    the recursive macro.

1.22.113  –  MACZERO

 Assembler cannot evaluate expression. A 0 expression value is
 assumed.

    Informational: The assembler cannot evaluate this expression due
    to errors it encountered. Therefore, a 0 value is assumed.

    User Action: Check the expression for forward or external
    references.

1.22.114  –  MAXIF

 Maximum nesting of .IF directives exceeded.

    Error: The maximum depth nesting of .IF directives has been
    exceeded.

    User Action: Check your source code for possible restructuring.

1.22.115  –  MAXLEXOP

 More than N lexical operators encountered; check for a recursive
 lexical string symbol.

    Error: Your source line contains an excessive number of lexical
    operators. A recursive lexical string symbol definition occurs
    when you initially define a lexical string symbol in terms
    of itself using the lexical substitution operator. While the
    assembler normally interprets lexical substitution operators
    during lexical string symbol definition, it cannot in this case
    because the lexical string symbol is not yet defined. When the
    assembler later expands such a lexical string symbol with the
    imbedded self reference, infinite recursion results.

    User Action: Check your source code for recursive lexical string
    symbol definitions and redefine them to avoid recursion.

1.22.116  –  MISSENDC

 Missing .ENDC directive(s).

    Warning: The assembler could not find a terminating .ENDC
    conditional directive.

    User Action: Check your source code.

1.22.117  –  MISSINGENDM

 Missing .ENDM directive.

    Error: The assembler could not find a terminating .ENDM directive
    to match a .MACRO directive.

    User Action: Check your source code.

1.22.118  –  MISSINGENDR

 Missing .ENDR directive.

    Error: The assembler could not find an .ENDR directive to
    terminate an .IRP or a.REPEAT block.

    User Action: Check your source code.

1.22.119  –  MISSQUOTE

 Missing closing double-quote character in string literal.

    Error: The closing double-quote is missing from the string
    literal.

    User Action: Check your source code and insert a closing double-
    quote for a string literal.

1.22.120  –  MODCODLOCCTR

 Restoring the location counter in the current context causes an
 illegal modification of the location counter for a psect with the
 EXE and NOMIX attributes.

    Error: You cannot modify the location counter in a psect with the
    EXE and NOMIX attributes.

    User Action: If you need to modify the location counter, specify
    the MIX psect attribute. See Chapter 5 in the Reference Manual
    for a description of the MIX psect attribute.

1.22.121  –  NOBEGEX

 Assembler encountered an unmatched .END_EXACT directive.

    Error: The assembler encountered an .END_EXACT directive before a
    .BEGIN_EXACT directive.

    User Action: Check your source code.

1.22.122  –  NOCA

 You did not specify a code address as argument 2 with
 .PROCEDURE_DESCRIPTOR.

    Error: You did not specify a code address as the second argument
    to the .PROCEDURE_DESCRIPTOR directive.

    User Action: The code address must be a nontemporary label
    defined in a psect with the EXE or NOMIX attribute. Check your
    source code.

1.22.123  –  NOQUAL

 Instruction qualifiers are invalid with this opcode.

    Error: You cannot specify instruction qualifiers with this
    opcode.

    User Action: See Appendix A in the Reference Manual for a
    complete list of opcodes and valid instruction qualifiers.

1.22.124  –  NOTAQUAL

 An item you specified in the qualifier list is invalid with this
 opcode.

    Error: The instruction qualifier you specified with the opcode is
    invalid.

    User Action: See Appendix A in the Reference Manual for a
    complete list of opcodes and valid instruction qualifiers.

1.22.125  –  NOTENOUGHARGS

 Not enough arguments for instruction.

    Error: The instruction needs one or more additional arguments.

    User Action: Check the argument numbers and required formats as
    specified in Chapter 5 in the Reference Manual.

1.22.126  –  NOTINMACRO

 This statement must occur only within a macro.

    Error: The statement you specified is only allowed within a
    macro.

    User Action: See Chapter 2 in the Reference Manual for a
    description of the statement specified.

1.22.127  –  NOTINSEM

 Missing functionality in SEM.

    Error: This functionality is missing in the assembler.

    User Action: Please report the problem to Digital.

1.22.128  –  NUMSYM

 XXXXX is already a numeric symbol name; it cannot also be a lexical
 string symbol name.

    Error: You cannot define a numeric symbol and a lexical string
    symbol by the same name.

    User Action: Check your source code and remove either the numeric
    or the lexical string symbol definition.

1.22.129  –  OPTIGN

 The assembler is ignoring one or more VAX MACRO options.

    Informational: The assembler detected and ignored a VAX MACRO
    option.

    User Action: Remove the VAX MACRO options from your MACRO-64
    Assembler for OpenVMS Alpha Systems program.

1.22.130  –  OVERLAP

 Assembler detected overlapping initializers at offset NN. This
 initial value overlaps but is not an exact replacement for a
 previous initial value.

    Error: You are trying to assign or initialize multiple values to
    the same location. This is not allowed.

    User Action: Check your source code.

1.22.131  –  PSECTALIGNCON

 PSECT alignment conflicts with earlier declaration.

    Error: A previously specified psect alignment attribute conflicts
    with the flagged psect attribute.

    User Action: Check all declarations of the psect. See the
    description of the .PSECT directive and psect attributes.

1.22.132  –  PSECTATTRCON

 PSECT attribute conflicts with earlier declaration.

    Error: A previously specified psect attribute conflicts with the
    flagged psect attribute.

    User Action: Check all declarations of the psect. See the
    description of the .PSECT directive and psect attributes.

1.22.133  –  REGREDEF

 You attempted to redefine a previously defined register symbol with
 a different value.

    Warning: You are attempting to change the definition of a
    register symbol that either you have previously defined or that
    MACRO-64 has predefined.

    User Action: Check for conflicts with the register-symbol
    identifier you have specified. If you wish to redefine a register
    symbol, you must first cancel its previous definition with the
    .UNDEFINE_REG directive.

1.22.134  –  REDUNDELSE

 You cannot specify more than one .ELSE directive within a single .IF
 block.

    Error: The assembler encountered more than one .ELSE directive
    within a single .IF block.

    User Action: Check your source code.

1.22.135  –  RESTOREWOSAVE

 PSECT .RESTORE without .SAVE.

    Error: You entered a .RESTORE_PSECT directive without a previous
    corresponding .SAVE_PSECT directive.

    User Action: Check the uses of .SAVE_PSECT and .RESTORE_PSECT in
    your source code.

1.22.136  –  SAVESTACKOVER

 Internal SEM PSECT .SAVE stack overflow.

    Fatal: An internal error has occurred.

    User Action: Gather as much information as possible about the
    circumstances under which the error occurred and report the
    problem to Digital.

1.22.137  –  SRCREAD

 Error reading source file.

    Error: The assembler encountered an error in reading your source
    file.

    User Action: Check file specifications, protections, and so
    forth.

1.22.138  –  SYMBOLREDECL

 Illegal redefinition of symbol.

    Error: The symbol is already defined as a label or explicitly
    declared as externally defined with the .EXTERNAL directive.

    User Action: Check all uses of this symbol.

1.22.139  –  TOOMANYARGS

 Too many arguments for instruction.

    Error: The instruction contains one or more arguments than
    necessary.

    User Action: Check the argument numbers and required formats as
    specified in Chapter 5 in the Reference Manual.

1.22.140  –  TOOMANYMACARG

 You specified more arguments than are defined for this macro.

    Error: You specified more arguments on the macro call than were
    specified for its definition.

    User Action: Check the macro definition and point of call in your
    source code.

1.22.141  –  TOOMANYMACPARAMS

 Too many macro parameters.

    Error: You specified too many macro parameters.

    User Action: Check your source code.

1.22.142  –  TRUNCDATA

 Data truncation warning.

    Warning: You specified a data value that is out of range for the
    specified directive, which results in data truncation.

    User Action: Specify a smaller value.

1.22.143  –  UNDCA

 You specified an undefined code address with the procedure
 descriptor.

    Error: The code address you specified as the second argument to
    the .PROCEDURE_DESCRIPTOR directive is undefined.

    User Action: The code address must be a nontemporary label
    defined in a psect with the EXE or NOMIX attribute. Check your
    source code.

1.22.144  –  UNDEFSYM

 Undefined symbol or label. Assembler assumes an .EXTERNAL
 definition.

    Warning: The referenced label or symbol does not have an explicit
    definition and an external definition is assumed.

    User Action: Use the .EXTERNAL directive to declare the symbol.

1.22.145  –  UNEXPELSE

 Unexpected .ELSE directive.

    Error: The assembler encountered an unexpected .ELSE directive.

    User Action: Check the use of the .ELSE directive in your source
    code to insure proper positioning with a .IF and .ENDC directive.

1.22.146  –  UNEXPENDC

 Unexpected .ENDC directive.

    Error: The assembler could not find a terminating .ENDC for a
    macro conditional directive, such as .IF.

    User Action: Check your source code.

1.22.147  –  UNEXPENDM

 Unexpected .ENDM directive.

    Error: The assembler encountered an unexpected .ENDM directive.

    User Action: Check your source code for matching .MACRO/.ENDM
    pairs.

1.22.148  –  UNEXPENDR

 Unexpected .ENDR directive.

    Error: The assembler encountered an unexpected .ENDR directive.

    User Action: Check your source code for matching .REPEAT/.ENDR
    and .IRP/.ENDR directive pairs.

1.22.149  –  UNEXPIFF

 Unexpected .IF_FALSE (.IFF) directive.

    Error: The assembler encountered an unexpected .IF_FALSE
    directive.

    User Action: Check your source code to insure that this directive
    occurs within an .IF block.

1.22.150  –  UNEXPIFT

 Unexpected .IF_TRUE (.IFT) directive.

    Error: The assembler encountered an unexpected .IF_TRUE
    directive.

    User Action: Check your source code to insure that this directive
    occurs within an .IF block.

1.22.151  –  UNEXPIFTF

 Unexpected .IF_TRUE_FALSE (.IFTF) directive.

    Error: The assembler encountered an unexpected .IF_TRUE_FALSE
    directive.

    User Action: Check your source code to insure that this directive
    occurs within an .IF block.

1.22.152  –  UNEXPMEXIT

 Unexpected .MEXIT directive.

    Error: The assembler encountered an unexpected .MEXIT directive.

    User Action: Check your source code.

1.22.153  –  UNKDIR

 Assembler found unknown directive XXXXX.

    Error: An internal error has occured.

    User Action: Gather as much information as possible about the
    circumstances under which the error occurred and report the
    problem to Digital.

1.22.154  –  UNKENDISOPTION

 You specified an unknown .ENABLE/.DISABLE option.

    Error: The option you specified for .ENABLE/.DISABLE is
    incorrect.

    User Action: Check the option specified with the .ENABLE/.DISABLE
    directive.

1.22.155  –  UNKNOWNATTR

 Unknown PSECT attribute.

    Error: The assembler does not recognize the specified psect
    attribute.

    User Action: See the description of the .PSECT directive and
    psect attributes.

1.22.156  –  UNTERMEX

 Assembler detected N unterminated .BEGIN_EXACT directive(s) in psect
 XXXXX.

    Error: Unmatched .BEGIN_EXACT directive(s) occur for the
    indicated psect.

    User Action: Check your source code.

1.22.157  –  VAXDIR

 The assembler is ignoring one or more VAX MACRO directives or
 options. Assembler continues processing with the next line.

    Informational: The assembler detected and ignored a VAX MACRO
    directive or option.

    User Action: Remove the VAX MACRO directives from your MACRO-64
    Assembler for OpenVMS Alpha Systems program.

1.22.158  –  VMACELSE

 You cannot specify .ELSE in the same .IF block with either .IF_FALSE
 (.IFF), .IF_TRUE (.IFT), or .IF_TRUE_FALSE (.IFTF).

    Error: The assembler encountered an .ELSE directive within the
    same .IF block as an .IF_FALSE, .IF_TRUE, or .IF_FALSE directive.

    User Action: Check your source code and remove either the .ELSE
    directive or the .IF_x directive.

1.22.159  –  WRONGMACID

 Macro name in .ENDM does not match corresponding .MACRO.

    Error: The macro name you specified as the optional argument to
    the .ENDM directive does not match the name you specified with
    the corresponding .MACRO directive.

    User Action: Check your souce code for matching .MACRO/.ENDM
    directive pairs.

1.22.160  –  WRONGPL

 The code address you specify with the .PROCEDURE_DESCRIPTOR
 directive must occur BEFORE its definition as a local or global
 label.

    Error: The code address you specify as the second argument to the
    .PROCEDURE_DESCRIPTOR directive must occur before its definition
    as a nontemporary label defined in a psect with the EXE or NOMIX
    attribute.

    User Action: Check your source code.

1.23  –  Example Location

    When you install MACRO-64 from the Freeware CD, a number of
    MACRO-64 examples are placed in the SYS$EXAMPLES directory.
    To find these examples, enter the following command at the
    DCL prompt:

    $ DIRECTORY SYS$EXAMPLES:MACRO64$*.M64

    Each example contains comments that tell you what the example
    does, and how to assemble and run the example.

2    /MIGRATION

    The MACRO/MIGRATION command invokes the MACRO Compiler for
    OpenVMS Systems to compile one or more VAX MACRO assembly
    language source files into native OpenVMS Alpha object code.

    Format

      MACRO/MIGRATION  filespec[+...]

2.1  –  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.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.3  –  Qualifiers

2.3.1    /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.

2.3.2    /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).

2.3.3    /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)

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

2.3.5    /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.

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

    DIRECTIVES      Reports unsupported directives.

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

    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.

    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.

2.3.6    /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.

2.3.7    /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.

2.3.8    /MACHINE

       /MACHINE
       /NOMACHINE (default)

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

2.3.9    /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.

2.3.10    /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
    [NO]VAXREGS    OpenVMS Alpha systems only: Allow the use of VAX
                   registers (R0 through R12) as temporary registers
                   when they appear to be unused
    ALL            All optimizations
    NONE           No optimizations

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

2.3.11    /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.

2.3.12    /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.

2.3.13    /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.

2.3.14    /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.

2.3.15    /TIE

       /TIE (default)
       /NOTIE

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

2.3.16    /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.

2.3.17    /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.4  –  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.5  –  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

2.5.1  –  .BRANCH LIKELY

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

    Format

      .BRANCH_LIKELY

    There are no parameters for this directive.

2.5.1.1  –  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.

2.5.1.2  –  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$.

2.5.2  –  .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.

2.5.2.1  –  Description

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

    On OpenVMS Alpha systems, when .BRANCH_UNLIKELY precedes a
    conditional backwards branch, the compiler will change the
    conditional branch and the code such that the branch is a forward
    branch to an unconditional backwards branch. .BRANCH_UNLIKELY
    should only be used in cases where the branch is very unlikely,
    not just less frequent than the fall-through case.

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

2.5.2.2  –  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.

2.5.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]

2.5.3.1  –  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
    two cases:

    o  If you are using the VAXREGS (OpenVMS Alpha only) optimization
       option. This optimization allows the compiler to use as
       temporary registers any of the VAX registers which are not
       explicitly being used by the VAX MACRO code.

    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
    two cases:

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

    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.

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

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

 preserve=<>

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

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

2.5.4  –  .DEFINE PAL

    OpenVMS Alpha only.

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

    Format

      .DEFINE_PAL  name, pal_opcode, [,operand_descriptor_list]

2.5.4.1  –  Parameters

 name

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

 pal_opcode

    Opcode value of the PALcode function.

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

 operand_descriptor_list

    A list of operand descriptors that specifies the number of
    operands and the type of each. Up to six operand descriptors are
    allowed in the list. Be careful to specify operands correctly so
    that the compiler can correctly track register and stack usage.
    The following table lists the operand descriptors:

    Access
    Type                              Data Type

                Byte         Word        Longword    Octaword

    Address     AB           AW          AL          AQ
    Read-only   RB           RW          RL          RQ
    Modify      MB           MW          ML          MQ
    Write-only  WB           WW          WL          WQ

2.5.4.2  –  Description

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

2.5.4.3  –  Example

  .DEFINE_PAL MTPR_USP, <^X23>, RQ

                                   NOTE

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

2.5.5  –  .DISABLE

    Disables compiler features over a range of source code.

    Format

      .DISABLE  argument-list

2.5.5.1  –  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.

2.5.6  –  .ENABLE

    Enables compiler features over a range of source code.

    Format

      .ENABLE  argument-list

2.5.6.1  –  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.

2.5.7  –  .EXCEPTION ENTRY

    OpenVMS Alpha only.

    Declares the entry point of an exception service routine to the
    compiler.

    Format

      .EXCEPTION_ENTRY  [preserve] [,stack_base]

2.5.7.1  –  Parameters

 preserve=<>

    Register set that forces the compiler to save and restore across
    the routine call the contents of registers. By default, the
    compiler saves at routine entry and restores at routine exit
    the full 64-bit contents of any register that is modified by a
    routine.

    In the case of an .EXCEPTION_ENTRY routine, exception dispatching
    saves R2 through R7 on the stack (along with the PC and PSL) and
    the values of these registers are restored by the REI instruction
    executed by the routine itself. Other registers, if used, are
    saved in code generated by the compiler, and all other registers
    are saved if the routine issues a CALL or JSB instruction.

 stack_base

    Register into which the stack pointer (SP) value is moved at
    routine entry. At exception entry points, exception dispatching
    pushes onto the stack registers R2 through R7, the PC, and the
    PSL. Note that the Alpha counterpart for the VAX register known
    as the PSL is the processor status (PS) register. The value
    returned to the register specified in the stack_base helps an
    exception service routine locate the values of these registers.

    You can use the macro $INTSTKDEF in SYS$LIBRARY:LIB.MLB to define
    symbols for the area on the stack where R2-R7, the PC, and the
    PSL are stored. The symbols are:

    o  INTSTK$Q_R2

    o  INTSTK$Q_R3

    o  INTSTK$Q_R4

    o  INTSTK$Q_R5

    o  INTSTK$Q_R6

    o  INTSTK$Q_R7

    o  INTSTK$Q_PC

    o  INTSTK$Q_PS

    You can then use these symbols in the exception routine, as
    offsets to the stack_base value. By using the appropriate
    symbolic offset with the stack_base value, the exception routine
    can access the saved contents of any of these registers. For
    example, the exception routine could examine the PSL to see what
    access mode was in effect when the exception was taken.

2.5.7.2  –  Description

    The .EXCEPTION_ENTRY directive indicates the entry point of an
    exception service routine. At routine entry, R3 must contain the
    address of the procedure descriptor. The routine must exit with
    an REI instruction.

    You should declare with the .EXCEPTION_ENTRY directive all of the
    following interrupt service routines:

    o  Interval clock

    o  Interprocessor interrupt

    o  System/processor correctable error

    o  Power failure

    o  System/processor machine abort

    o  Software interrupt

2.5.8  –  .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.

2.5.8.1  –  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.

2.5.9  –  .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]

2.5.9.1  –  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
    two cases:

    o  If you are using the VAXREGS (OpenVMS Alpha only) optimization
       option. This optimization allows the compiler to use as
       temporary registers any of the VAX registers which are not
       explicitly being used by the VAX MACRO code.

    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
    two cases:

    o  If you are using the VAXREGS (OpenVMS Alpha only) optimization
       option. This optimization allows the compiler to use as
       temporary registers any of the VAX registers which are not
       explicitly being used by the VAX MACRO code.

    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 Alpha systems, the compiler may use registers R13 and
    above as temporary registers if they are unused in the routine
    source code. Because R13 through R15 must be preserved, if
    modified, on OpenVMS Alpha systems, the compiler preserves those
    registers if it uses them.

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

 preserve=<>

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

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

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

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

                                   NOTE

       For procedures declared with the .JSB_ENTRY directive,
       the MACRO compiler automatically generates a null frame
       procedure descriptor on OpenVMS Alpha.

       Because no new context is set up by a null frame procedure,
       a side effect is that there is no guarantee of completely
       accurate debugger information about such procedures in
       response to SHOW CALLS and SHOW STACK commands. For example,
       the line number in the called null procedure (to which a JSB
       is done) may be reported as the line number in the calling
       procedure from which the JSB is issued.

2.5.10  –  .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]

2.5.10.1  –  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.

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

    However, if they appear in the scratch register set declaration,
    the compiler will not preserve them if it uses them as temporary
    registers. As a result, these registers may be scratched at
    routine exit, even if they were not used in the routine source
    but are in the scratch set.

    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

2.5.10.2  –  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.

2.5.11  –  .LINKAGE PSECT

    OpenVMS Alpha only.

    Allows the name of the linkage section psect to be changed.

    Format

      .LINKAGE_PSECT  program-section-name

2.5.11.1  –  Parameters

 program_section_name

    Name of the program section. The name can contain up to 31
    characters, including any alphanumeric character and the special
    characters underline (_), dollar sign ($), and period (.).

2.5.11.2  –  Description

    The .LINKAGE_PSECT directive allows you to locate a routine's
    linkage section by reference to other psects within the routine.
    This facilitates such operations as locking code within memory
    and forcing code location. An example of forcing code location is
    to explicitly place the psect in the image created by the linker,
    using linker options. This would let you use adjacent psects to
    find their bounds.

    You can use the .LINKAGE_PSECT directive multiple times within
    a single source module to set different linkage sections for
    different routines. However, note that a routine's linkage
    section remains the same for the entire routine. The name
    of the routine's linkage section is the one specified in the
    last .LINKAGE_PSECT directive before the routine's entry point
    directive.

    The compiler reports a fatal error if different linkage sections
    are specified for routines that share code paths.

    The .LINKAGE_PSECT directive sets the psect attributes to be
    the same as the default linkage psect $LINKAGE. The attributes
    are the same as the normal psect default attributes except the
    linkage psect is set NOEXE NOWRT.

    You can change the linkage section psect attributes using the
    .PSECT directive after declaring the psect with .LINKAGE_PSECT.

2.5.11.3  –  Example

        .LINKAGE_PSECT LINK_001
        .PSECT LINK_000
  LS_START:
        .PSECT LINK_002
  LS_END:

      This code allows a program to use LS_START and LS_END in
      computations to determine the location and size of the linkage
      section (LINK_001) of the routine.

2.5.12  –  .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

2.5.12.1  –  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.

2.5.12.2  –  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.

2.5.12.3  –  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.

2.5.13  –  .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

2.5.13.1  –  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.

2.5.13.2  –  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

    The .SET_REGISTERS directive and its read and written qualifiers
    are required on every routine call that passes or returns data in
    any register from R2 through R12, if you specify the command line
    qualifier and option /OPTIMIZE=VAXREGS (OpenVMS Alpha only). That
    is because the compiler allows the use of unused VAX registers as
    temporary registers when you specify /OPTIMIZE=VAXREGS.

2.5.13.3  –  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.

2.5.14  –  .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

2.5.14.1  –  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.

2.5.14.2  –  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.

2.5.14.3  –  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.

2.6  –  MACRO Compiler Built-Ins

    On OpenVMS Alpha systems, the compiler provides two sets of
    built-ins:

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

    o  Alpha PALcode built-ins that are used to emulate the VAX
       instructions for which there are no Alpha equivalents and to
       perform other functions such as quadword queue manipulations.

    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.

2.6.1  –  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.

    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.

    On OpenVMS Alpha, the best environment in which to run code
    that contains the byte and word built-ins is on a system that
    implements these instructions in hardware. If you run such code
    on an Alpha system that implements them by software emulation,
    the following limitations exist:

    o  Significant performance loss

       The overhead of handling the exception to trigger the software
       emulation causes a significant performance loss. If software
       emulation is in effect, you will see this message:

       %SYSTEM-I-EMULATED,
        an instruction not implemented on this processor was emulated

    o  Some capabilities not present in the software emulation

       The software emulation is not capable of providing all
       the capabilities that would be present on a system that
       implemented the the instructions in hardware. Code that
       executes in inner access modes and at elevated IPL is allowed
       to use these instructions. For example, activation of the
       software emulator above IPL 2 will not cause a bug check.
       However, certain applications where these instructions
       might be useful, such as direct writes to hardware control
       registers, will be impossible, because such applications
       require the presence of address lines whose function cannot
       be emulated.

    Furthermore, if the code with these built-ins executes on a
    system without either the byte and word software emulator or
    a processor that implements the byte and word instructions in
    hardware, it will incur a fatal exception, such as the following:

    %SYSTEM-F-OPCDEC, opcode reserved to Digital fault at
    PC=00000000000020068,PS=0000001B

                                   NOTE

       Memory references in the MACRO compiler built-ins are always
       assumed to be quadword aligned except in EVAX_SEXTB, EVAX_
       SEXTW, EVAX_LDBU, EVAX_LDWU, EVAX_STB, EVAX_STW, EVAX_LDQU,
       and EVAX_STQU.

    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

2.6.2  –  Alpha PALcode Built-Ins

    Alpha PALcode built-ins, primarily for privileged code, are used
    in the same way that Alpha instruction built-ins are used with
    two exceptions:

    o  For the queue PAL functions, the compiler does not move the
       input arguments to the Alpha registers before issuing the PAL
       call as it does for all other functions. Therefore, you must
       supply the code to do that.

    o  When using a built-in for a PAL call that returns a value, the
       source code must explicitly read R0 for the return value.

    Certain Alpha PALcode built-ins, EVAX_INSQHIQR, EVAX_INSQTIQR,
    EVAX_REMQHIQR, and EVAX_REMQHITR, support the manipulation of
    quadword queues, a function that VAX MACRO does not support. If
    you use these built-ins, you must supply the code to move the
    input arguments to R16 (and R17, for EVAX_INSQxxxx), as shown in
    the following example:

    MOVAB  Q_header, R16  ; Set up address of queue header for PAL call
    EVAX_REMQHIQR         ; Remove quadword queue entry
    EVAX_STQ  R0, entry   ; Save entry address returned in R0

    The Alpha PALcode built-ins are listed in the following table.

                                   NOTE

       You can use the .DEFINE_PAL compiler directive to custom-
       define a built-in for an Alpha PALcode operation that is not
       listed in this table.

    Built-in         Operands  Description

    EVAX_CFLUSH      <RQ>      Cache flush
    EVAX_DRAINA      <>        Drain aborts
    EVAX_LDQP        <AQ>      Load quadword physical
    EVAX_STQP        <AQ,RQ>   Store quadword physical
    EVAX_SWPCTX      <AQ>      Swap privileged context
    EVAX_BUGCHK      <RQ>      Bugcheck
    EVAX_CHMS        <>        Change mode supervisor
    EVAX_CHMU        <>        Change mode user
    EVAX_IMB         <>        Instruction memory barrier
    EVAX_SWASTEN     <RQ>      Swap AST enable
    EVAX_WR_PS_SW    <RQ>      Write processor status software field

    EVAX_MTPR_ASTEN  <RQ>      Move to processor register ASTEN
    EVAX_MTPR_ASTSR  <RQ>      Move to processor register ASTSR
    EVAX_MTPR_AT     <RQ>      Move to processor register AT
    EVAX_MTPR_FEN    <RQ>      Move to processor register FEN
    EVAX_MTPR_IPIR   <RQ>      Move to processor register IPIR
    EVAX_MTPR_IPL    <RQ>      Move to processor register IPL
    EVAX_MTPR_PRBR   <RQ>      Move to processor register PRBR
    EVAX_MTPR_SCBB   <RQ>      Move to processor register SCBB
    EVAX_MTPR_SIRR   <RQ>      Move to processor register SIRR
    EVAX_MTPR_TBIA   <>        Move to processor register TBIA
    EVAX_MTPR_TBIAP  <>        Move to processor register TBIAP
    EVAX_MTPR_TBIS   <AQ>      Move to processor register TBIS
    EVAX_MTPR_TBISD  <AQ>      Move to processor register, TB
                               invalidate single DATA
    EVAX_MTPR_TBISI  <AQ>      Move to processor register, TB
                               invalidate single ISTREAM
    EVAX_MTPR_ESP    <AQ>      Move to processor register ESP
    EVAX_MTPR_SSP    <AQ>      Move to processor register SSP
    EVAX_MTPR_USP    <AQ>      Move to processor register USP

    EVAX_MFPR_ASN    <>        Move from processor register ASN
    EVAX_MFPR_AT     <>        Move from processor register AT
    EVAX_MFPR_FEN    <>        Move from processor register FEN
    EVAX_MFPR_IPL    <>        Move from processor register IPL
    EVAX_MFPR_MCES   <>        Move from processor register MCES
    EVAX_MFPR_PCBB   <>        Move from processor register PCBB
    EVAX_MFPR_PRBR   <>        Move from processor register PRBR
    EVAX_MFPR_PTBR   <>        Move from processor register PTBR
    EVAX_MFPR_SCBB   <>        Move from processor register SCBB
    EVAX_MFPR_SISR   <>        Move from processor register SISR
    EVAX_MFPR_TBCHK  <AQ>      Move from processor register TBCHK
    EVAX_MFPR_ESP    <>        Move from processor register ESP
    EVAX_MFPR_SSP    <>        Move from processor register SSP
    EVAX_MFPR_USP    <>        Move from processor register USP
    EVAX_MFPR_WHAMI  <>        Move from processor register WHAMI

    EVAX_INSQHILR    <>        Insert entry into longword queue at
                               head interlocked-resident
    EVAX_INSQTILR    <>        Insert entry into longword queue at
                               tail interlocked-resident
    EVAX_INSQHIQR    <>        Insert entry into quadword queue at
                               head interlocked-resident
    EVAX_INSQTIQR    <>        Insert entry into quadword queue at
                               tail interlocked-resident
    EVAX_REMQHILR    <>        Remove entry from longword queue at
                               head interlocked-resident
    EVAX_REMQTILR    <>        Remove entry from longword queue at
                               tail interlocked-resident
    EVAX_REMQHIQR    <>        Remove entry from quadword queue at
                               head interlocked-resident
    EVAX_REMQTIQR    <>        Remove entry from quadword queue at
                               tail interlocked-resident

    EVAX_GENTRAP     <>        Generate trap exception

    EVAX_READ_UNQ    <>        Read unique context
    EVAX_WRITE_UNQ   <RQ>      Write unique context

2.7  –  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.

2.7.1  –  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.

2.7.1.1  –  $BYTES TO PAGES

    Converts a byte count to a page count.

    Format

      $BYTES_TO_PAGES  source_bytcnt, dest_pagcnt, rightshift,

                       roundup=YES, quad=YES

2.7.1.1.1  –  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.

2.7.1.2  –  $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

2.7.1.2.1  –  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.

2.7.1.3  –  $PAGES TO BYTES

    Converts a page count to a byte count.

    Format

      $PAGES_TO_BYTES  source_pagcnt, dest_bytcnt, leftshift,

                       quad=YES

2.7.1.3.1  –  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.

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

2.7.1.4.1  –  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.

2.7.1.5  –  $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

2.7.1.5.1  –  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

2.7.1.6  –  $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

2.7.1.6.1  –  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.

2.7.2  –  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.

2.7.2.1  –  $POP64

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

    Format

      $POP64  reg

2.7.2.1.1  –  Parameters

 reg

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

2.7.2.1.2  –  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.

2.7.2.2  –  $PUSH64

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

    Format

      $PUSH64  reg

2.7.2.2.1  –  Parameters

 reg

    Register to be pushed onto the stack.

2.7.2.2.2  –  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.

2.7.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 HP 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.

2.7.3.1  –  $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]

2.7.3.1.1  –  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.

2.7.3.1.2  –  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.

2.7.3.2  –  $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]

2.7.3.2.1  –  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.

2.7.3.2.2  –  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.

2.7.3.3  –  $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.

2.7.3.3.1  –  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.

2.7.3.4  –  $LOCK PAGE

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

    Format

      $LOCK_PAGE  [error]

2.7.3.4.1  –  Parameters

 [error]

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

2.7.3.4.2  –  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.

2.7.3.5  –  $UNLOCK PAGE

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

    Format

      $UNLOCK_PAGE  [error][,LINK_SECT]

2.7.3.5.1  –  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.

2.7.3.5.2  –  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.8  –  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.

2.8.1  –  $SETUP CALL64

    Initializes the call sequence.

    Format

      $SETUP_CALL64  arg_count, inline=true | false

2.8.1.1  –  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.

2.8.1.2  –  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. However, they can be used within the range, except where
    (on Alpha only) R16 through R21 interfere with the argument
    registers already set up. In such cases, higher temporary
    registers should be used instead.

                                   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.

2.8.2  –  $PUSH ARG64

    Does the equivalent of argument pushes for a call.

    Format

      $PUSH_ARG64  argument

2.8.2.1  –  Parameters

 argument

    The argument to be pushed.

2.8.2.2  –  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.

    OpenVMS Alpha systems only: The macro also checks for references
    to argument registers that have already been set up for the
    current $CALL64. If it finds such references, a warning is
    reported to advise the user to be careful not to overwrite an
    argument register before it is used as the source in a $PUSH_
    ARG64.

    OpenVMS Alpha systems only: The same checking is done for AP
    references when there are six or fewer arguments; they are
    allowed, but the compiler cannot prevent you from overwriting
    one before you use it. Therefore, if such references are found,
    an informational message is reported.

    OpenVMS Alpha systems only: Note that if the operand uses a
    symbol whose name includes one of the strings R16 through R21,
    not as a register reference, this macro might report a spurious
    error. For example, if the invocation $PUSH_ARG64 SAVED_R21 is
    made after R21 has been set up, this macro will unnecessarily
    report an informational message about overwriting argument
    registers.

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

2.8.3  –  $CALL64

    Invokes the target routine.

    Format

      $CALL64  call_target

2.8.3.1  –  Parameters

 call_target

    The routine to be invoked.

2.8.3.2  –  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.

2.8.4  –  $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

2.8.4.1  –  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.

2.8.4.2  –  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.

2.8.4.3  –  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$.

2.8.5  –  $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

2.8.5.1  –  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.

2.8.5.2  –  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.

2.8.5.3  –  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.
Close Help