Our next macro is a utility macro to help us load data into a register.
The macro will examine the operand and determine what action to take. There are four possible actions depending on the operand.
(Rx) – will generate a LR to load the target register from the operand register Rx
(addr) – Will generate a L to load the target register with the data at address location addr.
addr – Will generage a LA to load the target register with the value addr
‘string’ – Will generate a LA to load the target register with a literal string. The default string type is C for character. Optionally a length may be specified.
MACRO &NAME @RGCK &FLD,®=,&LEN=,&TYPE=C
The macro has four parameters, two of which must be specified. &FLD is the operand. ® is the target register and should be specified in using an Equated value (Rx). &LEN is optional and is used to specify a length when a literal string is generated. If &LEN is not specified, no explicit length will be used for the literal. &TYPE indicates the type of literal to be generated. If &TYPE is not specified, C will be assumed for character.
AIF ('&FLD'(1,1) NE '(').NOREG AIF ('&FLD(1)' EQ '®').DONE .* AIF ('&FLD(1)' EQ 'R0').LR AIF ('&FLD(1)' EQ 'R1').LR
First we check to see if the operand is enclosed in parentheses indicating either a register or a target for a LA. We do this by checking the first character of the &FLD parameter. If the target and operand registers are both the same then there is nothing to be done and we can exit. Else the operand is checked against the our standard register equate names (Rx). If it matches a value from R0 – R16 we branch to the .LR label.
AIF ('&FLD(1)' EQ 'R15').LR .* &NAME L ®,&FLD(1) MEXIT ,
If no match is found we fall through the tests and generate a L instruction.
.NOREG ANOP , AIF ('&FLD'(1,1) EQ '''').STRING &NAME LA ®,&FLD(1) MEXIT , .* .*
Now we check for a string indicated by a single quote in the first position of the operand. If it is not a string we generate a LA.
.STRING ANOP , AIF (T'&LEN EQ 'O').NOLEN &NAME LA ®,=&TYPE.L&LEN&FLD MEXIT , .NOLEN ANOP , &NAME LA ®,=&TYPE&FLD MEND
If it is a string we check to see if a length value (&LEN) is specified. If not we generate a LA for a literal with no length specification. Else we generate the LA using the specified length value for our literal.
Below is the full macro.
MACRO &NAME @RGCK &FLD,®=,&LEN=,&TYPE=C .* AIF ('&FLD'(1,1) NE '(').NOREG AIF ('&FLD(1)' EQ '®').DONE .* AIF ('&FLD(1)' EQ 'R0').LR AIF ('&FLD(1)' EQ 'R1').LR AIF ('&FLD(1)' EQ 'R2').LR AIF ('&FLD(1)' EQ 'R3').LR AIF ('&FLD(1)' EQ 'R4').LR AIF ('&FLD(1)' EQ 'R5').LR AIF ('&FLD(1)' EQ 'R6').LR AIF ('&FLD(1)' EQ 'R7').LR AIF ('&FLD(1)' EQ 'R8').LR AIF ('&FLD(1)' EQ 'R9').LR AIF ('&FLD(1)' EQ 'R10').LR AIF ('&FLD(1)' EQ 'R11').LR AIF ('&FLD(1)' EQ 'R12').LR AIF ('&FLD(1)' EQ 'R13').LR AIF ('&FLD(1)' EQ 'R14').LR AIF ('&FLD(1)' EQ 'R15').LR .* &NAME L ®,&FLD(1) MEXIT , .* .* .LR ANOP , &NAME LR ®,&FLD(1) .DONE ANOP , MEXIT , .* .* .NOREG ANOP , AIF ('&FLD'(1,1) EQ '''').STRING &NAME LA ®,&FLD(1) MEXIT , .* .* .STRING ANOP , AIF (T'&LEN EQ 'O').NOLEN &NAME LA ®,=&TYPE.L&LEN&FLD MEXIT , .NOLEN ANOP , &NAME LA ®,=&TYPE&FLD MEND