DIRECTORY DragOpsCross USING [FieldDescriptor, IFUStackSize, Inst, ProcessorRegister, StackedStatusWord, TrapIndex, Word, ZerosWord], DragOpsCrossUtils USING [CardToWord, HalvesToWord, TrapIndexToBytePC, WordToBytes, WordToHalves], LizardCache USING [CacheBase], Rope USING [ROPE]; LizardHeart: CEDAR DEFINITIONS IMPORTS DragOpsCrossUtils = BEGIN OPEN DragOpsCross, DragOpsCrossUtils; LizardIFUStackSize: NAT = MIN[ MAX[IFUStackSize+7, 16], MAX[IFUStackSize+7, 32], MAX[IFUStackSize+7, 64], MAX[IFUStackSize+7, 128], MAX[IFUStackSize+7, 256]]; LizardIFUStackIndex: TYPE = [0..LizardIFUStackSize); CacheBase: TYPE = LizardCache.CacheBase; Processor: TYPE = REF ProcessorRep; -- eventually something else ProcessorRep: TYPE = RECORD [ logger: ChangeLogger _ NIL, youngest: LizardIFUStackIndex _ 0, eldest: LizardIFUStackIndex _ 0, stackEntries: LizardIFUStackIndex _ 0, euBusyReg: ProcessorRegister _ euJunk, euCarry: BOOL _ FALSE, resetRequested: BOOL _ TRUE, rescheduleRequested: BOOL _ FALSE, trapsEnabled: BOOL _ FALSE, userMode: BOOL _ FALSE, version: [0..255] _ 0, stats: ProcessorStats _ [], lastCallRtn: INT _ 0, -- inst count of last call/return instBuffer: InstBuffer _ NIL, ifuCache: CacheBase _ NIL, euCache: CacheBase _ NIL, regs: ARRAY ProcessorRegister OF Word _ ALL[ZerosWord], regsGood: ARRAY ProcessorRegister OF BOOL _ ALL[FALSE], ifuStack: ARRAY LizardIFUStackIndex OF IFUStackEntry _ ALL[[ZerosWord, []]] ]; InstBuffer: TYPE = REF InstBufferRep; InstBufferRep: TYPE = RECORD [ basePC: Word _ ZerosWord, -- PC corresponding to startValid nextPC: Word _ ZerosWord, -- next PC in straightline code validWords: CARDINAL _ 0, -- # of words in buffer bytesDiscarded: INT _ 0, -- # of bytes ahead of PC discarded forcedEmpty: INT _ 0, -- # of times forced empty busyUntil: INT _ 0, -- cycle # the ifu cache is busy until words: SEQUENCE max: NAT OF Word ]; ProcessorStats: TYPE = RECORD [ instructions: INT _ 0, cycles: INT _ 0, euFetches: INT _ 0, euStores: INT _ 0, instBytes: INT _ 0, fallThruGood, fallThruBad: INT _ 0, jumpGood, jumpBad: INT _ 0, jumpBackU, jumpBackG, jumpBackB: INT _ 0, jumps: INT _ 0, calls: INT _ 0, stackOver: INT _ 0, regBusyCycles: INT _ 0, instBufferCycles: INT _ 0, lookaheadProbes: INT _ 0, lookaheadRejects: INT _ 0, returnInterlockCycles: INT _ 0 ]; ChangeLogger: TYPE = REF ChangeLoggerRep; ChangeLoggerRep: TYPE = RECORD [ data: REF _ NIL, regChange: RegChangeProc _ NIL, memChange: MemChangeProc _ NIL, ioChange: IOChangeProc _ NIL, instStart: InstStartProc _ NIL, instDone: InstDoneProc _ NIL ]; RegChangeProc: TYPE = PROC [data: REF, processor: Processor, reg: ProcessorRegister, old,new: Word]; MemChangeProc: TYPE = PROC [data: REF, processor: Processor, addr: Word, old,new: Word]; IOChangeProc: TYPE = PROC [data: REF, processor: Processor, addr: Word, old,new: Word]; InstStartProc: TYPE = PROC [data: REF, processor: Processor, thisPC: Word, inst: Inst, rest: Word]; InstDoneProc: TYPE = PROC [data: REF, processor: Processor, newPC, rtnPC: Word, control: Control, cycles: INT]; IFUStackEntry: TYPE = RECORD [pc: Word, status: DragOpsCross.StackedStatusWord]; Control: TYPE = {nextInst, doCall, doReturn, doSwitch, doAbort}; ALUOps: TYPE = MACHINE DEPENDENT { SAdd(0), SSub(1), UAdd(2), USub(3), VAdd(4), VSub(5), LAdd(6), LSub(7), FOP(8), FOPK(9), And(10), Or(11), Xor(12), BndChk(13), Reserve14(14), Reserve15(15), Reserve16(16), Reserve17(17), Reserve18(18), Reserve19(19), Reserve20(20), Reserve21(21), Reserve22(22), Reserve23(23), Reserve24(24), Reserve25(25), Reserve26(26), Reserve27(27), Reserve28(28), Reserve29(29), Reserve30(30), Reserve31(31)}; EUPageFault: TrapIndex = MapFault; EUWriteFault: TrapIndex = MemAccessFault; NoFault: TrapIndex = ALUCondFalse; NewProcessor: PROC [ifuCache,euCache: CacheBase, logger: ChangeLogger] RETURNS [Processor]; InstructionExecute: PROC [processor: Processor]; FlushInstBuffer: PROC [processor: Processor]; Signs: TYPE = MACHINE DEPENDENT { a0b0c0 (0), a0b0c1 (1), a0b1c0 (2), a0b1c1 (3), a1b0c0 (4), a1b0c1 (5), a1b1c0 (6), a1b1c1 (7)}; ALUHelper: PROC [a,b,c: BOOL] RETURNS [Signs] = INLINE { RETURN [LOOPHOLE[ 4*LOOPHOLE[a, CARDINAL] + 2*LOOPHOLE[b, CARDINAL] + LOOPHOLE[c, CARDINAL]]]; }; InstBytes: PROC [inst: Inst] RETURNS [bytes: [1..5]] = INLINE { SELECT LOOPHOLE[inst, CARDINAL] FROM < 40B => bytes _ 1; < 100B => bytes _ 5; ENDCASE => bytes _ LOOPHOLE[inst, CARDINAL] / 64; }; RegPlus: PROC [reg: ProcessorRegister, delta: INTEGER] RETURNS [ProcessorRegister] = INLINE { RETURN [LOOPHOLE[(LOOPHOLE[reg, CARDINAL] + LOOPHOLE[delta, CARDINAL]) MOD 256]]; }; StackPlus: PROC [reg: ProcessorRegister, delta: INTEGER] RETURNS [ProcessorRegister] = INLINE { RETURN [LOOPHOLE[(LOOPHOLE[reg, CARDINAL] + LOOPHOLE[delta, CARDINAL]) MOD 128]]; }; AlphaZ: PROC [rest: Word] RETURNS [CARDINAL] = INLINE { RETURN [LOOPHOLE[WordToBytes[rest][3]]]; }; AlphaBetaZ: PROC [rest: Word] RETURNS [CARDINAL] = INLINE { RETURN [LOOPHOLE[WordToHalves[rest][1]]]; }; AlphaS: PROC [rest: Word] RETURNS [INTEGER] = INLINE { i: INTEGER _ LOOPHOLE[WordToBytes[rest][3], CARDINAL]; RETURN [IF i > 127 THEN i _ i - 256 ELSE i]; }; AlphaBetaS: PROC [rest: Word] RETURNS [INTEGER] = INLINE { RETURN [LOOPHOLE[WordToHalves[rest][1]]]; }; BetaZ: PROC [rest: Word] RETURNS [CARDINAL] = INLINE { RETURN [LOOPHOLE[WordToBytes[rest][2]]]; }; BetaS: PROC [rest: Word] RETURNS [INTEGER] = INLINE { i: INTEGER _ LOOPHOLE[WordToBytes[rest][2], CARDINAL]; RETURN [IF i > 127 THEN i _ i - 256 ELSE i]; }; WordToReg: PROC [word: Word] RETURNS [ProcessorRegister] = INLINE { RETURN [LOOPHOLE[WordToBytes[word][3]]]; }; RegToWord: PROC [reg: ProcessorRegister] RETURNS [Word] = INLINE { RETURN [HalvesToWord[[LOOPHOLE[0], LOOPHOLE[reg]]]]; }; TrapPC: PUBLIC PROC [tx: DragOpsCross.TrapIndex] RETURNS [Word] = INLINE { RETURN [CardToWord[DragOpsCrossUtils.TrapIndexToBytePC[tx]]]; }; DoALUOp: PUBLIC PROC [processor: Processor, wordA,wordB: Word, op: ALUOps, trap: TrapIndex] RETURNS [res: Word, resCode: TrapIndex _ NoFault]; FieldUnit: PUBLIC PROC [Left,Right: Word, fd: FieldDescriptor] RETURNS [out: Word]; WillPushOverflow: PUBLIC PROC [processor: Processor] RETURNS [BOOL]; OutsideEnvelope: PUBLIC SIGNAL [explanation: Rope.ROPE]; END. ΪLizardHeart.mesa Copyright c 1984, 1985, 1986 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) May 18, 1987 7:25:17 pm PDT McCreight, January 14, 1986 11:10:48 am PST A power of two that is significantly larger than the real stack size. for relative jumps (U: uncond, G: good predict, B: badPredict) Number of unconditional jump instructions Number of call instructions Stack overflows Cycles spent waiting due to register conflicts Cycles spent waiting for instructions Cache fetches due to instruction buffer lookahead Reject cycles due to instruction buffer lookahead Cycles spent waiting for returns too close together Copied from /Indigo/Dragon/Rosemary/Dragon.mesa Used to indicate page fault from cache, even for IFU fetches. Used to indicate write protect fault from EU cache. Any unused code will do. But we need a state to indicate that everything is OK. This routine flushes the instruction buffer. This occurs on a bad jump prediction, a trap, or an xop. INLINE routines for picking apart various pieces of the input Utility Routines for manipulating data (incomplete) Turns a trap index into a byte PC. This is a full routine to keep from making the compiler unhappy with excessive INLINEs. ... returns TRUE if the next push will overflow the IFU stack. Signals OutsideEnvelope in illegal cases. The program has been caught red-handed doing something that no reasonable Dragon program should do; something for which the hardware response needn't be defined. Κ e˜codešœ™Kšœ Οmœ=™HK™/K™+—˜šΟk ˜ Kšœ žœi˜{KšœžœJ˜aKšœ žœ ˜Kšœžœžœ˜——headšœ žœž ˜Kšžœ˜Kšœž œ žœž˜-K˜šœžœžœ˜Kšžœ˜Kšžœ˜Kšžœ˜Kšžœ˜Kšžœ˜KšœE™E—Kšœžœ˜4K˜Kšœ žœ˜(K˜Kšœ žœžœΟc˜Ašœžœžœ˜Kšœžœ˜Kšœ"˜"Kšœ ˜ Kšœ&˜&Kšœ&˜&Kšœ žœžœ˜Kšœžœžœ˜Kšœžœžœ˜"Kšœžœžœ˜Kšœ žœžœ˜Kšœ˜Kšœ˜Kšœ žœŸ!˜8Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœžœžœ ˜7Kš œ žœžœžœžœžœ˜7Kšœ žœžœžœ˜KK˜K˜—Kšœ žœžœ˜%šœžœžœ˜K–18 sp tabStopsšœŸ!˜;K–18 sp tabStopsšœŸ˜9K–18 sp tabStopsšœ žœŸ˜1K–18 sp tabStopsšœžœŸ#˜—šœžœ˜Kšœ)™)—šœžœ˜Kšœ™—šœ žœ˜Kšœ™—šœžœ˜Kšœ.™.—šœžœ˜Kšœ%™%—šœžœ˜Kšœ1™1—šœžœ˜Kšœ1™1—šœžœ˜Kšœ3™3—K˜K˜—Kšœžœžœ˜)šœžœžœ˜ Kšœžœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœž˜Kšœ˜K˜—šœžœ˜Kšžœžœ?˜N—šœžœ˜Kšžœžœ3˜B—šœžœ˜Kšžœžœ3˜B—šœžœ˜Kšžœžœ>˜M—šœžœ˜KšžœžœFžœ˜ZK˜—Kšœžœžœ4˜PK˜Kšœ žœ3˜@K˜šœžœžœž œ˜"Kšœ/™/KšœHžœžœΉ˜K˜—šΟn œ˜"Kšœ1žœ ™=—š  œ˜)Kšœ*žœ™3K˜—š œ˜"KšœMžœ™P—K˜š  œžœ5žœ ˜[K˜—Kš œžœ˜0K˜š œžœ˜-Kšœf™fK˜——šœ=™=K˜šœžœžœž œ˜!K˜0K˜0K˜—š   œžœ žœžœ žœ˜8šžœžœ˜Kš œžœžœžœžœžœžœ˜L—K˜K˜—š  œžœžœžœ˜?šžœžœžœž˜$K˜K˜Kšžœ žœžœ˜1—K˜K˜—š  œžœ!žœžœžœ˜]Kšžœžœžœžœžœžœžœ˜QK˜K˜—š  œž˜Kšœ žœžœžœ˜OKšžœžœžœžœžœžœžœ˜QK˜K˜—š  œžœžœžœžœ˜7Kšžœžœ˜(K˜K˜—š   œžœžœžœžœ˜;Kšžœžœ˜)K˜K˜—š  œžœžœžœžœ˜6Kšœžœžœžœ˜6Kšžœžœ žœ žœ˜,K˜K˜—š   œžœžœžœžœ˜:Kšžœžœ˜)K˜K˜—š  œžœžœžœžœ˜6Kšžœžœ˜(K˜K˜—š  œžœžœžœžœ˜5Kšœžœžœžœ˜6Kšžœžœ žœ žœ˜,K˜K˜—š  œžœžœžœ˜CKšžœžœ˜(Kšœ˜K˜—š  œžœžœ žœ˜BKšžœžœžœ ˜4Kšœ˜—K™Kšœ3™3K˜š œž œžœ žœ˜JKšœ{™{Kšžœ7˜=K˜—K˜š œž œGžœ+˜ŽK˜—Kš  œž œ)žœ ˜SK˜š  œžœžœžœžœ˜DKšœi™i—K˜šœžœžœžœ˜8Kšœ‘™‘—K˜K˜—Kšžœ˜K˜—…—n'­