Instruction Set
One of the more interesting things about the System/3 was its instruction set. This was optimised for two key aspects of the product: limited availability of main memory, and the RPG programming language.
The original S/3 (models 10 and then 6, 8 & 12) had 29 instructions, all occupying between 2 and 6 bytes (16 to 48 bits). The first 4 bits conveyed a lot of information: "1111" meant this was an instruction without operands, known as a command. e.g. Start I/O (the I/O op being defined by previously loaded I/O registers). "11xx" and "xx11" meant a 1-operand instruction, such as a Branch. If xx was 00 the operand was addressed by its full 16-bit address. xx=01 or 10 meant base-displacement addressing was used, using index register 1 or 2 respectively. A base address would previously have been loaded into one of the two index registers and the instruction contained the displacement of up to just 256 bytes (8 bits of addressing).
Other patterns for this first half-byte indicated a 2-operand instruction. "0000" meant both operands were addressed by their direct 16-bit address. "0100": operand 1 uses reg 1 as its base; operand 2 uses direct addressing. "0110": operand 1 uses reg 1 as its base, operand 2 uses reg 2. And so on.
The remaining 4 bits of the first byte further defined the instruction. This structure meant that there was the capability to have up to 64 operations in all: 16 commands (though there were never more than five across the whole product range); 16 1-operand instructions starting with 11xx; 16 1-operand instructions starting with xx11; 16 2-operand instructions.
As well as the two index registers already mentioned (referred to as 1 and 2, or binary 01 and 10) there were other registers. "Reg 4" (0100) was the instruction address register (IAR) which pointed at the current instruction. "Reg 8" (1000) was the address recall register (ARR), set by certain instructions. Among these was the conditional branch (mnemonic BC) which used it to point to the byte immediately following the branch operation. For IBM mainframe folks this means that the S/3 branch could be likened to a conditional BALR (branch and link register). Very useful when branching to a sub-routine, and returning after it had processed. Finally, "Reg 16" (00010000) was the program status register (PSR), holding such things as the results of a compare instruction. Note that registers were used only for addressing and program status, not for arithmetic.
The arithmetic instructions provided among the 29 instructions were binary add/subtract (provided to help manipulate addresses) and decimal add/subtract. Multiplication and division were not provided for by the standard hardware, and had to be handled by software routines. There was no floating point provision at all. All this continued to be true even with the later and generally more sophisticated Systems/34 and 36.
All the above got more complicated with the System/3 model 15, and the Systems/34 and 36. Though still using 16-bit addressing, all these systems could support well over 64K of main storage (up to 512K and theoretically more), so address translation was used to swap from one 64K address space to another. Address Translation Registers were set to define the actual address space in use at any one time, their contents being concatenated with the 16-bit address used by a program to produce a real address. These "ATRs" were privileged, available only to the operating system.
As an aside, the original S/3 model 10 (and the later model 12) had an optional crude form of multi-programming called the Dual Program Feature. This provided no more main memory addressing, but gave two sets of registers and instructions which flipped from one "program level" to the other. The standard I/O instructions were also modified to flip when an I/O was started. It was possible to manipulate the other program level's instruction address register, so you could play tricks on the machine.
So far, only the first byte of the instruction has been explained here. The next ("Q") byte was generally a qualifier, such as specifying the number of bytes to be moved in a move characters op or the condition to test for in a Branch. A couple of instructions used this byte for a 1-byte "immediate" operand. The remaining byte(s) were for the displacement(s) or address(es) for operands, or the details for some commands.
Here's an example to show all this at work: a simple command, Conditional Jump, a special type of conditional branch (forward only, up to 256 bytes) suitable mainly for jumping over short blocks of code: Op code byte= F2 (this is in hexadecimal, Hex F is binary 1111, Hex 2 (0010) defines the op); Q byte= 00000001 specifies that we "jump" if the condition register has the "equal" bit on; Operand= 00011000: if the condition is met we jump forward 24 bytes.
As previously stated, this instruction set was optimised for two aspects of the System/3 family. The first was the small amount of memory available, the second was the RPG programming language. Those who know anything about early RPG will know about indicators—binary switches used to control program flow. Over 100 of these were available to the programmer and they were well used. (Less so in more recent practice). By using the instruction formats explained above, many of the indicator-oriented operations could be fit into just 3 bytes. For example... a line of RPG might test an indicator for "On": 3 bytes for a "Test Bits On" op; then 3 bytes for a Jump, as previously described, and useful to the RPG compiler. Saving the odd byte here and there was good when you had only 64K to play with—and, on the S/3 itself, that had to include the operating system (which grew to about 20K on the model 10 with the introduction of the "Communication Control Program", CCP).
Read more about this topic: IBM System/3
Famous quotes containing the words instruction and/or set:
“Much of the pressure contemporary parents feel with respect to dressing children in designer clothes, teaching young children academics, and giving them instruction in sports derives directly from our need to use our children to impress others with our economic surplus. We find good rather than real reasons for letting our children go along with the crowd.”
—David Elkind (20th century)
“For freedom Christ has set us free. Stand firm, therefore, and do not submit again to a yoke of slavery.”
—Bible: New Testament, Galatians 5:1.