LizardRosemaryCheckSynchImpl.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by McCreight, March 11, 1986 11:59:25 am PST
Herrmann, September 5, 1985 10:53:41 am PDT
DIRECTORY
Atom,
Dragon,
DragonRosemary,
DragOpsCross,
DragOpsCrossUtils,
LizardRosemary;
LizardRosemaryCheckSynchImpl: CEDAR PROGRAM
IMPORTS Atom, DragonRosemary, LizardRosemary, DragOpsCrossUtils =
BEGIN OPEN LizardRosemary;
CSynch: PROC [ lizardSimRef: REF Simulation, clusterInst: ClusterInst ] RETURNS [deltaInstrCount: INT ← 1] -- LizardRosemary.CheckSynchProc -- =
BEGIN
CheckAInB: PROC [ a, b: REF ANY ] =
BEGIN
FOR la: LIST OF REF ANYNARROW[a, LIST OF REF ANY], la.rest WHILE la#NIL DO
WITH la.first SELECT FROM
rsa: RegStore => {
IF rsa.instr<clusterInst.instr THEN EXIT; -- ancient history
SELECT rsa.reg FROM
euJunk, euToKBus, IN [euBogus..ifuLast] => LOOP;
euMAR => LOOP; -- haven't quite got this synchronized yet
ENDCASE => -- look for it in the other list
FOR lb: LIST OF REF ANYNARROW[b, LIST OF REF ANY], lb.rest DO
IF lb = NIL THEN GOTO NotFound;
WITH lb.first SELECT FROM
rsb: RegStore => {
IF rsb.instr<rsa.instr THEN GOTO NotFound;
IF rsb.instr=rsa.instr AND rsb.reg=rsa.reg THEN {
IF rsb.data#rsa.data THEN GOTO NotFound ELSE EXIT;
};
};
ctb: CacheTrans =>
IF ctb.instr<clusterInst.instr THEN GOTO NotFound;
ENDCASE => NULL;
REPEAT
NotFound=> DragonRosemary.Assert[FALSE,
"Cluster & Rosemary disagree on register store"];
ENDLOOP;
};
cta: CacheTrans =>
IF cta.instr<clusterInst.instr THEN EXIT;
ENDCASE => NULL;
ENDLOOP;
END; -- of CheckAInB
sim: Simulation;
IF clusterInst.instr >= 0 THEN {
Rosemary instruction number clusterInst.instr has finished, for better or worse.
IF (sim ← lizardSimRef^) # NIL THEN {
Get Lizard to do the same instruction, and then compare them.
SELECT clusterInst.trapPC FROM
reschedulePC => { -- Get Lizard to Reschedule on the next instruction
status: DragOpsCross.IFUStatusRec ← LOOPHOLE[sim.processor.regs[ifuStatus]];
status.reschedule ← TRUE;
sim.processor.regs[ifuStatus] ← LOOPHOLE[status];
deltaInstrCount ← 0; -- Lizard doesn't generate a trapped instruction for Reschedule
};
ENDCASE => {
lizardNewPC: Dragon.Word ← DragOpsCrossUtils.WordToCard[sim.processor.regs[ifuPC]];
DragonRosemary.Assert[ sim.processor.stats.instructions = clusterInst.instr , "Cluster & Lizard instruction counts disagree"];
DragonRosemary.Assert[ lizardNewPC = clusterInst.pc , "Cluster & Lizard PC's disagree"];
DoInstruction[sim];
CheckAInB[a: Atom.GetProp[$Cluster, $RegStores], b: sim.lastInstrOps];
CheckAInB[a: sim.lastInstrOps, b: Atom.GetProp[$Cluster, $RegStores]];
DragonRosemary.Assert[ (sim.control=doAbort) = clusterInst.trapped, "Cluster & Lizard disagree about trap"];
IF clusterInst.trapped THEN deltaInstrCount ← 0;
};
};
IF clusterInst.op = x377B AND clusterInst.alpha = 0FFH AND clusterInst.beta = 0FFH THEN
ERROR SuccessHalt;
IF (clusterInst.op = dTrap) OR (clusterInst.op = x377B) THEN SIGNAL Breakpoint;
};
END;
reschedulePC: Dragon.HexWord = DragOpsCrossUtils.TrapIndexToBytePC[RescheduleTrap];
ifuPageFaultPC: Dragon.HexWord = DragOpsCrossUtils.TrapIndexToBytePC[IFUPageFaultTrap];
LizardRosemary.csProcRec.proc ← CSynch;
END.