-- file: PeepholeZ.mesa -- last edited by Sweet on 11-Aug-82 10:52:34 -- last edited by Satterthwaite on December 16, 1982 11:12 am DIRECTORY Alloc: TYPE USING [Notifier], Code: TYPE USING [codeptr], CodeDefs: TYPE USING [Base, CCIndex, CCNull, CodeCCIndex, codeType], ComData: TYPE USING [textIndex, switches], ESCAlpha: TYPE, FOpCodes: TYPE, Log: TYPE USING [Error], Mopcodes: TYPE, OpCodeParams: TYPE USING [ BYTE, ExternalProcBase, ExternalProcSlots, GlobalAddressSlots, GlobalBase, GlobalDoubleLoadSlots, GlobalLoadSlots, LocalAddressSlots, LocalBase, LocalDoubleLoadSlots, LocalDoublePutSlots, LocalDoubleStoreSlots, LocalLoadSlots, LocalProcBase, LocalProcSlots, LocalPutSlots, LocalStoreSlots, ReadLocalIndirect0Slots, ReadSlots, zEFCn, zGAn, zLAn, zLFCn, zLGDn, zLGn, zLLDn, zLLn, zPLDn, zPLn, zRLI0n, zRn, zSLDn, zSLn], OpTableDefs: TYPE USING [InstLength], P5: TYPE USING [NumberOfParams, P5Error, C0, C1, C1W, C2, LoadConstant], PeepholeDefs: TYPE USING [InitParameters, PackPair, PeepState], P5U: TYPE USING [DeleteCell]; PeepholeZ: PROGRAM IMPORTS CPtr: Code, MPtr: ComData, Log, OpTableDefs, P5, P5U, PeepholeDefs EXPORTS PeepholeDefs = BEGIN OPEN PeepholeDefs, OpCodeParams, CodeDefs; -- imported definitions BYTE: TYPE = OpCodeParams.BYTE; CodeCCIndex: TYPE = CodeDefs.CodeCCIndex; cb: CodeDefs.Base; -- code base (local copy) PeepholeZNotify: PUBLIC Alloc.Notifier = BEGIN -- called by allocator whenever table area is repacked cb ← base[codeType]; END; UnconvertedInstruction: SIGNAL [opcode: WORD] = CODE; PeepZ: PUBLIC PROC [start: CodeCCIndex] = BEGIN -- convert to real instructions (ie from qXXX to zXXX) OPEN ESCAlpha, Mopcodes, FOpCodes; next, ci: CCIndex; state: PeepState; recentSource: CARDINAL ← 0; next ← start; UNTIL (ci ← next) = CCNull DO next ← cb[ci].flink; WITH cc: cb[ci] SELECT FROM code => IF ~cc.realinst THEN BEGIN OPEN state; DC: PROC = INLINE {P5U.DeleteCell[c]}; InitParameters[@state, LOOPHOLE[ci], c]; SELECT cInst FROM qACD => MakeReal[ zACD, c]; qADC => MakeReal[ zADC, c]; qADD => MakeReal[zADD, c]; qADDSB => MakeReal[zADDSB, c]; qAF => {Esc[aAF]; DC[]}; qAL0IB => MakeReal[ zAL0IB, c]; qAND => MakeReal[ zAND, c]; qBC => {Esc[aBC]; DC[]}; qBC => {Esc[aBC]; DC[]}; qBITBLT => {Esc[aBITBLT]; DC[]}; qBLTEL => {Esc[aBLEL]; DC[]}; qBLTECL => {Esc[aBLECL]; DC[]}; qBLT => MakeReal[ zBLT, c]; qBLTC => MakeReal[ zBLTC, c]; qBLTL => MakeReal[ zBLTL, c]; qBLTCL => MakeReal[ zBLTCL, c]; qBNDCK => MakeReal[ zBNDCK, c]; qCATCH => MakeReal[zCATCH, c]; qCATCHFSI => { cc.inst ← zJ2; cc.isize ← 2; cc.realinst ← TRUE}; -- strange but true qDADD => MakeReal[ zDADD, c]; qDB => IF cP[1] = 0 THEN {P5.C0[zD0]; DC[]} ELSE MakeReal[ zDB, c]; qDBL => MakeReal[ zDBL, c]; qDBS => {EscL[bDBS, cP[1]]; DC[]}; qDCMP => MakeReal[ zDCMP, c]; qDDBL => MakeReal[ zDDBL, c]; qDDIV => {Esc[aSDDIV]; DC[]}; qDDUP => MakeReal[ zDDUP, c]; qDEC => MakeReal[ zDEC, c]; qDEXCH => MakeReal[ zDEXCH, c]; qDI => {Esc[aDI]; DC[]}; qDINC => MakeReal[ zDINC, c]; qDIS => MakeReal[ zDIS, c]; qDIS2 => MakeReal[ zDIS2, c]; qDMOD => { Esc[aSDDIV]; P5.C0[zREC2]; P5.C0[zDEXCH]; P5.C0[zDIS2]; DC[]}; qDMUL => {Esc[aDMUL]; DC[]}; qDSHIFT => {Esc[aDSHIFT]; DC[]}; qDSK => {EscL[bDSK, cP[1]]; DC[]}; qDSUB => MakeReal[ zDSUB, c]; qDUDIV => {Esc[aUDDIV]; DC[]}; qDUMOD => { Esc[aUDDIV]; P5.C0[zREC2]; P5.C0[zDEXCH]; P5.C0[zDIS2]; DC[]}; qDUP => MakeReal[ zDUP, c]; qEFC => IF cP[1] IN ExternalProcSlots THEN {P5.C0[zEFCn+cP[1]-ExternalProcBase]; DC[]} ELSE MakeReal[ zEFCB, c]; qEI => {Esc[aEI]; DC[]}; qEXCH => MakeReal[ zEXCH, c]; qEXDIS => MakeReal[ zEXDIS, c]; qFADD => {Esc[aFADD]; DC[]}; qFCOMP => {Esc[aFCOMP]; DC[]}; qFDIV => {Esc[aFDIV]; DC[]}; qFF => {Esc[aFF]; DC[]}; qFLOAT => {Esc[aFLOAT]; DC[]}; qFMUL => {Esc[aFMUL]; DC[]}; qFSUB => {Esc[aFSUB]; DC[]}; qGA => SELECT cP[1] FROM IN GlobalAddressSlots => {P5.C0[zGAn+cP[1]-GlobalBase]; DC[]}; IN BYTE => MakeReal[ zGAB, c]; ENDCASE => {P5.C1W[zGAW, cP[1]]; DC[]}; qINC => MakeReal[ zINC, c]; qKFCB => IF MPtr.switches['y] THEN {MPtr.textIndex ← recentSource; Log.Error[implicitCall]} ELSE MakeReal[ zKFCB, c]; qLA => SELECT cP[1] FROM IN LocalAddressSlots => {P5.C0[zLAn+cP[1]-LocalBase]; DC[]}; LocalBase+6 => {P5.C0[zLA6]; DC[]}; LocalBase+8 => {P5.C0[zLA8]; DC[]}; IN BYTE => MakeReal[ zLAB, c]; ENDCASE => {P5.C1W[zLAW, cP[1]]; DC[]}; qLCO => { P5.C1W[zLIW, cP[1]]; WITH cb[CPtr.codeptr] SELECT FROM code => lco ← TRUE; ENDCASE => ERROR; DC[]}; qLUDIV => {Esc[aLUDIV]; DC[]}; qLFC => IF cP[1] IN LocalProcSlots THEN {P5.C0[zLFCn+cP[1]-LocalProcBase]; DC[]} ELSE MakeReal[ zLFCB, c]; qLG => {MoveVar[global, load, single, cP[1]]; DC[]}; qLGD => {MoveVar[global, load, double, cP[1]]; DC[]}; qLI => {P5.LoadConstant[cP[1]]; DC[]}; qLID => IF cP[1] = 0 THEN {P5.C0[zLID0]; DC[]} ELSE {P5.LoadConstant[cP[1]]; P5.C0[zLI0]; DC[]}; qLINT => {Esc[aLINT]; DC[]}; qLKB => MakeReal[ zLKB, c]; qLL => {MoveVar[local, load, single, cP[1]]; DC[]}; qLLD => {MoveVar[local, load, double, cP[1]]; DC[]}; qLLK => MakeReal[ zLLKB, c]; qLLOB => {EscL[bLLOB, cP[1]]; DC[]}; qLP => MakeReal[zLP, c]; qLST => {EscL[bLSK, cP[1]]; DC[]}; qLSTE => {EscL[bLSTE, cP[1]]; DC[]}; qLSTF => {EscL[bLSTF, cP[1]]; DC[]}; qME => {Esc[aME]; DC[]}; qMR => {Esc[aMR]; DC[]}; qMUL, qAMUL => MakeReal[ zMUL, c]; qMW => {Esc[aMW]; DC[]}; qMX => {Esc[aMX]; DC[]}; qNC => {Esc[aNC]; DC[]}; qNEG => MakeReal[ zNEG, c]; qNILCK => {Esc[aNILCK]; DC[]}; qNILCKL => {Esc[aNILCKL]; DC[]}; qIOR => MakeReal[ zIOR, c]; qPI => {Esc[aPI]; DC[]}; qPL => {MoveVar[local, put, single, cP[1]]; DC[]}; qPLD => {MoveVar[local, put, double, cP[1]]; DC[]}; qPO => {Esc[aPO]; DC[]}; qPS => {Move[sput, single, cP[1], 0]; DC[]}; qPSD => {Move[sput, double, cP[1], 0]; DC[]}; qPSDL => {Move[sputlong, double, cP[1], 0]; DC[]}; qPSF => {Move[sput, partial, cP[1], cP[2]]; DC[]}; qPSL => {Move[sputlong, single, cP[1], 0]; DC[]}; qPSLF => {Move[sputlong, partial, cP[1], cP[2]]; DC[]}; qR => {Move[read, single, cP[1], 0]; DC[]}; qRC => {EscL[bRC, cP[1]]; DC[]}; qRD => {Move[read, double, cP[1], 0]; DC[]}; qRDL => {Move[readlong, double, cP[1], 0]; DC[]}; qREC => MakeReal[ zREC, c]; qREC2 => MakeReal[ zREC2, c]; qREQ => {Esc[aREQ]; DC[]}; qRET => MakeReal[ zRET, c]; qRF => {Move[read, partial, cP[1], cP[2]]; DC[]}; qRCFS => {Esc[aRCFS]; DC[]}; qRLFS => MakeReal[zRLFS, c]; qRGI => MakeGPReal[zRGIP, c]; qRGIL => MakeGPReal[zRGILP, c]; qRKDI => MakeReal[zRKDIB, c]; qRKI => MakeReal[zRKIB, c]; qRL => {Move[readlong, single, cP[1], 0]; DC[]}; qRLDI => IF cP[1] = LocalBase AND cP[2] = 0 THEN { P5.C0[zRLDI00]; DC[]} ELSE MakeLPReal[zRLDIP, c]; qRLDIL => MakeLPReal[zRLDILP, c]; qRLF => {Move[readlong, partial, cP[1], cP[2]]; DC[]}; qRLI => IF cP[1] = LocalBase AND cP[2] IN ReadLocalIndirect0Slots THEN { P5.C0[zRLI0n+cP[2]]; DC[]} ELSE MakeLPReal[zRLIP, c]; qRLIF => MakeLPFReal[zRLIPF, c]; qRLIL => MakeLPReal[zRLILP, c]; qRLILF => MakeLPFReal[zRLILPF, c]; qRSTR => MakeReal[ zRS, c]; qRSTRL => MakeReal[ zRLS, c]; qSDIV => {Esc[aSDIV]; DC[]}; qSFC => MakeReal[ zSFC, c]; qSG => {MoveVar[global, store, single, cP[1]]; DC[]}; qSGD => {MoveVar[global, store, double, cP[1]]; DC[]}; qSHIFT => MakeReal[ zSHIFT, c]; qSHIFTSB => SELECT INTEGER[cP[1]] FROM 0 => DC[]; 1 => {P5.C0[zDBL]; DC[]}; IN [-15..15] => MakeReal[ zSHIFTSB, c]; ENDCASE => {P5.LoadConstant[cP[1]]; P5.C0[zSHIFT]; DC[]}; qSL => {MoveVar[local, store, single, cP[1]]; DC[]}; qSLD => {MoveVar[local, store, double, cP[1]]; DC[]}; qSUB => MakeReal[ zSUB, c]; qTRPL => MakeReal[ zTRPL, c]; qUDCMP => MakeReal[ zUDCMP, c]; qUDIV => {Esc[aUDIV]; DC[]}; qW => {Move[write, single, cP[1], 0]; DC[]}; qWD => {Move[write, double, cP[1], 0]; DC[]}; qWDL => {Move[writelong, double, cP[1], 0]; DC[]}; qWF => {Move[write, partial, cP[1], cP[2]]; DC[]}; qWLFS => MakeReal[zWLFS, c]; qWL => {Move[writelong, single, cP[1], 0]; DC[]}; qWLDIL => MakeLPReal[zWLDILP, c]; qWLF => {Move[writelong, partial, cP[1], cP[2]]; DC[]}; qWLI => MakeLPReal[zWLIP, c]; qWLIL => MakeLPReal[zWLILP, c]; qWS => {Move[swrite, single, cP[1], 0]; DC[]}; qWSD => {Move[swrite, double, cP[1], 0]; DC[]}; qWSDL => {Move[swritelong, double, cP[1], 0]; DC[]}; qWSF => {Move[swrite, partial, cP[1], cP[2]]; DC[]}; qWSL => {Move[swritelong, single, cP[1], 0]; DC[]}; qWSLF => {Move[swritelong, partial, cP[1], cP[2]]; DC[]}; qWSTR => MakeReal[ zWS, c]; qWSTRL => MakeReal[ zWLS, c]; qXOR => {Esc[aXOR]; DC[]}; -- Cedar extensions qBLZL => {Esc[aBLZL]; DC[]}; qGCRT => MakeMiscReal[aCREFTYPE, c]; qPSCIDL => {MoveCounted[sputlong, TRUE, cP[1]]; DC[]}; qPSCDL => {MoveCounted[sputlong, FALSE, cP[1]]; DC[]}; qWCIDL => {MoveCounted[writelong, TRUE, cP[1]]; DC[]}; qWCDL => {MoveCounted[writelong, FALSE, cP[1]]; DC[]}; qWSCIDL => {MoveCounted[swritelong, TRUE, cP[1]]; DC[]}; qWSCDL => {MoveCounted[swritelong, FALSE, cP[1]]; DC[]}; ENDCASE => {SIGNAL UnconvertedInstruction[cInst]; DC[]}; END; other => WITH cc SELECT FROM source => recentSource ← index; ENDCASE => NULL; ENDCASE => NULL; ENDLOOP; END; Esc: PROC [alpha: BYTE] = INLINE {P5.C1[Mopcodes.zESC, alpha]}; EscL: PROC [alpha, beta: BYTE] = INLINE {P5.C2[Mopcodes.zESCL, alpha, beta]}; MakeReal: PROC [i: BYTE, c: CodeCCIndex] = BEGIN IF cb[c].realinst OR P5.NumberOfParams[cb[c].inst] # OpTableDefs.InstLength[i]-1 THEN P5.P5Error[1025]; cb[c].inst ← i; cb[c].realinst ← TRUE; END; MakeLPReal: PROC [i: BYTE, c: CodeCCIndex] = BEGIN IF cb[c].realinst OR P5.NumberOfParams[cb[c].inst] # OpTableDefs.InstLength[i]-1+1 THEN P5.P5Error[1027]; P5.C1[i, PackPair[cb[c].parameters[1]-LocalBase, cb[c].parameters[2]]]; P5U.DeleteCell[c]; END; MakeGPReal: PROC [i: BYTE, c: CodeCCIndex] = BEGIN IF cb[c].realinst OR P5.NumberOfParams[cb[c].inst] # OpTableDefs.InstLength[i]-1+1 THEN P5.P5Error[1028]; P5.C1[i, PackPair[cb[c].parameters[1]-GlobalBase, cb[c].parameters[2]]]; P5U.DeleteCell[c]; END; MakeLPFReal: PROC [i: BYTE, c: CodeCCIndex] = BEGIN IF cb[c].realinst OR P5.NumberOfParams[cb[c].inst] # OpTableDefs.InstLength[i]-1+1 THEN P5.P5Error[1027]; P5.C2[i, PackPair[cb[c].parameters[1]-LocalBase, cb[c].parameters[2]], cb[c].parameters[3]]; P5U.DeleteCell[c]; END; MakeGPFReal: PROC [i: BYTE, c: CodeCCIndex] = BEGIN IF cb[c].realinst OR P5.NumberOfParams[cb[c].inst] # OpTableDefs.InstLength[i]-1+1 THEN P5.P5Error[1028]; P5.C2[i, PackPair[cb[c].parameters[1]-GlobalBase, cb[c].parameters[2]], cb[c].parameters[3]]; P5U.DeleteCell[c]; END; cpeep9: PROC = BEGIN -- find 2-instruction sequences RETURN END; cpeep10: PROC = BEGIN -- find bit-testing jumps RETURN END; Mdirection: TYPE = {read, write, swrite, sput, readlong, writelong, swritelong, sputlong}; Mtype: TYPE = {single, double, partial}; MVdirection: TYPE = {load, store, put}; MVtype: TYPE = {single, double}; MVclass: TYPE = {global, local}; MoveB: ARRAY MVclass OF ARRAY MVtype OF ARRAY MVdirection OF BYTE = [ global: [ single: [Mopcodes.zLGB, Mopcodes.zSGB, Mopcodes.zNOOP], double: [Mopcodes.zLGDB, Mopcodes.zSGDB, Mopcodes.zNOOP]], local: [ single: [Mopcodes.zLLB, Mopcodes.zSLB, Mopcodes.zPLB], double: [Mopcodes.zLLDB, Mopcodes.zSLDB, Mopcodes.zPLDB]]]; RWB: ARRAY MVdirection [load..store] OF ARRAY MVtype [single..double] OF BYTE = [ [Mopcodes.zRB, Mopcodes.zRDB], [Mopcodes.zWB, Mopcodes.zWDB]]; RW0: ARRAY MVdirection [load..store] OF ARRAY MVtype [single..double] OF BYTE = [ [Mopcodes.zR0, Mopcodes.zRD0], [Mopcodes.zW0, Mopcodes.zNOOP]]; MoveVar: PROC [c: MVclass, d: MVdirection, t: MVtype, offset: WORD] = BEGIN -- handles LG, SG, LL, SL, LGD, SGD, LLD, SLD, PL class instructions OPEN Mopcodes; SELECT c FROM local => SELECT t FROM single => SELECT d FROM load => IF offset IN LocalLoadSlots THEN BEGIN P5.C0[zLLn+offset-LocalBase]; RETURN END; store => IF offset IN LocalStoreSlots THEN BEGIN P5.C0[zSLn+offset-LocalBase]; RETURN END; put => IF offset IN LocalPutSlots THEN BEGIN P5.C0[zPLn+offset-LocalBase]; RETURN END; ENDCASE; double => SELECT d FROM load => SELECT offset FROM IN LocalDoubleLoadSlots => {P5.C0[zLLDn+offset-LocalBase]; RETURN}; LocalBase+10 => {P5.C0[zLLD10]; RETURN}; ENDCASE; store => SELECT offset FROM IN LocalDoubleStoreSlots => {P5.C0[zSLDn+offset-LocalBase]; RETURN}; LocalBase+8 => {P5.C0[zSLD8]; RETURN}; ENDCASE; put => IF offset IN LocalDoublePutSlots THEN BEGIN P5.C0[zPLDn+offset-LocalBase]; RETURN END; ENDCASE; ENDCASE; global => SELECT t FROM single => SELECT d FROM load => IF offset IN GlobalLoadSlots THEN BEGIN P5.C0[zLGn+offset-GlobalBase]; RETURN END; ENDCASE; double => SELECT d FROM load => SELECT offset FROM IN GlobalDoubleLoadSlots => {P5.C0[zLGDn+offset-GlobalBase]; RETURN}; GlobalBase+2 => {P5.C0[zLGD2]; RETURN}; ENDCASE; ENDCASE; ENDCASE; ENDCASE; IF offset NOT IN BYTE THEN BEGIN P5.C1W[IF c = global THEN zGAW ELSE zLAW, offset]; IF d = store AND t = double THEN P5.C1[zWDB, 0] ELSE P5.C0[RW0[d][t]]; RETURN END; P5.C1[MoveB[c][t][d], offset]; END; Move: PROC [d: Mdirection, t: Mtype, offset, field: WORD] = BEGIN -- handles R, W, RF, WF, WS, WSF, PS, PSF class instructions OPEN Mopcodes; IF d = read AND t = single AND offset IN ReadSlots THEN BEGIN P5.C0[zRn+offset]; RETURN END; IF offset NOT IN BYTE THEN BEGIN P5.LoadConstant[offset]; IF d >= readlong THEN BEGIN IF LOOPHOLE[offset, INTEGER]>0 THEN P5.C0[zADC] ELSE { P5.LoadConstant[177777B]; P5.C0[zDADD]} END ELSE P5.C0[zADD]; offset ← 0; END; IF offset = 0 THEN SELECT d FROM read => SELECT t FROM single => P5.C0[zR0]; double => P5.C0[zRD0]; partial => P5.C1[zR0F, field]; ENDCASE; -- single tested above write => SELECT t FROM single => P5.C0[zW0]; double => P5.C1[zWDB, offset]; partial => P5.C1[zW0F, field]; ENDCASE; readlong => SELECT t FROM single => P5.C0[zRL0]; double => P5.C0[zRDL0]; partial => P5.C1[zRL0F, field]; ENDCASE; writelong => SELECT t FROM single => P5.C1[zWLB, offset]; double => P5.C1[zWDLB, offset]; partial => P5.C1[zWL0F, field]; ENDCASE; sput => SELECT t FROM single => P5.C1[zPSB, offset]; double => P5.C0[zPSD0]; partial => P5.C1[zPS0F, field]; ENDCASE; swrite => SELECT t FROM single => {P5.C1[zPSB, offset]; P5.C0[zDIS]}; double => {P5.C0[zPSD0]; P5.C0[zDIS]}; partial => P5.C1[zWS0F, field]; ENDCASE; sputlong => SELECT t FROM single => P5.C1[zPSLB, offset]; double => P5.C1[zPSDLB, offset]; partial => P5.C2[zPSLF, offset, field]; ENDCASE; swritelong => SELECT t FROM single => {P5.C1[zPSLB, offset]; P5.C0[zDIS2]}; double => {P5.C1[zPSDLB, offset]; P5.C0[zDIS2]}; partial => {P5.C2[zPSLF, offset, field]; P5.C0[zDIS2]}; ENDCASE; ENDCASE ELSE SELECT d FROM read => SELECT t FROM single => P5.C1[zRB, offset]; double => P5.C1[zRDB, offset]; partial => P5.C2[zRF, offset, field]; ENDCASE; write => SELECT t FROM single => P5.C1[zWB, offset]; double => P5.C1[zWDB, offset]; partial => P5.C2[zWF, offset, field]; ENDCASE; sput => SELECT t FROM single => P5.C1[zPSB, offset]; double => P5.C1[zPSDB, offset]; partial => P5.C2[zPSF, offset, field]; ENDCASE; swrite => SELECT t FROM single => {P5.C1[zPSB, offset]; P5.C0[zDIS]}; double => {P5.C1[zPSDB, offset]; P5.C0[zDIS]}; partial => {P5.C2[zPSF, offset, field]; P5.C0[zDIS]}; ENDCASE; readlong => SELECT t FROM single => P5.C1[zRLB, offset]; double => P5.C1[zRDLB, offset]; partial => P5.C2[zRLF, offset, field]; ENDCASE; writelong => SELECT t FROM single => P5.C1[zWLB, offset]; double => P5.C1[zWDLB, offset]; partial => P5.C2[zWLF, offset, field]; ENDCASE; sputlong => SELECT t FROM single => P5.C1[zPSLB, offset]; double => P5.C1[zPSDLB, offset]; partial => P5.C2[zPSLF, offset, field]; ENDCASE; swritelong => SELECT t FROM single => {P5.C1[zPSLB, offset]; P5.C0[zDIS2]}; double => {P5.C1[zPSDLB, offset]; P5.C0[zDIS2]}; partial => {P5.C2[zPSLF, offset, field]; P5.C0[zDIS2]}; ENDCASE; ENDCASE; END; -- Cedar extensions MoveCounted: PROC [d: Mdirection, init: BOOL, offset: WORD] = BEGIN OPEN Mopcodes; SELECT d FROM sputlong, swritelong => BEGIN countedPut: ARRAY BOOL OF BYTE = [FALSE: zPSCDLB, TRUE: zPSCIDLB]; P5.C1[countedPut[init], offset]; IF d = swritelong THEN P5.C0[zDIS2]; END; writelong => BEGIN countedWrite: ARRAY BOOL OF BYTE = [FALSE: zWCDLB, TRUE: zWCIDLB]; IF offset NOT IN BYTE THEN BEGIN P5.LoadConstant[offset]; IF LOOPHOLE[offset, INTEGER] > 0 THEN P5.C0[zADC] ELSE {P5.LoadConstant[177777b]; P5.C0[zDADD]}; offset ← 0; END; P5.C1[countedWrite[init], offset]; END; ENDCASE; END; MakeMiscReal: PROC [alpha: BYTE, c: CodeCCIndex] = BEGIN Esc[alpha]; P5U.DeleteCell[c]; END; END.