DIRECTORY Alloc: TYPE USING [Notifier], Code: TYPE USING [codeptr], CodeDefs: TYPE USING [ Base, CCIndex, CCNull, CodeCCIndex, codeType, JumpCCIndex], FOpCodes: TYPE USING [qGADRB, qLADRB, qLG, qLI, qLL, qRIG, qRIL], OpCodeParams: TYPE USING [BYTE, GlobalHB, LoadImmediateSlots, LocalHB, zLIn], OpTableDefs: TYPE USING [InstLength], P5: TYPE USING [NumberOfParams, P5Error], P5U: TYPE USING [AllocCodeCCItem, DeleteCell, ParamCount], PeepholeDefs: TYPE USING [ JumpPeepState, NullComponent, NullJumpState, NullState, PeepComponent, PeepState, StateExtent], PrincOps: TYPE USING [FieldDescriptor, zLIB, zLIN1, zLINB, zLINI, zLIW], PrincOpsUtils: TYPE USING [BITAND, BITOR, BITSHIFT, COPY]; PeepholeU: PROGRAM IMPORTS CPtr: Code, PrincOpsUtils, P5U, OpTableDefs, P5 EXPORTS P5, PeepholeDefs = PUBLIC BEGIN OPEN OpCodeParams, CodeDefs, PeepholeDefs; BYTE: TYPE = OpCodeParams.BYTE; cb: CodeDefs.Base; -- code base (local copy) PeepholeUNotify: Alloc.Notifier = BEGIN -- called by allocator whenever table area is repacked cb _ base[codeType]; END; GenRealInst: BOOL; SetRealInst: PROC [b: BOOL] = {GenRealInst _ b}; HalfByteGlobal: PROC [c: CCIndex] RETURNS [BOOL] = BEGIN IF c = CCNull THEN RETURN [FALSE]; RETURN [WITH cb[c] SELECT FROM code => inst = FOpCodes.qLG AND parameters[1] IN GlobalHB, ENDCASE => FALSE] END; HalfByteLocal: PROC [c: CCIndex] RETURNS [BOOL] = BEGIN IF c = CCNull THEN RETURN [FALSE]; RETURN [WITH cb[c] SELECT FROM code => inst = FOpCodes.qLL AND parameters[1] IN LocalHB, ENDCASE => FALSE] END; LoadInst: PROC [c: CCIndex] RETURNS [BOOL] = BEGIN 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] END; PackPair: PROC [l, r: [0..16)] RETURNS [WORD] = BEGIN OPEN PrincOpsUtils; RETURN [BITOR[BITSHIFT[l, 4], BITAND[r, 17b]]] END; UnpackPair: PROC [w: WORD] RETURNS [l, r: [0..16)] = BEGIN OPEN PrincOpsUtils; RETURN [l: BITAND[BITSHIFT[w, -4], 17b], r: BITAND[w, 17b]] END; UnpackFD: PROC [d: PrincOps.FieldDescriptor] RETURNS [p, s: CARDINAL] = BEGIN RETURN [p: d.posn, s: d.size] END; InitParameters: PROC [ p: POINTER TO PeepState, ci: CodeCCIndex, extent: StateExtent] = BEGIN -- ci # CCNull and cb[ci].cctag = code 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 BEGIN p.bInst _ inst; FOR i IN [1..P5U.ParamCount[p.b]] DO p.bP[i] _ parameters[i] ENDLOOP; END; 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 BEGIN p.aInst _ inst; FOR i IN [1..P5U.ParamCount[p.a]] DO p.aP[i] _ parameters[i] ENDLOOP; END; ENDCASE; END; CondFillInC: PRIVATE PROC [p: POINTER TO PeepState, ci: CodeCCIndex] = BEGIN IF GenRealInst OR ~cb[ci].realinst THEN {p.cComp _ NullComponent; p.c _ ci; FillInC[p]} ELSE {p^ _ NullState; p.c _ ci}; END; FillInC: PRIVATE PROC [p: POINTER TO PeepState] = BEGIN -- p.c is initialized and p.c # CCNull and cb[p.c].cctag = code 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; END; InitJParametersBC: PROC [p: POINTER TO JumpPeepState, ci: JumpCCIndex] = BEGIN -- ci # CCNull and cb[ci].cctag = jump bi: CCIndex; p^ _ NullJumpState; p.c _ ci; IF (bi _ PrevInteresting[ci]) = CCNull THEN RETURN; CPtr.codeptr _ ci; WITH cc: cb[bi] SELECT FROM code => BEGIN 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; END; ENDCASE; END; SlidePeepState1: PROC [p: POINTER TO PeepState, ci: CodeCCIndex] = BEGIN PrincOpsUtils.COPY[ from: @p.cComp, to: @p.bComp, nwords: PeepComponent.SIZE]; CondFillInC[p, ci]; END; SlidePeepState2: PROC [p: POINTER TO PeepState, ci: CodeCCIndex] = BEGIN PrincOpsUtils.COPY[ from: @p.bComp, to: @p.aComp, nwords: 2*PeepComponent.SIZE]; CondFillInC[p, ci]; END; NextInteresting: PROC [c: CCIndex] RETURNS [CCIndex] = BEGIN -- skip over startbody, endbody, and source other CCItems 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] END; PrevInteresting: PROC [c: CCIndex] RETURNS [CCIndex] = BEGIN -- skip over startbody, endbody, and source other CCItems 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] END; LoadConstant: PROC [c: UNSPECIFIED] = BEGIN 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, PrincOpsUtils.BITAND[ic,377B]] ELSE C1W[zLIW, ic]; END; C0: PROC [i: BYTE] = BEGIN -- outputs an parameter-less instruction c: CodeCCIndex; IF InstParamCount[i] # 0 THEN P5.P5Error[962]; c _ PeepAllocCodeCCItem[i,0]; cb[c].inst _ i; END; C1: PROC [i: BYTE, p1: WORD] = BEGIN -- outputs a one-parameter instruction c: CodeCCIndex _ PeepAllocCodeCCItem[i,1]; cb[c].inst _ i; cb[c].parameters[1] _ p1; END; C1W: PROC [i: BYTE, p1: WORD] = BEGIN -- outputs a one-parameter(two-byte-param) instruction c: CodeCCIndex _ PeepAllocCodeCCItem[i,2]; cb[c].inst _ i; cb[c].parameters[1] _ PrincOpsUtils.BITSHIFT[p1, -8]; cb[c].parameters[2] _ PrincOpsUtils.BITAND[p1, 377B]; END; C2: PROC [i: BYTE, p1, p2: WORD] = BEGIN -- outputs a two-parameter instruction c: CodeCCIndex _ PeepAllocCodeCCItem[i,2]; cb[c].inst _ i; cb[c].parameters[1] _ p1; cb[c].parameters[2] _ p2; END; C3: PROC [i: BYTE, p1, p2, p3: WORD] = BEGIN -- outputs a three-parameter instruction c: CodeCCIndex _ PeepAllocCodeCCItem[i,3]; cb[c].inst _ i; cb[c].parameters[1] _ p1; cb[c].parameters[2] _ p2; cb[c].parameters[3] _ p3; END; InstParamCount: PROC [i: BYTE] RETURNS [CARDINAL] = BEGIN RETURN [IF GenRealInst THEN OpTableDefs.InstLength[i]-1 ELSE P5.NumberOfParams[i]] END; PeepAllocCodeCCItem: PROC [i: BYTE, n: [0..3]] RETURNS [c: CodeCCIndex] = BEGIN IF InstParamCount[i] # n THEN P5.P5Error[963]; c _ P5U.AllocCodeCCItem[n]; cb[c].realinst _ GenRealInst; IF GenRealInst THEN cb[c].isize _ n+1; RETURN END; Delete2: PROC [a,b: CCIndex] = {P5U.DeleteCell[a]; P5U.DeleteCell[b]}; Delete3: PROC [a,b,c: CCIndex] = {P5U.DeleteCell[a]; P5U.DeleteCell[b]; P5U.DeleteCell[c]}; END. ìfile: PeepholeU.mesa last edited by Sweet on March 20, 1980 12:11 PM last edited by Satterthwaite November 2, 1982 4:58 pm Last Edited by: Maxwell, August 11, 1983 9:20 am imported definitions otherwise, p.cComp = NullComponent Ê í˜Jšœ™Jšœ0™0Jšœ5™5J™0J˜šÏk ˜ Jšœœœ ˜Jšœœœ ˜šœ œœ˜J˜;—Jšœ œœ-˜AJšœœœœ/˜MJšœ œœ˜%Jšœœœ˜)Jšœœœ+˜:šœœœ˜J˜FJ˜—Jšœ œœ4˜HJš œœœœœœœ˜:J˜—šœ ˜Jšœ0˜7Jšœ˜Jšœœœ&˜7J˜Jšœ™J˜Jšœœœ˜J˜J˜JšœÏc˜-J˜˜!Jšœž6˜=J˜Jšœ˜J˜—Jšœ œ˜J˜JšÏn œœœ˜0J˜J˜šŸœœœœ˜2Jš˜Jšœ œœœ˜"šœœœ˜Jšœœœ ˜:Jšœœ˜—Jšœ˜J˜—šŸ œœœœ˜1Jš˜Jšœ œœœ˜"šœœœ˜Jšœœœ ˜9Jšœœ˜—Jšœ˜J˜—šŸœœœœ˜,Jšœœ ˜Jšœ œœœ˜"šœœœ˜šœœœ˜'Jšœ-œ˜2Jšœœ˜—Jšœœ˜—Jšœ˜J˜J˜—šŸœœœœ˜/Jšœœ˜Jšœœœœ ˜.Jšœ˜J˜—šŸ œœœœ˜4Jšœœ˜Jšœœœœ ˜;Jšœ˜J˜—šŸœœœœ˜GJš˜Jšœ˜Jšœ˜J˜—šŸœœ˜Jšœœœ3˜@Jšœž&˜,J˜Jšœœ˜ J˜Jšœœœœ˜2J˜ Jšœ œœ˜Jšœ%œœ˜3Jšœœ˜šœœ˜˜šœ œ ˜ Jš˜J˜Jšœœœœ˜EJšœ˜——Jšœ˜—Jšœ œœ˜Jšœ%œœ˜3Jšœœ˜šœœ˜˜šœ œ ˜ Jš˜J˜Jšœœœœ˜EJšœ˜——Jšœ˜—Jšœ˜J˜—š Ÿ œœœœœ˜FJš˜šœ œ˜'J˜/—Jšœ˜ Jšœ˜J˜—š Ÿœœœœœ ˜1Jšœž?˜EJšœ"™"J˜J˜šœœœ˜.J˜ Jšœ˜—Jšœ˜J˜—šŸœœœœ"˜HJšœž&˜,J˜ J˜Jšœ%œœ˜3J˜šœ œ˜˜Jš˜Jšœœœœ˜.Jšœœ˜J˜šœœœ˜.J˜Jšœ˜—Jšœ˜—Jšœ˜—Jšœ˜J˜—šŸœœœœ˜BJš˜šœœ˜J˜J˜ Jšœœ˜—J˜Jšœ˜J˜—šŸœœœœ˜BJš˜šœœ˜J˜J˜ Jšœœ˜—J˜Jšœ˜J˜—šŸœœœ ˜6Jšœž9˜?šœ˜#šœ œ˜šœ œœ˜Jšœ œ˜Jšœ˜—Jšœœ˜—Jšœ˜—Jšœ˜ Jšœ˜J˜—šŸœœœ ˜6Jšœž9˜?šœ˜#šœ œ˜šœ œœ˜Jšœ œ˜Jšœ˜—Jšœœ˜—Jšœ˜—Jšœ˜ Jšœ˜J˜—šŸ œœ œ˜%Jš˜Jšœ ˜Jšœœ˜ Jšœœœ˜3Jšœœ˜šœ˜Jšœ#˜%J˜J˜Jšœœ˜šœ˜ šœœœ˜Jšœœ ˜(—Jšœ˜——Jšœ˜J˜J˜—šŸœœœ˜Jšœž(˜.J˜Jšœœ˜.J˜J˜Jšœ˜J˜J˜—šŸœœœœ˜Jšœž&˜,J˜*J˜J˜Jšœ˜J˜J˜—šŸœœœœ˜Jšœž6˜