This is the documentation for the OPCODES package.  The OPCODES package         
consists of three files:                                                        
                                                                                
  OPCODES  MACLIB       Contains the macros which allow assembly                
  OPCODES  ASSEMBLE     Is a test program which uses all instructions           
  OPCODES  README       Is the documentation -- this file                       
                                                                                
The purpose of the OPCODES package is to allow newer instructions to            
be used with older assemblers which don't support those instructions.           
In particular, it was designed to augment the function of IBM's                 
Assembler XF, which has passed into the public domain.  However, even           
newer assemblers, such as IBM's High Level Assembler, may not support           
all of the instructions, depending on which version/release/maintenance         
level you are using; so this package may be useful to users with                
newer assemblers as well.  Since a mnemonic known to the assembler              
takes precedence over a macro, the macros provided will only be used            
if the assembler you are using doesn't recognize the instruction.               
                                                                                
In most cases, OPCODES should be listed last on your GLOBAL MACLIB              
statement.  For example, HCPGPI MACLIB contains the IUCV macro, which           
implements all of the IUCV functions, such as IUCV RECEIVE, etc.                
OPCODES also contains an IUCV macro, but it only implements the IUCV            
instruction mnemonic itself.  Chances are you will never use the IUCV           
macro provided with OPCODES: it is there for completeness' sake only.           
The only time you are likely to use it is when you assemble the OPCODES         
ASSEMBLE file for testing purposes.  (The OPCODES ASSEMBLE file is not          
only useful for testing the macros, it is also useful for testing               
disassemblers, such as the one provided with TRACK.)                            
                                                                                
This package provides support for all instructions listed in IBM                
z/Architecture Principles of Operation, SA22-7832-04, as well as                
older 370-mode-only instructions which are not documented in the above          
publication.  There are also macros provided for some undocumented              
instructions which are valid in S/390 or z/Architecture mode, such              
as SERVC, and some assembler instructions, such as CCW0 and CCW1.               
This release of OPCODES does not provide support for the vector                 
facility instructions of older S/390 models.                                    
                                                                                
Before listing the caveats and limitations of these macros, I want to           
start by saying this: if you think you are going to assemble recently           
written IBM code without the High-Level Assembler, you are probably             
going to be disappointed.  IBM-written code usually has dependencies            
on High-Level Assembler which go beyond the newer instructions, such            
as statement label names, sequence symbol names, or symbolic variable           
names which are longer than eight characters.  There may be other               
dependencies as well, such as labeled or dependent USING statements.            
Assembler XF cannot handle such code.  These macros will do you no good         
in such cases.                                                                  
                                                                                
                                                                                
Limitations:                                                                    
                                                                                
                                                                                
1.  The long displacement facility is not supported.  Macros are                
provided for instructions which use the long displacement facility,             
such as CLIY, but the DH field will always be forced to zero by the             
macro expansion.  Thus, the actual displacement must be between 0 and           
4095, inclusive.  If it is not, you will get assembly errors.  For              
example, consider the following code:                                           
                                                                                
-----------------------------------------------------------------------         
                                                                                
TEST     CSECT                                                                  
         USING TEST,12                                                          
         CLIY  TARGET,C'A'                                                      
         DS    XL4096                                                           
TARGET   DC    C' '                                                             
         END                                                                    
                                                                                
-----------------------------------------------------------------------         
                                                                                
High-Level Assembler can handle this and will assemble                          
                                                                                
EBC1 C006 0155                                                                  
                                                                                
as the machine-language instruction.  The base register is 12 (hex C)           
and the displacement is 1006, stored in two parts.  The low-order 12            
bits is stored following the base register as 006.  The high-order              
eight bits of the (signed) displacement is 01, stored after the                 
low-order part.  The op-code is EB55, stored in two pieces as the first         
and last byte of the instruction.  The immediate value, C1 (the letter          
A) is stored following the EB.  If you use Assembler XF with the                
OPCODES macros, the CLIY macro invocation will expand as                        
                                                                                
         DC    0H'0',X'EB',AL1(C'A'),S(TARGET),X'0055'                          
                                                                                
Notice that the storage location, TARGET, is referenced by a traditional        
S-type address constant, requiring a base register and a traditional,           
unsigned, 12-bit displacement.  Since the required displacement exceeds         
4095 (X'FFF'), an assembly error is generated:                                  
                                                                                
IFO209  ADDRESSABILITY ERROR- BASE AND DISPLACEMENT CANNOT BE RESOLVED          
 AND ARE SET TO 0                                                               
                                                                                
