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.