Introduction
Opcodes are written in octal, as the PDP-11 handbooks do: SS is a six-bit source operand field, DD a six-bit destination field
(addressing modes), R a register number, NN an offset or number. Bit 15 of the double-operand and most
single-operand opcodes selects the byte form (MOVB, CLRB and so on), which shares its row with the word form.
The four columns N Z V C show the effect on the condition codes: * set from the result, 0 cleared, 1 set, - not changed, L loaded from the stack or a vector.
The Model column names the feature group (the models page says which models have it); base is on every model. No cycle counts are given: they differ for every model.
Double-operand instructions
| Instruction | Opcode | N Z V C | Model | Effect |
|---|---|---|---|---|
mov src,dstmovb src,dst | 01SSDD11SSDD | * * 0 - | base | dst = src. MOVB to a register sign-extends the byte into the whole register; to memory only the byte is stored. |
cmp src,dstcmpb src,dst | 02SSDD12SSDD | * * * * | base | Computes src − dst, sets the codes, stores nothing. Note the order: the destination is subtracted from the source. After it, BEQ is “equal”, and the signed and unsigned branches compare src with dst. |
bit src,dstbitb src,dst | 03SSDD13SSDD | * * 0 - | base | Tests src AND dst, sets the codes, stores nothing. |
bic src,dstbicb src,dst | 04SSDD14SSDD | * * 0 - | base | Bit clear: dst = dst AND NOT src. |
bis src,dstbisb src,dst | 05SSDD15SSDD | * * 0 - | base | Bit set: dst = dst OR src. |
add src,dst | 06SSDD | * * * * | base | dst = dst + src. V is set when two operands of the same sign give a result of the other sign; C is the carry out of bit 15. There is no byte form: bit 15 selects sub. |
sub src,dst | 16SSDD | * * * * | base | dst = dst − src. V is set on signed overflow; C is set when there was a borrow. |
Single-operand instructions
| Instruction | Opcode | N Z V C | Model | Effect |
|---|---|---|---|---|
clr dstclrb dst | 0050DD1050DD | 0 1 0 0 | base | dst = 0. |
com dstcomb dst | 0051DD1051DD | * * 0 1 | base | dst = NOT dst (ones complement). |
inc dstincb dst | 0052DD1052DD | * * * - | base | dst = dst + 1. V is set when dst was the largest positive number. C is not changed. |
dec dstdecb dst | 0053DD1053DD | * * * - | base | dst = dst − 1. V is set when dst was the largest negative number. C is not changed. |
neg dstnegb dst | 0054DD1054DD | * * * * | base | dst = −dst (twos complement). C is cleared only when the result is 0. |
adc dstadcb dst | 0055DD1055DD | * * * * | base | dst = dst + C: the multiple-precision add of the carry. |
sbc dstsbcb dst | 0056DD1056DD | * * * * | base | dst = dst − C. |
tst dsttstb dst | 0057DD1057DD | * * 0 0 | base | Sets N and Z from dst; nothing is stored. |
swab dst | 0003DD | * * 0 0 | base | Swaps the two bytes of dst. N and Z reflect the new low byte. |
sxt dst | 0067DD | - * 0 - | ltd | Sign extend: dst = −1 if N is set, 0 if it is clear (Z is set when N is clear). Used with the multiple-precision ash, div and compares. |
Shifts and rotates
| Instruction | Opcode | N Z V C | Model | Effect |
|---|---|---|---|---|
ror dstrorb dst | 0060DD1060DD | * * * * | base | Rotate right through C: C goes into the top bit, the low bit into C. V = N xor C. |
rol dstrolb dst | 0061DD1061DD | * * * * | base | Rotate left through C. |
asr dstasrb dst | 0062DD1062DD | * * * * | base | Arithmetic shift right by one (the sign is kept); the low bit goes to C. |
asl dstaslb dst | 0063DD1063DD | * * * * | base | Shift left by one; the top bit goes to C. V is set if the sign changed. |
The shifts by more than one are ASH and ASHC of the extended instruction set.
Branches
A branch is one word: the opcode in the high byte and a signed 8-bit offset, counted in words, in the low byte. The target is the address after the branch plus twice the offset, so a branch reaches 128 words back to 127 words forward. The disassembler shows the target address. A longer jump is JMP.
| Instruction | Opcode | N Z V C | Model | Branches if |
|---|---|---|---|---|
br addr | 000400 + offset | - - - - | base | always |
bne addr | 001000 + offset | - - - - | base | not equal: Z = 0 |
beq addr | 001400 + offset | - - - - | base | equal: Z = 1 |
bge addr | 002000 + offset | - - - - | base | signed greater or equal: N xor V = 0 |
blt addr | 002400 + offset | - - - - | base | signed less: N xor V = 1 |
bgt addr | 003000 + offset | - - - - | base | signed greater: Z or (N xor V) = 0 |
ble addr | 003400 + offset | - - - - | base | signed less or equal: Z or (N xor V) = 1 |
bpl addr | 100000 + offset | - - - - | base | plus: N = 0 |
bmi addr | 100400 + offset | - - - - | base | minus: N = 1 |
bhi addr | 101000 + offset | - - - - | base | unsigned higher: C = 0 and Z = 0 |
blos addr | 101400 + offset | - - - - | base | unsigned lower or the same: C or Z = 1 |
bvc addr | 102000 + offset | - - - - | base | overflow clear: V = 0 |
bvs addr | 102400 + offset | - - - - | base | overflow set: V = 1 |
bcc addr (also bhis) | 103000 + offset | - - - - | base | carry clear: C = 0 (unsigned higher or the same) |
bcs addr (also blo) | 103400 + offset | - - - - | base | carry set: C = 1 (unsigned lower) |
sob r,addr | 077RNN | - - - - | ltd | R = R − 1, then branches back if R is not zero. NN is a 6-bit count of words backwards: the target is the address after the SOB minus twice NN. The condition codes are not changed. |
In the UNIX assembler the carry branches are also called bec and bes (“error clear/set”, the way system calls report an error in C), and the long forms jbr, jeq and so on are pseudo-instructions that expand to a branch or to a branch over a JMP.
Jumps and subroutines
| Instruction | Opcode | N Z V C | Model | Effect |
|---|---|---|---|---|
jmp dst | 0001DD | - - - - | base | PC = the address of the operand (not its contents). jmp @#addr and jmp addr jump to a fixed place; jmp (r1) to the address in R1; jmp @(r1)+ through a table. Mode 0 (a register) has no address: the instruction traps through vector 4. |
jsr r,dst | 004RDD | - - - - | base | Jump to subroutine: push R, then R = PC (the return address), then PC = the address of the operand. With pc as R it is the plain call, jsr pc,addr; with another register the register carries the return address and may point at arguments after the call. Mode 0 traps through vector 4. |
rts r | 00020R | - - - - | base | Return: PC = R, then R is popped from the stack. rts pc is the plain return. With another register it returns through that register (the pair of jsr r5,…). |
mark nn | 0064NN | - - - - | ltd | Return from a subroutine that was passed NN words of arguments on the stack: SP = PC + 2·NN, PC = R5, R5 is popped. It is executed from the stack: a routine puts a MARK word on its own stack and returns to it. |
Traps and interrupts
| Instruction | Opcode | N Z V C | Model | Effect |
|---|---|---|---|---|
emt nn | 104000 + NN | L L L L | base | Emulator trap through vector 30: pushes PSW and PC and loads the new ones. RT-11 uses it for system calls: the number NN is the request code (emt 374 and emt 375 take a block of arguments in R0). |
trap nn (UNIX: sys nn) | 104400 + NN | L L L L | base | Trap through vector 34. UNIX uses it for system calls: NN is the call number; arguments are in registers or in the words that follow the instruction (see the a.out pages). |
bpt | 000003 | L L L L | base | Breakpoint trap through vector 14 (debuggers). |
iot | 000004 | L L L L | base | I/O trap through vector 20. |
rti | 000002 | L L L L | base | Return from interrupt or trap: pop PC, then pop PSW. |
rtt | 000006 | L L L L | ltd | As RTI, except that a pending trace trap is not taken after it: debuggers use it so a trace does not trap at once on its own return. |
Condition codes and no-operation
One word with the bits 3–0 selecting N, Z, V and C and bit 4 saying clear (0) or set (1): the range 000240 to 000277. They can be combined in one word.
| Instruction | Opcode | N Z V C | Model | Effect |
|---|---|---|---|---|
nop | 000240 | - - - - | base | No operation (000260, set with no bits, does the same). |
clc clv clz cln | 000241 000242 000244 000250 | the named one cleared | base | Clear carry, overflow, zero, negative. |
sec sev sez sen | 000261 000262 000264 000270 | the named one set | base | Set carry, overflow, zero, negative. |
ccc, scc | 000257, 000277 | all cleared, all set | base | Clear or set all four. Other combinations are written clc!clv in MACRO-11 (the disassembler writes them in the order N Z V C). |
The explorer’s anchor #cc for these opcodes is this section.
Processor control
| Instruction | Opcode | N Z V C | Model | Effect |
|---|---|---|---|---|
halt | 000000 | - - - - | base | Stops the processor (kernel mode). In user mode it traps through vector 4. |
wait | 000001 | - - - - | base | Waits for an interrupt: the processor idles until a device interrupts. |
reset | 000005 | - - - - | base | Resets the bus and every device (kernel mode only; a no-operation in user mode). |
spl n | 00023N | - - - - | spl | Sets the processor priority (PSW bits 7–5) to N, 0 to 7 (kernel mode only). The next instruction runs before an interrupt can be taken. |
mfpt | 000007 | - - - - | mfpt | Move from processor type: puts a code for the processor model in R0. The codes are not listed here. |
The extended instruction set
Register first or second, always as in MACRO-11. In the UNIX assembler these are also called mpy (mul), dvd, als and alsc.
| Instruction | Opcode | N Z V C | Model | Effect |
|---|---|---|---|---|
mul src,r | 070RSS | * * 0 * | eis | R:R+1 = R × src, a signed 32-bit product (R should be even: with an odd R only the low 16 bits are stored). C is set when the product does not fit in 16 bits. |
div src,r | 071RSS | * * * * | eis | The signed 32-bit R:R+1 divided by src: the quotient goes to R, the remainder to R+1. R must be even. V is set (and the registers are left alone) when the quotient does not fit in 16 bits or the divisor is zero; C is set on a zero divisor. |
ash src,r | 072RSS | * * * * | eis | Shifts R by the signed 6-bit count in the low bits of src: positive left, negative right (arithmetic). C is the last bit shifted out; V is set if the sign changed at any step. |
ashc src,r | 073RSS | * * * * | eis | The same on the 32-bit R:R+1. |
xor r,dst | 074RDD | * * 0 - | ltd | dst = dst XOR R. (There is no XOR of two memory operands.) Part of the “limited” set with MARK, RTT, SOB and SXT: it does not need the MUL group. |
Previous-space moves and later models
On the models with memory management, the processor keeps a current and a previous mode in the PSW. The four instructions MFPI, MTPI, MFPD and MTPD move a word between the previous mode’s address space and the current stack: how an operating system reaches the user’s memory and stack. MFPS, MTPS, CSM, TSTSET and WRTLCK belong to the later models (the 11/44, the LSI-11, F-11, T-11 and J-11 families).
| Instruction | Opcode | N Z V C | Model | Effect |
|---|---|---|---|---|
mfpi src | 0065SS | * * 0 - | mfpi | Pushes the word at src, taken from the previous mode’s instruction space, on the current stack. With a register as src it pushes that register of the previous mode. |
mtpi dst | 0066DD | * * 0 - | mfpi | Pops a word and stores it at dst in the previous mode’s instruction space. |
mfpd src | 1065SS | * * 0 - | mfpd | As MFPI but from the previous mode’s data space (separate instruction and data space: 11/45, 11/70 and later). |
mtpd dst | 1066DD | * * 0 - | mfpd | As MTPI but into the previous mode’s data space. |
mfps dst | 1067DD | * * 0 - | mxps | Move from processor status: the low byte of the PSW (priority, T, condition codes) to dst. The models that do not map the PSW in memory have it; the 11/70 does not. |
mtps src | 1064SS | L L L L | mxps | Move to processor status: loads the low byte of the PSW from src. |
csm dst | 0070DD | - - - - | csm | Call to supervisor mode: a call gate for supervisor-mode code (11/44, J-11). The flags and the precise effect were not sourced. |
tstset dst | 0072DD | ? ? ? ? | multiproc | Test and set, interlocked for multiprocessor systems (J-11). Its flags and effect were not sourced beyond the name. |
wrtlck dst | 0073DD | ? ? ? ? | multiproc | Write and lock, interlocked (J-11). Not sourced beyond the name. |
Not described
Known, not yet covered
- Cycle counts and the precise order of bus cycles for every model; the effect of an instruction on a trap during its operand fetch.
- The commercial instruction set (CIS): the words 076000–076777 are shown as reserved.
Unknown
- The flags and exact effect of CSM, TSTSET and WRTLCK; the codes MFPT returns.
- The behaviour of the reserved words on real models.
Links
Reference
- PDP-11 instruction set – mdfs.net
- PDP-11 architecture – Wikipedia
- UNIX Assembler Reference Manual – the UNIX spellings (
sys,bec,jbr,mpy)