MC Press Online

Saturday, Mar 25th

Last updateFri, 17 Mar 2017 12pm

You are here: Home ARTICLES Programming RPG Analyzing the MI Instruction Stream of an OPM Program

Programming / RPG

Analyzing the MI Instruction Stream of an OPM Program

Support MC Press - Visit Our Sponsors

NEW BOOK!

Evolve Your RPG Coding: Move from OPM to ILE ... and Beyond


ORDER YOUR COPY

*******************

Click for this Month's

Bookstore Special Deals

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

Junlei Li

Junlei Li is a programmer from Tianjin, China, with 10 years of experience in software design and programming. Junlei Li began programming under i5/OS (formerly known as AS/400, iSeries) in late 2005. He is familiar with most programming languages available on i5/OS—from special-purpose languages such as OPM/ILE RPG to CL to general-purpose languages such as C, C++, Java; from strong-typed languages to script languages such as QShell and REXX. One of his favorite programming languages on i5/OS is machine interface (MI) instructions, through which one can discover some of the internal behaviors of i5/OS and some of the highlights of i5/OS in terms of operating system design.

 

Junlei Li's Web site is http://i5toolkit.sourceforge.net/, where his open-source project i5/OS Programmer's Toolkit (https://sourceforge.net/projects/i5toolkit/) is documented.

BLOG COMMENTS POWERED BY DISQUS