If you need to use instructions that use the long displacement facility,        
and the displacement really is outside the range 0-4095, and your               
assembler does not support the instruction, you must "hand code"                
your instruction.  For example, the following sequence is equivalent            
to the original test case:                                                      
                                                                                
-----------------------------------------------------------------------         
                                                                                
TEST     CSECT                                                                  
         USING TEST,12                                                          
*        CLIY  TARGET,C'A'                                                      
         DC    0H'0',X'EB',AL1(C'A'),AL.4(12),AL.12(TARGET-TEST),AL1((T*        
               ARGET-TEST)/4096),X'55'                                          
         DS    XL4096                                                           
TARGET   DC    C' '                                                             
         END                                                                    
                                                                                
-----------------------------------------------------------------------         
                                                                                
Note: due to the eccentricities of two's complement binary integer              
arithmetic, the technique must be altered slightly if the required              
displacement is negative.  Consider the following example:                      
                                                                                
-----------------------------------------------------------------------         
                                                                                
TEST     CSECT                                                                  
TARGET   DC    C' '                                                             
         DS    XL4095                                                           
         DS    XL6                                                              
HERE     EQU   *                                                                
         USING HERE,12                                                          
*        CLIY  TARGET,C'A'                                                      
         DC    0H'0',X'EB',AL1(C'A'),AL.4(12),AL.12(TARGET-HERE),AL1((T*        
               ARGET-HERE+1)/4096-1),X'55'                                      
         END                                                                    
                                                                                
-----------------------------------------------------------------------         
                                                                                
It is left as an exercise to the reader to prove that the above code            
generates the correct displacement, for both the low-order and high-            
order parts, for all valid negative displacements.  But it does.                
                                                                                
Note that with a 20-bit signed binary integer displacement, the valid           
displacement range is -524288 through +524287.  If the displacement             
is outside these boundaries, the assembler will generate an error if            
it supports the instruction directly.  But if you are using the                 
"hand-coded" technique listed above, and the displacement is outside            
these boundaries, the error goes undetected at assembly time.                   
The assembler simply preserves the low-order twelve bits of the first           
expression and the low-order eight bits of the second expression and            
goes on its merry way with no indication of a problem.  To detect               
such errors, you can add some checking code.  The above two examples            
are repeated below with checking code added.                                    
                                                                                
-----------------------------------------------------------------------         
                                                                                
TEST     CSECT                                                                  
         USING TEST,12                                                          
*        CLIY  TARGET,C'A'                                                      
         DC    0H'0',X'EB',AL1(C'A'),AL.4(12),AL.12(TARGET-TEST),AL1((T*        
               ARGET-TEST)/4096),X'55',0AL4(TARGET-TEST+2146959360)             
         DS    XL4096                                                           
TARGET   DC    C' '                                                             
         END                                                                    
                                                                                
TEST     CSECT                                                                  
TARGET   DC    C' '                                                             
         DS    XL4095                                                           
         DS    XL6                                                              
HERE     EQU   *                                                                
         USING HERE,12                                                          
*        CLIY  TARGET,C'A'                                                      
         DC    0H'0',X'EB',AL1(C'A'),AL.4(12),AL.12(TARGET-HERE),AL1((T*        
               ARGET-HERE+1)/4096-1),X'55',0AL4(TARGET-HERE-2146959360)         
         END                                                                    
                                                                                
-----------------------------------------------------------------------         
                                                                                
Notice the "0AL4(...)" expression which was tacked on to the end.               
The duplication factor of zero means that no space is reserved for the          
constant.  And the length modifier (L4) means than no boundary                  
alignment will take place.  Therefore, it does not affect the                   
assembly at all.  However, the expression is still evaluated.  And if           
the displacement is outside the boundaries, the value inside the                
parentheses of the 0AL4 expression will exceed the architectural                
limit of a fullword signed binary integer (-2147483648 to +2147483647).         
This will generate the following assembler error message:                       
                                                                                
IFO235  ARITHMETIC OVERFLOW NEAR OPERAND COLUMN xx                              
                                                                                
where xx is the column number of the closing right parenthesis of               
the 0AL4 expression, with column 1 being the beginning of the operand           
field on the first "card" and continuing logically through the                  
continuations.  If you add " DS 256XL4096" in front of the "HERE"               
label in the second example above, you can generate this error.                 
The logical operand column number will be 112.                                  
                                                                                
