EVAX_ZAP Zero bytes Yes EVAX_ZAPNOT Zero bytes with NOT Yes mask 3 Itanium[R]_Instruction_Built-Ins Built-in Operands Description IA64_BREAK Generate a break instruction fault with the immediate operand provided IA64_ Generate a move-from-indirect-register GETINDREG instruction with the first operand as the destination, the second operand as a literal specifying which indirect register file to access, and the third operand as the index into the register file IA64_GETREG Generate a move-from-application- register or move-from-control-register instruction with the first operand as the destination and the second operand as a literal specifying which application or control register to read IA64_LFETCH Generate a line prefetch (LFETCH) or IA64_LFETCH_EXCL exclusive line prefetch (LFETCH.EXCL) instruction using the first operand as the address to prefetch and the second operand for either the reg-base-update- form or the imm-base-update-form. If the operand is the literal zero, the no-base-update-form will be used IA64_PROBER Generate a probe.r instruction with the first argument as the destination, the second argument as the virtual address to probe, and the third operand as the privilege level IA64_PROBEW Generate a probe.w instruction with the first argument as the destination, the second argument as the virtual address to probe, and the third operand as the privilege level IA64_RSM Generate a reset system mask ('RSM') instruction with the specified mask IA64_RUM Generate a reset user mask ('RUM') instruction with the specified mask IA64_SETREG Generate a move-to-application-register or move-to-control-register instruction with the first operand as a literal specifying which application or control register to write and the second operand as the value to write into the register IA64_SRLZD <> Generate a serialize data ('SRLZD') instruction IA64_SRLZI <> Generate a serialize instruction ('SRLZI') instruction IA64_SSM Generate a set system mask ('SSM') instruction with the specified mask IA64_SUM Generate a set user mask ('SUM') instruction with the specified mask IA64_TAK Generate a read translation access key ('TAK') instruction 2 Macros_for_Porting_from_VAX_to_Alpha_or_I64 The following macros facilitate the porting of VAX MACRO code to an OpenVMS Alpha or OpenVMS I64 system. The macros are grouped according to their function. 3 Calculating_Page-Size_Values The following macros provide a standard, architecture-independent means for calculating page-size dependent values: o $BYTES_TO_PAGES o $NEXT_PAGE o $PAGES_TO_BYTES o $PREVIOUS_PAGE o $ROUND_RETADR o $START_OF_PAGE These macros reside in the directory SYS$LIBRARY:STARLET.MLB and can be used by both application code and system code. Because application code does not have access to SYSTEM_DATA_CELLS, you must supply the relevant masks, shift values, and so on. The shift values are correlated with the page size of the processor. The rightshift values are negative; the leftshift values are positive, as shown in Shift Values. Table D-1 Shift Values Page size rightshift leftshift 512 bytes (VAX) -9 9 8K (OpenVMS Alpha or -13 13 OpenVMS I64) 16K -14 14 32K -15 15 64K -16 16 Typically, the application issues a call to $GETSYI (specifying the SYI$_PAGESIZE item descriptor) to obtain the CPU-specific page size and then compute other values from the page size that is returned. The following conventions apply to the macros described in this section: o If the destination operand is blank, the source operand is used as the destination. o All macros conditionalize code on the symbols VAXPAGE and BIGPAGE. o Several macros allow for page-size-independent code on VAX systems with the independent=YES argument. These macros generate code in which I-stream fetches are changed to memory accesses. Because this is inherently slower on a VAX system, the default value of the independent argument is NO. 4 $BYTES_TO_PAGES Converts a byte count to a page count. Format $BYTES_TO_PAGES source_bytcnt, dest_pagcnt, rightshift, roundup=YES, quad=YES 5 Parameters source_bytcnt Source byte count. dest_pagcnt Destination of page count. rightshift Location of application-provided value to shift (in place of multiply). This value is a function of the page size, as shown in the table on shift values. roundup=YES If YES, page-size-1 is added to byte count before shifting; if NO, page count is truncated. Any other value is treated as the user-specified address of the page-size-1 value. Note that roundup=YES is incompatible with the presence of the rightshift argument; invoking the macro with both these arguments generates a compile-time warning. quad=YES If YES, the conversion supports 64-bit addressing. If NO, the conversion does not support 64-bit addressing. 4 $NEXT_PAGE Computes the virtual address of the first byte in the next page. Format $NEXT_PAGE source_va, dest_va, clearbwp=NO, user_pagesize_addr, user_mask_addr, quad=YES 5 Parameters source_va Source virtual address. dest_va Destination of virtual address within next page. clearbwp=NO If YES, masks the byte-within-page portion of the source virtual address. The clearbwp=NO option is a performance enhancement, avoiding unnecessary instructions if you know you are starting on a page boundary or you are intending to divide by page-size anyway. user_pagesize_addr Location of the page-size value (returned by a call to the $GETSYI system service specifying the SYI$_PAGESIZE item descriptor) in the application data area. If this argument is blank, the macro uses MMG$GL_PAGESIZE (bigpage) or MMG$C_VAX_ PAGE_SIZE (vaxpage). user_mask_addr Location of the application-provided byte-within-page mask. If this argument is blank, the macro uses MMG$GL_BWP_MASK if user_ pagesize_addr is also blank. Otherwise, it subtracts 1 from the contents of the user_pagesize_addr and uses that value. quad=YES If YES, the conversion supports 64-bit addressing. If NO, the conversion does not support 64-bit addressing. 4 $PAGES_TO_BYTES Converts a page count to a byte count. Format $PAGES_TO_BYTES source_pagcnt, dest_bytcnt, leftshift, quad=YES 5 Parameters source_pagcnt Source page count. dest_bytcnt Destination of byte count. leftshift Location of application-provided value to shift (in place of multiply). This value is a function of the page size, as shown in the table on shift values. quad=YES If YES, the conversion supports 64-bit addressing. If NO, the conversion does not support 64-bit addressing. 4 $PREVIOUS_PAGE Computes the virtual address of the first byte in the previous page. Format $PREVIOUS_PAGE source_va, dest_va, clearbwp=NO, user_pagesize_addr, user_mask_addr, quad=YES 5 Parameters source_va Source virtual address. dest_va Destination of virtual address within previous page. clearbwp=NO If YES, masks the byte-within-page portion of the source virtual address. The clearbwp=NO option is a performance enhancement, avoiding unnecessary instructions if you know you are starting on a page boundary or you are intending to divide by page-size anyway. user_pagesize_addr Location of the page-size value (returned by a call to the $GETSYI system service specifying the SYI$_PAGESIZE item descriptor) in the application data area. If this argument is blank, the macro uses MMG$GL_PAGESIZE (bigpage) or MMG$C_VAX_ PAGE_SIZE (vaxpage). user_mask_addr Location of the application-provided byte-within-page mask. If this argument is blank, the macro uses MMG$GL_BWP_MASK if user_ pagesize_addr is also blank. Otherwise, it subtracts 1 from the contents of the user_pagesize_addr and uses that value. quad=YES If YES, the conversion supports 64-bit addressing. If NO, the conversion does not support 64-bit addressing. 4 $ROUND_RETADR Rounds the range implied by the virtual addresses in a retadr array returned from a memory management system service to a range that is the factor of CPU-specific pages. The return value can be supplied as an inadr array in a subsequent call to another memory management system service. Format $ROUND_RETADR retadr, full_range, user_mask_addr, direction=ASCENDING 5 Parameters retadr Address of array of two 32-bit addresses, typically returned from $CRMPSC or a similar service. This value can be in the form of either "label" or "(Rx)". full_range Output array of two longwords. FULL_RANGE[0] is retadr[0] rounded down to a CPU-specific page boundary, and FULL_RANGE[1] is retadr[1] rounded up to one less than a CPU-specific page boundary (that is, to the last byte in the page). user_mask_addr Location of application-provided byte-within-page mask. If this argument is blank, the macro uses MMG$GL_BWP_MASK on an OpenVMS Alpha or OpenVMS I64 system and VA$M_BYTE on an OpenVMS VAX system. direction=ASCENDING Direction of rounding. The keywords are defined in the following table: ASCENDING retadr[0] < retadr[1] DESCENDING retadr[1] < retadr[0] UNKNOWN Values are compared at run time, then proper rounding is performed 4 $START_OF_PAGE Converts a virtual address to the address of the first byte within that page. Format $START_OF_PAGE source_va, dest_va, user_mask_addr, quad=YES 5 Parameters source_va Source virtual address. dest_va Destination of virtual address of first byte within page. user_mask_addr Location of application-provided byte-within-page mask. If this argument is blank, the macro uses MMG$GL_BWP_MASK on an OpenVMS Alpha or OpenVMS I64 system and MMG$C_VAX_PAGE_SIZE - 1 (defined in $pagedef) on an OpenVMS VAX system. quad=YES If YES, the conversion supports 64-bit addressing. If NO, the conversion does not support 64-bit addressing. 3 Saving_and_Restoring_64-Bit_Registers Frequently, VAX MACRO source code must save and restore register values, because that is part of the defined interface or because the code requires work registers. On OpenVMS VAX, code can invoke any number of macros to do this. On OpenVMS Alpha and OpenVMS I64, you cannot simply replace these macros with 64-bit pushes and pops to and from the stack, because there is no guarantee that the macro caller has a quadword-aligned stack. Instead, you should replace such macro invocations with $PUSH64 and $POP64 macros. These macros, located in STARLET.MLB, preserve all 64 bits of a register but use longword references to do so. 4 $POP64 Pops the 64-bit value on the top of the stack into a register. Format $POP64 reg 5 Parameters reg Register into which the macro places the 64-bit value from the top of the stack. 5 Description $POP64 takes the 64-bit value at the top of the stack and places it in a register using longword instructions. This is to avoid using quadword instructions when an alignment fault should be avoided, but restoring all 64 bits is necessary. 4 $PUSH64 Pushes the contents of a 64-bit register onto the stack. Format $PUSH64 reg 5 Parameters reg Register to be pushed onto the stack. 5 Description $PUSH64 takes a 64-bit register and puts it on the stack using longword instructions. This is to avoid using quadword instructions when an alignment fault should be avoided, but saving all 64 bits is necessary. 3 Locking_Pages_into_a_Working_Set Five macros are provided for locking pages into a working set. These macros reside in SYS$LIBRARY:LIB.MLB. For a description of how to use these macros, see the VSI OpenVMS MACRO Compiler Porting and User's Guide. Three macros are used for image initialization-time lockdown, and two macros are used for on-the-fly lockdown. NOTE If the code is being locked because the IPL will be raised above 2, where page faults cannot occur, make sure that the delimited code does not call run-time library or other procedures. The VAX MACRO compiler generates calls to routines to emulate certain VAX instructions. An image that uses these macros must link against the system base image so that references to these routines are resolved by code in a nonpageable executive image. For OpenVMS I64 systems, these macros are still under development and additional OpenVMS routines are being provided to lock working sets. See the OpenVMS I64 Release Notes for more information. 4 $LOCK_PAGE_INIT Required in the initialization routines of an image that is using $LOCKED_PAGE_START and $LOCKED_PAGE_END to delineate areas to be locked at initialization time. Format $LOCK_PAGE_INIT [error] 5 Parameters [error] Address to which to branch if one of the $LKWSET calls fail. If this address is reached, R0 reflects the status of the failed call, and R1 contains 0 if the call to lock the code failed, or 1 if that call succeeded but the call to lock the linkage section failed. 5 Description $LOCK_PAGE_INIT creates the necessary psects and issues the $LWKSET calls to lock into the working set the code and linkage sections that were declared by $LOCKED_PAGE_START and $LOCKED_ PAGE_END. R0 and R1 are destroyed by this macro. The psects locked by this macro are $LOCK_PAGE_2 and $LOCK_ LINKAGE_2. If code sections in other modules, written in other languages, use these psects, they will be locked by an invocation of this macro in a VAX MACRO module. 4 $LOCKED_PAGE_END Marks the end of a section of code that may be locked at image initialization time by the $LOCK_PAGE_INIT macro. Format $LOCKED_PAGE_END [link_sect] 5 Parameters [link_sect] Psect to return to if the linkage psect in effect when the $LOCKED_PAGE_START macro was executed was not the default linkage psect, $LINKAGE. 5 Description $LOCKED_PAGE_END is used with $LOCKED_PAGE_START to delineate code that may be locked at image initialization time by the $LOCK_PAGE_INIT macro. The code delineated by these macros must contain complete routines-execution cannot fall through either macro, nor can you branch into or out of the locked code. Any attempt to branch into or out of the locked code section or to fall through the macros will be flagged by the compiler with an error. 4 $LOCKED_PAGE_START Marks the start of a section of code that may be locked at image initialization time by the $LOCK_PAGE_INIT macro. Format $LOCKED_PAGE_START There are no parameters for this macro. 5 Description $LOCKED_PAGE_START is used with $LOCKED_PAGE_END to delineate code that may be locked at image initialization time by the $LOCK_PAGE_INIT macro. The code delineated by these macros must contain complete routines-execution may not fall through either macro, nor may the locked code be branched into or out of. Any attempt to branch into or out of the locked code section or to fall through the macros will be flagged by the compiler with an error. 4 $LOCK_PAGE Marks the beginning of a section of code to be locked on-the-fly. Format $LOCK_PAGE [error] 5 Parameters [error] Address to branch to if one of the $LKWSET calls fail. 5 Description This macro is placed inline in executable code and must be followed by the $UNLOCK_PAGE macro. The $LOCK_PAGE/$UNLOCK_PAGE macro pair creates a separate routine in a separate psect. $LOCK_ PAGE locks the pages and linkage section of this separate routine into the working set and JSRs to it. All code between this macro and the matching $UNLOCK_PAGE macro is included in the locked routine and is locked down. All registers are preserved by this macro unless the error address parameter is present and one of the calls fail. If that happens, R0 reflects the status of the failed call. R1 then contains 0 if the call to lock the code failed or 1 if that call succeeded but the call to lock the linkage section failed. If the ERROR parameter is used, the ERROR label must be placed outside the scope of the $LOCK_PAGE and $UNLOCK_PAGE pair. This is because the error routine is branched to before calling the subroutine that the $LOCK_PAGE and $UNLOCK_PAGE routines create. Note that since the locked code is made into a separate routine, any references to local stack storage within the routine will have to be changed, as the stack context is no longer the same. Also, you cannot branch into or out of the locked code from the rest of the routine. 4 $UNLOCK_PAGE Marks the end of a section of code to be locked on-the-fly. Format $UNLOCK_PAGE [error][,LINK_SECT] 5 Parameters [error] An error address to which to branch if one of the $ULKWSET calls fail. [link_sect] Linkage psect to return to if the linkage psect in effect when the $LOCK_PAGE macro was executed was not the default linkage psect, $LINKAGE. 5 Description $UNLOCK_PAGE returns from the locked routine created by the $LOCK_PAGE and $UNLOCK_PAGE macro pair and then unlocks the pages and linkage section from the working set. This macro is placed inline in executable code after a $LOCK_PAGE macro. All registers are preserved by this macro unless the error address parameter is present and one of the calls fail. If that happens, R0 reflects the status of the failed call. R1 then contains 0 if the call to unlock the code failed or 1 if that call succeeded but the call to unlock the linkage section failed. If the error parameter is used, the error label must be placed outside the scope of the $LOCK_PAGE and $UNLOCK_PAGE pair. This is because the error routine is branched to after returning from the subroutine created by the $LOCK_PAGE and $UNLOCK_PAGE routines. 2 Macros_for_64-Bit_Addressing These macros reside in the directory SYS$LIBRARY:STARLET.MLB and can be used by both application code and system code. The page macros accommodate for 64-bit addresses. The support is provided by the QUAD=NO/YES parameter. You can use certain arguments to these macros to indicate register sets. To express a register set, list the registers, separated by commas, within angle brackets. For example: If the set contains only one register, the angle brackets are not required. 3 $SETUP_CALL64 Initializes the call sequence. Format $SETUP_CALL64 arg_count, inline=true | false 4 Parameters arg_count The number of arguments in the call. inline Forces inline expansion, rather than creation of a JSB routine, when set to TRUE. If there are six or fewer arguments on OpenVMS Alpha, or eight or fewer on OpenVMS I64, the default is inline=false. 4 Description This macro initializes the state for a 64-bit call. It must be used before using $PUSH_ARG64 and $CALL64. If there are six or fewer arguments on OpenVMS Alpha, or eight or fewer on OpenVMS I64, the code is always in line. By default, if there are more than six arguments on OpenVMS Alpha or eight arguments on OpenVMS I64, this macro creates a JSB routine that is invoked to perform the actual call. However, if the inline option is specified as inline=true, the code is generated in line. This option should be enabled only if the code in which it appears has a fixed stack depth. A fixed stack depth can be assumed if no RUNTIMSTK or VARSIZSTK messages have been reported. Otherwise, if the stack alignment is not at least quadword, there might be many alignment faults in the called routine and in anything the called routine calls. The default behavior (inline=false) does not have this problem. If there are more than six arguments on OpenVMS Alpha or eight arguments on OpenVMS I64, there can be no references to AP or SP between a $SETUP_CALL64 and the matching $CALL64, because the $CALL64 code may be in a separate JSB routine. In addition, temporary registers (R16 and above) may not survive the $SETUP_ CALL64. NOTE The $SETUP_CALL64, $PUSH_ARG64, and $CALL64 macros are intended to be used in an inline sequence. That is, you cannot branch into the middle of a $SETUP_CALL64/$PUSH_ ARG64/$CALL64 sequence, nor can you branch around $PUSH_ ARG64 macros or branch out of the sequence to avoid the $CALL64. 3 $PUSH_ARG64 Does the equivalent of argument pushes for a call. Format $PUSH_ARG64 argument 4 Parameters argument The argument to be pushed. 4 Description This macro pushes a 64-bit argument for a 64-bit call. The macro $SETUP_CALL64 must be used before you can use $PUSH_ARG64. Arguments will be read as aligned quadwords. That is, $PUSH_ARG64 4(R0) will read the quadword at 4(R0), and push the quadword. Any indexed operations will be done in quadword mode. To push a longword value from memory as a quadword, first move it into a register with a longword instruction, and then use $PUSH_ ARG64 on the register. Similarly, to push a quadword value that you know is not aligned, move it to a temporary register first, and then use $PUSH_ARG64. If the call contains more than six arguments on OpenVMS Alpha or eight arguments on OpenVMS I64, this macro checks for SP or AP references in the argument. If the call contains more than six arguments on OpenVMS Alpha or eight arguments on OpenVMS I64, SP references are not allowed, and AP references are allowed only if the inline option is used. Note that $PUSH_ARG64 cannot be in conditional code. $PUSH_ ARG64 updates several symbols, such as the remaining argument count. Attempting to write code that branches around a $PUSH_ ARG64 in the middle of a $SETUP_CALL64/$CALL64 sequence will not work properly. 3 $CALL64 Invokes the target routine. Format $CALL64 call_target 4 Parameters call_target The routine to be invoked. 4 Description This macro calls the specified routine, assuming $SETUP_CALL64 has been used to specify the argument count, and $PUSH_ARG64 has been used to push the quadword arguments. This macro checks that the number of pushes matches what was specified in the setup call. The call_target operand must not be AP- or SP-based. 3 $IS_32BITS Checks the sign extension of the low 32 bits of a 64-bit value and directs the program flow based on the outcome of the check. Format $IS_32BITS quad_arg, leq_32bits, gtr_32bits, temp_reg=22 4 Parameters quad_arg A 64-bit quantity, either in a register or in an aligned quadword memory location. leq_32bits Label to branch to if quad_arg is a 32-bit sign-extended value. gtr_32bits Label to branch to if quad_arg is greater than 32 bits. temp_reg=22 Register to use as a temporary register for holding the low longword of the source value-R22 is the default. 4 Description $IS_32BITS checks the sign extension of the low 32 bits of a 64- bit value and directs the program flow based on the outcome of the check. 4 Examples 1.$is_32bits R9, 10$ In this example, the compiler checks the sign extension of the low 32 bits of the 64-bit value at R9 using the default temporary register, R22. Depending on the type of branch and the outcome of the test, the program either branches or continues in line. 2.$is_32bits 4(R8), 20$, 30$, R28 In this example, the compiler checks the sign extension of the low 32 bits of the 64-bit value at 4(R8) using R28 as a temporary register and, based on the check, branches to either 20$ or 30$. 3 $IS_DESC64 Tests the specified descriptor to determine if it is a 64-bit format descriptor, and directs the program flow based on the outcome of the test. Format $IS_DESC desc_addr, target, size=long | quad 4 Parameters desc_addr The address of the descriptor to test. target The label to branch to if the descriptor is in 64-bit format. size=long|quad The size of the address pointing to the descriptor. The default value is size=long. 4 Description $IS_DESC64 tests the fields that distinguish a 64-bit descriptor from a 32-bit descriptor. If it is in 64-bit form, a branch is taken to the specified target. The address to be tested is read as a longword, unless size=quad is specified. 4 Examples 1.$is_desc64 r9, 10$ In this example, the descriptor pointed to by R9 is tested, and if it is in 64-bit form, a branch to 10$ is taken. 2.$is_desc64 8(r0), 20$, size=quad In this example, the quadword at 8(R0) is read, and the descriptor it points to is tested. If it is in 64-bit form, a branch to 20$ is taken.