DIRECTORY Basics USING [BITXOR], DragOpsCross USING [XopBase, TrapBase, TrapWidthBytes, bytesPerWord, TrapIndex, Word], --XopBase, TrapBase, TrapWidthBytes, Inst, wordsPerPage, bytesPerWord, charsPerWord, bitsPerByte, bitsPerCharacter, bitsPerWord, logWordsPerPage, logBitsPerByte, logBitsPerChar, logBytesPerWord, logCharsPerWord, logBitsPerWord, logBytesPerPage, PageCount, PageNumber, maxPagesInVM, SixBitIndex, FiveBitIndex, Word, TwoWords, FourBitIndex, Half, ThreeBitIndex, FourHalves, TwoHalves, Byte, ZerosByte, OnesByte, EightBytes, FourBytes, ByteIndex, BytesPerWord, TwoBytes, Comparison, ByteAddress, WordAddress, FieldDescriptor, TrapWidthWords, KernalLimit, TrapIndex, StackUnderflowTrap, IFUPageFaultTrap, ResetTrap, IFUStackOverflowTrap, EUStackOverflowTrap, RescheduleTrap, ALUCondOver, ALUCondBC, ALUCondIL, ALUCondDO, EUPageFault, EUWriteFault, AUFault, euStack, euJunk, euMAR, euField, euConstant, euAux, euBogus, euLast, ifuXBus, ifuStatus, ifuSLimit, ifuYoungestL, ifuYoungestPC, ifuEldestL, ifuEldestPC, ifuBogus, ifuL, ifuS, ifuPC, ifuLast, IFUStatusRec, IFUStackIndex, IFUStackSize, IFUOverflow, EUStackIndex, EUStackSize, EULocalIndex, EULocals, EUAuxIndex, EUAuxRegs, EUConstIndex, EUConstants, IOLocation, ioRescheduleRequest, ioResetRequest DragOpsCrossUtils USING [CardToWord], --BytePCToWordAddress, WordAddressToBytePC, IOOperandToCard, CardToIOOperand, FieldDescriptorToCard, CardToFieldDescriptor, StatusToWord, WordToStatus, 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, TrapIndexToBytePC, XopToBytePC HandCoding, --Has opcode and register defs. HandCodingPseudos, --GenLabel, GenLabelHere, SetLabel, Halt, Pause, MakeLabelGlobal, UseLabel8B, UseLabel16, UseLabel32, ProcedureEntry, ProcedureExit, EnableTraps, IndexedJump, SetupField, ExtractField, ShiftLeft, LoadProcessorReg, StoreProcessorReg, DisableTraps, CauseReschedule, CauseReset, GetSPLimit, SetSPLimit, GetL, SetL, GetYoungestPC, GetYoungestL, GetEldestPC, GetEldestL, SetYoungestPC, SetYoungestL, SetEldestPC, SetEldestL HandCodingSupport; --Area, GetCurrentArea, ReserveData, SetOutputPC, GetProc, PutProc, ProcList, NewArea, GenWithArea, Gen1WithArea, ForceOut, GetOutputPC, WordAlign, OutputByte, OutputOneByte, OutputAlphaBeta, OutputAlphaBetaGammaDelta, OutputWord GenLICJ: CEDAR PROGRAM IMPORTS Basics, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; Word: TYPE = DragOpsCross.Word; 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]]; }; area: Area = GetCurrentArea[]; oldPC: LONG CARDINAL; start: Label = GenLabel[]; dummy: Label = GenLabel[]; const0OK: Label = GenLabel[]; enterLIQBTest: Label = GenLabel[]; enterLIDBTest: Label = GenLabel[]; enterLIBTest: Label = GenLabel[]; enterJEBTest: Label = GenLabel[]; GenLI: PROC = { TestE1: PROC [] ~ { ok1: Label _ GenLabel[]; ok2: Label _ GenLabel[]; bad1: Label _ GenLabel[]; drRJEB[left: topSrc, right: belowSrc, dist: UseLabel8B[ok1]]; Pause[]; --Bug: [s] = [s-1] but RJEB didn't jump. SetLabel[ok1]; drRJNEB[left: popSrc, right: belowSrcPop, dist: UseLabel8B[bad1]]; drJB[UseLabel8A[ok2]]; SetLabel[bad1]; Pause[]; --Bug: [s] = [s-1] but RJNEB jumped. SetLabel[ok2]; }; TestE2: PROC [] ~ { ok1: Label _ GenLabel[]; ok2: Label _ GenLabel[]; bad1: Label _ GenLabel[]; drJ1[]; --No-op to preserve alignment drRAND[c: const1, a: topSrc, b: popSrc]; drRJEBJ[left: topSrc, right: const1, dist: UseLabel8B[ok1]]; Pause[]; --Bug: [s] = const1 but RJEBJ didn't jump. SetLabel[ok1]; drRJNEBJ[left: popSrc, right: const1, dist: UseLabel8B[bad1]]; drJB[UseLabel8A[ok2]]; SetLabel[bad1]; Pause[]; --Bug: [s] = const1 but RJNEB jumped. SetLabel[ok2]; }; TestNE1: PROC [] ~ { ok1: Label _ GenLabel[]; ok2: Label _ GenLabel[]; bad1: Label _ GenLabel[]; drRJNEB[left: topSrc, right: belowSrc, dist: UseLabel8B[ok1]]; Pause[]; --Bug: [s] # [s-1] but RJNEB didn't jump. SetLabel[ok1]; drRJEB[left: popSrc, right: belowSrcPop, dist: UseLabel8B[bad1]]; drJB[UseLabel8A[ok2]]; SetLabel[bad1]; Pause[]; --Bug: [s] # [s-1] but RJEB jumped. SetLabel[ok2]; }; TestNE2: PROC [] ~ { ok1: Label _ GenLabel[]; ok2: Label _ GenLabel[]; bad1: Label _ GenLabel[]; drJ1[]; --No-op to preserve word alignment drRAND[c: const1, a: topSrc, b: popSrc]; drRJNEBJ[left: topSrc, right: const1, dist: UseLabel8B[ok1]]; Pause[]; --Bug: [s] # const1 but RJNEBJ didn't jump. SetLabel[ok1]; drRJEBJ[left: popSrc, right: const1, dist: UseLabel8B[bad1]]; drJB[UseLabel8A[ok2]]; SetLabel[bad1]; Pause[]; --Bug: [s] # const1 but RJEBJ jumped. SetLabel[ok2]; }; GenLIQBTest: PROC [value: LONG CARDINAL] = { w: Word _ CardToWord[value]; nw: Word _ CardToWord[LOOPHOLE[- LOOPHOLE[value, INT] - 1, LONG CARDINAL]]; z: Word _ CardToWord[0]; nz: Word _ CardToWord[37777777777B]; drLIQB[w]; drLIQB[w]; TestE1[]; drLIQB[w]; drLIQB[z]; TestNE1[]; drLIQB[z]; drLIQB[w]; TestNE1[]; drLIQB[nw]; drLIQB[nz]; TestNE1[]; drLIQB[nz]; drLIQB[nw]; TestNE1[]; drLIQB[nw]; drLIQB[nw]; TestE1[]; drLIQB[w]; drLIQB[w]; TestE2[]; drLIQB[w]; drLIQB[z]; TestNE2[]; drLIQB[z]; drLIQB[w]; TestNE2[]; drLIQB[nw]; drLIQB[nz]; TestNE2[]; drLIQB[nz]; drLIQB[nw]; TestNE2[]; drLIQB[nw]; drLIQB[nw]; TestE2[]; }; GenLIDBTest: PROC [value: CARDINAL] = { w: Word _ CardToWord[LONG[value]]; drLIDB[value]; drLIQB[w]; TestE1[]; }; GenLIBTest: PROC [value: CARDINAL] = { drLIB[value]; drLIDB[value]; TestE1[]; }; GenJEBTest: PROC [value: CARDINAL] = { ok1: Label _ GenLabel[]; ok2: Label _ GenLabel[]; ok3: Label _ GenLabel[]; ok4: Label _ GenLabel[]; bad: Label _ GenLabel[]; notValue: CARDINAL _ Basics.BITXOR[value, 377B]; drLIB[value]; drJEBB[value, UseLabel8B[ok1]]; Pause[]; --JEBB should have jumped but didn't SetLabel[ok1]; drLIB[value]; drJNEBB[0, UseLabel8B[ok2]]; Pause[]; --JNEBB should have jumped but didn't SetLabel[ok2]; drLIB[value]; drJEBB[0, UseLabel8B[bad]]; drLIB[value]; drJNEBB[value, UseLabel8B[bad]]; drLIB[notValue]; drJEBBJ[377B, UseLabel8B[bad]]; drLIB[notValue]; drJNEBBJ[notValue, UseLabel8B[bad]]; drLIB[notValue]; drJEBBJ[notValue, UseLabel8B[ok3]]; Pause[]; --JEBBJ should have jumped but didn't SetLabel[ok3]; drLIB[notValue]; drJNEBBJ[377B, UseLabel8B[ok4]]; SetLabel[bad]; Pause[]; SetLabel[ok4]; }; val: LONG CARDINAL _ 1; hval: CARDINAL _ 1; bval: CARDINAL _ 1; jval: CARDINAL _ 1; WordAlign[area]; SetLabel[enterLIQBTest]; drJ1[]; drJ1[]; drJ1[]; UNTIL val = 0 DO GenLIQBTest[val]; val _ val + val; ENDLOOP; SetLabel[enterLIDBTest]; UNTIL hval = 0 DO GenLIDBTest[hval]; hval _ hval + hval; ENDLOOP; SetLabel[enterLIBTest]; UNTIL bval = 400B DO GenLIBTest[bval]; bval _ bval + bval; ENDLOOP; SetLabel[enterJEBTest]; UNTIL jval = 400B DO GenJEBTest[jval]; jval _ jval + jval; ENDLOOP; }; SetLabel[dummy]; Pause[]; Pause[]; Pause[]; Pause[]; Pause[]; Halt[123B]; oldPC _ GetOutputPC[area]; FillTrap[ResetTrap, start]; FillXop[0, dummy]; FillXop[377B, dummy]; SetOutputPC[oldPC]; WordAlign[area]; SetLabel[start]; --Simulator execution begins here on a Reset. drASL[255]; --When there is nothing on the stack, S should be at L-1 drLC0[]; drJEBB[0, UseLabel8B[const0OK]]; Pause[]; --const0 wrong SetLabel[const0OK]; drJDB[UseLabel16[enterLIQBTest]]; GenLI[]; Halt[177777B]; --Terminate here at the end of the program }; END. ´GenLICJ.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Edward Fiala February 7, 1986 1:35:30 pm PST McCreight, January 7, 1986 3:48:37 pm PST When it finishes without error, this diagnostic executes a Halt[177777B] at PC = 4034017B, instruction 2560, cycle 6804. The Xop trap locations assigned to each opcode are at at opcode*TrapWidthBytes + xopBase*bytesPerWord = 4,000,000B + 20B * opcode, and the trap location assigned to each trap are at TrapIndex*TrapWidthBytes + TrapBase*bytesPerWord = 4,002,000B + 20B * TrapIndex. The TrapIndex definitions are in DragOpsCross. This procedure generates tests on LIQB, RJEB, RJEBJ, RJNEB, and RJNEBJ for each of the 32 values of 2^n. Each subtest loads two values onto the evaluation stack and tests whether or not a true jump opcode jumps and a false jump opcode doesn't jump. The first jump of each test leaves both stack operands on the stack; the second jump pops the two arguments from the stack. Value combinations tested are as follows for a particular value w = 2^n: w w w 0 0 w w' 0' 0' w' w' w'. Then LIDB is tested against LIQB for all 16 values of 2^n using RJEB; finally, LIB is tested against LIQB for all 8 values of 2^n. Don't screw with these tests; code alignment is important to make sure that bypass paths are used or not used when expected. TestE1, TestE2, TestNE1, and TestNE2 must each produce exactly 4*n + 2 code bytes. TestE1 produces 10 code bytes. a1 and a2 are still on the stack; a1 and a2 have been popped from the stack; TestE2 produces 14 code bytes. It is the same as TestE1 but uses RJEBJ and RJNEBJ instead of RJEB and RJNEB, and it uses RAND to move the one of the arguments to const1 so that the B bypass path can be tested. This one exercises the B bypass path a1 and a2 are still on the stack; a1 and a2 have been popped from the stack; TestNE produces 10 code bytes. a1 and a2 are still on the stack; a1 and a2 have been popped from the stack; TestNE2 produces 14 code bytes. It is the same as TestNE1 but uses RJNEBJ and RJEBJ instead of RJNEB and RJEB, and it uses RAND to move one of the arguments to const1 so that the B bypass path can be tested. a1 and a2 are still on the stack; a1 and a2 have been popped from the stack; nw _ ones complement of w. Each LIQB opcode is 5 bytes and each TestXX procedure produces 10 bytes, so 20 total bytes or 5 words are produced for each test; this means that byte alignment of the first test is preserved for subsequent tests. To for sure exercise the EU's A bypass path, the first conditional jump must finish in the same word as the last byte of the preceding opcode. This is arranged by beginning on a word boundary and inserting three J1's before the first test. The next group of tests are identical to the previous group but RJEBJ and RJNEBJ are used instead of RJEB and RJNEB, and the B bypass path is executed instead of the A bypass path by using RAND to move the top stack argument to const1; 24 bytes are produced for each test. GenLIDBTest produces 18 code bytes. GenLIBTest produces 15 code bytes. Test JEBB and JNEBB on an 8-bit value. These 3 no-ops cause the last byte of the 2nd LIQB opcode for each test to appear in the first byte of a word, so that the conditional jump which follows appears in the same word and exercises the B bypass path. Opcodes 0 and 377B are intercepted by the simulator, but make them trap to dummy here anyway. **Don't bum this instruction; code alignment is important here.** ÊŠ–81.25 in leftMargin 1.25 in rightMargin 6.0 in lineLength˜codešœ ™ Kšœ Ïmœ7™BK™,K™)K™K™x—K˜šÏk ˜ Kšœžœžœ˜Kšœ žœEÏcý˜Ô KšœžœŸË˜ñKšœ Ÿ˜+KšœŸ¢˜µKšœŸå˜øK˜—šœ žœž˜KšžœL˜SKšœžœžœE˜QK˜K–20 sp tabStopsšœžœ˜K˜šÏnœžœ˜ K˜Kšœ¶™¶š œžœžœ˜/Kšœc˜cKšœ˜K˜K˜—š œžœ.˜˜>K˜KšœŸ%˜>K˜Kšœ*™*K˜K˜—K˜Kšœ™š œžœ˜K˜K˜K˜Kšœ>˜>Kšœ Ÿ)˜2K˜K˜Kšœ!™!KšœA˜AK˜KšœŸ#˜K˜Kšœ*™*K˜K˜—K˜š  œžœ žœžœ˜,K˜Kšœ™Kš œžœžœžœžœžœ˜KK˜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šœ žœ žœ˜0K˜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˜šžœ ž˜Kšœ˜Kšœ˜Kšžœ˜—K˜K˜šžœ ž˜Kšœ˜Kšœ˜Kšžœ˜—K˜K˜šžœ ž˜Kšœ˜Kšœ˜Kšžœ˜—K˜—K˜J˜J˜8K˜Kšœ]™]Kšœ˜Kšœ˜K˜Kšœ˜Kšœ˜J˜Kšœ˜KšœŸ-˜>Kšœ Ÿ8˜DKšœ˜Kšœ ˜ Kšœ Ÿ˜Kšœ˜KšœA™AK˜!K˜K˜JšœŸ*˜9˜K˜——Kšžœ˜—K˜—…—*3h