DragonMicroPLAImplC.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by McCreight, April 9, 1984 11:12:17 am PST
Last edited by TWilliams, August 9, 1984 5:57:59 pm PDT
Last edited by Curry, August 14, 1984 9:59:17 am PDT
DIRECTORY
Basics,
Dragon,
DragonMicroPLA,
DragOpsCross;
DragonMicroPLAImplC: CEDAR PROGRAM
IMPORTS DragonMicroPLA, Basics EXPORTS DragonMicroPLA =
BEGIN OPEN DragonMicroPLA;
IndexedTrapBytePC: PROC[trap: DragOpsCross.TrapIndex, offset: NAT 𡤀]
RETURNS[trapPC: Dragon.HexWord] = {
index: NATLOOPHOLE[trap, NAT] + offset;
trapPC ← DragOpsCross.bytesPerWord *
(DragOpsCross.TrapBase+DragOpsCross.TrapWidthWords * index) };
GetMicroTrap: PUBLIC PROC[aArgs: PhAArgs] RETURNS [m: MicroTrap, newState: IFUState] = {
OPEN aArgs;
trapsCurrentlyEnabled:BOOL;
newState.cycle ← (SELECT TRUE FROM
done   => 0,
delayed  => state.cycle,
aluCondResult2 AND condEffect2=microJump => 32,
ENDCASE   => state.cycle+1);
newState.rescheduleWaiting ←
reschedule OR
ifuStatusControl.reschedule=set OR
state.rescheduleWaiting AND ifuStatusControl.reschedule#clear;
newState.inhibitTraps ←
iTrapEffect3=disable OR
ifuStatusControl.inhibit=set OR
state.inhibitTraps AND
(ifuStatusControl.inhibit#clear AND NOT iTrapEffect3=enable);
trapsCurrentlyEnabled ←
iTrapEffectPending=enable OR
iTrapEffectPending#disable AND NOT newState.inhibitTraps;
SELECT TRUE FROM
reset => {
newState.cycle     ←  0;
newState.exceptions    ←  aboutToReset;
newState.rescheduleWaiting ←  FALSE;
newState.inhibitTraps   ←  TRUE; 
m.killPipe      ← TRUE };
state.exceptions = aboutToReset => { -- First PhA after Reset goes away
newState.cycle     ← 0;
newState.exceptions    ← reset;
newState.rescheduleWaiting ← FALSE;
newState.inhibitTraps   ← TRUE;
m.killPipe       ← TRUE };
pBusFault3 # None => {
newState.cycle   ← 0;
newState.exceptions  ← epFault;
newState.inhibitTraps ← TRUE;
m.killPipe    ← TRUE };
aluCondResult2 AND condEffect2=macroTrap AND NOT pBusReject3=> {
newState.cycle   ← 0;
newState.exceptions  ← euCC;
newState.inhibitTraps ← TRUE;
m.killPipe    ← TRUE };
pBusReject3 => { 
newState.exceptions ← epReject; 
m.killPipe ← FALSE };
aluCondResult2 AND condEffect2=macroJump => {--cond jump switched
newState.cycle  ← 0;
newState.exceptions ← cJump; 
m.killPipe   ← TRUE };
newState.cycle # 0 => { 
newState.exceptions ← none; 
m.killPipe   ← FALSE };
state.exceptions=rschlWait AND delayed OR
newState.rescheduleWaiting AND trapsCurrentlyEnabled=> {
newState.exceptions  ← rschlWait;
m.killPipe    ← FALSE };
state.exceptions=iStkOFlow AND delayed OR
iStkOverflow AND (pushPending OR NOT popPending)
AND trapsCurrentlyEnabled => {
newState.exceptions  ← iStkOFlow;
m.killPipe    ← FALSE };
state.exceptions=eStkOFlow AND delayed OR
eStkOverflow AND trapsCurrentlyEnabled => {
newState.exceptions  ← eStkOFlow;
m.killPipe    ← FALSE };
state.exceptions=iFtchFault AND delayed OR
preFetchFaulted => {
newState.exceptions  ← iFtchFault;
m.killPipe    ← FALSE };
ENDCASE => {
newState.exceptions  ← none;
m.killPipe    ← FALSE };
SELECT newState.exceptions FROM
aboutToReset => m.trapPC←IndexedTrapBytePC[ResetTrap];
reset   => m.trapPC←IndexedTrapBytePC[ResetTrap];
epFault  => m.trapPC←IndexedTrapBytePC[EUPbusTrap0,LOOPHOLE[pBusFault3,NAT]];
euCC   => m.trapPC←IndexedTrapBytePC[ALUCondEZ,LOOPHOLE[aluCond2,NAT]];
epReject  => m.trapPC𡤀
cJump  => m.trapPC𡤀
rschlWait  => m.trapPC←IndexedTrapBytePC[RescheduleTrap];
iStkOFlow => m.trapPC←IndexedTrapBytePC[IFUStackOverflowTrap];
eStkOFlow => m.trapPC←IndexedTrapBytePC[EUStackOverflowTrap];
iFtchFault => m.trapPC←IndexedTrapBytePC[IFUPageFaultTrap];
none   => m.trapPC←IndexedTrapBytePC[StackUnderflowTrap];
ENDCASE  => ERROR};
GetMicroInst: PUBLIC PROC [phBArgs: PhBArgs] RETURNS [ accumMicro: MicroInst ] = BEGIN
ByteArray: TYPE = PACKED ARRAY [0..8) OF BOOLEAN;
opTest: ByteArray;
alphaTest: ByteArray;
betaTest: ByteArray;
firstHit: BOOLTRUE;
FOR PlaRowPointer: INT IN [0..PLAMinterms) DO
plaRow: PlaRow ← PLA[PlaRowPointer];
sigRow: SigPhBArgs ← plaRow.andRow.sigPhBArgs;
argRow: PhBArgs ← plaRow.andRow.phBArgs;
IF sigRow.state.cycle THEN IF phBArgs.state.cycle#argRow.state.cycle THEN LOOP;
IF sigRow.state.rescheduleWaiting THEN IF phBArgs.state.rescheduleWaiting#argRow.state.rescheduleWaiting THEN LOOP;
IF sigRow.state.inhibitTraps THEN IF phBArgs.state.inhibitTraps#argRow.state.inhibitTraps THEN LOOP;
IF sigRow.state.exceptions THEN IF phBArgs.state.exceptions#argRow.state.exceptions THEN LOOP;
TRUSTED {
opTest ← LOOPHOLE[
Basics.BITXOR[LOOPHOLE[argRow.op], LOOPHOLE[phBArgs.op]], ByteArray];
alphaTest ← LOOPHOLE[Basics.BITXOR[argRow.alpha, phBArgs.alpha], ByteArray];
betaTest ← LOOPHOLE[Basics.BITXOR[argRow.beta, phBArgs.beta], ByteArray];
};
IF sigRow.op.bit0 THEN IF opTest[0] THEN LOOP;
IF sigRow.op.bit1 THEN IF opTest[1] THEN LOOP;
IF sigRow.op.bit2 THEN IF opTest[2] THEN LOOP;
IF sigRow.op.bit3 THEN IF opTest[3] THEN LOOP;
IF sigRow.op.bit4 THEN IF opTest[4] THEN LOOP;
IF sigRow.op.bit5 THEN IF opTest[5] THEN LOOP;
IF sigRow.op.bit6 THEN IF opTest[6] THEN LOOP;
IF sigRow.op.bit7 THEN IF opTest[7] THEN LOOP;
IF sigRow.alpha.bit0 THEN IF alphaTest[0] THEN LOOP;
IF sigRow.alpha.bit1 THEN IF alphaTest[1] THEN LOOP;
IF sigRow.alpha.bit2 THEN IF alphaTest[2] THEN LOOP;
IF sigRow.alpha.bit3 THEN IF alphaTest[3] THEN LOOP;
IF sigRow.alpha.bit4 THEN IF alphaTest[4] THEN LOOP;
IF sigRow.alpha.bit5 THEN IF alphaTest[5] THEN LOOP;
IF sigRow.alpha.bit6 THEN IF alphaTest[6] THEN LOOP;
IF sigRow.alpha.bit7 THEN IF alphaTest[7] THEN LOOP;
IF sigRow.beta.bit0 THEN IF betaTest[0] THEN LOOP;
IF sigRow.beta.bit1 THEN IF betaTest[1] THEN LOOP;
IF sigRow.beta.bit2 THEN IF betaTest[2] THEN LOOP;
IF sigRow.beta.bit3 THEN IF betaTest[3] THEN LOOP;
IF sigRow.beta.bit4 THEN IF betaTest[4] THEN LOOP;
IF sigRow.beta.bit5 THEN IF betaTest[5] THEN LOOP;
IF sigRow.beta.bit6 THEN IF betaTest[6] THEN LOOP;
IF sigRow.beta.bit7 THEN IF betaTest[7] THEN LOOP;
IF sigRow.delayACycle THEN IF phBArgs.delayACycle#argRow.delayACycle THEN LOOP;
IF sigRow.iStkEmpty THEN IF phBArgs.iStkEmpty#argRow.iStkEmpty THEN LOOP;
IF sigRow.pushPending THEN IF phBArgs.pushPending#argRow.pushPending THEN LOOP;
IF sigRow.popPending THEN IF phBArgs.popPending#argRow.popPending THEN LOOP;
IF sigRow.instReady THEN IF phBArgs.instReady#argRow.instReady THEN LOOP;
IF firstHit THEN {
firstHit ← FALSE;
accumMicro ← plaRow.orRow.m
}
ELSE accumMicro ← OrMicroInst[ accumMicro, plaRow.orRow.m];
ENDLOOP;
END;
AddPLARow: PUBLIC PROC [sigPhBArgs: SigPhBArgs, phBArgs: PhBArgs, m: MicroInst] ={
opcode: CARDINAL;
TRUSTED { opcode ← LOOPHOLE[ phBArgs.op, CARDINAL] };
IF sigPhBArgs.op.bit0 THEN { -- Assumes opcode is significant if bit 0 is .
opCodeMap[opcode] ← TRUE;
IF NOT ( sigPhBArgs.op.bit5 OR sigPhBArgs.op.bit6 OR sigPhBArgs.op.bit7 ) THEN {
opcode ← opcode - (opcode MOD 8);
FOR opcodeInRange:INT IN [opcode..opcode+8) DO
opCodeMap[opcodeInRange] ← TRUE;
ENDLOOP;
IF NOT sigPhBArgs.op.bit4 THEN {
opcode ← opcode - (opcode MOD 16);
FOR opcodeInRange:INT IN [opcode+8..opcode+16) DO
opCodeMap[opcodeInRange] ← TRUE;
ENDLOOP;
};
};
};
PLA[PLAMinterms] ← [ andRow: [sigPhBArgs, phBArgs], orRow: [m]];
PLAMinterms ← PLAMinterms + 1;
};
OrMicroInst: PROC [ m1: MicroInst, m2: MicroInst] RETURNS [ m3: MicroInst] = {
sizeMicro: CARDINAL = SIZE[MicroInst];
TRUSTED {
m1Array: POINTER TO ARRAY [0..sizeMicro) OF UNSPECIFIEDLOOPHOLE[@m1];
m2Array: POINTER TO ARRAY [0..sizeMicro) OF UNSPECIFIEDLOOPHOLE[@m2];
m3Array: POINTER TO ARRAY [0..sizeMicro) OF UNSPECIFIEDLOOPHOLE[@m3];
FOR mArrayPointer: INT IN [0..sizeMicro) DO
m3Array[mArrayPointer] ← Basics.BITOR[m1Array[mArrayPointer], m2Array[mArrayPointer]];
ENDLOOP;
};
};
GeneratePLA;
END.