MDMainImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Willie-sue, May 8, 1986 5:06:52 pm PDT
Dave Rumph, November 21, 1986 11:44:54 am PST
taken from mdMain.bcpl
DIRECTORY
Basics USING [BITAND, BITSHIFT],
BasicTime USING [GMT, Now, Period],
Commander USING [CommandProc, Register],
CommandTool USING [ArgumentVector, CurrentWorkingDirectory, Parse],
IO,
PrincOpsUtils USING [LongZero],
Rope,
VM USING [AddressForPageNumber, PagesForWords, SimpleAllocate],
MDDefs,
MDGlobalVars,
MDOps,
MDUtils;
MDMainImpl: CEDAR MONITOR
IMPORTS
Basics, BasicTime, Commander, CommandTool, IO, PrincOpsUtils, Rope, VM,
MDGlobalVars, MDOps, MDUtils
EXPORTS MDDefs
= BEGIN OPEN MDDefs, MDGlobalVars;
Error: PUBLIC SIGNAL[explanation: ROPENIL] = CODE;
StartMicroD: ENTRY Commander.CommandProc = {
ENABLE UNWIND => NULL;
wDir: ROPE ← CommandTool.CurrentWorkingDirectory[];
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd];
cmdLine: ROPE = Rope.Concat["MicroD", cmd.commandLine];
ok: BOOL;
startTime: BasicTime.GMT = BasicTime.Now[];
nIMWords: INT ← IMsize* SIZE[IMRecord];
nIFUMWords: INT = IFUMsize* SIZE[IFUMRecord];
nIMWords: INTSIZE[IMRecord];
nIMWords ← nIMWords * IMsize;
[srcFileList, ok] ← MDOps.InitMicroDVars[cmdLine, wDir, argv];
IF ~ok THEN RETURN;
allocate space for data structures
IF ifumArrayHead = NIL THEN TRUSTED {
buf: LONG POINTER
VM.AddressForPageNumber[VM.SimpleAllocate[VM.PagesForWords[nIFUMWords]].page];
ifumArrayHead ← LOOPHOLE[buf];
buf ← VM.AddressForPageNumber[VM.SimpleAllocate[VM.PagesForWords[nIMWords]].page];
imArrayHead ← LOOPHOLE[buf];
buf ←
VM.AddressForPageNumber[VM.SimpleAllocate[VM.PagesForWords[ALUFMsize]].page];
alufmArrayHead ← LOOPHOLE[buf];
buf ← VM.AddressForPageNumber[VM.SimpleAllocate[VM.PagesForWords[RMsize]].page];
rmArrayHead ← LOOPHOLE[buf];
};
now to initialize
imLocked ← ALL[FALSE];
rmBits ← ALL[FALSE];
alufmBits ← ALL[FALSE];
ifumBits ← ALL[FALSE];
BEGIN ENABLE ABORTED => {
MDOps.Report[infoOnly, "\n* * * Aborted\n"];
IF outFile.strm # NIL THEN outFile.strm.Close[ ! IO.Error => CONTINUE];
outFile.strm ← NIL;
IF listingFile.strm # NIL THEN listingFile.strm.Close[ ! IO.Error => CONTINUE];
listingFile.strm ← NIL;
};
TRUSTED {
ifumPtr: MDDefs.IFUMRecordPtr ← ifumArrayHead;
PrincOpsUtils.LongZero[ifumArrayHead, nIFUMWords];
PrincOpsUtils.LongZero[imArrayHead, nIMWords];
PrincOpsUtils.LongZero[alufmArrayHead, ALUFMsize];
PrincOpsUtils.LongZero[rmArrayHead, RMsize];
FOR i: IFUMIndex IN [0..IFUMsize) DO
MDUtils.IFUMPtr[i].ifumWord0.ifad ← WNull;
ENDLOOP;
};
IF ~MDOps.LoadBinaryFiles[srcFileList]  -- this closes any open source files
THEN { Finish[startTime]; RETURN};
IF ~MDOps.InitialScan[]   -- Mark IFU entries, check common errors
THEN { Finish[startTime]; RETURN};
IF ~MDOps.SetupLinks[]  -- Setup branch linkages
THEN { Finish[startTime]; RETURN};
IF ~MDOps.BuildALists[]  -- Form allocation lists
THEN { Finish[startTime]; RETURN};
IF ~MDOps.DoAssignments[] THEN { Finish[startTime]; RETURN};
IF fatalErrors THEN {  -- Still want storage map
MDOps.ListIMUsed[listingFile];
IF mapFile # NIL THEN MDOps.DoMapIM[mapFile];
Finish[startTime];
RETURN
};
IF ~DoCheckPass[] THEN { Finish[startTime]; RETURN};
IF ~MDOps.FixupJCN[] THEN { Finish[startTime]; RETURN};
MDOps.DumpImage[outFile];
MDOps.DumpSyms[outFile];
MDOps.PutEndMarker[outFile];
outFile.strm.Close[];
outFile.strm ← NIL;
MDOps.ListIM[listingFile, srcFileList];
MDOps.ListIMUsed[listingFile];
MDOps.ListNonIM[listingFile, listingLevel];
IF listSymbols THEN {
IF listingLevel < 0 THEN MDOps.ListRM[listingFile];
MDOps.ListOtherSyms[listingFile];
};
IF absFile # NIL THEN MDOps.DoListAbs[absFile];
IF mapFile # NIL THEN MDOps.DoMapIM[mapFile];
IF occupiedFile # NIL THEN MDOps.DoMapOccupied[occupiedFile];
IF chartFile # NIL THEN MDOps.DoMapChart[chartFile];
IF regsFile # NIL THEN MDOps.DoMapRM[regsFile];
Finish[startTime];
listingFile.strm.Close[];
listingFile.strm ← NIL;
END;
};
Finish: PROC[startTime: BasicTime.GMT] = {
now: BasicTime.GMT = BasicTime.Now[];
secs: INT = BasicTime.Period[startTime, now];
MDOps.Report[infoOnly, "\nFinished at %g, (%g seconds)\n", IO.time[now], IO.int[secs]];
};
DoCheckPass: PROC RETURNS[ok: BOOL] = TRUSTED {
Check all addressability constraints
we checked for duplicate assignment as we went along
OPEN Basics;
ok ← TRUE;
the following loop is equivalent to bcpl's reloadIM - NOT TRUE!!!
FOR i: CARDINAL IN [0..nInstructions) DO
imPtr: IMRecordPtr = MDUtils.IMPtr[i];
imPtr.wx0.W0Addr ← imPtr.word0.W0Addr;
ENDLOOP;
MDOps.Report[infoOnly, "Checking assignment...\n"];
FOR i: CARDINAL IN [0..nInstructions) DO
imPtr: IMRecordPtr = MDUtils.IMPtr[i];
a0: CARDINAL = imPtr.wx0.W0Addr;
i1: CARDINAL = imPtr.wx1.W1AddrAndGroupLink;
a1: CARDINAL;
ip1: IMRecordPtr;
a1Bit: WORD;
IF (imPtr.wx0.globalAndIFUSeq # 0) AND
(MDUtils.CardAnd[a0, globalZero] # 0) THEN {
ok ← FALSE;
MDOps.Report[infoOnly, "******%bb....bad assignment for global\n", IO.card[i]];
};
IF i1 = WExt THEN LOOP;
ip1 ← MDUtils.IMPtr[i1];
a1 ← ip1.wx0.W0Addr;
a1Bit ← BITSHIFT[100000B, -BITAND[LOOPHOLE[a1], 17B]];  -- oneBits!(a1&17B)
IF (imPtr.wx2.iscond # 0) AND (imPtr.wx1.returns = 0) THEN {
i2: CARDINAL = imPtr.wx2.W2AddrAndbLink;
a2: CARDINAL = MDUtils.IMPtr[i2].wx0.W0Addr;
IF IsOdd[a1] OR (a2 # a1+1) OR
( (imPtr.wx1.jbc # 0) AND
( (BITAND[a1Bit, jbctMask] = 0) OR
(BITAND[a1, PageMask] # BITAND[a0, PageMask])) ) THEN {
ok ← FALSE;
MDOps.Report[infoOnly,
"******%bb (%bb) -> %bb (%bb), %bb....bad assignment for conditional\n",
IO.card[i], IO.card[a0], IO.card[i1], IO.card[a1] ];
MDOps.Report[infoOnly,
" %bb (%bb)....bad assignment for conditional\n", IO.card[i2], IO.card[a2] ];
};
};
IF ((imPtr.wx2.goes # 0) AND (BITAND[a1Bit, goedtoMask] = 0)) OR
(( imPtr.wx1.calls # 0) AND (imPtr.wx1.returns = 0) AND
(BITAND[a1Bit, calledMask] = 0) ) THEN {
ok ← FALSE;
MDOps.Report[infoOnly,
"******%bb (%bb) -> %bb (%bb)....bad assignment for GOTO or CALL\n",
IO.card[i], IO.card[a0], IO.card[i1], IO.card[a1] ];
};
the following means no constraint on successor
IF imPtr.wx1.usesFN = 0 OR imPtr.wx1.returns # 0 THEN LOOP;
IF (MDUtils.CardAnd[a1, PageMask] # MDUtils.CardAnd[a0, PageMask]) AND
(MDUtils.CardAnd[a1, globalZero] # 0) THEN {
ok ← FALSE;
MDOps.Report[infoOnly, "*******"];
MDUtils.PutAData[i];
MDOps.Report[infoOnly, " -> "];
MDUtils.PutAData[i1];
MDOps.Report[infoOnly, "....bad assignment -- can't get there\n"];
};
ENDLOOP;
};
IsOdd: PROC[i: CARDINAL] RETURNS[BOOL] =
{ RETURN[Basics.BITAND[LOOPHOLE[i], 1] # 0] };
Commander.Register["MicroD", StartMicroD, "Placer for Dorado microcode"];
END.