#DO macro group

Use this macro group to process specific code based on one of the following:

  • A conditional expression
  • A branch register (BCT, BCTR, BXLE, or BXH).

The #DO macro group includes the following macros:

  • #EXIF
  • #OREL
  • #DOEX
  • #ELOP
  • #EDO.

See #DO Macro Group Processing for diagrams that show the processing flow of the #DO macro group.

Format

Read syntax diagramSkip visual syntax diagram#DOWHILE=Conditional ExpressionUNTIL=Conditional ExpressionTIMES=(reg1,initval,initval,reg2,initval,save1,,reg2,,save1)FROM Using BC or BCRFROM Using BXH or BXLEINFONCE,PREFIX=#@ LB,PREFIX= labelcode1#EXIFConditional Expressioncode2#ORELcode3#DOEXConditional Expressioncode4#ELOPcode5#EDO
Note: A #DO statement can contain one of each of the WHILE, UNTIL, TIMES, and FROM conditions.
FROM Using BC or BCR
Read syntax diagramSkip visual syntax diagramFROM=(reg1,initval,initval,reg2,,reg2),BY= byval,TO=(toval,INCLUSIVE,EXCLUSIVE)
FROM Using BXH or BXLE
Read syntax diagramSkip visual syntax diagramBXLE,BXH,FROM=(reg1,initval,initval,save1,,save1),BY=(byreg,byval2,byval2,save2,,save2),TO=(toreg,toval2)
#DO
specifies the start of the #DO structure.
WHILE
specifies the start of a #DO WHILE loop based on a conditional expression. Any code that follows this parameter is processed only if and while the conditional expression is true. See Conditional Expression Format for information about the syntax of a conditional expression.
UNTIL
specifies the start of a #DO UNTIL loop based on a conditional expression. Any code that follows this parameter is processed at least once and is repeated until the conditional expression is true. See Conditional Expression Format for information about the syntax of a conditional expression.
TIMES
specifies the number of times to repeat the loop. Any code that follows this parameter is repeated based on a loop counter.
FROM
specifies the number of times to repeat the loop. Any code that follows this parameter is repeated based on a loop counter.

The form of #DO FROM using a BC or BCR loop is the basic form. The form of #DO FROM using a BXH or BXLE loop allows values to be saved during the processing of the loop. The type of loop generated depends on the following:

  • Number of parameters
  • Use of initial values
  • Use of negative values
  • Number of registers used.
