Appendix 1. Dragon Instruction Set
m = memory word, r = execution unit stack register, a = auxiliary register, c = constants register, S = stack pointer, L = local base pointer, PC = program counter, Procr = processor register, ProcBus = processor bus, FieldDesc = field unit descriptor, FieldOp = field operation FP = floating point (ALU and MULT), fpA = A-FP-operand, fpALen = length of fpA skip, carry, resultCarry, status, IFUStack are self-explanatory, [,] = pair, . = concatenation, ! = Trap
m, n = unsigned halfbyte, B = unsigned byte, b = signed byte, H = unsigned halfword, h = signed halfword, W = unsigned word, x, y, z = register (aux, local, const or top of stack), s = r[S] or r[S-1],
OI[op:[0..255]] OB[op,lit:[0..255]] ODB[op,lit:CARDINAL] OQB[op,lit:LONG CARDINAL]
LR[op:[0..255]] LRB[op:[0..255],disp:[0..255]] LRRB[op,disp:[0..255],reg1,reg2:[0..15]]
RR[op:[0..255],cOpt,aOpt,bOpt,aux:[0..1],c,a,b:[0..15]]
QR[op:[0..255],bOpt,aux:[0..1],b:[0..15]] JBB[op:[0..255],dist:[-128..127],lit:[0..255]]
RJB[op:[0..255],sdd,sd,opt,aux:[0..1],reg:[0..15],dist:[-128..127]]
(opt,aux,reg) = (0,0,Loc) (0,1,a)
in: (1,*,0-11):c (1,*,12/14):r[S]dS=0/-1 (1,*,13/15):r[S-1]dS=0/-1
out: (1,*,0-11):c (1,*,12):r[S] (1,*,13):r[S-1] (1,*,14/15):r[S+1]dS=0/1)
sdd: 0/1:dS=0/-1 sd: 0/1:r[S]/r[S-1]
Loads
222B OB(2) LIB B r[S+1] ← B; S ← S+1
322B ODB(3) LIDB H r[S+1] ← H; S ← S+1
062B OQB(5) LIQB W r[S+1] ← W; S ← S+1
110B OI(1) DUP r[S+1] ← r[S]; S ← S+1
140B+n LR(1) LR n r[S+1] ← r[L+n]; S ← S+1
130B+n OI(1) LC n r[S+1] ← c[n]; S ← S+1
230B OB(2) RB B r[S] ← m[r[S]+B]
334B OB(2) IN B r[S] ← m[r[S]+B] (bypassing cache)
202B QR(2) QRX y r[S] ← m[r[S]+y]
232B OB(2) RSB B r[S+1] ← m[r[S]+B]; S ← S+1
240B+n LRB(2) LRI n B r[S+1] ← m[r[L+n]+B]; S ← S+1
102B OI(1) RX r[S-1] ← m[r[S-1]+r[S]]; S ← S-1
320B ODB(3) LGF H r[S+1] ← m[a[0]+H]; S ← S+1
220B OB(2) LIP B r[S+1] ← Procr[B]; S ← S+1
234B OB(2) PIN B r[S] ← ProcBus[B, r[S]]
Stores
111B OI(1) DIS S ← S-1
113B OI(1) EXDIS r[S-1] ← r[S]; S ← S-1
160B+n LR(1) SR n r[L+n] ← r[S]; S ← S-1
231B OB(2) WB B m[r[S]+B] ← r[S-1]; S ← S-2
335B OB(2) OUT B m[r[S]+B] ← r[S-1]; S ← S-2 (bypassing cache)
233B OB(2) WSB B m[r[S-1]+B] ← r[S]; S ← S-2
237B OB(2) PSB B m[r[S-1]+B] ← r[S]; S ← S-1
260B+n LRB(2) SRI n B m[r[L+n]+B] ← r[S]; S ← S-1
221B OB(2) SIP B Procr[B] ← r[S]; S ← S-1
235B OB(2) POUT B ProcBus[B] ← r[S]
Moves
112B OI(1) EXCH [ r[S-1], r[S] ] <=> [ r[S], r[S-1] ]
330B LRRB(3) RAI B m n r[L+m] ← m[a[n]+B]
332B LRRB(3) RRI B m n r[L+m] ← m[r[L+n]+B]
331B LRRB(3) WAI B m n m[a[n]+B] ← r[L+m]
333B LRRB(3) WRI B m n m[r[L+n]+B] ← r[L+m]
302B RR(3) RRX z x y z ← m[x+y]
Field operations
373B ODB(3) FSDB H FieldDesc ← r[S] + H; S ← S-1
370B ODB(3) SHL H r[S] ← FieldOp[r[S], 0, H]
371B ODB(3) SHR H r[S] ← FieldOp[r[S], r[S], H]
372B ODB(3) SHD H r[S-1] ← FieldOp[r[S-1], r[S], H]; S ← S-1
312B RR(3) RFU z x y z ← FieldOp[x, y, FieldDesc]
Logic operations
301B RR(3) RAND z x y z ← x AND y
201B QR(2) QAND y r[S] ← r[S] AND y
300B RR(3) ROR z x y z ← x OR y
200B QR(2) QOR y r[S] ← r[S] OR y
310B RR(3) RXOR z x y z ← x XOR y
? QR(2) QXOR y r[S] ← r[S] XOR y
Arithmetic operations
211B OB(2) AL B L ← L + B
210B OB(2) ALS B L ← S + B
213B OB(2) AS B S ← S + B
212B OB(2) ASL B S ← L + B
304B RR(3) RADD z x y z ← x + y + carry; carry ← 0 (! int ov)
204B QR(2) QADD y r[S] ← r[S] + y + carry; carry ← 0 (! int ov)
104B OI(1) ADD r[S-1] ← r[S-1] + r[S] + carry; carry ← 0; S ← S-1 (! int ov)
224B OB(2) ADDB B r[S] ← r[S] + B + carry; carry ← 0 (! int ov)
324B ODB(3) ADDDB H r[S] ← r[S] + H + carry; carry ← 0 (! int ov)
316B RR(3) RUADD z x y z ← x + y + carry; carry ← resultCarry (no !)
314B RR(3) RVADD z x y z ← x + y (no !)
306B RR(3) RLADD z x y z ← x + y; carry ← 0 (Lisp Add)
206B QR(2) QLADD y r[S] ← r[S] + y; carry ← 0 (Lisp Add)
106B OI(1) LADD r[S-1] ← r[S-1] + r[S]; carry ← 0; S ← S-1 (Lisp Add)
305B RR(3) RSUB z x y z ← x - y - carry; carry ← 0 (! int ov)
205B QR(2) QSUB y r[S] ← r[S] - y - carry; carry ← 0 (! int ov)
105B OI(1) SUB r[S-1] ← r[S-1] - r[S] - carry; carry ← 0; S ← S-1 (! int ov)
225B OB(2) SUBB B r[S] ← r[S] - B - carry; carry ← 0 (! int ov)
325B ODB(3) SUBDB H r[S] ← r[S] - H - carry; carry ← 0 (! int ov)
317B RR(3) RUSUB z x y z ← x - y - carry; carry ← resultCarry (no !)
315B RR(3) RVSUB z x y z ← x - y (no !)
307B RR(3) RLSUB z x y z ← x - y; carry ← 0 (Lisp Subtract)
207B QR(2) QLSUB y r[S] ← r[S] - y; carry ← 0 (Lisp Subtract)
107B OI(1) LSUB r[S-1] ← r[S-1] - r[S]; carry ← 0; S ← S-1 (Lisp Subtract)
121B OI(1) SMUL r[S-1].r[S] ← r[S-1] * r[S]
122B OI(1) UDIV [ r[S-2], r[S-1] ] ← r[S-2].r[S-1] DIV, MOD r[S]; S ← S-1
223B OB(2) SFP B set FP-status or FP-operand fpA depending on control bits B;
S ← S-fpALen
374B ODB(3) FLIP H fpA ← fpA op (r[S-1].)r[S] (op, type and length spex in H)
375B ODB(3) FLOP H r[S] ← fpA op (r[S-1].)r[S] (op, type and length spex in H)
Jumps/Checks (j = jump predicted)
126B OI(1) J1 skip
226B OB(2) J2 B skip
326B ODB(3) J3 H skip
066B OQB(5) J5 W skip
227B OB(2) JB b PC ← PC + b
327B ODB(3) JDB h PC ← PC + h
067B OQB(5) DJ W PC ← W
127B OI(1) SJ PC ← PC + r[S]; S ← S-1
341B(355B) RJB(3) RJEB(j) s y b IF s = y THEN PC ← PC + b
345B(351B) RJB(3) RJNEB(j) s y b IF s # y THEN PC ← PC + b
347B(353B) RJB(3) RJGB(j) s y b IF s > y THEN PC ← PC + b
346B(352B) RJB(3) RJGEB(j) s y b IF s >= y THEN PC ← PC + b
342B(356B) RJB(3) RJLB(j) s y b IF s < y THEN PC ← PC + b
343B(357B) RJB(3) RJLEB(j) s y b IF s <= y THEN PC ← PC + b
360B(362B) JBB(3) JEBB(j) b B IF r[S] = B THEN PC ← PC + b; S ← S-1
361B(363B) JBB(3) JNEBB(j) b B IF r[S] # B THEN PC ← PC + b; S ← S-1
103B OI(1) BC IF NOT (0<= r[S-1]< r[S]) THEN !; S ← S-1
303B RR(3) RBC z x y IF NOT (0<= x< y) THEN !; z ← x
203B QR(2) QBC y IF NOT 0<= r[S]< y THEN !
214B OB(2) CST B r[S+1] ← m[Loc[S-2]+B];
IF r[S+1]= r[S] THEN m[r[S-2]+B] ← r[S-1]; S ← S+1
Procedure calls/Returns
321B ODB(3) LFC h call proc: PC ← PC + h
061B OQB(5) DFC W call proc: PC ← W
114B OI(1) SFC call proc: IFUStack ← [PC, L]; PC ← r[S]; S ← S-1
115B OI(1) SFCI call proc: IFUStack ← [PC, L]; PC ← m[r[S]]
124B OI(1) KFC r[S+1] ← status; S ← S+1; set kernel mode; !
116B OI(1) RETN return via [PC, L] from IFUStack
216B OB(2) RET B return via [PC, L] from IFUStack; S ← L + B
217B OB(2) RETK B status ← r[S]; return via [PC, L] from IFUStack; S ← L + B