<> <> <> <> <<>> <DragOps>DragOpsCross.mesa with many thanks to Russ.>> <<>> DIRECTORY Rope, PrincOps; TamDefs: CEDAR DEFINITIONS = BEGIN <> <<>> numFrames: NAT = 6; numWordsPerFrame: NAT = 48; <<>> Word: TYPE = PACKED ARRAY FiveBitIndex OF BOOL; ZerosWord: Word = LOOPHOLE[LONG[0]]; <> OnesWord: Word = LOOPHOLE[LONG[-1]]; <> <<>> wordsPerPage: CARDINAL = 1024; bytesPerWord: CARDINAL = 4; charsPerWord: CARDINAL = 4; bitsPerByte: CARDINAL = 8; bitsPerCharacter: CARDINAL = 8; bitsPerWord: CARDINAL = bitsPerByte*bytesPerWord; bytesPerPage: CARDINAL = wordsPerPage*bytesPerWord; logWordsPerPage: CARDINAL = 10; -- LogBase2[wordsPerPage] logBitsPerByte: CARDINAL = 3; --LogBase2[bitsPerByte] logBitsPerChar: CARDINAL = 3; --LogBase2[bitsPerCharacter] logBytesPerWord: CARDINAL = 1; --LogBase2[bytesPerWord] logCharsPerWord: CARDINAL = 1; --LogBase2[bytesPerWord] logBitsPerWord: CARDINAL = logBitsPerByte + logBytesPerWord; logBytesPerPage: CARDINAL = logBytesPerWord + logWordsPerPage; PageCount: TYPE = INT; <> PageNumber: TYPE = INT; <> maxPagesInVM: PageCount = LONG[4]*LONG[1024]*LONG[1024]; <<22-bit page index>> OneBitIndex: TYPE = [0..1]; TwoBitIndex: TYPE = [0..3]; ThreeBitIndex: TYPE = [0..7]; FourBitIndex: TYPE = [0..16); FiveBitIndex: TYPE = [0..32); SixBitIndex: TYPE = [0..64); SevenBitIndex: TYPE = [0..128); TwoWords: TYPE = ARRAY [0..1] OF Word; Half: TYPE = PACKED ARRAY FourBitIndex OF BOOL; ZerosHalf: Half = LOOPHOLE[0]; OnesHalf: Half = LOOPHOLE[-1]; FourHalves: TYPE = ARRAY [0..3] OF Half; TwoHalves: TYPE = ARRAY [0..1] OF Half; Byte: TYPE = PACKED ARRAY ThreeBitIndex OF BOOL; ZerosByte: Byte = LOOPHOLE[0]; OnesByte: Byte = LOOPHOLE[377B]; EightBytes: TYPE = PACKED ARRAY [0..7] OF Byte; FourBytes: TYPE = PACKED ARRAY ByteIndex OF Byte; ByteIndex: TYPE = [0..bytesPerWord); BytesPerWord: NAT = 4; TwoBytes: TYPE = PACKED ARRAY [0..1] OF Byte; Comparison: TYPE = MACHINE DEPENDENT {less(0), equal(1), greater(2)}; <> ByteAddress: TYPE = RECORD [Word]; <> WordAddress: TYPE = RECORD [Word]; <> <<>> TaggedWord: TYPE = RECORD [tag: TwoBitIndex, data: Word]; XBitRec: TYPE = RECORD [refcount: FourBitIndex, cdr: TwoBitIndex]; FullWord: TYPE = RECORD [xBits: XBitRec, tagWord: TaggedWord]; ZeroTaggedBus: TaggedWord = [tag: 0, data: ZerosWord]; ZeroFullBus: FullWord = [[refcount: 0, cdr: 0], [tag: 0, data: ZerosWord]]; UCodeWord: TYPE = RECORD [ rCxt, wCxt, newTopCxt, newBotCxt, altCxt, cycle, memOp, euOp, tag, rd1addr, rd2addr, w2addr, dswap, raddr, waddr, newArg, newArg2, newTos, k, k2, dpCondRes, muxCondRes, euCondRes, memCondRes, writeT, writeF, jumpT, jumpF, opLength, misc: NAT ]; DPCondCodeWord: TYPE = RECORD [tag: [0..3], word: CARD]; DPCondCodeRec: TYPE = RECORD [d1, nD1, d2, nD2, d1XorD2: DPCondCodeWord]; ClockRec: TYPE = MACHINE DEPENDENT RECORD [ clock (0: 00..00): BOOL _ FALSE, clock2 (0: 01..01): BOOL _ FALSE, clockstate (0: 02..02): BOOL _ FALSE, writeOk (0: 03..03): BOOL _ FALSE, done (0: 04..04): BOOL _ FALSE, stall (0: 05..05): BOOL _ FALSE ]; <> <<>> <> <> <<>> <> StackFrame: TYPE = MACHINE DEPENDENT { frameHead (0), -- beginning of Stack Frame pvarExt (7), -- pvar overflow (extension) slot varsEnd (15), -- end of vars space stackPtr (16), -- Stack ptr. word pc (17), -- PC nameTable (18), -- name table entry funHeader (19), -- Function Header entry cLink (20), -- clink entry stackStart (21), -- start of additional vars or stack stackEnd (numWordsPerFrame) }; ProcessorRegister: TYPE = MACHINE DEPENDENT { <> cxtZero (0), -- starting address for context 0 (global) cxtOne (64), -- starting address for context 1 cxtTwo (128), -- starting address for context 2 cxtThree (192), -- starting address for context 3 cxtFour (256), -- starting address for context 4 cxtFive (320), -- starting address for context 5 cxtGlobal (384), -- starting address for global context lastReg (407), -- last real processor reg curPC (408), -- last committed pc nextPC (409) }; StackedStatusWord: TYPE = MACHINE DEPENDENT RECORD [ version (0: 00..07): [0..255] _ 0, padBits (0: 08..13): [0..63] _ 0, userMode (0: 14..14): BOOL _ FALSE, -- TRUE => user, FALSE => kernel trapsEnabled (0: 15..15): BOOL _ FALSE, padByte (0: 16..23): [0..255] _ 0, lBase (0: 24..31): [0..255] _ 0 ]; -- EU local frame base EuUnits: TYPE = MACHINE DEPENDENT { NOP (0), Adder (1), LU (2), Shifter (3), Prior (4), LdMult (6), UnLdMult (7)}; LuOpType: TYPE = MACHINE DEPENDENT { tAND (1), tXOR (6), tOR (7), tNOR (8), tNAND (14)}; AdderOpType: TYPE = MACHINE DEPENDENT { tADD (0), tADDC (1), tSUB (8), tSUBC (9)}; EuControlRec: TYPE = MACHINE DEPENDENT RECORD [ euUnit (0: 00..02): EuUnits, euBits (0: 03..15): SELECT OVERLAID EuUnits FROM Adder => [adderOp (0: 03..15): AdderOpType], LU => [luOp (0: 03..15): LuOpType] ENDCASE ]; <> BytesToWord: PROC [fb: FourBytes] RETURNS [Word] = TRUSTED INLINE { RETURN[LOOPHOLE[fb, Word]]; }; BytesToHalf: PROC [tb: TwoBytes] RETURNS [Half] = TRUSTED INLINE { RETURN[LOOPHOLE[tb, Half]]; }; WordToBytes: PROC [w: Word] RETURNS [FourBytes] = TRUSTED INLINE { RETURN[LOOPHOLE[w, FourBytes]]; }; HalfToBytes: PROC [h: Half] RETURNS [TwoBytes] = TRUSTED INLINE { RETURN[LOOPHOLE[h, TwoBytes]]; }; HalvesToWord: PROC [th: TwoHalves] RETURNS [Word] = TRUSTED INLINE { RETURN[LOOPHOLE[th, Word]]; }; WordToHalves: PROC [w: Word] RETURNS [TwoHalves] = TRUSTED INLINE { RETURN[LOOPHOLE[w, TwoHalves]]; }; HighHalf: PROC [w: Word] RETURNS [Half] = TRUSTED INLINE { RETURN[LOOPHOLE[w, TwoHalves][0]]; }; LowHalf: PROC [w: Word] RETURNS [Half] = TRUSTED INLINE { RETURN[LOOPHOLE[w, TwoHalves][1]]; }; LeftHalf: PROC [w: Word] RETURNS [Half] = TRUSTED INLINE { RETURN[LOOPHOLE[w, TwoHalves][0]]; }; RightHalf: PROC [w: Word] RETURNS [Half] = TRUSTED INLINE { RETURN[LOOPHOLE[w, TwoHalves][1]]; }; SwapHalves: PROC [w: Word] RETURNS [Word] = TRUSTED MACHINE CODE { PrincOps.zEXCH; }; <> <> WordToInt: PROC [w: Word] RETURNS [INT] = TRUSTED MACHINE CODE { PrincOps.zEXCH; }; IntToWord: PROC [int: INT] RETURNS [Word] = TRUSTED MACHINE CODE { PrincOps.zEXCH; }; WordToCard: PROC [w: Word] RETURNS [CARD] = TRUSTED MACHINE CODE { PrincOps.zEXCH; }; HalfToCard: PROC [h: Half] RETURNS [CARDINAL] = TRUSTED INLINE { RETURN [LOOPHOLE[h, CARDINAL]]; }; ByteToCard: PROC [b: Byte] RETURNS [[0..255]] = TRUSTED INLINE { RETURN [LOOPHOLE[b]]; }; CardToWord: PROC [card: CARD] RETURNS [Word] = TRUSTED MACHINE CODE { PrincOps.zEXCH; }; CardToHalf: PROC [card: CARDINAL] RETURNS [Half] = TRUSTED INLINE { RETURN [LOOPHOLE[card, Half]]; }; CardToByte: PROC [card: [0..255]] RETURNS [Byte] = TRUSTED INLINE { RETURN [LOOPHOLE[card, Byte]]; }; <> <<>> TamAnd: PROC [a,b: Word] RETURNS [Word] = INLINE { <> RETURN [HalvesToWord[[ HalfAnd[LeftHalf[a], LeftHalf[b]], HalfAnd[RightHalf[a], RightHalf[b]] ]]]; }; TamOr: PROC [a,b: Word] RETURNS [Word] = INLINE { <> RETURN [HalvesToWord[[ HalfOr[LeftHalf[a], LeftHalf[b]], HalfOr[RightHalf[a], RightHalf[b]] ]]]; }; TamXor: PROC [a,b: Word] RETURNS [Word] = INLINE { <> RETURN [HalvesToWord[[ HalfXor[LeftHalf[a], LeftHalf[b]], HalfXor[RightHalf[a], RightHalf[b]] ]]]; }; TamNot: PROC [w: Word] RETURNS [Word] = INLINE { <> RETURN [HalvesToWord[[ HalfNot[LeftHalf[w]], HalfNot[RightHalf[w]] ]]]; }; VanillaAdd: PROC [a,b: Word] RETURNS [Word] = INLINE { <> RETURN [IntToWord[WordToInt[a]+WordToInt[b]]]; }; VanillaSub: PROC [a,b: Word] RETURNS [Word] = INLINE { <> RETURN [IntToWord[WordToInt[a]-WordToInt[b]]]; }; AddDelta: PROC [delta: INT, w: Word] RETURNS [Word] = TRUSTED MACHINE CODE { <> PrincOps.zEXCH; PrincOps.zDADD; PrincOps.zEXCH; }; <> <<>> HalfNot: PROC [h: Half] RETURNS [nh: Half] = TRUSTED MACHINE CODE { <> PrincOps.zLIN1; PrincOps.zXOR }; HalfAnd: PROC [h0,h1: Half] RETURNS [h: Half] = TRUSTED MACHINE CODE { <> PrincOps.zAND; }; HalfOr: PROC [h0,h1: Half] RETURNS [h: Half] = TRUSTED MACHINE CODE { <> PrincOps.zOR; }; HalfXor: PROC [h0,h1: Half] RETURNS [h: Half] = TRUSTED MACHINE CODE { <> PrincOps.zXOR; }; HalfShift: PROC [h: Half, dist: INTEGER] RETURNS [Half] = TRUSTED MACHINE CODE { <= 0) or right (if dist <= 0).>> PrincOps.zSHIFT; }; <> DoubleWordShiftRight: PROC [w0, w1: Word, dist: SixBitIndex] RETURNS [Word] = TRUSTED INLINE { <> <> SELECT dist FROM < 16 => RETURN [HalvesToWord[[ HalfOr[HalfShift[LeftHalf[w0], -dist], HalfShift[RightHalf[w1], 16-dist]], HalfOr[HalfShift[RightHalf[w0], -dist], HalfShift[LeftHalf[w0], 16-dist]]]]]; ENDCASE => { RETURN [HalvesToWord[[ HalfOr[HalfShift[RightHalf[w1], 16-dist], HalfShift[LeftHalf[w1], 32-dist]], HalfOr[HalfShift[LeftHalf[w0], 16-dist], HalfShift[RightHalf[w1], 32-dist]]]]]; }; }; DoubleWordShiftLeft: PROC [w0,w1: Word, dist: SixBitIndex] RETURNS [Word] = TRUSTED INLINE { <> SELECT dist FROM < 16 => RETURN [HalvesToWord[[ HalfOr[HalfShift[LeftHalf[w0], dist], HalfShift[RightHalf[w0], dist-16]], HalfOr[HalfShift[RightHalf[w0], dist], HalfShift[LeftHalf[w1], dist-16]]]]]; ENDCASE => { RETURN [HalvesToWord[[ HalfOr[HalfShift[RightHalf[w0], dist-16], HalfShift[LeftHalf[w1], dist-32]], HalfOr[HalfShift[LeftHalf[w1], dist-16], HalfShift[RightHalf[w1], dist-32]]]]]; }; }; SingleWordShiftLeft: PROC [word: Word, dist: SixBitIndex] RETURNS [Word] = TRUSTED INLINE { <> SELECT dist FROM < 16 => RETURN [HalvesToWord[[ HalfOr[HalfShift[LeftHalf[word], dist], HalfShift[RightHalf[word], dist-16]], HalfShift[RightHalf[word], dist]]]]; ENDCASE => { RETURN [HalvesToWord[[HalfShift[RightHalf[word], dist-16], ZerosHalf]]]; }; }; SingleWordShiftRight: PROC [word: Word, dist: SixBitIndex] RETURNS [Word] = TRUSTED INLINE { <> SELECT dist FROM < 16 => RETURN [HalvesToWord[[ HalfShift[LeftHalf[word], -dist], HalfOr[HalfShift[LeftHalf[word], 16-dist], HalfShift[RightHalf[word], -dist]] ]]]; ENDCASE => { RETURN [HalvesToWord[[ZerosHalf, HalfShift[LeftHalf[word], 16-dist]]]]; }; }; END.