Note: #DO FROM is only available for compatibility with older applications. Use the #DO TIMES form for new applications.
INF
specifies an unconditional loop. You must code a #DOEX or #EXIF macro to avoid creating an infinite loop.
ONCE
creates a non-loop where the processing is performed only once. This parameter allows you to use the conditional branching macros (#EXIF, #DOEX, and so on) to construct a procedure that is processed the same way as inline code.
reg1
is a register that contains the loop counter. When you specify the TIMES parameter, the value in reg1 must be positive.
initval
is an initial value for the loop counter that gets loaded into the register specified by reg1.

The value of initval can be:

  • A numeric value
  • Another general register (enclosed in parentheses)
  • A literal (byte, halfword, or fullword)
  • A length (with a value less than 4096)
  • An equate
  • A label
  • An address.

You can enter an address in one of the following ways:

  • A/label
  • L/label

In both cases, the initial value is the address of label label.

You can enter labels in one of the following ways:

  • X/label, which indicates that the initial value is the 1 byte at label.
  • H/label, which indicates that the initial value is the 2 bytes (halfword) starting at label.
  • label, which indicates that the initial value is the 4 bytes (fullword) starting at label.
reg2
is the branch register. If you specify reg2 with the TIMES parameter, a BCTR loop is generated. If you do not specify reg2 with the TIMES parameter, a BCT loop is generated. If you specify reg2 with the FROM parameter, a BCR loop is generated. If you do not specify reg2 with the FROM parameter, a BC loop is generated.
save1
is a fullword area where reg1 is saved. This allows reg1 to be used during the execution of the loop. If you specify save1 with the TIMES parameter, a BCT loop is generated.
BY=byval
specifies the value with which to increment reg1, where byval is the value. This value is added to the value in reg1 at the end of each iteration.

The valid values for byval are the same as for initval, with the exception of single-byte fields or single-byte literals.

TO=toval
specifies when to end the loop, where toval is a field that contains the ending value for the loop. The value in toval is compared with the value in reg1 at the end of each iteration.

The valid values for toval are the same as for initval, with the exception of single-byte fields or single-byte literals.

INCLUSIVE
processes the loop including the ending value, toval.
EXCLUSIVE
processes the loop excluding the ending value, toval.
BXLE
specifies a BXLE loop.
BXH
specifies a BXH loop.
BY=byreg
specifies the increment value, where byreg is a register that contains the value with which to increment reg1.
byval2
is an initial increment value to load into the register specified by byreg.
save2
is a full or double word save area into which byreg and toreg are saved. They are stored at the beginning of each iteration and reloaded at the end of each iteration before the BXLE or BXH loop. Only 1 fullword is required during the loop processing if byreg and toreg are the same odd-numbered register.
TO=toreg
specifies when to end the loop, where toreg is a register that contains the ending value for the loop, where:
  • If byreg is an even-numbered register, toreg must be the next (odd-numbered) register.
  • If byreg is an odd-numbered register, toreg must be the same register.
toval2
is an initial value to load in toreg.
PREFIX=label
specifies a prefix for all link labels generated by this macro group, where label is a 4-character alphabetic name.
code1
is the code to process.
#EXIF
specifies the start of the exit code to process when the conditional expression is true. See Conditional Expression Format for information about the syntax of a conditional expression. After the exit code is performed, processing exits from the whole #DO group. If the conditional expression is false, #EXIF branches to the next #OREL macro.
code2
is the exit code to process when the #EXIF condition is true. The exit code consists of any code between the #EXIF macro and the next sequential #OREL macro.
#OREL
specifies the start of the code to process when the previous #EXIF condition is not true. After the code is processed, control returns to the top of the loop and processing continues.

For clarity, it is recommended that you always code a matching #OREL macro for each #EXIF macro. However, if you do not specify the #OREL macro, it will be automatically generated between a #EXIF macro and any of the following:

  • #DOEX macro
  • #ELOP macro
  • Another #EXIF macro.
code3
is the code to process when the previous #EXIF condition is false.
#DOEX
exits from the loop based on a conditional expression. See Conditional Expression Format for information about the syntax of a conditional expression. If the conditional expression is true, #DOEX branches to the #ELOP macro. If the #ELOP macro is not specified, processing branches to the #EDO macro.
Note: The #DOEX macro provides a conditional exit from the iteration loop. This optional exit is a violation of structured programming rules. Restrict the use of this macro to special cases where you would otherwise have to:
  • Use a #GOTO macro. See #GOTO Macro Group for more information about the #GOTO macro.
  • Set and test an additional indicator.
code4
is the code to process when the #DOEX condition is false.
#ELOP
ends the iteration loop and specifies the start of any code to be processed at the end of the loop. The #ELOP macro must be the last structured programming macro (SPM) in the #DO group before the #EDO macro. If you do not specify the #ELOP macro, it is automatically generated by the #EDO macro.
code5
is the code to process at the end of the loop. This code is processed only once when the iteration loop ends. This code is bypassed only when the iteration is ended by a true #EXIF condition.
#EDO
specifies the end of the loop-end processing and the whole #DO group.

Entry requirements

None.

Return conditions

Control is returned to the next sequential instruction after the #EDO macro statement unless another assembler instruction or macro passes control outside the #DO structure.

Programming considerations

  • All labels used in the SPM conditional expression can be no more than 32 characters long. Any additional characters are truncated.
  • All SPM conditional expressions can be no more than 128 characters long. Any additional characters are truncated.
  • The #DO, #EXIF, #OREL, #DOEX, #ELOP, and #EDO macros can only be used with the #DO macro group.
  • Each macro statement and assembler instruction must begin on a new line in the application.
  • A section of code (represented by code1, and so on) can consist of any number of standard assembler instructions, including other SPMs or assembler macros.
  • The SPMs generate assembler instructions according to the specified macro parameters. The necessary branch instructions and link labels are generated internally to support the nonsequential processing. The SPMs generate standard link labels in the following format: #@LBn EQU *

    Where:

    #@LB
    is the link-label prefix.
    n
    is a sequence number that is generated automatically.

    You can use the PREFIX parameter to change the standard link-label prefix.

  • The labels generated by macros nested inside a structure have the standard prefix #@LB unless another PREFIX parameter is specified with the inner SPMs.
  • If symbols referred to by reg1, reg2, byval, toval, byreg, or toreg are changed during loop processing, the results cannot be predicted.
  • For #DO FROM using a BXH or BXLE loop, if all the parameter registers are loaded previously with the values necessary to process the loop, you must specify the BXH or BXLE parameter. See ESA/370 Principles of Operation or ESA/390 Principles of Operation for more information about the BXH and BXLE instructions.
  • A #DO macro statement can contain one of each of the following parameters:
    • WHILE
    • UNTIL
    • TIMES
    • FROM.
  • Additional loop-end processing can be performed (only once) between the #ELOP and #EDO macros.
  • The #ELOP macro is reached when:
    • The iteration ends because the #DO WHILE condition is false (normal loop completion)
    • The iteration ends because the #DO UNTIL condition is true (normal loop completion)
    • The iteration ends with a #DOEX condition.
  • You can also force an exit with a #EXIF macro combined with a #OREL macro. If the #EXIF condition is true, any code between the #EXIF macro and the next #OREL macro is processed and exits to the #EDO macro. If the #EXIF condition is false, processing continues after the #OREL macro.

Examples

  • In the following #DO WHILE example, a #DOEX macro is used to exit the loop if R2 = R3.
            #DO   WHILE=(OC,FLD,FLD,NZ)
               :
    *   Code to be processed repeatedly only if FLD is not zero.
    *   This code will be done more than once only as long as
    *   R2 does not equal R3 because of the following #DOEX.
               :
             #DOEX (CR,R2,EQ,R3)
               :
    *   Exit the loop if R2 = R3.
    *   Code to be processed repeatedly if FLD is not zero and
    *   R2 does not equal R3.
               :
             #EDO
  • The following is an example of a simple #DO UNTIL loop.
            #DO   UNTIL=(CLC,FLDA,GE,FLDB)
              :
    *   Code to be processed at least once, and more than
    *   once as long as FLDA remains less than FLDB.
              :
             #EDO
  • The following is an example of a full #DO UNTIL loop using all the #DO group parameters.
            #DO   UNTIL=(CR,R2,GE,R3)
               :
    *   Code to process until R2 >= R3.
    *   This is done on each iteration, and at least once.
               :
             #EXIF TM,0(R2),X'FF',O
               :
    *   Code to process if the bits are set to X'FF'.
    *   Exit processing is performed (once only) the first
    *   time the TM results in ones.
    *   Processing continues at the #EDO macro.
               :
             #OREL
               :
    *   Code to process if the bits are not set.
    *   Processing to be done on each iteration, as long as no exits
    *   are taken.
               :
             #EXIF CH,R4,NL,MAX
               :
    *   Code for another #EXIF process: Maximum reached.
    *   Exit processing to be performed (once only) the first
    *   time R4 >= MAX.
    *   Processing continues at the #EDO macro.
               :
    *** #OREL generated automatically here
    *
             #DOEX CLC,4(4,R2),EQ,=F'0'
               :
    *   If #DOEX indicates no more items, go to #ELOP macro for
    *   loop-end processing.
    *
    *   Code to be processed on each iteration, as long as no exits
    *   are taken.
               :
             #ELOP
               :
    *   End of loop, start loop-end processing.
    *   Loop-end processing is done once only as a result of
    *   iteration termination by the UNTIL condition (R2 >= R3),
    *   or because the #DOEX exit was taken.
    *
    *   If one of the #EXIF exits was taken, this code is never
    *   processed.
               :
             #EDO
  • In the following #DO TIMES example, a BCT loop is processed the number of times specified by the value in register 2 (R2). The loop count was previously loaded in R2. R2 is used for a BCT instruction and contains successive values down to 1. On exit from the #EDO, R2 is 0.
            #DO  TIMES=(R2)
               :
    *   Code to process the number of times specified by the
    *   value in R2.
               :
             #EDO
  • In the following #DO TIMES example, a BCTR loop is processed 100 times. R2 and R3 are used for a BCTR instruction. R2 contains successive values 100, 99, 98, and so on down to 1; R3 holds the address of the start of the loop for the BCTR. On exit from the #EDO, R2 is 0.
            #DO  TIMES=(R2,100,R3)
               :
    *   Code to process 100 times.
               :
             #EDO
  • In the following #DO TIMES example, the value in EBW000 is loaded in R15 and a BCT loop is generated.
            #DO  TIMES=(R15,X/EBW000)
               :
    *   Code to process the number of times specified by the value in
    *   the byte at EBW000.
               :
             #EDO
  • In the following #DO FROM example, a simple BC loop is generated. The processing is performed at least once with R3=0, then successively (with 4, 8, 12, and so on) up to and including the last value less than or equal to the contents of fullword in EBW000. For example,
    • If EBW000 contains 16, the last iteration is done with R3=16.
    • If EBW000 contains 15, the last iteration is done with R3=12.
            #DO  FROM=(R3,0),BY=4,TO=(EBW000)
               :
    *   Code to process the specified number of times.
               :
             #EDO
  • In the following #DO FROM example, a BC loop is generated that excludes the ending loop count. The processing is performed at least once with R3 equal to the contents of the fullword EBW000. At the end of each iteration, R3 is incremented by the length of field FL and compared to halfword EBW020. The loop continues as long as R3 is less than EBW020. For example, if EBW000 contains 10, EBW020 contains 100, and L'FL is 10, the iterations are performed with R3=10, 20, 30, and so on up to 90, but not 100.
            #DO  FROM=(R3,EBW000),BY=L'FL,TO=(H/EBW020,EXCLUSIVE)
               :
    *   Code to process the specified number of times.
               :
             #EDO
  • In the following #DO FROM example, a BXLE loop is generated. Processing is performed 10 times with R2 successively equal to 10, 20, 30, and so on up to 100.
            #DO  FROM=(R2,10),BY=(R4,10),TO=(R5,100)
               :
    *   Code to process 10 times.
               :
             #EDO
  • In the following #DO FROM example, a BXH loop is generated. Processing is performed at least once, with R2 successively equal to 100, 96, 92, and so on down to the last value that is greater than the contents of R5. R5 is initialized with an LA R5,VAL instruction. For example, if R5 contains 3, the processing is done 25 times with 4 as the last value used in R2.
            #DO  FROM=(R2,100),BY=(R4,-4),TO=(R5,A/VAL)
               :
    *   Code to process the specified number of times.
               :
             #EDO
  • In the following #DO FROM example, a BXLE loop is generated and registers are saved during processing. Processing is performed at least once, with R3 successively equal to 1000, 1020, 1040, and so on up to the last value less than or equal to the contents of R15 (initialized from fullword EBW048). R5 is initialized with an LA R5,VAL instruction. The registers are saved during loop processing and reloaded by #ELOP for the BXLE:
    • R3 in EBW040
    • R14 in EBW044
    • R15 in EBW048.
    If there is no #ELOP macro, the #EDO macro reloads the registers.
            #DO   FROM=(R3,1000,EBW040),BY=(R14,20,EBW044),TO=(R15,EBW048)
               :
    *   Code to process the specified number of times.
               :
             #EDO
  • In the following #DO FROM example, a BXLE loop is generated. In this example, the BXLE parameter is required because the type of loop cannot be determined from the parameters.
            #DO  BXLE,FROM=(R2),BY=(R4),TO=(R5)
               :
    *   Code to process using a BXLE loop based on the contents of
    *   R2, R4, and R5.
               :
             #EDO
  • In the following example, the WHILE and UNTIL parameters are used together.
            #DO   WHILE=(LTR,R0,R0,Z),UNTIL=(CR,R2,LE,R3)
    *
    *   The WHILE condition is tested here.
               :
    *   loop processing
               :
    *   The UNTIL condition is tested here.
    *
             #EDO
  • In the following example, the WHILE and TIMES parameters are used together.
            #DO   WHILE=(CR,R2,EQ,R3),TIMES=(R14,10)
    *
    *   The WHILE condition is tested here.
               :
    *   loop processing
               :
    *   The TIMES BCT is generated here.
    *
             #EDO
  • In the following example, the WHILE, UNTIL, and TIMES parameters are used together.
            #DO   WHILE=(R3,NZ),UNTIL=(R2,EQ,R4),TIMES=(R5,#ITEMS)
    *
    *   The WHILE condition is tested here.
               :
    *   loop processing
               :
    *   The UNTIL condition is tested here.
    *
    *   The TIMES BCT is generated here.
    *
             #EDO