<> <> <> <> <> <<>> DIRECTORY Basics, Dragon, DragonMicroPLA, DragOpsCross; DragonMicroPLAImplC: CEDAR PROGRAM IMPORTS DragonMicroPLA, Basics EXPORTS DragonMicroPLA = BEGIN OPEN DragonMicroPLA; IndexedTrapBytePC: PROC[trap: DragOpsCross.TrapIndex, offset: NAT _0] RETURNS[trapPC: Dragon.HexWord] = { index: NAT _ LOOPHOLE[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_0; cJump => m.trapPC_0; 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: BOOL _ TRUE; 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 UNSPECIFIED _ LOOPHOLE[@m1]; m2Array: POINTER TO ARRAY [0..sizeMicro) OF UNSPECIFIED _ LOOPHOLE[@m2]; m3Array: POINTER TO ARRAY [0..sizeMicro) OF UNSPECIFIED _ LOOPHOLE[@m3]; FOR mArrayPointer: INT IN [0..sizeMicro) DO m3Array[mArrayPointer] _ Basics.BITOR[m1Array[mArrayPointer], m2Array[mArrayPointer]]; ENDLOOP; }; }; GeneratePLA; END.