<> <> <> <> DIRECTORY Dragon, DragonFP, DragonMicrocode, DragOpsCross; DragonMicrocodeImpl: CEDAR PROGRAM IMPORTS Dragon, DragonFP EXPORTS DragonMicrocode = BEGIN OPEN DragonMicrocode; 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.delayed _ FALSE; newState.done _ FALSE; newState.cycle _ (SELECT TRUE FROM state.done => 0, state.delayed => state.cycle, aluCondResult2 AND condEffect2=microJump => 2*state.cycle, 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 state.delayed OR newState.rescheduleWaiting AND trapsCurrentlyEnabled=> { newState.exceptions _ rschlWait; m.killPipe _ FALSE }; state.exceptions=iStkOFlow AND state.delayed OR iStkOverflow AND (pushPending OR NOT popPending) AND trapsCurrentlyEnabled => { newState.exceptions _ iStkOFlow; m.killPipe _ FALSE }; state.exceptions=eStkOFlow AND state.delayed OR eStkOverflow AND trapsCurrentlyEnabled => { newState.exceptions _ eStkOFlow; m.killPipe _ FALSE }; state.exceptions=iFtchFault AND state.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 => Dragon.Assert[FALSE]}; GetMicroInst: PUBLIC PROC [bArgs: PHBargs] RETURNS [ m: MicroInst, newState: IFUState ]={ OPEN bArgs; opcode: DragOpsCross.Inst; TRUSTED {opcode _ LOOPHOLE[op]}; newState _ state; newState.delayed _ FALSE; <> <> SELECT TRUE FROM state.exceptions = aboutToReset => m _ [ doMacroJump: FALSE, getNextMacro: FALSE, xBSource: trapPCGenerator, lSource: [ zero, one ], sSource: [ zero, zero ] ]; state.exceptions = reset => m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: trapPCGenerator, lSource: [ zero, one ], sSource: [ zero, zero ] ]; state.exceptions = epFault, state.exceptions = euCC => m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: trapPCGenerator, xASource: bAddrIFUReg, bReg: ifuLevel3LS, lSource: [ xBus, zero ], sSource: [ xBus, zero ], pushLevel3: TRUE ]; state.exceptions = epReject => {m _ NoOpMicro; newState.delayed _ TRUE}; state.exceptions = cJump => m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: pipe3PC, xASource: bAddrIFUReg, bReg: ifuLevel3LS, lSource: [ xBus, zero ], sSource: [ xBus, zero ] ]; delayACycle => {m _ NoOpMicro; newState.delayed _ TRUE}; state.cycle#0 => { SELECT opcode FROM dMUL => SELECT state.cycle FROM IN [1..16] => m _ [ getNextMacro: FALSE, xBSource: pc, aReg: [ s, minus1 ], -- Product.msw bReg: [ s, zero ], -- Multiplicand cReg: [ s, minus1 ], -- Product.msw aluOp: MulStep ]; 17 => m _ [ getNextMacro: TRUE, cReg: [ s, zero ], -- Product.lsw _ MQ aluOp: RdMQ ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; dDIV => SELECT state.cycle FROM 1 => m _ [ getNextMacro: FALSE, xBSource: pc, aReg: [ s, minus2 ], -- Dividend.msw to R1 bReg: [ s, minus1 ], -- Dividend.lsw to MQ cReg: [ s, minus1 ], -- Remainder aluOp: PassLtWtMQ ]; IN [2..33] => m _ [ getNextMacro: FALSE, xBSource: pc, aReg: [ s, minus1 ], -- Remainder bReg: [ s, zero ], -- Divisor cReg: [ s, minus1 ], -- Remainder aluOp: DivStep ]; 34 => m _ [ getNextMacro: TRUE, aluOp: RdMQ, -- Quotient cReg: [ s, minus2 ], -- Quotient deltaS: -1 ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; dFP => { SELECT state.cycle FROM 1 => SELECT DragonFP.GetFPOpType[alpha] FROM setMode => m _ [getNextMacro: TRUE]; sglUnCom, sglUnAlu, sglUnCvt => m _ NoOpMicro; dblUnCom, dblUnAlu, dblUnCvt, sglBiCom, sglBiAlu, sglBiMult => m _ [ getNextMacro: FALSE, xBSource: pc, bReg: [ s, minus1 ], xASource: fpLdAMsw, euPBusCmd: StoreFP ]; dblBiCom, dblBiAlu, dblBiMult => m _ [ getNextMacro: FALSE, xBSource: pc, bReg: [ s, minus1 ], xASource: fpLdBMsw, euPBusCmd: StoreFP ]; ENDCASE => Dragon.Assert[FALSE]; 2 => SELECT DragonFP.GetFPOpType[alpha] FROM sglUnCom, sglUnAlu, sglUnCvt, dblUnCom, dblUnAlu, dblUnCvt, sglBiCom, sglBiAlu, sglBiMult => m _ NoOpMicro; dblBiCom, dblBiAlu, dblBiMult => m _ [ getNextMacro: FALSE, xBSource: pc, bReg: [ s, minus2 ], xASource: fpLdALsw, euPBusCmd: StoreFP ]; ENDCASE => Dragon.Assert[FALSE]; 3 => SELECT DragonFP.GetFPOpType[alpha] FROM sglUnCom, sglUnAlu, sglUnCvt, dblUnCom, dblUnAlu, dblUnCvt, sglBiCom, sglBiAlu, sglBiMult => m _ NoOpMicro; dblBiCom, dblBiAlu, dblBiMult => m _ [ getNextMacro: FALSE, xBSource: pc, bReg: [ s, minus3 ], xASource: fpLdAMsw, euPBusCmd: StoreFP ]; ENDCASE => Dragon.Assert[FALSE]; 4 => SELECT DragonFP.GetFPOpType[alpha] FROM sglUnCom => m _ [ getNextMacro: TRUE, deltaS: -1, xASource: fpUnldMsw, euPBusCmd: FetchFPAlu ]; sglUnAlu => m _ [ getNextMacro: TRUE, cReg: [ s, zero ], xASource: fpUnldMsw, euPBusCmd: FetchFPAlu ]; sglUnCvt => m _ [ getNextMacro: FALSE, xBSource: pc, cReg: [ s, zero ], xASource: fpUnldMsw, euPBusCmd: FetchFPAlu ]; dblUnCom, dblUnAlu, dblUnCvt, sglBiCom, sglBiAlu, sglBiMult, dblBiCom, dblBiAlu, dblBiMult => m _ NoOpMicro; ENDCASE => Dragon.Assert[FALSE]; 5 => SELECT DragonFP.GetFPOpType[alpha] FROM sglUnCvt => m _ [ getNextMacro: TRUE, deltaS: +1, cReg: [ s, one ], xASource: fpUnldLsw, euPBusCmd: FetchFPAlu ]; dblUnCom, sglBiCom => m _ [ getNextMacro: TRUE, deltaS: -2, xASource: fpUnldMsw, euPBusCmd: FetchFPAlu ]; dblUnAlu => m _ [ getNextMacro: FALSE, xBSource: pc, cReg: [ s, minus1 ], xASource: fpUnldMsw, euPBusCmd: FetchFPAlu ]; dblUnCvt, sglBiAlu => m _ [ getNextMacro: TRUE, deltaS: -1, cReg: [ s, minus1 ], xASource: fpUnldMsw, euPBusCmd: FetchFPAlu ]; sglBiMult => m _ [ getNextMacro: TRUE, deltaS: -1, cReg: [ s, minus1 ], xASource: fpUnldMsw, euPBusCmd: FetchFPMult ]; dblBiCom, dblBiAlu, dblBiMult => m _ NoOpMicro; ENDCASE => Dragon.Assert[FALSE]; 6 => SELECT DragonFP.GetFPOpType[alpha] FROM dblUnAlu => m _ [ getNextMacro: TRUE, cReg: [ s, zero ], xASource: fpUnldLsw, euPBusCmd: FetchFPAlu ]; dblBiCom, dblBiAlu, dblBiMult => m _ NoOpMicro; ENDCASE => Dragon.Assert[FALSE]; 7 => SELECT DragonFP.GetFPOpType[alpha] FROM dblBiCom => m _ [ getNextMacro: FALSE, xBSource: pc, deltaS: -2, -- Two more left for next cycle xASource: fpUnldMsw, euPBusCmd: FetchFPAlu ]; dblBiAlu => m _ [ getNextMacro: FALSE, xBSource: pc, cReg: [ s, minus3 ], xASource: fpUnldMsw, euPBusCmd: FetchFPAlu ]; dblBiMult => m _ NoOpMicro; ENDCASE => Dragon.Assert[FALSE]; 8 => SELECT DragonFP.GetFPOpType[alpha] FROM dblBiCom => m _ [ getNextMacro: TRUE, deltaS: -2, -- Last two xASource: fpUnldMsw, euPBusCmd: FetchFPAlu ]; dblBiAlu => m _ [ getNextMacro: TRUE, deltaS: -2, cReg: [ s, minus2 ], xASource: fpUnldLsw, euPBusCmd: FetchFPAlu ]; dblBiMult => m _ [ getNextMacro: FALSE, xBSource: pc, cReg: [ s, minus3 ], xASource: fpUnldMsw, euPBusCmd: FetchFPMult ]; ENDCASE => Dragon.Assert[FALSE]; 9 => SELECT DragonFP.GetFPOpType[alpha] FROM dblBiMult => m _ [ getNextMacro: TRUE, deltaS: -2, cReg: [ s, minus2 ], xASource: fpUnldLsw, euPBusCmd: FetchFPMult ]; ENDCASE => Dragon.Assert[FALSE]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ] }; dSIFUR => SELECT state.cycle FROM 1, 2 => m _ NoOpMicro; -- to allow ALU result to reach Result3 3 => <> <> m _ [ getNextMacro: TRUE, deltaS: -1 ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; dSJ => SELECT state.cycle FROM 1, 2, 3 => m _ NoOpMicro; -- to allow Xa to latch Result3 4 => -- S _ S-1 m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: pcPlusXA, deltaS: -1 ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; dSFC => SELECT state.cycle FROM 1, 2, 3 => m _ NoOpMicro; -- to allow Xa to latch Result3 4 => -- S _ S-1 m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: xA, deltaS: -1, pipedPLSASpec: pLenLSnext, iStackPostEffect: push ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; dSFCI => SELECT state.cycle FROM 1, 2, 3 => m _ NoOpMicro; -- to allow Xa to latch Result3 4 => m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: xA, deltaS: 0, -- shouldn't SFCI pop S? pipedPLSASpec: pLenLSnext, iStackPostEffect: push ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; dCST => SELECT state.cycle FROM <> 1 => -- IF [S+1] = [S] THEN double microPC m _ [ getNextMacro: FALSE, xBSource: pc, aReg: [ s, one ], bReg: stackTop, aluOp: VSub, condSel: EZ, condEffect: microJump ]; 2, 3 => m _ NoOpMicro; -- Allow ALU result to get back 4 => -- [] _ ([S-2]+alpha)^, release hold, S _ S+1 m _ [ aReg: [ s, minus2 ], xASource: alpha, aluRtIsK: TRUE, deltaS: 1, aluOp: VAdd, euPBusCmd: Fetch ]; 6 => -- target of microjump, ([S-2]+alpha)^ _ [S-1], release hold, S _ S+1 m _ [ aReg: [ s, minus2 ], bReg: [ s, minus1 ], xASource: alpha, aluRtIsK: TRUE, deltaS: 1, aluOp: VAdd, euPBusCmd: Store ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; dEXCH => SELECT state.cycle FROM 1 => m _ [ dontBypass: TRUE, bReg: [ s, minus1 ], cReg: stackTop ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; ENDCASE => -- unimplemented opcode SELECT Dragon.OpLength[op] FROM 2, 3, 5 => SELECT state.cycle FROM 1 => m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: xopGenerator, pipedPLSASpec: pLenLSnext, iStackPostEffect: push, deltaS: 1 ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; }; -- of successor microinstructions of multi-micro macros state.exceptions = rschlWait, state.exceptions = iStkOFlow, state.exceptions = eStkOFlow, state.exceptions = iFtchFault => m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: trapPCGenerator, iStackPostEffect: push, iTrapPostEffect: disable ]; NOT instReady OR (opcode=dRET OR opcode=dRETT OR opcode=dRETN OR opcode=dLIFUR) AND (pushPending OR popPending) OR opcode = dEP AND popPending => {m _ NoOpMicro; newState.delayed _ TRUE}; opcode = dEP AND (iStkEmpty AND NOT pushPending) => <> m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: trapPCGenerator, lSource: [ s, alpha ], pipedPLSASpec: pLenLSnext, iStackPostEffect: push, -- this push differentiates this trap from the following iTrapPostEffect: disable ]; (opcode = dRET OR opcode = dRETT OR opcode = dRETN) AND iStkEmpty => <> m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: trapPCGenerator, sSource: (IF opcode = dRET THEN [ l, alpha ] ELSE [ s, zero ]), iTrapPostEffect: disable ]; ENDCASE => m _ DecodeFirstMicroOfNewMacro[op, alpha, beta ]; newState.done _ m.doMacroJump OR m.getNextMacro OR state.cycle = 0 AND NOT instReady; }; -- of GetMicroInst DecodeFirstMicroOfNewMacro: PROC [ op: Dragon.Opcode, alpha: Dragon.HexByte, beta: Dragon.HexByte ] RETURNS [m: MicroInst] = { instruction: PACKED ARRAY [0..3] OF Dragon.Byte = [op, alpha, beta, 0]; opcode: DragOpsCross.Inst; TRUSTED {opcode _ LOOPHOLE[op]}; <<>> <> SELECT opcode FROM IN DragOpsCross.JBBformatRange => { CheckOpLength[op, 3]; m _ [ aReg: stackTop, xASource: beta, aluRtIsK: TRUE, deltaS: -1, aluOp: VSub, condSel: (SELECT opcode FROM dJEBB, dJNEBBJ => EZ, ENDCASE => NE), condEffect: macroJump, doMacroJump: (SELECT opcode FROM dJEBBJ, dJNEBBJ => TRUE, ENDCASE => FALSE), getNextMacro: (SELECT opcode FROM dJEBBJ, dJNEBBJ => FALSE, ENDCASE => TRUE), xBSource: (SELECT opcode FROM dJEBBJ, dJNEBBJ => pcPlusAlphaS, ENDCASE => pcPlusLen), pipedPLSASpec: (SELECT opcode FROM dJEBBJ, dJNEBBJ => pLenLSnext, ENDCASE => pAlphasLSnext) ] }; IN DragOpsCross.RJBformatRange => { rj: DragOpsCross.RJBformat; TRUSTED {rj _ LOOPHOLE[instruction]}; CheckOpLength[op, 3]; m _ [ aReg: [ s, (SELECT TRUE FROM rj.sd => minus1, ENDCASE => zero) ], bReg: [ (SELECT TRUE FROM rj.opt AND NOT (rj.reg MOD 16 >= 8) => cBase, rj.opt AND NOT (rj.reg MOD 8 >= 4) => cBase, rj.opt AND (rj.reg MOD 16 >= 8) AND (rj.reg MOD 8 >= 4) => s, NOT rj.opt AND rj.aux => aBase, ENDCASE -- NOT rj.opt AND NOT rj.aux -- => l), (SELECT TRUE FROM rj.opt AND NOT (rj.reg MOD 16 >= 8) => beta47, rj.opt AND NOT (rj.reg MOD 8 >= 4) => beta47, rj.opt AND (rj.reg MOD 16 >= 8) AND (rj.reg MOD 8 >= 4) AND NOT (rj.reg MOD 2 >= 1) => zero, rj.opt AND (rj.reg MOD 16 >= 8) AND (rj.reg MOD 8 >= 4) AND (rj.reg MOD 2 >= 1) => minus1, ENDCASE -- NOT rj.opt -- => beta47)], deltaS: (IF (rj.opt AND (rj.reg MOD 16 >= 8) AND (rj.reg MOD 8 >= 4) AND (rj.reg MOD 4 >= 2)) THEN -1 ELSE 0)+(IF rj.sdd THEN -1 ELSE 0), aluOp: VSub, condSel: (SELECT opcode FROM dRJEB, dRJNEBJ => EZ, dRJEBJ, dRJNEB => NE, dRJLB, dRJGEBJ => LZ, dRJLBJ, dRJGEB => GE, dRJLEB, dRJGBJ => LE, dRJLEBJ, dRJGB => GZ, ENDCASE => False), condEffect: macroJump, doMacroJump: (SELECT opcode FROM dRJEBJ, dRJNEBJ, dRJLBJ, dRJLEBJ, dRJGEBJ, dRJGBJ => TRUE, ENDCASE => FALSE), getNextMacro: (SELECT opcode FROM dRJEBJ, dRJNEBJ, dRJLBJ, dRJLEBJ, dRJGEBJ, dRJGBJ => FALSE, ENDCASE => TRUE), xBSource: (SELECT opcode FROM dRJEBJ, dRJNEBJ, dRJLBJ, dRJLEBJ, dRJGEBJ, dRJGBJ => pcPlusAlphaS, ENDCASE => pcPlusLen), pipedPLSASpec: (SELECT opcode FROM dRJEBJ, dRJNEBJ, dRJLBJ, dRJLEBJ, dRJGEBJ, dRJGBJ => pLenLSnext, ENDCASE => pAlphasLSnext) ] }; dJ1 => {CheckOpLength[op, 1]; m _ []}; dJ2 => {CheckOpLength[op, 2]; m _ []}; dJ3 => {CheckOpLength[op, 3]; m _ []}; dJ5 => {CheckOpLength[op, 5]; m _ []}; dJB => { CheckOpLength[op, 2]; m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: pcPlusAlphaS ] }; dJDB => { CheckOpLength[op, 3]; m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: pcPlusBetaAlphaS ] }; dDJ => { CheckOpLength[op, 5]; m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: deltaGammaBetaAlpha ] }; dSJ => { CheckOpLength[op, 1]; m _ [ -- ifuXBus _ [S] getNextMacro: FALSE, xBSource: pc, bReg: stackTop, cReg: ifuXBus ] }; dRET => { CheckOpLength[op, 2]; m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: iStackPC, xASource: bAddrIFUReg, bReg: ifuYoungestL, lSource: [ xBus, zero ], sSource: [ l, alpha ], iStackPostEffect: pop ] }; dRETN => { CheckOpLength[op, 1]; m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: iStackPC, xASource: bAddrIFUReg, bReg: ifuYoungestL, lSource: [ xBus, zero ], iStackPostEffect: pop ] }; dRETT => { CheckOpLength[op, 1]; m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: iStackPC, xASource: bAddrIFUReg, bReg: ifuYoungestL, lSource: [ xBus, zero ], iStackPostEffect: pop, iTrapPostEffect: enable ] }; dLFC => { CheckOpLength[op, 3]; m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: pcPlusBetaAlphaS, pipedPLSASpec: pLenLSnext, iStackPostEffect: push ] }; dDFC => { CheckOpLength[op, 5]; m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: deltaGammaBetaAlpha, pipedPLSASpec: pLenLSnext, iStackPostEffect: push ] }; dSFC => { CheckOpLength[op, 1]; m _ [ -- ifuXBus _ [S] getNextMacro: FALSE, xBSource: pc, bReg: stackTop, cReg: ifuXBus ] }; dSFCI => { CheckOpLength[op, 1]; m _ [ -- ifuXBus _ [S]^ getNextMacro: FALSE, xBSource: pc, bReg: stackTop, cReg: ifuXBus, euPBusCmd: Fetch ] }; dIN => { CheckOpLength[op, 2]; m _ [ aReg: stackTop, xASource: alpha, aluRtIsK: TRUE, cReg: stackTop, aluOp: VAdd, euPBusCmd: IOFetch ] }; dRB => { CheckOpLength[op, 2]; m _ [ aReg: stackTop, xASource: alpha, aluRtIsK: TRUE, cReg: stackTop, aluOp: VAdd, euPBusCmd: Fetch ] }; dRSB => { CheckOpLength[op, 2]; m _ [ aReg: stackTop, xASource: alpha, aluRtIsK: TRUE, cReg: [ s, one ], deltaS: 1, aluOp: VAdd, euPBusCmd: Fetch ] }; IN [dLRI0..dLRI15] => { CheckOpLength[op, 2]; m _ [ aReg: [ l, op47 ], xASource: alpha, aluRtIsK: TRUE, cReg: [ s, one ], deltaS: 1, aluOp: VAdd, euPBusCmd: Fetch ] }; <> dLGF => { CheckOpLength[op, 3]; m _ [ aReg: euGF, xASource: betaAlpha, aluRtIsK: TRUE, cReg: [ s, one ], deltaS: 1, aluOp: VAdd, euPBusCmd: Fetch ] }; dRRI, dRAI => { CheckOpLength[op, 3]; m _ [ aReg: [ (SELECT opcode FROM dRRI => l, ENDCASE => aBase), beta47], xASource: alpha, aluRtIsK: TRUE, cReg: [ l, beta03 ], aluOp: VAdd, euPBusCmd: Fetch ] }; <> dCST => { CheckOpLength[op, 2]; m _ [ getNextMacro: FALSE, xBSource: pc, aReg: [ s, minus2 ], xASource: alpha, aluRtIsK: TRUE, cReg: [ s, one ], aluOp: VAdd, euPBusCmd: FetchHold ] }; dOUT => { CheckOpLength[op, 2]; m _ [ aReg: stackTop, bReg: [ s, minus1 ], xASource: alpha, aluRtIsK: TRUE, deltaS: -2, aluOp: VAdd, euPBusCmd: IOStore ] }; dWB => { CheckOpLength[op, 2]; m _ [ aReg: stackTop, bReg: [ s, minus1 ], xASource: alpha, aluRtIsK: TRUE, deltaS: -2, aluOp: VAdd, euPBusCmd: Store ] }; dWSB => { CheckOpLength[op, 2]; m _ [ aReg: [ s, minus1 ], bReg: stackTop, xASource: alpha, aluRtIsK: TRUE, deltaS: -2, aluOp: VAdd, euPBusCmd: Store ] }; dPSB => { CheckOpLength[op, 2]; m _ [ aReg: [ s, minus1 ], bReg: stackTop, xASource: alpha, aluRtIsK: TRUE, deltaS: -1, aluOp: VAdd, euPBusCmd: Store ] }; IN [dSRI0..dSRI15] => { CheckOpLength[op, 2]; m _ [ aReg: [ l, op47 ], bReg: [ s, zero ], xASource: alpha, aluRtIsK: TRUE, deltaS: -1, aluOp: VAdd, euPBusCmd: Store ] }; dWRI, dWAI => { CheckOpLength[op, 3]; m _ [ aReg: [ (SELECT opcode FROM dWRI => l, ENDCASE => aBase), beta47], bReg: [ l, beta03 ], xASource: alpha, aluRtIsK: TRUE, aluOp: VAdd, euPBusCmd: Store ] }; dDIS => { CheckOpLength[op, 1]; m _ [deltaS: -1] }; dAS => { CheckOpLength[op, 2]; m _ [sSource: [s, alpha]] }; dAL => { CheckOpLength[op, 2]; m _ [lSource: [l, alpha]] }; dASL => { CheckOpLength[op, 2]; m _ [sSource: [ l, alpha]] }; dEP => { CheckOpLength[op, 2]; m _ [lSource: [ s, alpha]] }; dFSDB => { CheckOpLength[op, 3]; m _ [ xASource: betaAlpha, aluRtIsK: TRUE, cReg: euField ] }; dLIB => { CheckOpLength[op, 2]; m _ [ xASource: alpha, aluRtIsK: TRUE, cReg: [ s, one ], deltaS: 1 ] }; dLIDB => { CheckOpLength[op, 3]; m _ [ xASource: betaAlpha, aluRtIsK: TRUE, cReg: [ s, one ], deltaS: 1 ] }; dLIQB => { CheckOpLength[op, 5]; m _ [ xASource: deltaGammaBetaAlpha, aluRtIsK: TRUE, cReg: [ s, one ], deltaS: 1 ] }; IN [dLC0..dLC7] => { CheckOpLength[op, 1]; m _ [ bReg: [ cBase, op47 ], cReg: [ s, one ], deltaS: 1 ] }; IN [dLR0..dLR15] => { CheckOpLength[op, 1]; m _ [ bReg: [ l, op47 ], cReg: [ s, one ], deltaS: 1 ] }; IN [dSR0..dSR15] => { CheckOpLength[op, 1]; m _ [ bReg: [ s, zero ], cReg: [ l, op47 ], deltaS: -1 ] }; dDUP => { CheckOpLength[op, 1]; m _ [ bReg: stackTop, cReg: [ s, one ], deltaS: 1 ] }; dEXDIS => { CheckOpLength[op, 1]; m _ [ bReg: stackTop, cReg: [ s, minus1 ], deltaS: -1 ] }; dEXCH => { CheckOpLength[op, 1]; m _ [ getNextMacro: FALSE, xBSource: pc, bReg: stackTop, cReg: [ s, minus1 ] ] }; dSEUR => { CheckOpLength[op, 2]; m _ [ bReg: stackTop, cReg: [ zero, alpha ], deltaS: -1 ] }; dSIFUR => { CheckOpLength[op, 2]; m _ [ getNextMacro: FALSE, xBSource: pc, bReg: stackTop, cReg: [ zero, alpha ] ] }; dLEUR => { CheckOpLength[op, 2]; m _ [ bReg: [ zero, alpha ], cReg: [ s, one ], deltaS: 1 ] }; dLIFUR => { CheckOpLength[op, 2]; m _ [ bReg: [zero, alpha], xASource: bAddrIFUReg, aluRtIsK: TRUE, cReg: [ s, one ], deltaS: 1 ] }; dADDB => { CheckOpLength[op, 2]; m _ [ aReg: stackTop, xASource: alpha, aluRtIsK: TRUE, cReg: stackTop, aluOp: SAdd, condSel: OvFl ] }; dADDDB => { CheckOpLength[op, 3]; m _ [ aReg: stackTop, xASource: betaAlpha, aluRtIsK: TRUE, cReg: stackTop, aluOp: SAdd, condSel: OvFl ] }; dSUBB => { CheckOpLength[op, 2]; m _ [ aReg: stackTop, xASource: alpha, aluRtIsK: TRUE, cReg: stackTop, aluOp: SSub, condSel: OvFl ] }; dSHL, dSHR => { CheckOpLength[op, 3]; m _ [ aReg: stackTop, bReg: [ (IF opcode=dSHL THEN cBase ELSE s), zero ], xASource: betaAlpha, cReg: stackTop, aluOp: FOPK ] }; dADD => { CheckOpLength[op, 1]; m _ [ aReg: [ s, minus1 ], bReg: stackTop, cReg: [ s, minus1 ], deltaS: -1, aluOp: SAdd, condSel: OvFl, condEffect: macroTrap ] }; dSUB => { CheckOpLength[op, 1]; m _ [ aReg: [ s, minus1 ], bReg: [ s, zero ], cReg: [ s, minus1 ], deltaS: -1, aluOp: SSub, condSel: OvFl, condEffect: macroTrap ] }; dMUL => { CheckOpLength[op, 1]; m _ [ getNextMacro: FALSE, xBSource: pc, aReg: constantZero, -- R1 = Product.msw _ 0 bReg: [ s, minus1 ], -- MQ = Product.lsw | Multiplier _ Multiplier cReg: [ s, minus1 ], -- Product.msw aluOp: PassLtWtMQ ] }; dDIV => { CheckOpLength[op, 1]; m _ [ getNextMacro: FALSE, xBSource: pc, aReg: [ s, minus2 ], bReg: [ s, zero ], aluOp: VSub, condSel: GE, condEffect: macroTrap ] }; dFP => { CheckOpLength[op, 2]; SELECT DragonFP.GetFPOpType[alpha] FROM setMode => m _ [ getNextMacro: FALSE, -- delay one for KBus contention xBSource: pc, xASource: fpLdMode, euPBusCmd: StoreFP]; sglUnCom, sglUnAlu, sglUnCvt => m _ [ getNextMacro: FALSE, xBSource: pc, bReg: [ s, zero ], xASource: fpLdAMsw, euPBusCmd: StoreFP]; dblUnCom, dblUnAlu, dblUnCvt => m _ [ getNextMacro: FALSE, xBSource: pc, bReg: [ s, zero ], xASource: fpLdALsw, euPBusCmd: StoreFP]; sglBiCom, sglBiAlu, sglBiMult => m _ [ getNextMacro: FALSE, xBSource: pc, bReg: [ s, zero ], xASource: fpLdBMsw, euPBusCmd: StoreFP]; dblBiCom, dblBiAlu, dblBiMult => m _ [ getNextMacro: FALSE, xBSource: pc, bReg: [ s, zero ], xASource: fpLdBLsw, euPBusCmd: StoreFP]; ENDCASE => Dragon.Assert[FALSE] }; dBNDCK => { CheckOpLength[op, 1]; m _ [ aReg: [ s, minus1 ], bReg: [ s, zero ], deltaS: -1, aluOp: BndChk, condSel: BC, condEffect: macroTrap ] }; IN DragOpsCross.RRformatRange => { rr: DragOpsCross.RRformat; TRUSTED {rr _ LOOPHOLE[instruction]}; CheckOpLength[op, 3]; m _ [ aReg: [ (SELECT TRUE FROM rr.aOpt AND NOT (rr.a MOD 16 >= 8) => cBase, rr.aOpt AND NOT (rr.a MOD 8 >= 4) => cBase, rr.aOpt AND (rr.a MOD 16 >= 8) AND (rr.a MOD 8 >= 4) => s, NOT rr.aOpt AND rr.aux => aBase, ENDCASE -- NOT rr.aOpt AND NOT rr.aux -- => l), (SELECT TRUE FROM rr.aOpt AND NOT (rr.a MOD 16 >= 8) => alpha47, rr.aOpt AND NOT (rr.a MOD 8 >= 4) => alpha47, rr.aOpt AND (rr.a MOD 16 >= 8) AND (rr.a MOD 8 >= 4) AND NOT (rr.a MOD 2 >= 1) => zero, rr.aOpt AND (rr.a MOD 16 >= 8) AND (rr.a MOD 8 >= 4) AND (rr.a MOD 2 >= 1) => minus1, ENDCASE -- NOT rr.aOpt -- => alpha47)], bReg: [ (SELECT TRUE FROM rr.bOpt AND NOT (rr.b MOD 16 >= 8) => cBase, rr.bOpt AND NOT (rr.b MOD 8 >= 4) => cBase, rr.bOpt AND (rr.b MOD 16 >= 8) AND (rr.b MOD 8 >= 4) => s, NOT rr.bOpt AND rr.aux => aBase, ENDCASE -- NOT rr.bOpt AND NOT rr.aux -- => l), (SELECT TRUE FROM rr.bOpt AND NOT (rr.b MOD 16 >= 8) => beta47, rr.bOpt AND NOT (rr.b MOD 8 >= 4) => beta47, rr.bOpt AND (rr.b MOD 16 >= 8) AND (rr.b MOD 8 >= 4) AND NOT (rr.b MOD 2 >= 1) => zero, rr.bOpt AND (rr.b MOD 16 >= 8) AND (rr.b MOD 8 >= 4) AND (rr.b MOD 2 >= 1) => minus1, ENDCASE -- NOT rr.bOpt -- => beta47)], cReg: [ (SELECT TRUE FROM rr.cOpt AND NOT (rr.c MOD 16 >= 8) => cBase, rr.cOpt AND NOT (rr.c MOD 8 >= 4) => cBase, rr.cOpt AND (rr.c MOD 16 >= 8) AND (rr.c MOD 8 >= 4) => s, NOT rr.cOpt AND rr.aux => aBase, ENDCASE -- NOT rr.cOpt AND NOT rr.aux -- => l), (SELECT TRUE FROM rr.cOpt AND NOT (rr.c MOD 16 >= 8) => alpha03, rr.cOpt AND NOT (rr.c MOD 8 >= 4) => alpha03, rr.cOpt AND (rr.c MOD 16 >= 8) AND (rr.c MOD 8 >= 4) AND NOT (rr.c MOD 4 >= 2) AND NOT (rr.c MOD 2 >= 1) => zero, rr.cOpt AND (rr.c MOD 16 >= 8) AND (rr.c MOD 8 >= 4) AND NOT (rr.c MOD 4 >= 2) AND (rr.c MOD 2 >= 1) => minus1, rr.cOpt AND (rr.c MOD 16 >= 8) AND (rr.c MOD 8 >= 4) AND (rr.c MOD 4 >= 2) => one, ENDCASE -- NOT rr.cOpt -- => alpha03)], deltaS: INT[SELECT TRUE FROM rr.aOpt AND (rr.a MOD 16 >= 8) AND (rr.a MOD 8 >= 4) AND (rr.a MOD 4 >= 2) => -1, ENDCASE => 0]+ INT[SELECT TRUE FROM rr.bOpt AND (rr.b MOD 16 >= 8) AND (rr.b MOD 8 >= 4) AND (rr.b MOD 4 >= 2) => -1, ENDCASE => 0]+ INT[SELECT TRUE FROM rr.cOpt AND (rr.c MOD 16 >= 8) AND (rr.c MOD 8 >= 4) AND (rr.c MOD 4 >= 2) AND (rr.c MOD 2 >= 1) => 1, ENDCASE => 0], aluOp: (SELECT opcode FROM dRFU => FOP, dRADD => SAdd, dRAND => And, dRLADD => LAdd, dRLSUB => LSub, dROR => Or, dRRX => VAdd, dRSUB => SSub, dRUADD => UAdd, dRUSUB => USub, dRVADD => VAdd, dRVSUB => VSub, dRXOR => Xor, ENDCASE => Reserve31), condSel: (SELECT opcode FROM dRADD, dRSUB => OvFl, dRLADD, dRLSUB => IL, ENDCASE => False), euPBusCmd: (SELECT opcode FROM dRRX => Fetch, ENDCASE => NoOp) ] }; ENDCASE => -- unimplemented opcode SELECT Dragon.OpLength[op] FROM 1 => m _ [ doMacroJump: TRUE, getNextMacro: FALSE, xBSource: xopGenerator, pipedPLSASpec: pLenLSnext, iStackPostEffect: push ]; 2, 3, 5 => m _ [ getNextMacro: FALSE, xBSource: pc, xASource: deltaGammaBetaAlpha, aluRtIsK: TRUE, cReg: [ s, one ] ]; ENDCASE => Dragon.Assert[ FALSE, "Unimplemented Dragon microcode" ]; }; -- of DecodeFirstMicroOfNewMacro CheckOpLength: PROC [op: Dragon.HexByte, len: [0..5]] = {Dragon.Assert[ Dragon.OpLength[op] = len ]}; END.