Library /sys$common/syshlp/helplib.hlb  —  MACRO  /MIGRATION  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

1  –  .BRANCH LIKELY

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

    Format

      .BRANCH_LIKELY

    There are no parameters for this directive.

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.

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

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]

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.

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]

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

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.

4.3  –  Example

  .DEFINE_PAL MTPR_USP, <^X23>, RQ

                                   NOTE

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

5  –  .DISABLE

    Disables compiler features over a range of source code.

    Format

      .DISABLE  argument-list

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.

6  –  .ENABLE

    Enables compiler features over a range of source code.

    Format

      .ENABLE  argument-list

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.

7  –  .EXCEPTION ENTRY

    OpenVMS Alpha only.

    Declares the entry point of an exception service routine to the
    compiler.

    Format

      .EXCEPTION_ENTRY  [preserve] [,stack_base]

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.

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

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.

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.

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]

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.

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]

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

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.

11  –  .LINKAGE PSECT

    OpenVMS Alpha only.

    Allows the name of the linkage section psect to be changed.

    Format

      .LINKAGE_PSECT  program-section-name

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 (.).

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.

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.

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

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.

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.

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.

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

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.

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.

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.

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

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.

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.

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.
Close Help