An opcode, or operation code, is the word that names what an RPG statement does, such as CHAIN, IF or EVAL. This page is an index: find the operation by task, see how it is written in free-form RPGLE, and see which fixed-format opcodes it replaced when you meet them in older code.
It does not teach file input and output or program logic. For the syntax and behaviour of if, select, the loops, leave, iter, return and monitor, see the RPGLE Control-Flow Opcodes Reference. For how calculation specifications and logic blocks work, read RPGLE Calculation Specs and Logic Blocks. If you are new to the language, start with RPGLE for Beginners. For functions that start with a percent sign, use the RPGLE Built-in Functions Reference.
How to read this page
Free-form statements end with a semicolon. A free-form operation is written as the opcode name followed by its operands, with no column rules. Where an operation has an extender such as (e) for error handling, it is written in parentheses after the opcode.
Assignment and arithmetic
| Task | Free-form | Fixed-format opcodes replaced |
|---|---|---|
| Assign a value | result = expression; | EVAL, Z-ADD, Z-SUB, MOVE, MOVEL |
| Add | total = total + amount; or total += amount; | ADD |
| Subtract | total -= amount; | SUB |
| Multiply | total *= rate; | MULT |
| Divide | result = a / b; | DIV |
| Remainder | rest = %rem(a : b); | MVR |
| Square root | root = %sqrt(value); | SQRT |
Control flow
| Task | Free-form | Notes |
|---|---|---|
| Choose between two branches | if condition; ... elseif condition; ... else; ... endif; | Replaces IFxx, ELSE, ENDIF |
| Choose between many branches | select; when condition; ... other; ... endsl; | Replaces SELECT, WHEN, OTHER, ENDSL |
| Loop while a condition is true | dow condition; ... enddo; | Tests before each pass |
| Loop until a condition is true | dou condition; ... enddo; | Tests after each pass, so it runs at least once |
| Counted loop | for i = 1 to 10; ... endfor; | Replaces DO with a counter |
| Skip to the next pass | iter; | Inside a loop |
| Leave a loop | leave; | Inside a loop |
| Leave a subroutine | leavesr; | Inside a subroutine |
| Catch run-time errors | monitor; ... on-error; ... endmon; | Replaces many error indicators |
dcl-s i int(10);
dcl-s sum int(10);
for i = 1 to 5;
sum += i;
endfor; // sum is 15
File input and output
| Task | Free-form | Fixed-format opcodes |
|---|---|---|
| Read one record by key | chain key file; | CHAIN |
| Position before a key | setll key file; | SETLL |
| Position after a key | setgt key file; | SETGT |
| Read the next record | read file; | READ |
| Read the previous record | readp file; | READP |
| Read the next record with an equal key | reade key file; | READE |
| Add a record | write recordFormat; | WRITE |
| Change the last record read | update recordFormat; | UPDATE |
| Remove a record | delete key file; | DELETE |
After an I/O operation, test the result with %found or %eof instead of a result indicator. The operations that can fail on a missing record accept the (e) extender, then you test %error. The RPGLE File I/O Opcodes Reference gives the syntax of each file operation, and the RPGLE File and Error BIFs Reference explains what %found, %eof and %error report. Positioning, reading and changing records have their own pages: the RPGLE SETLL and SETGT Opcode Reference, the RPGLE READ, READE and READP Opcode Reference and the RPGLE UPDATE, WRITE and DELETE Opcode Reference. File behaviour is covered by lessons in the RPGLE series, not here.
Calls and procedures
| Task | Free-form | Fixed-format opcodes |
|---|---|---|
| Call a procedure | procName(parm1 : parm2); | CALLP |
| Call a program | callPgm(parm1 : parm2); through a prototype | CALL, PARM, PLIST |
| Return from a procedure | return value; | RETURN |
Strings, dates and arrays
Many string, date and array opcodes were replaced by built-in functions.
| Fixed-format opcode | Free-form equivalent |
|---|---|
SCAN | %scan |
SUBST | %subst |
CAT | + operator, usually with %trim |
CHECK, CHECKR | %check, %checkr |
XLATE | %xlate |
ADDDUR, SUBDUR | + or - with a duration, %diff |
EXTRCT | %subdt |
LOOKUP | %lookup |
Details are in the RPGLE String BIFs Reference and the RPGLE Date and Time BIFs Reference.
Operation extenders
An extender in parentheses after the opcode changes how the operation behaves. The most common ones are below.
| Extender | Meaning | Used with |
|---|---|---|
(e) | Handle an error yourself. The operation does not stop the program, and %error tells you whether it failed | File I/O, CALLP, some other operations |
(n) | Read without locking the record | CHAIN, READ, READE, READP |
(h) | Half-adjust (round) the result | Arithmetic and EVAL |
(p) | Pad the result with blanks | String operations such as SUBST and CAT |
chain(e) custKey custFile;
if %error();
// the read failed for a reason other than "not found"
elseif not %found(custFile);
// no record with that key
endif;
Choosing between DOW and DOU
dow tests before the first pass, so the loop body may never run. dou tests after each pass, so the body always runs at least once.
dcl-s attempts int(10) inz(0);
dcl-s ok ind inz(*off);
dou ok or attempts >= 3;
attempts += 1;
ok = tryOnce(); // tryOnce is a procedure that returns an indicator
enddo;
Output and diagnostics
| Task | Free-form |
|---|---|
| Show a message to the user | dsply message; |
| Sort an array | sorta array; |
| Dump program storage for debugging | dump; |
Choosing a file-read opcode
The file operations look alike but answer different questions. Pick by what you know about the record you want.
- Use
chainwhen you have a full key and want one record. It positions and reads in one step, and%foundtells you whether the record exists. The RPGLE CHAIN Opcode Reference covers its key forms and locks. - Use
setllthenreadewhen you want every record that has a given key.setllpositions the file at the first record with that key, andreadereads the next record only while the key still matches. - Use
readto process a file from the current position to the end, testing%eofafter each read. - Use
setgtwhen you want to start after the last record for a key, for example to find the next key value.
setll custKey orderFile;
reade custKey orderFile;
dow not %eof(orderFile);
// process one order for this customer
reade custKey orderFile;
enddo;
This pattern reads each record once and ends cleanly when the key changes or the file ends. Lessons in the RPGLE series cover file behaviour in more depth.
How free-form statements differ
In fixed format, an operation is placed in fixed columns: the opcode in one column range, the operands in others, and a result field and indicators in more. In free-form, an operation reads like a sentence: the opcode, then its operands, then a semicolon.
Three practical differences matter when you convert code. First, many opcodes disappear because an expression does the same job, so ADD, SUB, MULT and DIV become +, -, * and /. Second, result indicators give way to functions such as %found, %eof and %error, which say what happened by name. Third, a few opcodes keep their names and only change layout, such as CHAIN, READ, WRITE and SETLL.
When you read old code, translate it one operation at a time and keep the logic the same. The Fixed-Format to Free-Format Opcode Mapping shows each fixed-format line next to its free-form replacement. Do not combine operations while converting. Combine them afterwards, once the program passes its tests.
Common mistakes
- Converting
MOVELto=without checking field lengths. - Using a result indicator when
%found,%eofor%errorwould say what happened. - Choosing
DOWwhen the loop must run at least once. UseDOU. - Looking for a function with a percent sign in this table. Those are in the BIF references.
FAQ
What is an opcode in RPGLE?
The keyword that names an operation, such as CHAIN, IF or EVAL. In fixed format it sits in a fixed column. In free format it is the first word of the statement.
Do the old fixed-format opcodes still work?
Yes. They still compile. In free-form code, use the expression or BIF form instead.
Which opcodes should I stop using?
MOVE, MOVEL, Z-ADD, Z-SUB and the arithmetic opcodes have clearer free-form forms. Replace them when you change the code around them.
Summary
- Learn how calculation specifications and logic blocks fit together in RPGLE Calculation Specs and Logic Blocks.
- Use the RPGLE Built-in Functions Reference for the functions that replaced many opcodes.
- Read RPGLE Fixed, Free and Fully Free Specifications to see why free-form is the default for new code.