DIRECTORY --Basics USING [], DragOpsCross USING [XopBase, TrapBase, TrapWidthBytes, bytesPerWord, TrapIndex, Word, ProcessorRegister, IFUStackIndex], --Word, wordsPerPage, bytesPerWord, charsPerWord, bitsPerByte, bitsPerCharacter, bitsPerWord, bytesPerPage, logWordsPerPage, logBitsPerByte, logBitsPerChar, logBytesPerWord, logCharsPerWord, logBitsPerWord, logBytesPerPage, PageCount, PageNumber, maxPagesInVM, SixBitIndex, FiveBitIndex, TwoWords, FourBitIndex, Half, ThreeBitIndex, FourHalves, TwoHalves, Byte, ZerosByte, OnesByte, EightBytes, FourBytes, ByteIndex, BytesPerWord, TwoBytes, Comparison, ByteAddress, WordAddress, FieldDescriptor, RegIndex, PadByte, Lit8, Op4, Op8, JDist8, Inst, OIFormat, OQBformat, LRformat, QRformat, ShortRegQR, OBformat, LRBformat, RRformat, ODBformat, LRRBformat, RJBformat, ShortRegRJB, JBBformat, TrapWidthWords, TrapWidthBytes, XopBase, TrapBase, KernalLimit, TrapIndex, StackUnderflowTrap, IFUPageFaultTrap, ResetTrap, IFUStackOverflowTrap, EUStackOverflowTrap, RescheduleTrap, ALUCondFalse, ALUCondEZ, ALUCondLZ, ALUCondLE, ALUCondSpare, ALUCondNE, ALUCondGE, ALUCondGZ, ALUCondOver, ALUCondBC, ALUCondIL, ALUCondDO, ALUCondNotOver, ALUCondNB, ALUCondNI, ModeFault, MemAccessFault, IOAccessFault, EUPageFault, EUWriteFault, AUFault, euStack, euJunk, euToKBus, euMAR, euField, euConstant, euAux, euBogus, euLast, ifuYoungestL, ifuYoungestPC, ifuEldestL, ifuEldestPC, ifuSLimit, ifuBogus, ifuL, ifuS, ifuPC, ifuLast, EURegs, EULegalRegs, IFURegs, IFULegalRegs, StackedStatusWord, IFUStackIndex, IFUStackSize, IFUOverflow, EUStackIndex, EUStackSize, EULocalIndex, EULocals, EUAuxIndex, EUAuxRegs, EUConstIndex, EUConstants, IOLocation, ioRescheduleRequest, ioResetRequest, IOOperand, PCmdFormat, PCmdByteSelect, PCmdClass, PCmdSpace, PCmdDirection DragOpsCrossUtils USING [CardToWord], --InstToBytes, InstToFormat, BytePCToWordAddress, WordAddressToBytePC, IOOperandToCard, CardToIOOperand, FieldDescriptorToCard, CardToFieldDescriptor, BytesToWord, BytesToHalf, WordToBytes, HalfToBytes, HalvesToWord, WordToHalves, HighHalf, LowHalf, LeftHalf, RightHalf, SwapHalves, WordToInt, IntToWord, WordToCard, HalfToCard, ByteToCard, CardToWord, CardToHalf, CardToByte, DragAnd, DragOr, DragXor, DragNot, VanillaAdd, VanillaSub, AddDelta, HalfNot, HalfAnd, HalfOr, HalfXor, HalfShift, DoubleWordShiftLeft, SingleWordShiftLeft, SingleWordShiftRight, XopToBytePC, TrapIndexToBytePC, FieldUnit HandCoding, --Has opcode and register defs. HandCodingPseudos, --Label, SetLabel, GenLabel, GenLabelHere, UseLabel8A, UseLabel8B, UseLabel16, UseLabel32, LReg, PReg, SReg, AddReg, SubReg, SetRegConst, MoveReg, MoveRegI, LRegI, IndexedJump, ProcedureEntry, ProcedureExit, SetupField, ExtractField, ShiftLeft, LoadProcessorReg, StoreProcessorReg, CauseReschedule, CauseReset, GetSPLimit, SetSPLimit, GetYoungestPC, GetYoungestStatus, GetEldestPC, GetEldestStatus, SetYoungestPC, SetYoungestStatus, SetEldestPC, SetEldestStatus, Pause, Halt HandCodingSupport; --Area, GetProc, PutProc, ProcList, NewArea, GenWithArea, Gen1WithArea, ForceOut, GetCurrentArea, LoadArea, GetOutputPC, SetOutputPC, WordAlign, ReserveData, OutputByte, OutputOneByte, OutputAlphaBeta, OutputAlphaBetaGammaDelta, OutputWord GenReg: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; Word: TYPE = DragOpsCross.Word; ProcessorRegister: TYPE = DragOpsCross.ProcessorRegister; IFUStackIndex: TYPE = DragOpsCross.IFUStackIndex; ifuSLimit: CARDINAL = LOOPHOLE[ProcessorRegister.ifuSLimit, CARDINAL]; ifuEldestPC: CARDINAL = LOOPHOLE[ProcessorRegister.ifuEldestPC, CARDINAL]; ifuEldestL: CARDINAL = LOOPHOLE[ProcessorRegister.ifuEldestL, CARDINAL]; ifuYoungestPC: CARDINAL = LOOPHOLE[ProcessorRegister.ifuYoungestPC, CARDINAL]; ifuYoungestL: CARDINAL = LOOPHOLE[ProcessorRegister.ifuYoungestL, CARDINAL]; All: PROC = { FillXop: PROC [inst: CARDINAL, dest: Label] = { SetOutputPC[inst * DragOpsCross.TrapWidthBytes + DragOpsCross.XopBase * DragOpsCross.bytesPerWord]; drJDB[UseLabel16[dest]]; }; FillTrap: PROC [tx: DragOpsCross.TrapIndex, dest: Label] = { SetOutputPC[LOOPHOLE[tx, CARDINAL] * DragOpsCross.TrapWidthBytes + DragOpsCross.TrapBase * DragOpsCross.bytesPerWord]; drJDB[UseLabel16[dest]]; }; GenRegWrite: PROC [reg: CARDINAL, val: LONG CARDINAL] ~ { IF reg = ifuYoungestL THEN { drLIB[val]; SetYoungestStatus[]; } ELSE { drLIQB[CardToWord[val]]; drSIP[reg]}; }; GenRegRead: PROC [reg: CARDINAL, val: LONG CARDINAL] ~ { rdOK: Label = GenLabel[]; IF reg = ifuYoungestL THEN { GetYoungestStatus[]; drLIB[377B]; drAND[]; } ELSE IF reg = ifuEldestL THEN { GetEldestStatus[]; drLIB[377B]; drAND[]; } ELSE drLIP[reg]; drLIQB[CardToWord[val]]; drRJEBJ[popSrc, belowSrcPop, UseLabel8B[rdOK]]; Pause[]; SetLabel[rdOK]; }; --area: Area = GetCurrentArea[]; enterEUSLTest: Label = GenLabel[]; enterIFUSLTest: Label = GenLabel[]; GenEUSL: PROC = { testVal: LONG CARDINAL; SetLabel[enterEUSLTest]; testVal _ 8; GenRegWrite[0, 1]; FOR I: CARDINAL IN [3..127] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; FOR I: CARDINAL IN [130..131] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; FOR I: CARDINAL IN [136..159] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; testVal _ 8; GenRegRead[0, 1]; FOR I: CARDINAL IN [3..127] DO GenRegRead[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; FOR I: CARDINAL IN [130..131] DO GenRegRead[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; FOR I: CARDINAL IN [136..159] DO GenRegRead[I, testVal]; testVal _ IF testVal = 20000000000B THEN 1 ELSE testVal + testVal; ENDLOOP; drASL[4]; --S _ 5 GenRegWrite[1, 2]; GenRegWrite[2, 4]; GenRegRead[1, 2]; GenRegRead[2, 4]; drASL[255]; --S _ 0 again testVal _ 37777777767B; GenRegWrite[0, 37777777776B]; FOR I: CARDINAL IN [3..127] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; FOR I: CARDINAL IN [130..131] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; FOR I: CARDINAL IN [136..159] DO GenRegWrite[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; testVal _ 37777777767B; GenRegRead[0, 37777777776B]; FOR I: CARDINAL IN [3..127] DO GenRegRead[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; FOR I: CARDINAL IN [130..131] DO GenRegRead[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; FOR I: CARDINAL IN [136..159] DO GenRegRead[I, testVal]; testVal _ IF testVal = 17777777777B THEN 37777777776B ELSE testVal + testVal + 1; ENDLOOP; drASL[4]; --S _ 5 GenRegWrite[1, 37777777775B]; GenRegWrite[2, 37777777773B]; GenRegRead[1, 37777777775B]; GenRegRead[2, 37777777773B]; drASL[255]; --S _ 0 again }; GenIFUSL: PROC = { GenCallTest: PROC [dest: Label, lVal, rVal: CARDINAL] ~ { drLFC[UseLabel16[dest]]; GenRegRead[ifuYoungestL, rVal]; drRETN[]; Pause[]; SetLabel[dest]; GenRegWrite[ifuYoungestL, lVal]; }; testPCVal, testLVal: LONG CARDINAL; SetLabel[enterIFUSLTest]; testPCVal _ 1; testLVal _ 4; GenRegWrite[ifuSLimit, 0]; FOR I: CARDINAL IN IFUStackIndex DO GenRegWrite[ifuEldestPC, testPCVal]; testPCVal _ IF testPCVal = 20000000000B THEN 1 ELSE testPCVal + testPCVal; GenRegWrite[ifuEldestL, testLVal]; testLVal _ IF testLVal = 100B THEN 1 ELSE testLVal + testLVal; ENDLOOP; GenRegRead[ifuSLimit, 0]; FOR I: CARDINAL IN IFUStackIndex DO testLVal _ IF testLVal = 1 THEN 100B ELSE testLVal / 2; GenRegRead[ifuEldestL, testLVal]; testPCVal _ IF testPCVal = 1 THEN 20000000000B ELSE testPCVal / 2; GenRegRead[ifuEldestPC, testPCVal]; ENDLOOP; testPCVal _ 37777777776B; testLVal _ 173B; GenRegWrite[ifuSLimit, 177B]; FOR I: CARDINAL IN IFUStackIndex DO GenRegWrite[ifuEldestPC, testPCVal]; testPCVal _ IF testPCVal = 17777777777B THEN 37777777776B ELSE testPCVal + testPCVal + 1; GenRegWrite[ifuEldestL, testLVal]; testLVal _ IF testLVal = 77B THEN 176B ELSE testLVal + testLVal + 1 - 200B; ENDLOOP; GenRegRead[ifuSLimit, 177B]; FOR I: CARDINAL IN IFUStackIndex DO testLVal _ IF testLVal = 176B THEN 77B ELSE testLVal / 2 + 100B; GenRegRead[ifuEldestL, testLVal]; testPCVal _ IF testPCVal = 37777777776B THEN 17777777777B ELSE testPCVal / 2 + 20000000000B; GenRegRead[ifuEldestPC, testPCVal]; ENDLOOP; testPCVal _ 200000B; testLVal _ 1; FOR I: CARDINAL IN IFUStackIndex DO youngCall: Label = GenLabel[]; drLFC[UseLabel16[youngCall]]; SetLabel[youngCall]; GenRegWrite[ifuYoungestPC, testPCVal]; testPCVal _ IF testPCVal = 20000000000B THEN 1 ELSE testPCVal + testPCVal; GenRegWrite[ifuYoungestL, testLVal]; testLVal _ IF testLVal = 100B THEN 1 ELSE testLVal + testLVal; ENDLOOP; testPCVal _ 200000B; testLVal _ 1; FOR I: CARDINAL IN IFUStackIndex DO GenRegRead[ifuEldestL, testLVal]; testLVal _ IF testLVal = 100B THEN 1 ELSE testLVal + testLVal; GenRegRead[ifuEldestPC, testPCVal]; testPCVal _ IF testPCVal = 20000000000B THEN 1 ELSE testPCVal + testPCVal; ENDLOOP; { Call1: Label = GenLabel[]; Call2: Label = GenLabel[]; Call3: Label = GenLabel[]; Call4: Label = GenLabel[]; Call5: Label = GenLabel[]; Call6: Label = GenLabel[]; Call7: Label = GenLabel[]; Call8: Label = GenLabel[]; Call9: Label = GenLabel[]; Call10: Label = GenLabel[]; Call11: Label = GenLabel[]; Call12: Label = GenLabel[]; Call13: Label = GenLabel[]; Call14: Label = GenLabel[]; Call15: Label = GenLabel[]; EndCallTest: Label = GenLabel[]; drLFC[UseLabel16[Call1]]; drJDB[UseLabel16[EndCallTest]]; SetLabel[Call1]; GenRegWrite[ifuYoungestL, 1]; GenCallTest[Call2, 2, 1]; GenCallTest[Call3, 3, 2]; GenCallTest[Call4, 4, 3]; GenCallTest[Call5, 5, 4]; GenCallTest[Call6, 6, 5]; GenCallTest[Call7, 7, 6]; GenCallTest[Call8, 8, 7]; GenCallTest[Call9, 9, 8]; GenCallTest[Call10, 10, 9]; GenCallTest[Call11, 11, 10]; GenCallTest[Call12, 12, 11]; GenCallTest[Call13, 13, 12]; GenCallTest[Call14, 14, 13]; GenCallTest[Call15, 15, 14]; GenRegRead[ifuYoungestL, 15]; drRETN[]; SetLabel[EndCallTest]; }; }; GenEUSL[]; GenIFUSL[]; Halt[177777B]; --Terminate here at the end of the program }; END. ΈGenReg.mesa Copyright c 1985, 1986, 1987 by Xerox Corporation. All rights reserved. Edward Fiala February 7, 1986 2:59:57 pm PST McCreight, January 7, 1986 3:52:02 pm PST Curry, September 11, 1986 9:13:11 pm PDT Curry, September 11, 1986 12:07:36 pm PDT Removed references to ifuStatus (all unused). Changed comment for ifuSLimit's value from 242 to 241. Added definitions for SetYoungestL and GetYoungestL Remove incorrect comments on ifu register values Used GetYoungestL and SetYoungestL when doing LIP's and SIP's of ifuYoungestL in GenRegWrite, GenRegRead, and elsewhere. Fiala November 6, 1986 9:53:36 am PST Fix problem with not masking ifuEldestL before comparing it to desired L value (version number screws this up); removed careful write of ifuYoungestL because not needed for this diagnostic (saves many instructions). Fiala March 20, 1987 7:01:08 pm PST Eliminate Reset, Halt, and Pause stuff to run with GenDebugger. Fiala April 1, 1987 6:19:30 pm PST Make const1 to 3 read-only. ****Need to test that const1 to 3 have the values 1, 2, and 3****. This diagnostic should be loaded with "quad -cx GenDebugger GenReg". It tests EU and IFU registers using LIP and SIP and (in a limited way) using LFC and RETN. It presumes that LIQB and RJEBJ have been thoroughly tested by GenLICJ. When successfully executed it halts at instruction 2283, cycle 5383, PC 4057012B. Xops trap at opcode*TrapWidthBytes + xopBase*bytesPerWord = 4,000,000B + 20B * opcode. A trap's location is TrapIndex*TrapWidthBytes + TrapBase*bytesPerWord = 4,002,000B + 20B * TrapIndex. TrapIndex definitions are in DragOpsCross. Note that the write of the StackedStatusWord does not mask the upper fields in the word; not needed because userMode=FALSE and trapsEnabled=FALSE. SetYoungestL: PROC = { GetYoungestStatus[]; drLIQB[CardToWord[37777777400B]]; drAND[]; drOR[]; SetYoungestStatus[]; }; GenEUSL tests all EU registers except const0 using LIQB and SIP to consecutively write different values in all registers, then LIP, LIQB, and RJEB to read back and check all values. This test will catch addressing errors which cause the write of one register to wind up in another as well as storage failures. Register descriptions are in DragOpsCross.mesa. Skip over euJunk = 128 and 129; test euMar = 130 and euField = 131. euMar is a dumping place for memory addresses on address faults; it is (??) a regular register. euField is both a normal register and a collection of other logic to control the field unit; this test covers the register part of it; the other control logic can only be tested indirectly by noting whether or not the field unit performs correctly for values in euField. Const0, 1, 2, and 3 are read-only. Read and compare; must skip registers 1 and 2 which have been smashed by the various pushes during writing and reading. Const0 = 132. const0, 1, 2, and 3 are read-only. Finally, go back and test registers 1 and 2. Write with inverse values. Const0 = 132. const0, 1, 2, and 3 are read-only. Read and compare, skipping registers 1 and 2 smashed by stack operations. Const0 = 132. const0, 1, 2, and 3 are read-only. Finally, go back and test registers 1 and 2. GenIFUSL tests all IFU registers except ifuXBus (untestable) using LIQB and SIP to consecutively write different values in all registers, then LIP, LIQB, and RJEB to read back and check all values. The IFU stack is tested both when writing it with ifuEldestL/PC and when writing it with ifuYoungestL/PC and changing the stack depth with LFC/RETN. Current values of L, S, and PC cannot be read; the stack covers only previous frames. In normal operation, ifuEldestL/PC are written on IFU stack underflow when previous frames are restored to the registers, and read on IFU or EU stack overflow to remove frames from the registers. This test will catch addressing errors which cause the write of one register to wind up in another, and it checks the manipulation of the IFU stack and L register by LFC and RETN. The description of the funny IFU registers is in DragOpsCross.mesa. ifuXBus = base for IFU regs, can't be tested. ifuSLimit = stack limit register, 7-bit register. This register is written and read by GenIFUSL, but its function as a stack limit register is not tested. IFUStackSize = 15. ifuYoungestL = youngest L in IFU stack (user mode and traps enabled not tested). ifuYoungestPC = youngest PC in IFU stack. ifuEldestL = eldest L in IFU stack (user mode and traps enabled not tested). ifuEldestPC = eldest PC in IFU stack (read removes, write adds). Test with single 1-bit cycled left 1 position each time. Test with single 0-bit cycled left 1 position each time (i.e., inverse of first test). Test the ifu stack with LFC and ifuYoungestL/PC used to push and to write, and ifuEldestL/PC used to read and pop. Test the ifu stack with LFC used to push and to write PC, ifuYoungestL to write, and RETN used to read and pop. This test will malfunction unless L and PC are correctly manipulated by LFC and RETN. Note that only 15 calls can be made here because, even though there are 16 levels in the ifu stack, only 15 are usable by call and return; if a 16th LFC is given, then its RETN results in a stack underflow trap. Begin at PC = userBasePC = 1010000B * 4, L = 1, S = 0 as established in GenDebugger. Κ μ˜codešœ ™ Kšœ Οmœ=™HK™,K™)K™(™)Kšœ-™-Kšœ6™6Kšœ3™3J™0Jšœx™x—K™ύK™cK™‚K™KšœΌ™Ό—K˜šΟk ˜ Kšœ žœ˜Kšœ žœgΟcε ˜ή KšœžœŸΥ˜ϋKšœ Ÿ˜+KšœŸΪ˜νKšœŸο˜‚K˜—šœžœž˜KšžœD˜KKšœžœžœE˜QK˜K–20 sp tabStopsšœžœ˜ J–20 sp tabStopsšœžœ"˜9J–20 sp tabStopsšœžœ˜1J–20 sp tabStopsšœ žœžœžœ˜FJ–20 sp tabStopsšœ žœžœ žœ˜JJ–20 sp tabStopsšœ žœžœžœ˜HJ–20 sp tabStopsšœžœžœ"žœ˜NJ–20 sp tabStopsšœžœžœ!žœ˜LJ˜šΟnœžœ˜ K˜KšœV™Vš œžœžœ˜/Kšœc˜cKšœ˜K˜K˜—Kšœ‘™‘š œžœ.˜Kšžœ˜—K˜Kšœ˜šžœžœžœž˜#Kšœ žœžœžœ˜7K˜!Kšœ žœžœžœ˜BKšœ#˜#Kšžœ˜—K˜KšœV™VKšœ˜K˜Kšœ˜šžœžœžœž˜#Kšœ$˜$Kšœ žœžœžœ˜YK˜"Kšœ žœžœžœ ˜KKšžœ˜—K˜Kšœ˜šžœžœžœž˜#Kšœ žœžœžœ˜@K˜!Kšœ žœžœžœ˜\Kšœ#˜#Kšžœ˜—K˜Kšœr™rKšœ˜Kšœ ˜ š žœ œžœžœž˜#Kšœ˜Kšœ˜Kšœ˜Kšœ&˜&Kšœ žœžœžœ˜JK˜$Kšœ žœžœžœ˜>Kšžœ˜—K˜Kšœ˜Kšœ ˜ šžœžœžœž˜#Kšœ!˜!Kšœ žœžœžœ˜>Kšœ#˜#Kšœ žœžœžœ˜JKšžœ˜—K˜Kšœ›™›šž˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜ K˜Kšœ˜Kšœ˜Kšœ˜K˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜K˜ K˜K˜—K˜—K˜KšœT™TK˜ Jšœ ˜ JšœŸ*˜9˜K˜——Kšžœ˜——…—(ΈH\