OK, so if one can "hand-code" an assembler instruction that uses the            
long displacement facility by means of a complicated DC instruction,            
why can't the macro do it?  Well, the macro doesn't have all the                
information it needs to generate such an instruction.  Remember, in the         
general case, it's going to receive a general-purpose relocatable               
expression as an argument.  The macro would need to know (a) which              
CSECT or DSECT the relocatable expression resides in, (b) which base            
register to use, (c) the name of the symbol which gives zero                    
displacement from the base register, and (d) whether the displacement           
is going to evaluate to a positive or negative value at assembly time.          
The macro simply doesn't have this information available.  It relies            
on the assembler itself to generate a base and displacement by using            
the S-type address constant.  But the S-type address constant is                
limited to a 12-bit unsigned displacement.  So there you are.  I did            
the best I could with what I had available.                                     
                                                                                
Of course, the long displacement facility is valid (at execution                
time) in z/Architecture mode only.                                              
                                                                                
                                                                                
2.  Expressions involving location counter references which are                 
passed as arguments to these macros will often not assemble as                  
expected.  Therefore, you should not use them.  Consider the following          
example:                                                                        
                                                                                
-----------------------------------------------------------------------         
                                                                                
         .                                                                      
         .                                                                      
         .                                                                      
         CNOP  0,4                                                              
         LAM   2,4,*+8                                                          
         B     AROUND                                                           
         DS    3F                                                               
AROUND   DS    0H                                                               
         .                                                                      
         .                                                                      
         .                                                                      
                                                                                
-----------------------------------------------------------------------         
                                                                                
The intent of the programmer is to load access registers 2 through 4            
from the storage area defined by the "DS    3F" statement, then                 
branch around the storage area.  If the assembler supports the LAM              
instruction, this will work as expected.  But if the assembler does not         
support the LAM instruction and the LAM macro of OPCODES is invoked             
instead, the LAM macro invocation will expand as follows:                       
                                                                                
-----------------------------------------------------------------------         
                                                                                
         DC    0H'0',X'9A',AL.4(2,4),S(*+8)                                     
                                                                                
-----------------------------------------------------------------------         
                                                                                
Now you see the trouble.  The assembler doesn't "see" the location              
counter reference until it encounters the S-type adcon, which is                
two bytes later than the start of the LAM "instruction".  Instead of            
the location counter pointing to the X'9A', it points to the S-type             
address constant.  Thus, the code which gets generated will point to            
a location two bytes into the "DS    3F" area instead of pointing to            
the start of the area.  The following examples will both assemble               
correctly:                                                                      
                                                                                
-----------------------------------------------------------------------         
                                                                                
         .                                                                      
         .                                                                      
         .                                                                      
         CNOP  0,4                                                              
ME       LAM   2,4,ME+8                                                         
         B     AROUND                                                           
         DS    3F                                                               
AROUND   DS    0H                                                               
         .                                                                      
         .                                                                      
         .                                                                      
                                                                                
         .                                                                      
         .                                                                      
         .                                                                      
         CNOP  0,4                                                              
         LAM   2,4,YOU                                                          
         B     AROUND                                                           
YOU      DS    3F                                                               
AROUND   DS    0H                                                               
         .                                                                      
         .                                                                      
         .                                                                      
                                                                                
-----------------------------------------------------------------------         
                                                                                
Sometimes location counter references WILL work as expected.  Here's            
an example where it works:                                                      
                                                                                
-----------------------------------------------------------------------         
                                                                                
         .                                                                      
         .                                                                      
         .                                                                      
         CNOP  0,4                                                              
         BAS   1,*+16                                                           
         DS    3F                                                               
         L     15,=V(MYPROG)                                                    
         .                                                                      
         .                                                                      
         .                                                                      
                                                                                
-----------------------------------------------------------------------         
                                                                                
The intent of the programmer is to load the address of a parameter              
list (DS    3F) into register 1, then branch around it to the following         
instruction (L).  If the assembler does not support BAS and the BAS             
macro of OPCODES is invoked, the macro will expand like this:                   
                                                                                
-----------------------------------------------------------------------         
                                                                                
         BAL   1,*+16                                                           
         ORG   *-4                                                              
         DC    X'4D'                                                            
         ORG   *+3                                                              
                                                                                
-----------------------------------------------------------------------         
                                                                                
The macro works by substituting the BAL instruction for the BAS                 
instruction, then going back and redefining the op-code as X'4D'                
(instead of X'45').  Since both BAL and BAS have the same instruction           
format (RX), this works.  And since the location counter expression             
(*+16) is substituted into an instruction at the beginning of the               
macro expansion, it works as expected.                                          
                                                                                
