DIRECTORY IO, Rope, MDDefs, MDGlobalVars, MDOps, MDUtils; MDScanImpl: CEDAR PROGRAM IMPORTS IO, MDGlobalVars, MDOps, MDUtils EXPORTS MDOps, MDUtils = BEGIN OPEN MDDefs, MDGlobalVars; -- Mark IFU entries, check common errors InitialScan: PUBLIC PROC RETURNS[ok: BOOL] = { MDOps.Report[infoOnly, " Checking for errors...\n"]; IF ~PreScan[] THEN RETURN[FALSE]; RETURN[RealScan[]]; }; PreScan: PROC RETURNS[ok: BOOL] = TRUSTED { nIFUE: INTEGER _ 0; FOR i: CARDINAL IN [0..nInstructions) DO imPtr: MDDefs.IMRecordPtr = MDUtils.IMPtr[i]; IF ignoreOnPage THEN imPtr.word0.onPageAndPlaced _ 0; IF imPtr.word1.W1AddrAndGroupLink = WExt OR imPtr.word2.W2AddrAndbLink = WExt THEN { IF imPtr.word2.iscond = 1 THEN { MDOps.Report[infoOnly, "%g ....Conditional branch to external symbol\n", IO.int[i] ]; RETURN[FALSE]; } ELSE IF imPtr.word1.usesFN = 1 THEN { MDOps.Report[infoOnly, "%g ....Branches to external symbol, but FF is busy\n", IO.int[i] ]; RETURN[FALSE]; }; }; IF imPtr.word1.returns = 1 THEN imPtr.word2.iscond _ 0; imPtr.word0.brkPAndIFUE _ 0; ENDLOOP; FOR k: CARDINAL IN [0..nIFUInstructions) DO ifumPtr: IFUMRecordPtr = MDUtils.IFUMPtr[k]; imPtr: IMRecordPtr; iAddr: CARDINAL = ifumPtr.ifumWord0.ifad; IF iAddr = 7777B THEN LOOP; imPtr _ MDUtils.IMPtr[iAddr]; IF imPtr.word0.brkPAndIFUE = 0 THEN { iAddrLast: CARDINAL; nIFUE _ nIFUE + 1; iAddrLast _ iAddr + ifumPtr.ifumWord0.nEnt; FOR j: CARDINAL IN [iAddr .. iAddrLast] DO -- checking multiple entry points imP: MDDefs.IMRecordPtr = IMPtr[j]; IF imP.word0.brkPAndIFUE = 1 THEN RETURN[IFUErr[j]]; -- return[false] IF imP.word0.globalAndIFUSeq = 1 THEN { MDOps.Report[infoOnly, "%g ....Both IFU entry and global\n", IO.int[j]]; RETURN[FALSE]; }; imP.word0.brkPAndIFUE _ 1; IF j # iAddr THEN imP.word0.globalAndIFUSeq _ 1; ENDLOOP; } ELSE IF imPtr.word0.globalAndIFUSeq = 1 THEN RETURN[IFUErr[iAddr]]; ENDLOOP; IF nIFUE > IFUMsize THEN { MDOps.Report[infoOnly, "Too many (%g) IFU entries - max is %g\n", IO.int[nIFUE], IO.int[IFUMsize]]; RETURN[FALSE]; }; FOR i: CARDINAL IN [0 .. nInstructions) DO imPtr: IMRecordPtr = IMPtr[i]; IF imPtr.word1.W1AddrAndGroupLink = WNext THEN imPtr.word1.W1AddrAndGroupLink _ i+1; IF imPtr.word2.W2AddrAndbLink = WNext THEN imPtr.word2.W2AddrAndbLink _ i+1; ENDLOOP; RETURN[TRUE]; }; RealScan: PROC RETURNS[ok: BOOL] = TRUSTED { FOR i: CARDINAL IN [0 .. nInstructions) DO imPtr: IMRecordPtr _ IMPtr[i]; addr1, addr2: CARDINAL; addr1 _ imPtr.word1.W1AddrAndGroupLink; IF addr1 > nInstructions AND UsesW1[imPtr] THEN IF NOT (imPtr.word1.returns # 0 AND imPtr.word1.calls = 0) THEN { MDOps.Report[infoOnly, "%g....successor (%g) is beyond end of program\n", IO.card[i], IO.card[addr1] ]; RETURN[FALSE]; }; IF (addr2 _ imPtr.word2.W2AddrAndbLink) > nInstructions AND UsesW2[imPtr] THEN { IF imPtr.word2.iscond = 1 THEN MDOps.Report[infoOnly, "%g....one successor (%g) is beyond end of program\n", IO.card[i], IO.card[addr2] ] ELSE MDOps.Report[infoOnly, "%g....successor (%g) is beyond end of program\n", IO.card[i], IO.card[addr2] ]; RETURN[FALSE]; }; ENDLOOP; RETURN[TRUE]; }; IFUErr: PROC[addr: CARDINAL] RETURNS[BOOL] = { MDOps.Report[infoOnly, "%g ....Overlapping IFU entry sequences\n", IO.card[addr]]; RETURN[FALSE]; }; IMPtr: PUBLIC PROC[offset: CARDINAL] RETURNS[IMRecordPtr] = { RETURN[LOOPHOLE[imArrayHead + offset*SIZE[IMRecord]]] }; UsesW1: PROC[imPtr: MDDefs.IMRecordPtr] RETURNS[BOOL] = TRUSTED { RETURN[ ((imPtr.word1.returns = 0) OR (imPtr.word1.calls # 0)) AND (imPtr.word1.W1AddrAndGroupLink # WExt)] }; UsesW2: PROC[imPtr: MDDefs.IMRecordPtr] RETURNS[BOOL] = TRUSTED { RETURN[ ((imPtr.word2.iscond # 0) OR (imPtr.word1.calls # 0)) AND (imPtr.word1.W1AddrAndGroupLink # WExt)] }; END. TMDScanImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Willie-Sue, May 7, 1986 4:26:15 pm PDT taken from mdScan.bcpl Miscellaneous checking and cleanup: Remove onPage if appropriate Remove calls if oddcall set (since call does not return) If callerMask=-1, remove oddcall as well (i.e. RCALL=GOTO Remove iscond if returns set (for "conditional" IFU jumps) Prohibit conditional and FF-busy branches to external symbols Reset IFUE bit for IFU entry loop Indicate IFU entries change .+1 encoding to actual value Check constraints: Forbid branches beyond end of program Κά˜šœ™Icodešœ Οmœ1™—Jšžœžœ˜J˜šžœžœžœ˜%˜Jšœ7žœ ˜D—Jšžœžœ˜J˜—J˜—Jšžœžœ˜7Jšœ˜—Jšžœ˜—J™Jšœ™šžœžœžœž˜+Jšœ,˜,Jšœ˜Jšœžœ˜)Jšžœžœžœ˜J˜Jšœ˜šžœžœ˜%Jšœ žœ˜Jšœ˜Jšœ+˜+š žœžœžœžœŸ!˜MJšœ#˜#JšžœžœžœŸ˜Fšžœžœ˜'˜Jšœ&žœ ˜1—Jšžœžœ˜J˜—Jšœ˜Jšžœ žœ˜0Jšžœ˜J˜Jšžœžœ!žœžœ˜C——Jšžœ˜šžœžœ˜šœ˜Jšœ+žœ žœ˜L—Jšžœžœ˜Jšœ˜——J˜Jšœ#™#šžœžœžœž˜*Jšœ˜šžœ(ž˜.Jšœ'˜'—Jšžœ$žœ"˜LJšžœ˜—J˜Jšžœžœ˜ J˜—J˜š  œžœžœžœžœ˜,J™J™%J˜šžœžœžœž˜*Jšœ˜Jšœžœ˜Jšœ'˜'šžœžœž˜/šžœžœžœžœ˜AšœI˜IJšžœ žœ˜—Jšžœžœ˜J˜——šžœ6žœžœ˜Pšžœž˜šœM˜MJšžœ žœ˜—šž˜šœI˜IJšžœ žœ˜——Jšžœžœ˜J˜——Jšžœ˜—Jšžœžœ˜ J˜—J˜J˜š  œžœžœžœžœ˜.šœ˜Jšœ,žœ ˜;—Jšžœžœ˜Jšœ˜—J˜š  œžœžœ žœžœ˜;Jšœžœžœžœ˜:—J˜š  œžœžœžœžœ˜Ašžœ˜šœžœž˜:Jšœ(˜(——Jšœ˜—J˜š  œžœžœžœžœ˜Ašžœ˜šœžœž˜9Jšœ(˜(——Jšœ˜—J˜J˜Jšžœ˜——…—„΄