RESIOps.mesa
Last Edited by: Sweet, March 7, 1985 9:39:33 am PST
DIRECTORY
Basics,
RESInterpreter,
PrincOps;
RESIOps: CEDAR PROGRAM IMPORTS Basics, RI: RESInterpreter EXPORTS RESInterpreter = {
OPEN PrincOps;
Types and Global Data
Value: TYPE = RI.Value;
DValue: TYPE = RI.DValue;
Ptr1: TYPE = RI.Ptr1;
Ptr2: TYPE = RI.Ptr2;
LPtr1: TYPE = RI.LPtr1;
LPtr2: TYPE = RI.LPtr2;
LCB: TYPE = RI.LCB;
Machine: TYPE = RI.Machine;
Byte: TYPE = RI.Byte;
Bytes: TYPE = RI.Bytes;
Pair: TYPE = RI.Pair;
FieldDescriptor: TYPE = PrincOps.FieldDescriptor;
SignedOpByte: PUBLIC PROC [m: Machine] RETURNS [INTEGER] = {
alpha: RECORD [SELECT OVERLAID * FROM
int => [i: INTEGER],
pair => [bp: RI.Bytes],
ENDCASE];
alpha.bp.b2 ← RI.NextOpByte[m];
IF alpha.bp.b2 > 177B THEN alpha.bp.b1 ← 377B
ELSE alpha.bp.b1 ← 0;
RETURN [alpha.i]};
DoSignedJump: PUBLIC PROC [m: Machine, savedPc: CARDINAL, op: Byte] = {
alpha: INTEGER = SignedOpByte[m];
op2: INTEGER = RI.IntV[RI.Pop[m]];
op1: INTEGER = RI.IntV[RI.Pop[m]];
SELECT op FROM
zJLB => IF op1 < op2 THEN RI.SetPc[m, savedPc + alpha];
zJGEB => IF op1 >= op2 THEN RI.SetPc[m, savedPc + alpha];
zJGB => IF op1 > op2 THEN RI.SetPc[m, savedPc + alpha];
zJLEB => IF op1 <= op2 THEN RI.SetPc[m, savedPc + alpha];
ENDCASE;
};
DoUnsignedJump: PUBLIC PROC [m: Machine, savedPc: CARDINAL, op: Byte] = {
alpha: INTEGER = SignedOpByte[m];
op2: CARDINAL = RI.CardV[RI.Pop[m]];
op1: CARDINAL = RI.CardV[RI.Pop[m]];
SELECT op FROM
zJULB => IF op1 < op2 THEN RI.SetPc[m, savedPc + alpha];
zJUGEB => IF op1 >= op2 THEN RI.SetPc[m, savedPc + alpha];
zJUGB => IF op1 > op2 THEN RI.SetPc[m, savedPc + alpha];
zJULEB => IF op1 <= op2 THEN RI.SetPc[m, savedPc + alpha];
zJNEB => IF op1 # op2 THEN RI.SetPc[m, savedPc + alpha];
zJEQB => IF op1 = op2 THEN RI.SetPc[m, savedPc + alpha];
ENDCASE;
};
DoMonitorOps: PUBLIC PROC [m: Machine, op: Byte] = {
SELECT op FROM
Monitor stuff
zNOOP => NULL;
zME => {
ShortEnter: PROC [Value] RETURNS [Value] = TRUSTED MACHINE CODE {zME};
LongEnter: PROC [DValue] RETURNS [Value] = TRUSTED MACHINE CODE {zME};
v: Value;
SELECT m.sd FROM
1 => v ← ShortEnter[RI.Pop[m]];
2 => v ← LongEnter[RI.Pop2[m]];
ENDCASE => RI.Confusion[m];
RI.Push[m, v]};
zMRE => {
ShortReEnter: PROC [mon, cond: Value] RETURNS [Value] = TRUSTED MACHINE CODE {zMRE};
LongReEnter: PROC [mon, cond: DValue] RETURNS [Value] = TRUSTED MACHINE CODE {zMRE};
v: Value;
SELECT m.sd FROM
2 => {
c: Value ← RI.Pop[m];
mon: Value ← RI.Pop[m];
v ← ShortReEnter[mon: mon, cond: c]};
4 => {
c: DValue ← RI.Pop2[m];
mon: DValue ← RI.Pop2[m];
v ← LongReEnter[mon: mon, cond: c]};
ENDCASE => RI.Confusion[m];
RI.Push[m, v]};
zMXW => {
ShortExitWait: PROC [mon, cond, timeout: Value] = TRUSTED MACHINE CODE {zMXW};
LongExitWait: PROC [mon, cond: DValue, timeout: Value] = TRUSTED MACHINE CODE {zMXW};
SELECT m.sd FROM
3 => {
t: Value ← RI.Pop[m];
c: Value ← RI.Pop[m];
mon: Value ← RI.Pop[m];
ShortExitWait[mon: mon, cond: c, timeout: t]};
5 => {
t: Value ← RI.Pop[m];
c: DValue ← RI.Pop2[m];
mon: DValue ← RI.Pop2[m];
LongExitWait[mon: mon, cond: c, timeout: t]};
ENDCASE => RI.Confusion[m];
};
zMXD => {
ShortExit: PROC [Value] = TRUSTED MACHINE CODE {zMXD};
LongExit: PROC [DValue] = TRUSTED MACHINE CODE {zMXD};
SELECT m.sd FROM
1 => ShortExit[RI.Pop[m]];
2 => LongExit[RI.Pop2[m]];
ENDCASE => RI.Confusion[m];
};
zNOTIFY => {
ShortNotify: PROC [Value] = TRUSTED MACHINE CODE {zNOTIFY};
LongNotify: PROC [DValue] = TRUSTED MACHINE CODE {zNOTIFY};
SELECT m.sd FROM
1 => ShortNotify[RI.Pop[m]];
2 => LongNotify[RI.Pop2[m]];
ENDCASE => RI.Confusion[m];
};
zBCAST => {
ShortBroadcast: PROC [Value] = TRUSTED MACHINE CODE {zNOTIFY};
LongBroadcast: PROC [DValue] = TRUSTED MACHINE CODE {zNOTIFY};
SELECT m.sd FROM
1 => ShortBroadcast[RI.Pop[m]];
2 => LongBroadcast[RI.Pop2[m]];
ENDCASE => RI.Confusion[m];
};
zREQUEUE => {
LongRequeue: PROC [from: DValue, to: DValue, p: Value] = TRUSTED MACHINE CODE {zREQUEUE};
ShortRequeue: PROC [from: Value, to: Value, p: Value] = TRUSTED MACHINE CODE {zREQUEUE};
SELECT m.sd FROM
3 => {
p: Value ← RI.Pop[m];
to: Value ← RI.Pop[m];
from: Value ← RI.Pop[m];
ShortRequeue[from: from, to: to, p: p]};
5 => {
p: Value ← RI.Pop[m];
to: DValue ← RI.Pop2[m];
from: DValue ← RI.Pop2[m];
LongRequeue[from: from, to: to, p: p]};
ENDCASE => RI.Confusion[m];
};
ENDCASE;
};
DoLocalOps: PUBLIC PROC [m: Machine, op: Byte] = TRUSTED {
SELECT op FROM
Loads & Stores of Locals
zLL0, zLL1, zLL2, zLL3, zLL4, zLL5, zLL6, zLL7 => {
n: CARDINAL ← op - zLL0;
p: POINTER TO Value = m.l+PrincOps.localbase+n;
RI.ReadLocal[m, n];
RI.Push[m, p^]};
zLLB => {
n: CARDINALRI.NextOpByte[m];
p: POINTER TO Value = m.l+n;
RI.ReadLocal[m, n];
RI.Push[m, p^]};
zLLDB => {
n: CARDINALRI.NextOpByte[m];
p: POINTER TO DValue = LOOPHOLE[m.l+n];
RI.DoubleReadLocal[m, n];
RI.Push2[m, p^]};
zSL0, zSL1, zSL2, zSL3, zSL4, zSL5, zSL6, zSL7 => {
n: CARDINAL ← op - zSL0;
p: POINTER TO Value = m.l+PrincOps.localbase+n;
RI.StoreLocal[m, n];
p^ ← RI.Pop[m]};
zSLB => {
n: CARDINALRI.NextOpByte[m];
p: POINTER TO Value = m.l+n;
RI.StoreLocal[m, n];
p^ ← RI.Pop[m]};
zSLDB => {
n: CARDINALRI.NextOpByte[m];
p: POINTER TO DValue = LOOPHOLE[m.l+n];
RI.DoubleStoreLocal[m, n];
p^ ← RI.Pop2[m]};
zPL0, zPL1, zPL2, zPL3 => {
n: CARDINAL ← op - zPL0;
p: POINTER TO Value = m.l+PrincOps.localbase+n;
RI.StoreLocal[m, n];
p^ ← RI.Top[m]};
ENDCASE;
};
DoGlobalOps: PUBLIC PROC [m: Machine, op: Byte] = TRUSTED {
SELECT op FROM
Loads & Stores of Globals
zLG0, zLG1, zLG2, zLG3, zLG4, zLG5, zLG6, zLG7 => {
n: CARDINAL ← op - zLG0;
RI.Push[m, RI.Read[m, LONG[m.g+PrincOps.globalbase+n]]]};
zLGB => {
n: CARDINALRI.NextOpByte[m];
RI.Push[m, RI.Read[m, LONG[m.g+n]]]};
zLGDB => {
n: CARDINALRI.NextOpByte[m];
RI.Push2[m, RI.ReadDouble[m, LOOPHOLE[LONG[m.g+n]]]]};
zSG0, zSG1, zSG2, zSG3 => {
n: CARDINAL ← op - zSG0;
RI.Write[m, m.g+PrincOps.globalbase+n, RI.Pop[m]]};
zSGB => {
n: CARDINALRI.NextOpByte[m];
RI.Write[m, m.g+n, RI.Pop[m]]};
zSGDB => {
n: CARDINALRI.NextOpByte[m];
RI.WriteDouble[m, LOOPHOLE[LONG[m.g+n]], RI.Pop2[m]]};
ENDCASE;
};
DoLiteralOps: PUBLIC PROC [m: Machine, op: Byte] = TRUSTED {
SELECT op FROM
Loads of Constants
zLI0, zLI1, zLI2, zLI3, zLI4, zLI5, zLI6 => {
n: CARDINAL ← op - zLI0;
RI.Push[m, RI.VCard[n]]};
zLIN1 => {RI.Push[m, RI.VInt[-1]]};
zLINI => {RI.Push[m, RI.VCard[100000B]]};
zLIB => {
n: CARDINALRI.NextOpByte[m];
RI.Push[m, RI.VCard[n]]};
zLIW, zLCO => {
w: Bytes;
w.b1 ← RI.NextOpByte[m];
w.b2 ← RI.NextOpByte[m];
RI.Push[m, LOOPHOLE[w, Value]]};
zLINB => {
w: Bytes;
w.b1 ← 377B;
w.b2 ← RI.NextOpByte[m];
RI.Push[m, LOOPHOLE[w, Value]]};
zLADRB => {
n: CARDINALRI.NextOpByte[m];
RI.Push[m, RI.VPtr1[m.l+n]]};
zGADRB => {
n: CARDINALRI.NextOpByte[m];
RI.Push[m, RI.VPtr1[m.g+n]]};
ENDCASE;
};
DoReadOps: PUBLIC PROC [m: Machine, op: Byte] = TRUSTED {
SELECT op FROM
Reads from pointer on stack
zR0, zR1, zR2, zR3, zR4 => {
n: CARDINAL ← op - zR0;
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
RI.Push[m, RI.Read[m, LONG[p+n]]]};
zRB => {
n: CARDINALRI.NextOpByte[m];
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
RI.Push[m, RI.Read[m, LONG[p+n]]]};
zRBL => {
n: CARDINALRI.NextOpByte[m];
p: LPtr1 ← RI.LPtr1V[RI.Pop2[m]];
RI.Push[m, RI.Read[m, p+n]]};
zRD0 => {
n: CARDINAL ← 0;
p: Ptr2 ← RI.Ptr2V[RI.Pop[m]];
RI.Push2[m, RI.ReadDouble[m, LONG[p+n]]]};
zRDB => {
n: CARDINALRI.NextOpByte[m];
p: Ptr2 ← RI.Ptr2V[RI.Pop[m]];
RI.Push2[m, RI.ReadDouble[m, LONG[p+n]]]};
zRDBL => {
n: CARDINALRI.NextOpByte[m];
p: LPtr2 ← RI.LPtr2V[RI.Pop2[m]];
RI.Push2[m, RI.ReadDouble[m, p+n]]};
zRF => {
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
n: CARDINAL = RI.NextOpByte[m];
fd: FieldDescriptor ← LOOPHOLE[RI.NextOpByte[m]];
RI.Push[m, RI.ReadField[m, LONG[p+n], fd]]};
zRFL => {
p: LPtr1 ← RI.LPtr1V[RI.Pop2[m]];
n: CARDINAL = RI.NextOpByte[m];
fd: FieldDescriptor ← LOOPHOLE[RI.NextOpByte[m]];
RI.Push[m, RI.ReadField[m, p+n, fd]]};
ENDCASE;
};
DoWriteOps: PUBLIC PROC [m: Machine, op: Byte] = TRUSTED {
SELECT op FROM
Writes from pointer on stack
zWCDBL => {
DoCountedWrite: PROC [refVal: DValue, refLoc: LPtr2] = TRUSTED MACHINE CODE {zWCDBL, 0};
alpha: CARDINAL = RI.NextOpByte[m];
refLoc: LPtr2 ← RI.LPtr2V[RI.Pop2[m]] + alpha;
refVal: DValue ← RI.Pop2[m];
RefCount: TYPE = MACHINE DEPENDENT RECORD [filler (0:0..8): [0..777B], count (0:9..15): [0..177B]];
oldRef: LONG POINTER TO RefCount;
oldCount: NAT;
record various memory references
oldRef ← LOOPHOLE[RI.LPtr1V[RI.ReadDouble[m, refLoc]]];
IF oldRef # NIL THEN {
RI.ReadAtAddress[m, oldRef-2];
oldCount ← (oldRef-2).count;
IF oldCount = 2 (low bit is overflow, so this means decr will be to 0).
write to the ZCT (the microcode may be the only one that knows where)
RI.WriteAtAddress[m, oldRef-2];
};
RI.DoubleWriteAtAddress[m, refLoc];
RI.ReadAtAddress[m, RI.LPtr1V[refVal]-2]; -- increment ref count
RI.WriteAtAddress[m, RI.LPtr1V[refVal]-2];
DoCountedWrite[refVal: refVal, refLoc: refLoc];
};
zICDBL => {
DoCountedInitialize: PROC [refVal: DValue, refLoc: LPtr2] = TRUSTED MACHINE CODE {zICDBL, 0};
alpha: CARDINAL = RI.NextOpByte[m];
refLoc: LPtr2 ← RI.LPtr2V[RI.Pop2[m]] + alpha;
refVal: DValue ← RI.Pop2[m];
record various memory references
RI.DoubleWriteAtAddress[m, refLoc];
RI.ReadAtAddress[m, RI.LPtr1V[refVal]-2]; -- increment ref count
RI.WriteAtAddress[m, RI.LPtr1V[refVal]-2];
DoCountedInitialize[refVal: refVal, refLoc: refLoc];
};
zW0, zW1, zW2 => {
n: CARDINAL ← op - zW0;
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
v: Value ← RI.Pop[m];
RI.Write[m, LONG[p+n], v]};
zWB => {
n: CARDINALRI.NextOpByte[m];
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
v: Value ← RI.Pop[m];
RI.Write[m, LONG[p+n], v]};
zWBL => {
n: CARDINALRI.NextOpByte[m];
p: LPtr1 ← RI.LPtr1V[RI.Pop2[m]];
v: Value ← RI.Pop[m];
RI.Write[m, p+n, v]};
zWD0 => {
n: CARDINAL ← 0;
p: Ptr2 ← RI.Ptr2V[RI.Pop[m]];
v: DValue ← RI.Pop2[m];
RI.WriteDouble[m, LONG[p+n], v]};
zWDB => {
n: CARDINALRI.NextOpByte[m];
p: Ptr2 ← RI.Ptr2V[RI.Pop[m]];
v: DValue ← RI.Pop2[m];
RI.WriteDouble[m, LONG[p+n], v]};
zWDBL => {
n: CARDINALRI.NextOpByte[m];
p: LPtr2 ← RI.LPtr2V[RI.Pop2[m]];
v: DValue ← RI.Pop2[m];
RI.WriteDouble[m, p+n, v]};
zWF => {
n: CARDINALRI.NextOpByte[m];
fd: FieldDescriptor ← LOOPHOLE[RI.NextOpByte[m]];
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
v: Value ← RI.Pop[m];
RI.WriteField[m, LONG[p+n], fd, v]};
zWFL => {
n: CARDINALRI.NextOpByte[m];
fd: FieldDescriptor ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1 ← RI.LPtr1V[RI.Pop2[m]];
v: Value ← RI.Pop[m];
RI.WriteField[m, p+n, fd, v]};
ENDCASE;
};
DoReadIndirectOps: PUBLIC PROC [m: Machine, op: Byte] = TRUSTED {
SELECT op FROM
Read indirect through locals
zRXLP => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: Ptr1;
delta: CARDINALRI.CardV[RI.Pop[m]];
RI.ReadLocal[m, PrincOps.localbase+pr.p1];
p ← RI.Ptr1V[(m.l+PrincOps.localbase+pr.p1)^];
RI.Push[m, RI.Read[m, LONG[p+delta+pr.p2]]]};
zRXLPL => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1;
delta: CARDINALRI.CardV[RI.Pop[m]];
RI.DoubleReadLocal[m, PrincOps.localbase+pr.p1];
p ← RI.LPtr1V[LOOPHOLE[(m.l+PrincOps.localbase+pr.p1), Ptr2]^];
RI.Push[m, RI.Read[m, p+delta+pr.p2]]};
zRXGPL => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1;
delta: CARDINALRI.CardV[RI.Pop[m]];
p ← RI.LPtr1V[RI.ReadDouble[m, LOOPHOLE[LONG[m.g+PrincOps.globalbase+pr.p1]]]];
RI.Push[m, RI.Read[m, p+delta+pr.p2]]};
zRILP => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: Ptr1;
RI.ReadLocal[m, PrincOps.localbase+pr.p1];
p ← RI.Ptr1V[(m.l+PrincOps.localbase+pr.p1)^];
RI.Push[m, RI.Read[m, LONG[p+pr.p2]]]};
zRILPL => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1;
RI.DoubleReadLocal[m, PrincOps.localbase+pr.p1];
p ← RI.LPtr1V[LOOPHOLE[(m.l+PrincOps.localbase+pr.p1), Ptr2]^];
RI.Push[m, RI.Read[m, p+pr.p2]]};
zRIGP => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: Ptr1;
ReadGlobal[pr.p1];
p ← RI.Ptr1V[RI.Read[m, LONG[m.g+PrincOps.globalbase+pr.p1]]];
RI.Push[m, RI.Read[m, LONG[p+pr.p2]]]};
zRIGPL => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1;
ReadGlobalDouble[pr.p1];
p ← RI.LPtr1V[RI.ReadDouble[m, LOOPHOLE[LONG[m.g+PrincOps.globalbase+pr.p1]]]];
RI.Push[m, RI.Read[m, p+pr.p2]]};
zRIL0 => {
p: Ptr1;
RI.ReadLocal[m, PrincOps.localbase];
p ← RI.Ptr1V[(m.l+PrincOps.localbase)^];
RI.Push[m, RI.Read[m, LONG[p]]]};
ENDCASE;
};
DoWriteIndirectOps: PUBLIC PROC [m: Machine, op: Byte] = TRUSTED {
SELECT op FROM
Write indirect through locals
zWXLP => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: Ptr1;
delta: CARDINALRI.CardV[RI.Pop[m]];
RI.ReadLocal[m, PrincOps.localbase+pr.p1];
p ← RI.Ptr1V[(m.l+PrincOps.localbase+pr.p1)^];
RI.Write[m, LONG[p+delta+pr.p2], RI.Pop[m]]};
zWXLPL => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1;
delta: CARDINALRI.CardV[RI.Pop[m]];
RI.DoubleReadLocal[m, PrincOps.localbase+pr.p1];
p ← RI.LPtr1V[LOOPHOLE[(m.l+PrincOps.localbase+pr.p1), Ptr2]^];
RI.Write[m, p+delta+pr.p2, RI.Pop[m]]};
zWXGPL => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1;
delta: CARDINALRI.CardV[RI.Pop[m]];
p ← RI.LPtr1V[RI.ReadDouble[m, LOOPHOLE[LONG[m.g+PrincOps.globalbase+pr.p1]]]];
RI.Write[m, p+delta+pr.p2, RI.Pop[m]]};
zWILP => {
pr: Pair ← LOOPHOLE[ RI.NextOpByte[m]];
p: Ptr1;
RI.ReadLocal[m, PrincOps.localbase+pr.p1];
p ← RI.Ptr1V[(m.l+PrincOps.localbase+pr.p1)^];
RI.Write[m, LONG[p+pr.p2], RI.Pop[m]]};
zWILPL => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1;
RI.DoubleReadLocal[m, PrincOps.localbase+pr.p1];
p ← RI.LPtr1V[LOOPHOLE[(m.l+PrincOps.localbase+pr.p1), Ptr2]^];
RI.Write[m, p+pr.p2, RI.Pop[m]]};
zWIGPL => {
pr: Pair ← LOOPHOLE[RI.NextOpByte[m]];
p: LPtr1;
p ← RI.LPtr1V[RI.ReadDouble[m, LOOPHOLE[LONG[m.g+PrincOps.globalbase+pr.p1]]]];
RI.Write[m, p+pr.p2, RI.Pop[m]]};
ENDCASE;
};
DoWriteSwappedOps: PUBLIC PROC [m: Machine, op: Byte] = TRUSTED {
SELECT op FROM
Write Swapped
zWS0 => {
n: CARDINAL ← 0;
v: Value ← RI.Pop[m];
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
RI.Write[m, LONG[p+n], v]};
zWSB => {
n: CARDINALRI.NextOpByte[m];
v: Value ← RI.Pop[m];
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
RI.Write[m, LONG[p+n], v]};
zWSDB => {
n: CARDINALRI.NextOpByte[m];
v: DValue ← RI.Pop2[m];
p: Ptr2 ← RI.Ptr2V[RI.Pop[m]];
RI.WriteDouble[m, LONG[p+n], v]};
zWSF => {
n: CARDINALRI.NextOpByte[m];
fd: FieldDescriptor ← LOOPHOLE[RI.NextOpByte[m]];
v: Value ← RI.Pop[m];
p: Ptr1 ← RI.Ptr1V[RI.Pop[m]];
RI.WriteField[m, LONG[p+n], fd, v]};
ENDCASE;
};
DoShortArithmetic: PUBLIC PROC [m: Machine, op: Byte] = {
SELECT op FROM
Short arithmetic
zADD, zADD01 => {
c2: CARDINAL = RI.CardV[RI.Pop[m]];
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push[m, RI.VCard[c1+c2]]};
zSUB => {
c2: CARDINAL = RI.CardV[RI.Pop[m]];
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push[m, RI.VCard[c1-c2]]};
zMUL => {
c2: CARDINAL = RI.CardV[RI.Pop[m]];
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push2[m, RI.VLCard[Basics.LongMult[c1, c2]]];
m.sd ← m.sd - 1};
zDBL => {
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push[m, RI.VCard[c1*2]]};
zDIV => {
c2: CARDINAL = RI.CardV[RI.Pop[m]];
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push2[m, DivMod[c1, c2]];
m.sd ← m.sd - 1};
zLDIV => {
c2: CARDINAL = RI.CardV[RI.Pop[m]];
c1: LONG CARDINAL = RI.LCardV[RI.Pop2[m]];
RI.Push2[m, LongDivMod[c1, c2]];
m.sd ← m.sd - 1};
zNEG => {
c1: INTEGER = RI.IntV[RI.Pop[m]];
RI.Push[m, RI.VInt[-c1]]};
zINC => {
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push[m, RI.VCard[c1+1]]};
zAND => {
c2: CARDINAL = RI.CardV[RI.Pop[m]];
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push[m, RI.VCard[Basics.BITAND[c1, c2]]]};
zOR => {
c2: CARDINAL = RI.CardV[RI.Pop[m]];
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push[m, RI.VCard[Basics.BITOR[c1, c2]]]};
zXOR => {
c2: CARDINAL = RI.CardV[RI.Pop[m]];
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push[m, RI.VCard[Basics.BITXOR[c1, c2]]]};
zSHIFT => {
c2: INTEGER = RI.IntV[RI.Pop[m]];
c1: CARDINAL = RI.CardV[RI.Pop[m]];
RI.Push[m, RI.VCard[Basics.BITSHIFT[c1, c2]]]};
ENDCASE;
};
machine codes used above
DivMod: PROC [c1, c2: CARDINAL] RETURNS [DValue] = TRUSTED MACHINE CODE {
zDIV; zPUSH};
LongDivMod: PROC [c1: LONG CARDINAL, c2: CARDINAL] RETURNS [qr: DValue] = TRUSTED MACHINE CODE {
zLDIV; zPUSH};
}.