So sometimes location counter expressions will assemble as expected and         
sometimes they won't, depending on the implementation.  Since a specific        
implementation may change in the future, the exact implementation should        
not be relied upon.  The bottom line: don't use expressions involving           
the location counter as arguments to these macros.                              
                                                                                
                                                                                
3.  Argument specification errors or alignment errors will often not            
be detected by these macros.  Consider the following example:                   
                                                                                
-----------------------------------------------------------------------         
                                                                                
         DXR   0,2                                                              
                                                                                
-----------------------------------------------------------------------         
                                                                                
If the assembler supports DXR, you will get an assembly error                   
complaining about 2 being an invalid register specification, which              
it is.  DXR requires the low-numbered register of a floating point              
register pair for both operands.  2 is the upper half of register pair          
0-2.  But if the assembler doesn't support DXR and the DXR macro of             
OPCODES is invoked, it will expand like this:                                   
                                                                                
-----------------------------------------------------------------------         
                                                                                
         DC    0H'0',X'B22D',AL1(0),AL.4(0,2)                                   
                                                                                
-----------------------------------------------------------------------         
                                                                                
which is B22D0002.  This will assemble without errors.  But if you              
attempt to execute this code, you will get a specification exception            
(ABEND S0C6 in MVS parlance, or PROG 6 in VM parlance.)  Similarly,             
if storage areas are not aligned on their proper boundaries, there is           
often no error or warning message generated.  The goal was to correctly         
assemble valid code.  Detecting invalid code was not a priority.  If            
the macro happens to detect the error at assembly time you are lucky.           
                                                                                
                                                                                
4.  The macros which implement relative branch instructions, such as            
BRC, require a relocatable expression in the same CSECT as the                  
instruction.  Absolute expressions and references to symbols in other           
control sections are not supported.                                             
                                                                                
                                                                                
5.  The macros cannot add new function to existing instructions which           
your assembler DOES support.  For example,                                      
                                                                                
-----------------------------------------------------------------------         
                                                                                
         MXR   9,13                                                             
                                                                                
-----------------------------------------------------------------------         
                                                                                
is valid, if the basic-floating-point-extensions facility is installed          
and bit 13 of control register 0, the AFP register control bit, is 1.           
(In z/Architecture mode, that would be bit 45 of control register 0.)           
However, Assembler XF doesn't know about these additional floating point        
registers and will generate assembly errors.  There is not an MXR macro         
provided with this package, but even if there was, the assembler will           
not invoke a macro if the operation field is a valid mnemonic that the          
assembler knows about.  To get around these restrictions, you will need         
to "hand-code" the instruction.  For example:                                   
                                                                                
-----------------------------------------------------------------------         
                                                                                
*        MXR   9,13                                                             
         DC    0H'0',X'269D'                                                    
                                                                                
-----------------------------------------------------------------------         
                                                                                
                                                                                
6.  Violations of reentrancy are not necessarily detected by the RENT           
option when using these macros.  For example,                                   
                                                                                
-----------------------------------------------------------------------         
                                                                                
         STAM  1,1,X                                                            
         .                                                                      
X        DS    F                                                                
                                                                                
-----------------------------------------------------------------------         
                                                                                
If the assembler understands the STAM instruction and the RENT option           
is specified, the assembler will flag a possible violation of                   
reentrancy.  But if the assembler does not understand the STAM                  
instruction and the macro is invoked, it expands like this:                     
                                                                                
-----------------------------------------------------------------------         
                                                                                
         DC    0H'0',X'9B',AL.4(1,1),S(X)                                       
                                                                                
-----------------------------------------------------------------------         
                                                                                
Since the assembler does not know whether the storage reference to X            
in the S-type adcon is a fetch reference or a store reference, no               
violation is flagged.                                                           
                                                                                
                                                                                
7.  References to operands may be missing from the assembler cross-             
reference listings.                                                             
                                                                                
                                                                                
8.  Although there are AMODE and RMODE macros provided, they are                
there only to prevent assembly errors.  They cannot set the                     
requisite bits in the external symbol dictionary entries.  If you               
want the resulting object code to reflect the true AMODE and RMODE              
settings you have supplied on the AMODE and RMODE statements, you               
must edit the object code and twiddle the bits by hand.  Any                    
values other than RMODE 24 and AMODE 24 will result in warning                  
messages (an MNOTE with return code 4).                                         
                                                                                
                                                                                
I hope you find these macros useful.  Any questions, comments, tips,            
complaints, praise, etc. should be directed to:                                 
                                                                                
Steve Powell                                                                    
zlinuxman@yahoo.com                                                             
