Simon Coulter leaves us a gift before he departs.
As you probably know, Simon Coulter, a knowledgeable and versatile IBM i expert, passed away in October 2010. Simon was loved by many IBM i developers because he was one of the giants in the industry, on whose shoulders others could stand and reach for new heights.
Among all his posts in the news lists at midrange.com, there was one in which Simon introduced a technique that is critical to analyzing MI instruction streams of OPM programs: Re: QPROCT and QPRODT. In this post, he pointed out that the description information for MI instructions, in form of a 17-byte entry for each instruction, is stored in a hidden space object, QSYS/QPROCT. Additionally, he discovered the format of the 17-byte entries through experiments. This is the key to analyzing the MI instruction stream of OPM programs. Starting from this point, we finally have the opportunity to see clearly the format of MI instruction streams of OPM programs, which has never been publicly documented by IBM. Furthermore, by combining the instruction stream analysis technique with IBM's documentation on other components of OPM programs—such as the object definition table (ODT)—you can create an MI disassembler for OPM programs.
The Mystery Uncovered by Simon
Simon pointed out that the space object QSYS/QPROCT (with object type code/sub-type code hex 19DA) stores 17-byte entries, one for each MI instruction, beginning from offset hex 466 in its associated space. The number of those entries varies from release to release. By observing the dump result of QPROCT, you can find out the number is 230 for V5R4 and 468 for V5R2. Simon also provided the format of the 17-byte entries for MI instructions.
Format of Each 17-Byte Entry in QPROCT |
||
Offset(Hex) |
Data Type |
Description |
0 |
CHAR(8) |
Instruction name |
8 |
BIN(2) |
Instruction operation code |
A |
CHAR(1) |
Flags of optional instruction forms |
B |
CHAR(2) |
Flags of possibly resulting conditions |
D |
BIN(2) |
Number of required parameters |
F |
CHAR(2) |
"…unknown but related to header information. Non-x'ffff' values appear to be an increasing sequence. Each x'ffff' value has a corresponding non-x'ffff' entry in the header, but I haven't determined the relationship yet." |
The above format of 17-byte entries for MI instruction in QPROCT revealed a couple of critical keys for analyzing the instruction stream:
- The instruction name/operation code (op-code) mapping, which allows you determine the instruction name by a parsed op-code in the instruction stream
- The number of required operands for a specific instruction
Appendix A at the end of this article shows a complete list of instruction name/op-code mappings (along with numbers of required parameters) that was extracted from the QPROCT at release V5R4.
With Simon's help, it has become possible to clarify the format of an OPM program's instruction stream.
Analyzing an OPM Program's Instruction Stream, Step by Step
As we know, it's possible to retrieve the MI instruction stream component of an OPM program with proper observability via the MATPG (Materialize Program) instruction. The MATPG instruction can also return the following types of OPM program information that are necessary to an MI disassembler:
- The object definition table (ODT)—The ODT contains the views of all objects referred to in the instruction stream other than those objects that are immediate value operands in the instructions. An instruction operand in the instruction stream that contains a reference (possibly qualified) to an object in the ODT is called an "ODT object reference." The ODT consists of ODT directory vector (ODV) entries and optional ODT entry string (OES) entries. An ODV entry is required for each ODT object reference in the instruction stream.
- The HLL breakpoint offset mapping (BOM) table—The BOM table stores the mappings from breakpoints in an OPM MI program to corresponding MI instruction numbers. A breakpoint in an MI program is produced by a break (BRK) directive statement in the MI source of the program. The BOM table component can be used by compilers to relate HLL statement numbers to instruction numbers.
- The HLL symbol table that relates HLL names to ODT numbers
- The object mapping table (OMT)—The OMT entries correspond one for one with the ODV entries; each OMT entry gives a location mapping for the object defined by its associated ODV entry.
According to IBM's documentation on MATPG, you can get the following information about the materialized instruction stream:
- The instruction stream component consists of a 4-byte binary value that defines the total length of the instruction stream component and a variable-length array of 2-byte entries that defines the instruction stream.
- The 2-byte entries define instruction operation codes, instruction operation code extenders, or instruction operands.
Actually, the format of the 2-byte entries belonging to a single MI instruction in the instruction stream might optionally have one to four parts, like the following. Entries in brackets are optional.
Op-code [op-code-extenders] [operands] [branch-target-operands/indicator-operands] |
The Operation Code Entry
The first 2-byte entry for an instruction in the instruction stream is the op-code entry of the corresponding MI instruction. Note that an op-code entry extracted from the instruction stream cannot be directly used to match an op-code value in the QPROCT; only some of the bits of the op-code entry should be used to represent the real op-code of the MI instruction.
Format of the Op-Code Entry |
|
Bits |
Meaning |
Byte 0 |
|
Bits 0-2 |
Not used. |
Bit 3 |
If bit 3 = 0, the instruction doesn't have optional instruction forms, and bits 4-7 of byte 0 are used to represent the value of the op-code along with byte 1. If bit 3 = 1, the instruction might use one or more optional forms. Optional instruction forms include the short form, the round form, the branch form, and the indicator form. Bits 4-7 of the byte 0 are used to describe the usage of optional forms. Bit 3 itself is used to represent the value of the op-code along with byte 1. |
Bits 4-7 |
If bit 3 = 1, bits 4-7 of byte 0 are used to represent optional instruction forms. If bits 4-5 = 10, the indicator form (I form) is specified. If bits 4-5 = 11, the branch form (B form) is specified. If bit 6 = 1, the round form (R form) is specified. If bit 7 = 1, the short form (S form) is specified. |
Byte 1 |
All 8 bits of byte 1 are used to represent the value of the op-code along with byte 1. |
After extracting the real op-code, you can map the result op-code to the name of the instruction via the instruction name/op-code mappings stored in the QPROCT.
The Operation Code-Extender Entry
For MI instructions that use the branch form (B form) or the indicator form (I form), at least one resultant condition must be specified. All resultant conditions are categorized into four groups, and conditions in the same group are represented by the same value in an op-code-extender entry in the instruction stream. There can be up to four resultant conditions specified for a single MI instruction. If an instruction uses B form or I form (the bit 3 of byte 0 of its op-code entry is 1 and the bit 4 of byte 0 is 1), then the following facts are true:
- The 2-byte entry after the op-code entry is an op-code-extender entry that indicates the resultant conditions being specified with this instruction.
- Each 4 bits of the 2-byte op-code-extender entry represent a resultant condition specified with the instruction. The values for resultant conditions in different groups are showed in the following table.
- After the 2-byte entries representing the required instruction operands of the instruction, there are 2-byte entries in the same order for each branch target operand or indicator target operand corresponding to each resultant condition in the op-code-extender entry.
The following table shows the values of all 4-bit op-code extenders. For the resultant condition keywords belonging to each group, see Appendix B at the end of this article. Note that by adding N to the beginning of a resultant condition keyword, you can form a not condition. For example, the code for "not equal" is NEQ.
Values of 4-Bit Op-Code Extenders |
|
Group |
Value (Hex) |
Group-1 |
1 |
Group-2 |
2 |
Group-3 |
4 |
Group-4 |
7 |
NOT Group-1 |
9 |
NOT Group-2 |
A |
NOT Group-3 |
C |
NOT Group-4 |
F |
The Instruction Operand Entries
In the instruction stream of an instruction, after the op-code entry and an optional op-code-extender entry, there are zero to four 2-byte entries that represent the required operands of the instruction. The number of required operands of an instruction is available via the QPROCT. Note that if an instruction uses short form (S form), the number of instruction operands in the instruction stream will be one less than the number of required operands.
According to IBM's documentation on Program Object Specification, there are three types of instruction operands:
Null operands—The value of a null operand in the instruction stream is hex 0000.
Immediate operands—The value of an immediate operand is encoded in the 2-byte instruction operand entry directly. Immediate operands may have the following values:
• Signed binary representing a binary value of negative 4,096 to positive 4,095.
• Unsigned binary representing a binary value of 0 to 8,191.
• Byte string representing a single byte value from hex 00 to hex FF.
• Absolute instruction number representing an instruction number in the range of 1 to 8,191.
• Relative instruction number representing a displacement of an instruction relative to the instruction in which the operand occurs. This operand value may identify an instruction displacement of negative 4,096 to positive 4,095.
ODT object references—This type of operand contains a reference (possibly qualified) to an object in the ODT. Operands that are ODT object references may be simple operands or compound operands.
• The value encoded in the operand refers to a specific object defined in the ODT. Simple operands consist of a single 2-byte operand entry.
• A compound operand consists of a primary (2-byte) entry and a series of one to three secondary (2-byte) entries. A compound operand may be a subscript reference, a substring reference, or an explicit base reference.
The format of immediate operands is as follows:
Format of Immediate Operands |
|
Bits |
Description |
Bits 0 |
Sign of an immediate operand. 0 = Positive 1 = Negative |
Bit 1 |
Not used. |
Bit 2 |
Type of instruction operand. 1 = Immediate operand |
Bits 3-15 |
Value of an immediate operand. |
For example, the value of an unsigned binary scalar immediate operand 8191 is hex 3FFF; the value of a signed binary scalar immediate operand -55 is hex BFC9; and the value of a 1-byte character immediate operand 'A' is hex 20C1.
The format of the primary operand of a compound operand is shown in the following table:
Format of Compound Operands |
|
Bits |
Description |
Bits 0-2 |
Type of a compound operand 4 = Subscript reference 6 = Substring reference 8 = Explicit base reference C = Subscript reference to an explicit base reference E = Substring reference to an explicit base reference |
Bits 3-15 |
ODT object reference If bits 0-2 = 4, an ODT reference to the array If bits 0-2 = 6, an ODT reference to the base string object If bits 0-2 = 8, an ODT reference to the based object If bits 0-2 = C, an ODT reference to the based object If bits 0-2 = E, an ODT reference to the based object |
The secondary entries of a compound operand can be either an immediate operand or a simple operand, but cannot be another compound operand. For a subscript reference, after the primary entry, there is one secondary entry that specifies the index value to an element of the array. A substring reference has two secondary entries; the first specifies the value of substring start position, and the second specifies the value of substring length. An explicit base reference has a secondary entry that specifies the pointer on which to base the object for this operand. A subscript reference to an explicit base reference is the combination of a subscript reference and an explicit base reference; the secondary entries of it are an operand that specifies the pointer on which to base the object for this operand followed by one that specifies the index value to an element of the array. A substring reference to an explicit base has three secondary entries: an operand that specifies the pointer on which to base the object for this operand, an operand that specifies the value of the substring start position, and an operand that specifies the value of the substring length.
The Branch Target or Indicator Target Operands Entries
For MI instructions that use B form or I form, at least one resultant condition must be specified for an instruction using B form or I form. After the 2-byte entries representing the required instruction operands of the instruction, there are 2-byte entries specified in the same order for each branch target or indicator target operand corresponding to each resultant condition in the op-code-extender entry.
Put It All Together
Now let's exploit the techniques discussed above in a practical example. Assume that you have a compiled OPM RPG program called HELLO and you already have the parsed ODT table of HELLO at hand. The source of HELLO is like the following (HELLO.RPG).
E ARR 3 5 2A ARR(3) PKD(5,2) C Z-ADD1 WHR 20 ARRAY INDEX C Z-ADD19.69 ARR,1 C Z-ADD19.60 ARR,2 C Z-ADD19.65 ARR,3 C SORTAARR C ARR,2 LOKUPARR,WHR 91 HIGHER C 91 'INDEX' DSPLY WHR C N91 ':-(' DSPLY ARR,2 C SETON LR |
The beginning 4 bytes of HELLO's instruction stream component indicates that the total size of the instruction stream is hex 00000646 (1606 bytes). For simplicity, we will run through only a piece of the whole instruction stream, which corresponds to the 7th line in HELLO's source code. The ODT object references being used in this piece of instruction stream are listed in the following table:
ODT References |
||
Object Name |
ODT Index |
Object Type and Description |
*IN91 |
0016 |
Char(1) data object defined on char(1) array *IN(99) at position 91 |
*OFF |
000E |
Char(1) constant with initial value '0' |
.I |
0025 |
Bin(4) data object |
WHR |
0018 |
Packed(2,0) data object |
.LKF1000 |
009E |
Branch point pointing to instruction hex 31 |
ARR |
0017 |
Packed(5,2) array with three array elements |
.LKF2000 |
009F |
Branch point pointing to instruction hex 36 |
.LKF3000 |
00A0 |
Branch point pointing to instruction hex 38 |
*ON |
000D |
Char(1) constant with initial value '1' |
The part of instruction stream corresponding to HELLO's seventh line is highlighted in the following table:
Instruction Stream for to HELLO's Seventh Line |
|
Offset |
Instruction Stream |
000120 |
009C1042 40172003 009D0293 00C70000 00C530B2 0016000E 10420025 00183C46 |
000140 |
10004017 00254017 2002009F 11430025 20011C46 90000025 2003009E 10420018 |
000160 |
20011011 00A030B2 0016000D 10420018 00253CC2 C0000016 000D00B6 10B260A3 |
Assume the start instruction number is hex 2F. Let's apply the above-mentioned analyzing techniques to each instruction in this piece of instruction stream.
Instruction Hex 2F |
|
Instruction Stream |
30B2 0016 000E |
Op-code |
Op-code retrieved is hex 30B2. Since bit 3 of it is 1, the real op-code is composed by bit 3 and all bits of byte 1 (bits 7-15). So the real op-code is hex 10B2. According to Appendix A, the corresponding MI instruction name is CPYBLA (Copy Bytes Left-Adjusted). The number of required operands of it is 2. Since bits 4-7 of the op-code entry are binary 0000, this instruction does not use optional instruction forms and hence does not have op-code extender entries. |
Op-code Extenders |
None |
Operands |
Both of the two required operands of this instruction are ODT object references, hex 0016 and hex 000E, which refer to scalar data object *IN91 and constant *OFF, respectively. |
Disassembled MI Instruction |
CPYBLA *IN91,*OFF ; |
Instruction Hex 30 |
|
Instruction Stream |
1042 0025 0018 |
Op-code |
1042 (CPYNV (Copy Numeric Value)) |
Op-code Extenders |
None |
Operands |
ODT object references: .I ,WHR |
Disassembled MI Instruction |
CPYNV .I ,WHR ; |
Instruction Hex 31 |
|
Instruction Stream |
3C46 1000 4017 0025 4017 2002 009F |
Op-code |
Op-code retrieved is hex 3C46. Since bit 3 of it is 1, the real op-code is composed by bit 3 and all bits of byte 1 (bits 7-15). So the real op-code is hex 1046 (CMPNV (Compare Numeric Value)). The binary value 10 of bits 4-5 means that this instruction uses B form and therefore there should be an op-code extender entry after the op-code entry. The zero value of bits 6-7 means that this instruction uses neither R form or S form. |
Op-code Extenders |
The value hex 1000 of the op-code extender entry means that this instruction uses a Group-1 branch target keyword, which could be HI, MXD, NOR, POS, TR, or ZC. A corresponding branch target operand should be appended after the required operands of this instruction. |
Operands |
The first operand of this instruction is a compound operand that occupies two entries in the instruction stream: 4017 0025. According to what we discussed above, it's a subscript reference to ODT object 0017, array ARR; and the array-index operand is another ODT reference to ODT object 0025, scalar data object .I. Thus, the first operand is ARR(.I). Similarly, the second operand of this instruction is also a subscript reference, ARR(2). |
B/I Target Operands |
As is indicated by the op-code extender, this instruction has one branch target operand, the 2-byte entry following operand ARR(2), whose value is hex 009F. It's the branch point object .LKF2000 pointing to instruction hex 36. |
Disassembled MI Instruction |
CMPNV(B) ARR(.I),ARR(2) / HI(.LKF2000) ; |
Instruction Hex 32 |
|
Instruction Stream |
1143 0025 2001 |
Op-code |
The instruction name for op-code 1043 is ADDN (Add Numeric). The value 1 of bit 7 means this instruction uses short form. |
Op-code Extenders |
None |
Operands |
ODT object reference 0025 (.I) and binary immediate operand of value 1. |
Disassembled MI Instruction |
ADDN(S) .I,1 ; |
Instruction Hex 33 |
|
Instruction Stream |
1C46 9000 0025 2003 009E |
Op-code |
1046 (CMPNV) with B form |
Op-code Extenders |
NHI (not high) |
Operands |
ODT reference 0025 (.I) and binary immediate operand of value 3 |
B/I Target Operands |
Branch point .LKF1000, which points to instruction hex 31 |
Disassembled MI Instruction |
CMPNV(B) .I, 3 / NHI(.LKF1000) ; |
Instruction Hex 34 |
|
Instruction Stream |
1042 0018 2001 |
Op-code |
1042 (CPYNV (Copy Numeric Value)) |
Op-code Extenders |
None |
Operands |
ODT reference 0018 (WHR) and binary immediate operand of value 1 |
Disassembled MI Instruction |
CPYNV WHR ,1 ; |
Instruction Hex 35 |
|
Instruction Stream |
1011 00A0 |
Op-code |
1011 (B (Branch)) |
Op-code Extenders |
None |
Operands |
Branch point .LKF3000, which points to instruction hex 38 |
Disassembled MI Instruction |
B .LKF3000 ; |
Instruction Hex 36 |
|
Instruction Stream |
30B2 0016 000D |
Op-code |
10B2 (CPYBLA) |
Op-code Extenders |
None |
Operands |
*IN91, *ON |
Disassembled MI Instruction |
CPYBLA *IN91, *ON ; |
Instruction Hex 37 |
|
Instruction Stream |
1042 0018 0025 |
Op-code |
1042 (CPYNV) |
Op-code Extenders |
None |
Operands |
WHR, .I |
Disassembled MI Instruction |
CPYNV WHR ,.I ; |
Finally, let's compose the disassembled MI instructions and labels represented by branch points (.LKF1000, .LKF2000, and .LKF3000) into the final MI source code corresponding to HELLO's line 7, "C ARR,2 LOKUPARR,WHR 91".
Disassembled MI Source |
|
Instruction Number (Hex) |
MI Source |
2F |
CPYBLA *IN91, *OFF ; |
30 |
CPYNV .I, WHR ; |
|
.LKF1000: |
31 |
CMPNV(B) ARR(.I), ARR(2) / HI(.LKF2000) ; |
32 |
ADDN(S) .I, 1 ; |
33 |
CMPNV(B) .I, 3 / NHI(.LKF1000) ; |
34 |
CPYNV WHR ,1 ; |
35 |
B .LKF3000 ; |
|
.LKF2000: |
36 |
CPYBLA *IN91, *ON ; |
37 |
CPYNV WHR, .I ; |
|
.LKF3000: |
Notes on the disassembled MI source:
- Instruction 2F—Set off indicator *IN91 by copying the value '0' into it via CPYBLA.
- Instruction 30—Copy the value of packed(2,0) scalar WHR into an internal bin(4) scalar .I.
- Instruction 31—Compare array element ARR(.I) with ARR(2) and conditionally branch to label .LKF2000 if ARR(.I) is larger than ARR(2).
- Instruction 32—Increment the value of array index .I by 1.
- Instruction 33—Loop if array index .I is not larger than constant 3.
- Instructions 34, 35—After the loop, if there is no array element that fulfills the search criteria, copy the value 1 into WHR and then branch to the instruction hex 38 that is labeled by branch point .LKF3000.
- Instruction 36—When an array element fulfills the search criteria and the control flow is branched from instruction 31 to instruction 36, set on indicator *IN91 by copying the value '1' into it.
- Instruction 37—Save the current array-index value back to packed scalar WHR.
Congratulations! You've just managed to disassemble the instruction stream corresponding to one line of OPM RPG source statement. If you are new to MI, you might be a little surprised by the amount of work needed to implement an RPG LOKUP (Look up) operation at the MI level.
We can now look through the instruction stream of an OPM MI program. This is owing to Simon's work on the QPROCT object. Rest in peace, Simon.
Appendix A: Instruction Name/Op-Code Mappings (V5R4)
According to the format of the 17-byte QPROCT entries given by Simon, we can extract the op-code, name, and number of required operands for each MI instruction from the space object QSYS/QPROCT. The following 230 records are extracted from a QPROCT object at release V5R4.
Instruction Name/Op-Code Mappings |
||
Instruction Name |
Op-code (Hex) |
Number of Required Operands |
ADDLC |
1023 |
0003 |
ADDN |
1043 |
0003 |
AND |
1093 |
0003 |
B |
1011 |
0001 |
CLRBTS |
102E |
0002 |
CMPBLA |
10C2 |
0002 |
CMPBLAP |
10C3 |
0003 |
CMPBRA |
10C6 |
0002 |
CMPBRAP |
10C7 |
0003 |
CMPNV |
1046 |
0002 |
CAI |
1044 |
0004 |
CAT |
10F3 |
0003 |
CMF1 |
100B |
0003 |
CMF2 |
100C |
0004 |
CVTBC |
10AF |
0003 |
CVTCB |
108F |
0003 |
CVTCH |
1082 |
0002 |
CVTDFFP |
107F |
0003 |
CVTFPDF |
10BF |
0003 |
CVTCM |
108B |
0003 |
CVTCN |
1083 |
0003 |
CVTCS |
10CB |
0003 |
CVTEFN |
1087 |
0003 |
CVTHC |
1086 |
0002 |
CVTMC |
10AB |
0003 |
CVTNC |
10A3 |
0003 |
CVTSC |
10DB |
0003 |
CPYBBTA |
104C |
0004 |
CPYBBTL |
103C |
0004 |
CPYBTLLS |
102F |
0003 |
CPYBTRLS |
103F |
0003 |
CPYBTRAS |
101B |
0003 |
CPYBLA |
10B2 |
0002 |
CPYBLAP |
10B3 |
0003 |
CPYBOLA |
10BA |
0002 |
CPYBOLAP |
10BB |
0003 |
CPYBREP |
10BE |
0002 |
CPYBRA |
10B6 |
0002 |
CPYBRAP |
10B7 |
0003 |
CPYBTA |
102C |
0004 |
CPYBTL |
101C |
0004 |
CPYECLAP |
1053 |
0003 |
CPYHEXNN |
1092 |
0002 |
CPYHEXNZ |
1096 |
0002 |
CPYHEXZN |
109A |
0002 |
CPYHEXZZ |
109E |
0002 |
CPYNV |
1042 |
0002 |
DIV |
104F |
0003 |
DIVREM |
1074 |
0004 |
ECSCAN |
10D4 |
0004 |
EDIT |
10E3 |
0003 |
EXCHBY |
10CE |
0002 |
XOR |
109B |
0003 |
EXTREXP |
1072 |
0002 |
EXTRMAG |
1052 |
0002 |
MULT |
104B |
0003 |
NEG |
1056 |
0002 |
NOOP |
0000 |
0000 |
NOOPS |
0001 |
0001 |
OVRPGATR |
0006 |
0002 |
NOT |
108A |
0002 |
OR |
1097 |
0003 |
REM |
1073 |
0003 |
SCALE |
1063 |
0003 |
SCAN |
10D3 |
0003 |
SCANWC |
10E4 |
0004 |
SEARCH |
1084 |
0004 |
SETBTS |
101E |
0002 |
SETIP |
1022 |
0002 |
SSCA |
107B |
0003 |
SUBLC |
1027 |
0003 |
SUBN |
1047 |
0003 |
TSTRPLC |
10A2 |
0002 |
TSTBTS |
100E |
0002 |
TSTBUM |
102A |
0002 |
XLATE |
1094 |
0004 |
XLATEWT |
109F |
0003 |
XLATWTDS |
1077 |
0003 |
TRIML |
10A7 |
0003 |
VERIFY |
10D7 |
0003 |
CPRDATA |
1041 |
0001 |
DCPDATA |
1051 |
0001 |
CMPSW |
1037 |
0003 |
XLATEMB |
1071 |
0001 |
CIPHER |
10EF |
0003 |
GENUUID |
011D |
0001 |
CMPPTRA |
10D2 |
0002 |
CMPPTRT |
10E2 |
0002 |
CPYBWP |
0132 |
0002 |
MATCTX |
0133 |
0003 |
RSLVDP |
0163 |
0003 |
RSLVSP |
0164 |
0004 |
ADDSPP |
0083 |
0003 |
CMPPSPAD |
10E6 |
0002 |
CMPSPAD |
10F2 |
0002 |
SETDP |
0096 |
0002 |
SETDPADR |
0046 |
0002 |
SETDPAT |
004A |
0002 |
SETSPP |
0082 |
0002 |
SETSPPD |
0093 |
0003 |
SETSPPO |
0092 |
0002 |
SETSPPFP |
0022 |
0002 |
SETSPFP |
0032 |
0002 |
STSPPO |
00A2 |
0002 |
SUBSPP |
0087 |
0003 |
SUBSPPFO |
0033 |
0003 |
CMPPTRE |
1012 |
0002 |
CRTS |
0072 |
0002 |
DESS |
0025 |
0001 |
MATS |
0036 |
0002 |
MODS |
0062 |
0002 |
CRTINX |
0446 |
0002 |
DESINX |
0451 |
0001 |
FNDINXEN |
0494 |
0004 |
INSINXEN |
04A3 |
0003 |
MATINXAT |
0462 |
0002 |
MODINX |
0452 |
0002 |
RMVINXEN |
0484 |
0004 |
MATAL |
01B3 |
0003 |
MATAU |
0153 |
0003 |
MATAUOBJ |
013B |
0003 |
MATAUU |
0143 |
0003 |
MATUP |
013E |
0002 |
MATUPID |
013A |
0002 |
MODINVAU |
0141 |
0001 |
TESTAU |
10F7 |
0003 |
TESTEAU |
10FB |
0003 |
TESTTOBJ |
10A1 |
0001 |
TESTULA |
10E7 |
0003 |
MATPG |
0232 |
0002 |
MATBPGM |
02C6 |
0002 |
ACTBPGM |
02CE |
0002 |
RINZSTAT |
02C1 |
0001 |
ACTPG |
0212 |
0002 |
CALLX |
0283 |
0003 |
CALLI |
0293 |
0003 |
CLRIEXIT |
0250 |
0000 |
DEACTPG |
0225 |
0001 |
PEND |
0260 |
0000 |
MODASA |
02F2 |
0002 |
RTX |
02A1 |
0001 |
SETALLEN |
0242 |
0002 |
SETIEXIT |
0252 |
0002 |
STPLLEN |
0241 |
0001 |
XCTL |
0282 |
0002 |
MATACTAT |
0213 |
0003 |
MATAGPAT |
02D3 |
0003 |
MATEXCPD |
03D7 |
0003 |
MODEXCPD |
03EF |
0003 |
RETEXCPD |
03E2 |
0002 |
RTNEXCP |
03E1 |
0001 |
SIGEXCP |
10CA |
0002 |
SNSEXCPD |
03E3 |
0003 |
TESTEXCP |
104A |
0002 |
MATPRATR |
0333 |
0003 |
WAITTIME |
0349 |
0001 |
MATPRAGP |
0331 |
0001 |
DEQ |
1033 |
0003 |
ENQ |
036B |
0003 |
MATQAT |
0336 |
0002 |
MATQMSG |
033B |
0003 |
ENSOBJ |
0381 |
0001 |
MATAGAT |
03A2 |
0002 |
MATRMD |
0352 |
0002 |
SETACST |
0341 |
0001 |
ALCHSS |
03B3 |
0003 |
CRTHS |
03B2 |
0002 |
DESHS |
03B1 |
0001 |
FREHSS |
03B5 |
0001 |
FREHSSMK |
03B9 |
0001 |
MATHSAT |
03B7 |
0003 |
REALCHSS |
03BA |
0002 |
SETHSSMK |
03B6 |
0002 |
MATPRMSG |
039C |
0004 |
LOCK |
03F5 |
0001 |
LOCKSL |
03F6 |
0002 |
MATDRECL |
032E |
0002 |
MATAOL |
03FA |
0002 |
MATOBJLK |
033A |
0002 |
MATPRLK |
0312 |
0002 |
MATPRECL |
031E |
0002 |
MATSELLK |
033E |
0002 |
XFRLOCK |
0382 |
0002 |
UNLOCK |
03F1 |
0001 |
UNLOCKSL |
03F2 |
0002 |
LOCKOL |
03C1 |
0001 |
UNLOCKOL |
03C5 |
0001 |
MATEVTMN |
0379 |
0001 |
INCD |
0404 |
0004 |
DECD |
0414 |
0004 |
INCT |
0434 |
0004 |
DECT |
0444 |
0004 |
INCTS |
040C |
0004 |
DECTS |
042C |
0004 |
CDD |
0424 |
0004 |
CTD |
0454 |
0004 |
CTSD |
043C |
0004 |
CVTD |
040F |
0003 |
CVTT |
041F |
0003 |
CVTTS |
043F |
0003 |
MATCSD |
04E3 |
0003 |
MATCD |
04B3 |
0003 |
MATLUD |
04BB |
0003 |
MATMD |
04E7 |
0003 |
MATND |
04BF |
0003 |
MATNWID |
04B7 |
0003 |
MATCNNL |
040B |
0003 |
MATDMPS |
04DA |
0002 |
MATJPAT |
05A6 |
0002 |
MATJSAT |
05BE |
0002 |
MATJOAT |
05B6 |
0002 |
MATJOBJ |
05A7 |
0003 |
MATCBATR |
05C7 |
0003 |
MATINAT |
0526 |
0002 |
MATINV |
0516 |
0002 |
MATINVE |
0547 |
0003 |
MATINVS |
0546 |
0002 |
MATPTRL |
0513 |
0003 |
MATPTR |
0512 |
0002 |
MATPTRIF |
0517 |
0003 |
MATSOBJ |
053E |
0002 |
MATMDATA |
0522 |
0002 |
FNDRINVN |
0543 |
0003 |
MATINVAT |
0533 |
0003 |
MATMATR |
0636 |
0002 |
YIELD |
0610 |
0000 |
CRTMTX |
03C3 |
0003 |
DESMTX |
03C7 |
0003 |
LOCKMTX |
03D3 |
0003 |
UNLKMTX |
03D6 |
0002 |
Appendix B: Resultant Condition Keywords
Resultant Condition Keywords |
|
Group 1 |
|
|
HI (High) |
|
MXD (Mixed) |
|
NOR (Normalized) |
|
POS (Positive) |
|
TR (Truncated record) |
|
ZC (Zero and carry) |
Group 2 |
|
|
CR (Complete record) |
|
DEN (Denormalized) |
|
IGN (Exception ignored) |
|
LO (Low) |
|
NEG (Negative) |
|
NTZNTC (Not zero and no carry) |
|
RO (Receiver overrun) |
Group 3 |
|
|
AUTH (Authorized) |
|
DFR (Exception postponed) |
|
DQ (Dequeued) |
|
EQ (Equal) |
|
INF (Infinity) |
|
SE (Source all used) |
|
SGN (Signaled) |
|
ZER (Zero) |
|
ZNTC (Zero and no carry) |
Group 4 |
|
|
EC (Escape code encountered) |
|
NAN (Not a number ) |
|
NTZC (Not-zero and carry) |
|
UNEQ (Unequal) |
|
UNOR (Unordered) |
as/400, os/400, iseries, system i, i5/os, ibm i, power systems, 6.1, 7.1, V7, V6R1
LATEST COMMENTS
MC Press Online