The MLR Macro Language Structured Programming in VAX-11 Macro by Rodrick A. Eldridge Iowa State University - 1 - Overview This paper presents a set of macros which implement, in VAX-11 Macro, the structured programming structures presented in the following pages. The notation used to show the format of each macro is presented below: 1. Words in upper case must be entered exactly as show in either all upper case or all lower case letters. 2. Words in lower case may be any symbol allowed by the assembler. 3. Words in [ ] are optional; if specified, words in upper case must be intered as in 1. above; words in lower case may be entered as in 2. above. The [ ]'s are not entered as part of the word. 4. Words in { } are a list of possible choices separated by the symbol |; you may specify only one of the words listed. If specified, follow rules 1. and 2. above. The { }'s are not entered as part of the word. 5. Words in < > may be a list of symbols separated by commas or blanks. The < >'s are required. 6. The entire macro may be specified on one line; or broken up on several lines by placing the symbol - on lines to be continued. 7. Words followed by ... may be repeated zero or more times. Caution Do not use any symbols beginning with the letters "MLR_" in your program, these symbols are to be considered reserved for the MLR macros. Also, do not use any symbol that has has the same name as one of the MLR macros. - 2 - References 1. TOP-DOWN STRUCTURED PROGRAMMING TECHNIQUES, by Clement L. McGowan and John R. Kelly; Petrocelli/Charter, Mason/Charter Publications, 1975. (QA76.6.M318 1975) 2. COMPUTER PROGRAMMING AND ARCHITUCTURE -- The VAX 11, by Henry M. Levy and Richard H. Eckhouse, Jr; Digital Equipment Corporation, Digital Press, 1980. (QA76.8.V37) 3. VAX MACRO AND INSTRUCTION SET REFERENCE MANUAL; Digital Equipment Corporation, September 1984. (AA-Z700A-TE) 4. VAX ARCHITECTURE HANDBOOK; Digital Equipment Corporation. 5. TLXSPM - TELEX Structured Macros; MOSTEK OPS DECUS SIG tape submission. [VAX83A.DFWLUG.MOSTEK.OPSPLN.TLXSPM] 6. QUADMATH - Quadword Math; HUGHES AIRCRAFT DECUS SIG tape submission. [VAX83C.HUGHES] - 3 - ADDQ add,sum ADDQ3 add1,add2,sum These macros perform quadword addition. These macros will produce inline code to perform the quadword addition. However, if the macros: EXTERNAL MODULE ADDQ EXTERNAL MODULE ADDQ3 are specified before the ADDQ and ADDQ3 macros are specified, these macros will produce code to call external routines to preform the quadword addition instead. After the addition is performed, r0 will contain the following values: -1 sum < 0 0 sum = 0 1 sum > 0 The ADDQ macro is equivalent to the expression: sum = add + sum and the ADDQ3 macro is equivalent to the expression: sum = add1 + add2 Example: procedure add var sum: .blkq 1 add1: .blkq 1 add2: .blkq 1 begin addq3 add1,add2,sum if eql then . . . end end See also CLRQ, CMPQ, DIVQ4, MOVQ, MULQ, MULQ3, SUBQ, SUBQ3 and TSTQ. - 4 - CASE index [BASE=base] [TYPE=type] DO label1: OF END label2: OF END . . . labeln: OF END OTHERWISE END This macro implements the CASEB, CASEW or CASEL instruction, generates the case table from a list of branch distinations and calculates the index limit. If the "base" is not specified, BASE=#0 is assumed. If the "type" is not specified, TYPE=L is assumed. The OF macro begins code statements for the case index value corresponding with the "label" specified in the case table generated by the CASE macro. For every OF macro specified, a corresponding END macro must also be specified. The END macro corresponding to the OF macro will generate a branch to the end of the CASE structure. The OTHERWISE macro begins code statements for the default case, i.e. when the case "index" is outside the supplied. The OTHERWISE macro and it's corresponding code statements are optional. For every CASE macro specified, a corresponding END macro must also be specified. The END macro corresponding to the CASE macro will generate the appropriate labels. Example: case r1 base=#1 do one: of . . . end two: of . . . end three: of . . . end otherwise . . . end - 5 - CLRQ dst This instruction clears a quadword. After the quadword is cleared, r0 will contain the following value: 0 dst = 0 This macro will produce inline code to perform the quadword clear. However, if the macro: EXTERNAL MODULE CLRQ is specified before the CLRQ macro is specified, this macro will produce code to call an external routine to preform the quadword clear instead. Example: procedure clear var target: .blkq 1 begin clrq target . . . end See also ADDQ, ADDQ3, CMPQ, DIVQ4, MOVQ, MULQ, MULQ3, SUBQ, SUBQ3 and TSTQ. - 6 - CMPQ src,dst This macro performs quadword comparison. After the comparison is performed, r0 will contain the following values: -1 src < dst 0 src = dst 1 src > dst This macro will produce inline code to perform the quadword comparison. However, if the macro: EXTERNAL MODULE CMPQ is specified before the CMPQ macro is specified, this macro will produce code to call an external routine to preform the quadword comparison instead. Example: procedure compare var source: .blkq 1 target: .blkq 1 begin cmpq source,target if eql then . . . end end See also ADDQ, ADDQ3, CLRQ, DIVQ4, MOVQ, MULQ, MULQ3, SUBQ, SUBQ3 and TSTQ. - 7 - DESCR .BLKx length [address] [allot] This macro will allocate the appropriate descriptor structure for the storage type specified: One the following directives must be used in place of .BLKx. .BLKA addresses (longwords) .BLKB bytes .BLKD double-precision floating-point (quadwords) .BLKF single-precision floaging-point (longwords) .BLKG G_floating (quadwords) .BLKH H_floating (octawords) .BLKL longwords .BLKO octawords .BLKQ quadwords .BLKT characters (bytes) .BLKW words If "length" is specified as "0", a dynamic descriptor sturcture will be generated. If "address" is specified as "*", the DESCR macro will also generate the appropriate block storage allocation directive. If "address" is not specified, no storage allocation directive is generated; you must then follow the DESCR macro with the appropriate storage allocation directive. If "address" is specified and "allot" is specified as "*", the DESCR macro will generate the appropriate block storage allocation directive and assign it to the label "address". Example: var dynamic: descr .blkt 0 ; dynamic descriptor string: descr .blkt 512 * ; create descriptor and ; allocate 512 bytes buffer_descr: descr .blkt 512 buffer *; create descriptor and ; allocate 512 bytes, assigning ; it to the label buffer const device_length=64 var device_descr: descr .blkt device_length device_name device_name: .blkb device_length - 8 - DIVQ4 divisor,dividend,quotient,remainder This macro performs quadword division. After the division is performed, r0 will contain the following values: -1 quotient < 0 0 quotient = 0 1 quotient > 0 This macro will produce inline code to perform the quadword division. However, if the macro: EXTERNAL MODULE DIVQ4 is specified before the DIVQ4 macro is specified, this macro will produce code to call an external routine to preform the quadword division instead. The DIVQ4 macro is equivalent to the expression: (quoitent,remainder) = divisor / dividend Example: procedure divide var divisor: .blkq 1 dividend: .blkq 1 quotient: .blkq 1 remainder: .blkq 1 begin divq4 divisor,divident,quotient,remainder if eql then . . . end end See also ADDQ, ADDQ3, CLRQ, CMPQ, MOVQ, MULQ, MULQ3, SUBQ, SUBQ3 and TSTQ. - 9 - EXTERNAL variable EXTERNAL The EXTERNAL macro defines the variable or variable-list as external by generating the .EXTERNAL directive. This is used to specify variables that are external to the module or procedure being assembled. Example: EXTERNAL table EXTERNAL - 10 - EXTERNAL MODULE external-name [internal-name] The EXTERNAL MODULE macro specifies that "external-name" is an external module and that "" are the required arguments for the external module. If "internal-name" is specified, this specifies the internal name of the external module. Example: global module example external module LIB$DAY_OF_WEEK dayofweek var day: .blkl 1 num: .blkl 1 degrees: .blkf 1 begin . . . dayofweek day,num . . . movf degress,r0 sin . . . end - 11 - EXTERNAL PROCEDURE external-name [internal-name] The EXTERNAL MODULE macro specifies that "external-name" is an external procedure. If "internal-name" is specified, this specifies the internal name of the external procedure. Example: global module example external procedure MTH$SIN_R4 sin var degrees: .blkf 1 begin . . . movf degress,r0 sin . . . end - 12 - FOR index [FROM=initial] TO=limit [BY=increment] [TYPE=type] DO EXIT END The FOR macro will generate code to perform a loop using the ACB (add, compare and branch) assembly instruction; therefore, the loop will always execute at least once. If "initial" is not specified, the "index" is expected to already contain its inital value; otherwise, the FOR macro will generate the appropriate code to move the "initial" value to the "index". If "increment" is not specified, BY=#1 is assumed. If "type" is not specified, TYPE=L is assumed. The EXIT macro will generate code to branch to the next instruction following the END macro. The EXIT macro is optional. The END macro will generate the ACBx instruction to loop back to the corresponding FOR macro and generate the appropriate labels for the EXIT macro. For every FOR macro specified, a corresponding END macro must also be specified. In the example below, the END macro will branch back to the beginning of the FOR loop 10 times. procedure example const length=10 var limit: .long length-1 table: .blkl length begin for r1 from=#0 to=limit do clrl table[r1] end end - 13 - GLOBAL MODULE name [] - [PSECT=psect-name] - [MASK=] CONST constants VAR variables BEGIN EXIT [value] [TYPE=type] RETURN END The GLOBAL MODULE macro sets up the enviorment for a globally accessable module. If an is specified, each argument in the list will be appended to the module name and each resultant string is used in a constant assignment, assigning each with it's offset value from AP. The constant "narg" append to the module name is always assigned the value of 0 and represents the number of arguments passed to this module. If is not specified, MASK= is assumed. If "psect-name" is specified, then "psect-name" appended with the string "_global" will be the .PSECT name, otherwise, the name of the module appended with the string "_global" will be the .PSECT name. The CONST and VAR macros generate no code, but serves as a documentation aid. The CONST macro and VAR macro are optional and can be specified as often as required for documentation purposes. The BEGIN macro separates the data portion of a module from the code portion. The EXIT macro will generate a "$EXIT_S r0" instruction. If "value" is specified, the value will be moved to r0 before the $EXIT_S intruction is generated. If "type" is not specified, TYPE=L. The EXIT macro is optional. The RETURN macro will generate a "RET" instruction. The END macro is used to end the global module. If this is the last module in the assembly, the .END instruction can be specified instead of the END macro. Example: .title example global module example const $ssdef length=3 var table: .blkl 3 begin - 14 - if neq then exit #ss_insfarg else movl example.a(AP),table movl example.b(AP),table+4 movl example.c(AP),table+8 clrl r0 end return .end - 15 - GLOBAL PROCEDURE name - [PSECT=psect-name] CONST constants VAR variables BEGIN EXIT [value] [TYPE=type] RETURN END The GLOBAL PROCEDURE macro sets up the enviorment for a globally accessable procedure. If "psect-name" is specified, then "psect-name" appended with the string "_global" will be the .PSECT name, otherwise, the name of the procedure appended with the string "_code" will be the .PSECT name. The CONST and VAR macros generate no code, but serves as a documentation aid. The CONST macro and VAR macro are optional and can be specified as often as required for documentation purposes. The BEGIN macro separates the data portion of a procedure from the code portion. The EXIT macro will generate a "$EXIT_S r0" instruction. If "value" is specified, the value will be moved to r0 before the $EXIT_S intruction is generated. If "type" is not specified, TYPE=L. The EXIT macro is optional. The RETURN macro will generate a "RSB" instruction. The END macro is used to end the global procedure. If this is the last procedure in the assembly, the .END instruction can be specified instead of the END macro. Example: .title example global module procedure begin clrl r1 return .end - 16 - GOTO label The GOTO macro generates a word displacement branch to the "label" specified. Example: procedure example begin . . . label: . . . GOTO label end - 17 - IF predicate THEN ELSEIF predicate ELSE END The IF macro generates code to execute a alternative control structure. The "predicate" may take one of the following forms: 1. condition 2. instruction condition 3. instruction ... condition where "condition" is one of the following mnemonics: EQL EQLU NEQ NEQU GTR GTRU LSS LSSU GEQ GEQU LEQ LEQU CC CS VC VS and "instruction" can be any assembly instruction or macro. Compound predicates may be formed by using the boolean operators AND and OR. Note that the operators associate to the right, so that the implied grouping of "A OR B AND C OR D" is "A OR (B AND (C OR D))". In order to associate to the left, we use the operators ANDIF and ORIF. In other words, ANDIF and ORIF act as a closing parenthesis for the expression to their left and as an opening parenthesis for the expression to their right; hence, "A OR B ANDIF C OR D" is "(A OR B) AND (C OR D)". The ELSEIF macro ends the "true" part of an IF structure and begins a subsequent nested IF structure. The ELSEIF macro is optional and can be specified as often as required. For every ELSEIF macro specified, a correspsonding IF macro must also be specified. The ELSE macro ends the "true" part of an IF structure and begins the "false" part. The ELSE macro is optional. For every ELSE macro specified, a corresponding IF macro must also be specified. - 18 - The following IF structure: if lss then movl #1,digits elseif lss then movl #2,digits elseif lss then movl #3,digits elseif lss then movl #4,digits else movl #5,digits end is equivalent to: if lss then movl #1,digits if lss then movl #2,digits if lss then movl #3,digits if lss then movl #4,digits else movl #5,digits end end end end - 19 - LOOP CONTINUE EXIT END The LOOP macro begins a iterative control structure. The EXIT macro will generate code to branch to the next instruction after the corrensponding END macro. The EXIT macro is optional. The CONTINUE macro generates no code, but serves as a documentation aid. The CONTINUE macro is optional and can be specified as often as required. The END macro generates a branch back to the corresponding LOOP macro and also generates the appropriate label for the EXIT macro. For every LOOP macro specified, a corresponding END macro must also be specified. The WHILE macro, the REPEAT-UNTIL macro and the REPEAT-FOREVER macro are implemented using the LOOP and IF macros. Example: global module example var file : $fab record : $rab procedure process_file begin loop $get record if eql then movl #rms_normal,r0 exit elseif neq then exit end . . . end end begin . . . process_file if then exit end end See also WHILE and REPEAT - 20 - MODULE name - [PSECT=psect-name] - MASK= CONST constants VAR variables BEGIN EXIT [value] [TYPE=type] RETURN END This macro sets up the environment for an interal module. If "psect-name" is specified, then "psect-name" appended with the string "_local" will be the .PSECT name, otherwise, the name of the module appended with the string "_code" will be the .PSECT name. If is not specified, MASK= is assumed. The CONST and VAR macros generate no code, but serves as a documentation aid. The CONST and VAR macros are optional and can be specified as often as required for documentation purposes. The BEGIN macro separates the data portion of a module from the code portion. The EXIT macro will generate a "$EXIT_S r0" instruction. If "value" is specified, the value will be moved to r0 before the $EXIT_S intruction is generated. If "type" is not specified, TYPE=L is assumed. The RETURN macro will generated a "RET" instruction. The END macro is used to end the module. For every MODULE macro specified, an END macro must also be specified. If this is the last module in the assembly, an .END instruction can be specified instead of the END macro. Example: module name var save: .blkw 1 begin movl r0,save . . . movl save,r0 return end - 21 - MOVQ src,dst This instruction moves quadwords. After the quadword is moved the following condition, r0 will contain the following values: -1 dst < 0 0 dst = 0 1 dst > 0 This macro will produce inline code to perform the quadword move. However, if the macro: EXTERNAL MODULE MOVQ is specified before the MOVQ macro is specified, this macro will produce code to call an external routine to preform the quadword move instead. Example: procedure move var source: .blkq 1 target: .blkq 1 begin movq source,target if eql then . . . end end See also ADDQ, ADDQ3, CLRQ, CMPQ, DIVQ4, MULQ, MULQ3, SUBQ, SUBQ3 and TSTQ. - 22 - MULQ multiplier,product MULQ3 multiplier,multipland,product These macros perform quadword multiplication. After the multiplication is performed, r0 will contain the following values: -1 product < 0 0 product = 0 1 product > 0 These macros will produce inline code to perform the quadword multiplication. However, if the macros: EXTERNAL MODULE MULQ EXTERNAL MODULE MULQ3 are specified before the MULQ and MULQ3 macros are specified, these macros will produce code to call an external routine to preform the quadword multiplication instead. The MULQ macro is equivalent to the expression: product = multiplier * product and the MULQ3 macro is equivalent to the expression: product = multiplier * multipland Example: procedure multiply var multiplier: .blkq 1 multipland: .blkq 1 product: .blkq 1 begin mulq3 multiplier,multipland,product if eql then . . . end end See also ADDQ, ADDQ3, CLRQ, CMPQ, DIVQ4, MOVQ, SUBQ, SUBQ3 and TSTQ. - 23 - PROCEDURE name - [PSECT=psect-name] CONST constants VAR variables BEGIN EXIT [value] [TYPE=type] RETURN END This macro sets up the environment for an interal routine. If "psect-name" is specified, then "psect-name" appended with the string "_local" will be the .PSECT name, otherwise, the procedure name appended with the string "_code" will be the .PSECT name. The CONST and VAR macros generate no code, but serves as a documentation aid. The CONST and VAR macros are optional and can be specified as often as required for documentation purposes. The BEGIN macro separates the data portion of a procedure from the code portion. The EXIT macro will generate a "$EXIT_S r0" instruction. If "value" is specified, the value will be moved to r0 before the $EXIT_S intruction is generated. If "type" is not specified, TYPE=L is assumed and, therefore, a "MOVL value,r0" instruction would be generated. The RETURN macro will generated a "RSB" instruction. The END macro is used to end the procedure. For every PROCEDURE macro specified, an END MACRO must also be specified. If this is the last procedure in the assembly, the .END instruction can be specified instead of the END macro. Example: procedure name var save: .blkw 1 begin movl r0,save . . . movl save,r0 return end - 24 - PSECT psect-name END The PSECT macro sets up a .PSECT enviornment after saving the current enviornement by generating .SAVE_PSECT and .PSECT directives. "psect-name" will be the .PSECT name and have the "attributes" specified. The END macro restores the previous enviornment by generating a .RESTORE_PSECT directive. Example: PSECT example . . . END - 25 - REPEAT EXIT FOREVER The REPEAT-FOREVER iterative control structure: repeat . . . forever is equivalent to: loop . . . end See LOOP. - 26 - REPEAT EXIT UNTIL predicate The REPEAT-UNTIL iterative control structure: repeat . . . exit . . . until predicate is equivalent to: loop . . . exit . . . if predicate then exit end end See LOOP and IF. - 27 - RECORD name - [PSECT=psect-name] END The RECORD macro: record example . . . end is equivalent to: psect example_abs . . . end If "psect-name" is specified, then "psect-name" will be the .PSECT name; otherwise, the name of the record appended with the string "_abs" will be the psect name. For every RECORD macro specified, a corresponding END macro must also be specified. Example: record uic uic.member : .blkw 1 uic.group : .blkw 1 .=uic.member uic.longword : .blkl 1 end - 28 - SUBQ sub,dif SUBQ3 sub,min,dif These macros perform quadword subtraction. After the subtraction is performed, r0 will contain the following values: -1 dif < 0 0 dif = 0 1 dif > 0 This macro will produce inline code to perform the quadword subtraction. However, if the macros: EXTERNAL MODULE SUBQ EXTERNAL MODULE SUBQ3 are specified before the SUBQ and SUBQ3 macros are specified, therse macros will produce code to call an external routine to preform the quadword subtraction instead. The SUBQ macro is equivalent to the expression: dif = sub - dif and the SUBQ3 macro is equivalent to the expression: dif = sub - min Example: procedure subtract var sub: .blkq 1 dif: .blkq 1 begin subq sub,dif if eql then . . . end end See also ADDQ, ADDQ3, CLRQ, CMPQ, DIVQ4, MOVQ, MULQ, MULQ3, and TSTQ. - 29 - TSTQ dst This macro performs quadword comparison against zero. After the test is performed the following condition, r0 will contain the following values: -1 dst < 0 0 dst = 0 1 dst > 0 This macro will produce inline code to perform the quadword test. However, if the macro: EXTERNAL MODULE TSTQ is specified before the TSTQ macro is specified, this macro will produce code to call an external routine to preform the quadword test instead. Example: procedure test var target: .blkq 1 begin tstq target if eql then . . . end end See also ADDQ, ADDQ3, CLRQ, CMPQ, DIVQ4, MOVQ, MULQ, MULQ3, SUBQ and SUBQ3. - 30 - WHILE predicate DO EXIT END The WHILE iterative control structure: while predicate do . . . exit . . . end is equivalent to: loop if predicate then continue else exit end . . . exit . . . end See LOOP and IF. - 31 - Index ADDQ, 4 IF, 18 ADDQ3, 4 LOOP, 20 BEGIN, 14, 16, 21, 24 MODULE, 11, 14, 21 CASE, 5 MOVQ, 22 CLRQ, 6 MULQ, 23 CMPQ, 7 MULQ3, 23 CONST, 14, 16, 21, 24 CONTINUE, 20 OF, 5 OTHERWISE, 5 DESCR, 8 DIVQ4, 9 PROCEDURE, 12, 16, 24 DO, 5, 13, 31 PSECT, 25 ELSE, 18 RECORD, 28 ELSEIF, 18 REPEAT, 26 to 27 END, 5, 13 to 14, 16, 18, 20 to RETURN, 14, 16, 21, 24 21, 24 to 25, 28, 31 EXIT, 13 to 14, 16, 20 to 21, 24, SUBQ, 29 26, 31 SUBQ3, 29 EXTERNAL, 10 to 12 THEN, 18 TSTQ, 30 FOR, 13 FOREVER, 26 VAR, 14, 16, 21, 24 GLOBAL, 14, 16 GOTO, 17 WHILE, 31 - 32 -