Document revision date: 30 March 2001

## OpenVMS MACRO-32 Porting and User's Guide

Previous | Contents | Index

## $PUSH64

> Pushes the contents of an Alpha 64-bit register onto the stack.

### Format

> $PUSH64 reg

### Parameters

> #### reg

> Register to be pushed onto the stack.

### Description

> $PUSH64 takes an Alpha 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.

## D.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 complete description of how to use these macros, see Section 3.10.

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.

### D.3.1 Image Initialization-Time Lockdown

The three macros for image initialization-time lockdown follow:

- $LOCK_PAGE_INIT
- $LOCKED_PAGE_END
- $LOCKED_PAGE_START

## $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]

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

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

## $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]

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

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

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

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

### D.3.2 On-the-Fly Lockdown

The two macros for on-the-fly lockdown follow:

- $LOCK_PAGE
- $UNLOCK_PAGE

## $LOCK_PAGE

> Marks the beginning of a section of code to be locked on the fly.

### Format

> $LOCK_PAGE [error]

### Parameters

> #### [error]

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

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

## $UNLOCK_PAGE

> Marks the end of a section of code to be locked on the fly.

### Format

> $UNLOCK_PAGE [error][,LINK_SECT]

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

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

## Appendix E
MACRO-32 Macros for 64-Bit Addressing

This appendix describes the MACRO-32 macros for manipulating 64-bit addresses, for checking the sign extension of the low 32 bits of 64-bit values, and for checking descriptors for the 64-bit format.

These macros reside in the directory ALPHA$LIBRARY:STARLET.MLB (generally synonymous with SYS$LIBRARY:STARLET.MLB) and can be used by both application code and system code. The page macros have also been enhanced for 64-bit addresses. The support is provided by a new parameter, QUAD=NO/YES.

Note that you can use certain arguments to the macros described in this appendix 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.

## E.1 Macros for Manipulating 64-Bit Addresses

This section describes the following macros, designed to manipulate 64-bit addresses:

- $SETUP_CALL64
- $PUSH_ARG64
- $CALL64

## $SETUP_CALL64

> Initializes the call sequence.

### Format

> $SETUP_CALL64 arg_count, inline=true or false

### 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, the default is INLINE=FALSE.

### 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, the code is always in line.

> By default, if there are more than six arguments, 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, 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 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.

## $PUSH_ARG64

> Does the equivalent of argument pushes for a call.

### Format

> $PUSH_ARG64 argument

### Parameters

> #### argument

> The argument to be pushed.

### 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, this macro checks for SP or AP references in the argument. If the call contains more than six arguments, SP references are not allowed, and AP references are allowed only if the inline option is used.

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

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

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

## $CALL64

> Invokes the target routine.

### Format

> $CALL64 call_target

### Parameters

> #### call_target

> The routine to be invoked.

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

## E.2 Macros for Checking Sign Extension and Descriptor Format

The macros in this section are used for checking certain values and directing program flow based on the outcome of the check.

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

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

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

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

## $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 or quad

### 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

> The size of the address pointing to the descriptor. Acceptable values are "long" (the default) and "quad".

### Description

> $IS_DESC64 tests the fields which 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.

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

Index | Contents

| privacy and legal statement |
5601PRO_014.HTML