DIRECTORY Alloc USING [Notifier], Basics USING [BITAND, BITOR, BITSHIFT], Code USING [codeptr], CodeDefs USING [Base, CCIndex, CCNull, CodeCCIndex, codeType, JumpCCIndex], FOpCodes USING [qGADRB, qLADRB, qLG, qLI, qLL, qRIG, qRIL], OpCodeParams USING [BYTE, GlobalHB, LoadImmediateSlots, LocalHB, zLIn], OpTableDefs USING [InstLength], P5 USING [NumberOfParams, P5Error], P5U USING [AllocCodeCCItem, DeleteCell, ParamCount], PeepholeDefs USING [JumpPeepState, NullComponent, NullJumpState, NullState, PeepComponent, PeepState, StateExtent], PrincOps USING [FieldDescriptor, zLIB, zLIN1, zLINB, zLINI, zLIW], PrincOpsUtils USING [Copy]; PeepholeU: PROGRAM IMPORTS Basics, CPtr: Code, PrincOpsUtils, P5U, OpTableDefs, P5 EXPORTS P5, PeepholeDefs = BEGIN OPEN OpCodeParams, CodeDefs, PeepholeDefs; BYTE: TYPE = OpCodeParams.BYTE; cb: CodeDefs.Base; -- code base (local copy) PeepholeUNotify: PUBLIC Alloc.Notifier = { cb _ base[codeType]; }; GenRealInst: BOOL; SetRealInst: PUBLIC PROC [b: BOOL] = {GenRealInst _ b}; HalfByteGlobal: PUBLIC PROC [c: CCIndex] RETURNS [BOOL] = { IF c = CCNull THEN RETURN [FALSE]; RETURN [WITH cb[c] SELECT FROM code => inst = FOpCodes.qLG AND parameters[1] IN GlobalHB, ENDCASE => FALSE] }; HalfByteLocal: PUBLIC PROC [c: CCIndex] RETURNS [BOOL] = { IF c = CCNull THEN RETURN [FALSE]; RETURN [WITH cb[c] SELECT FROM code => inst = FOpCodes.qLL AND parameters[1] IN LocalHB, ENDCASE => FALSE] }; LoadInst: PUBLIC PROC [c: CCIndex] RETURNS [BOOL] = { OPEN FOpCodes; IF c = CCNull THEN RETURN [FALSE]; RETURN [WITH cb[c] SELECT FROM code => ~realinst AND (SELECT inst FROM qLI, qLL, qLG, qRIL, qRIG, qLADRB, qGADRB => TRUE, ENDCASE => FALSE), ENDCASE => FALSE] }; PackPair: PUBLIC PROC [l, r: [0..16)] RETURNS [WORD] = { RETURN [Basics.BITOR[Basics.BITSHIFT[l, 4], Basics.BITAND[r, 17b]]] }; UnpackPair: PUBLIC PROC [w: WORD] RETURNS [l, r: [0..16)] = { RETURN [l: Basics.BITAND[Basics.BITSHIFT[w, -4], 17b], r: Basics.BITAND[w, 17b]] }; UnpackFD: PUBLIC PROC [d: PrincOps.FieldDescriptor] RETURNS [p, s: CARDINAL] = { RETURN [p: d.posn, s: d.size] }; InitParameters: PUBLIC PROC [p: POINTER TO PeepState, ci: CodeCCIndex, extent: StateExtent] = { ai, bi: CCIndex; i: CARDINAL; p^ _ NullState; p.c _ ci; IF ~(GenRealInst OR ~cb[ci].realinst) THEN RETURN; FillInC[p]; IF extent = c THEN RETURN; IF (bi _ PrevInteresting[ci]) = CCNull THEN RETURN; p.b _ LOOPHOLE[bi]; WITH cb[bi] SELECT FROM code => IF GenRealInst OR ~realinst THEN { p.bInst _ inst; FOR i IN [1..P5U.ParamCount[p.b]] DO p.bP[i] _ parameters[i] ENDLOOP; }; ENDCASE; IF extent = bc THEN RETURN; IF (ai _ PrevInteresting[bi]) = CCNull THEN RETURN; p.a _ LOOPHOLE[ai]; WITH cb[ai] SELECT FROM code => IF GenRealInst OR ~realinst THEN { p.aInst _ inst; FOR i IN [1..P5U.ParamCount[p.a]] DO p.aP[i] _ parameters[i] ENDLOOP; }; ENDCASE; }; CondFillInC: PROC [p: POINTER TO PeepState, ci: CodeCCIndex] = { IF GenRealInst OR ~cb[ci].realinst THEN {p.cComp _ NullComponent; p.c _ ci; FillInC[p]} ELSE {p^ _ NullState; p.c _ ci}; }; FillInC: PROC [p: POINTER TO PeepState] = { CPtr.codeptr _ p.c; p.cInst _ cb[p.c].inst; FOR i: CARDINAL IN [1..P5U.ParamCount[p.c]] DO p.cP[i] _ cb[p.c].parameters[i]; ENDLOOP; }; InitJParametersBC: PUBLIC PROC [p: POINTER TO JumpPeepState, ci: JumpCCIndex] = { bi: CCIndex; p^ _ NullJumpState; p.c _ ci; IF (bi _ PrevInteresting[ci]) = CCNull THEN RETURN; CPtr.codeptr _ ci; WITH cc: cb[bi] SELECT FROM code => { IF ~(GenRealInst OR ~cc.realinst) THEN RETURN; p.b _ LOOPHOLE[bi]; p.bInst _ cc.inst; FOR i: CARDINAL IN [1..P5U.ParamCount[p.b]] DO p.bP[i] _ cc.parameters[i]; ENDLOOP; }; ENDCASE; }; SlidePeepState1: PUBLIC PROC [p: POINTER TO PeepState, ci: CodeCCIndex] = { PrincOpsUtils.Copy[ from: @p.cComp, to: @p.bComp, nwords: PeepComponent.SIZE]; CondFillInC[p, ci]; }; SlidePeepState2: PUBLIC PROC [p: POINTER TO PeepState, ci: CodeCCIndex] = { PrincOpsUtils.Copy[ from: @p.bComp, to: @p.aComp, nwords: 2*PeepComponent.SIZE]; CondFillInC[p, ci]; }; NextInteresting: PUBLIC PROC [c: CCIndex] RETURNS [CCIndex] = { WHILE (c _ cb[c].flink) # CCNull DO WITH cc: cb[c] SELECT FROM other => WITH cc SELECT FROM table => EXIT; ENDCASE; ENDCASE => EXIT; ENDLOOP; RETURN [c] }; PrevInteresting: PUBLIC PROC [c: CCIndex] RETURNS [CCIndex] = { WHILE (c _ cb[c].blink) # CCNull DO WITH cc: cb[c] SELECT FROM other => WITH cc SELECT FROM table => EXIT; ENDCASE; ENDCASE => EXIT; ENDLOOP; RETURN [c] }; LoadConstant: PUBLIC PROC [c: UNSPECIFIED] = { OPEN PrincOps; ic: INTEGER; IF ~GenRealInst THEN {C1[FOpCodes.qLI, c]; RETURN}; ic _ LOOPHOLE[c]; SELECT ic FROM IN LoadImmediateSlots => C0[zLIn+ic]; -1 => C0[zLIN1]; 100000B => C0[zLINI]; IN BYTE => C1[zLIB, ic]; ENDCASE => IF -ic IN BYTE THEN C1[zLINB, Basics.BITAND[ic,377B]] ELSE C1W[zLIW, ic]; }; C0: PUBLIC PROC [i: BYTE] = { c: CodeCCIndex; IF InstParamCount[i] # 0 THEN P5.P5Error[962]; c _ PeepAllocCodeCCItem[i,0]; cb[c].inst _ i; }; C1: PUBLIC PROC [i: BYTE, p1: WORD] = { c: CodeCCIndex _ PeepAllocCodeCCItem[i,1]; cb[c].inst _ i; cb[c].parameters[1] _ p1; }; C1W: PUBLIC PROC [i: BYTE, p1: WORD] = { c: CodeCCIndex _ PeepAllocCodeCCItem[i,2]; cb[c].inst _ i; cb[c].parameters[1] _ Basics.BITSHIFT[p1, -8]; cb[c].parameters[2] _ Basics.BITAND[p1, 377B]; }; C2: PUBLIC PROC [i: BYTE, p1, p2: WORD] = { c: CodeCCIndex _ PeepAllocCodeCCItem[i,2]; cb[c].inst _ i; cb[c].parameters[1] _ p1; cb[c].parameters[2] _ p2; }; C3: PUBLIC PROC [i: BYTE, p1, p2, p3: WORD] = { c: CodeCCIndex _ PeepAllocCodeCCItem[i,3]; cb[c].inst _ i; cb[c].parameters[1] _ p1; cb[c].parameters[2] _ p2; cb[c].parameters[3] _ p3; }; InstParamCount: PROC [i: BYTE] RETURNS [CARDINAL] = { RETURN [IF GenRealInst THEN OpTableDefs.InstLength[i]-1 ELSE P5.NumberOfParams[i]] }; PeepAllocCodeCCItem: PROC [i: BYTE, n: [0..3]] RETURNS [c: CodeCCIndex] = { IF InstParamCount[i] # n THEN P5.P5Error[963]; c _ P5U.AllocCodeCCItem[n]; cb[c].realinst _ GenRealInst; IF GenRealInst THEN cb[c].isize _ n+1; }; Delete2: PUBLIC PROC [a,b: CCIndex] = { P5U.DeleteCell[a]; P5U.DeleteCell[b]; }; Delete3: PUBLIC PROC [a,b,c: CCIndex] = { P5U.DeleteCell[a]; P5U.DeleteCell[b]; P5U.DeleteCell[c]; }; END. PeepholeU.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Sweet on March 20, 1980 12:11 PM Satterthwaite April 17, 1986 11:41:06 am PST Maxwell, August 11, 1983 9:20 am Russ Atkinson (RRA) March 6, 1985 9:36:28 pm PST imported definitions called by allocator whenever table area is repacked ci # CCNull and cb[ci].cctag = code p.c is initialized and p.c # CCNull and cb[p.c].cctag = code otherwise, p.cComp = NullComponent ci # CCNull and cb[ci].cctag = jump skip over startbody, endbody, and source other CCItems skip over startbody, endbody, and source other CCItems outputs an parameter-less instruction outputs a one-parameter instruction outputs a one-parameter(two-byte-param) instruction outputs a two-parameter instruction outputs a three-parameter instruction Κ d˜codešœ™Kšœ Οmœ1™