DIRECTORY
DragOpsCross USING [XopBase, TrapBase, TrapWidthBytes, bytesPerWord, TrapIndex, Word],
--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 [IntToWord, 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
GenRBC:
CEDAR
PROGRAM
IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport
= BEGIN OPEN DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport;
Word: TYPE = DragOpsCross.Word;
In this diagnostic, the auxiliary registers are called aux0, aux1, ..., aux15; the locals are called reg0, reg1, ..., reg15; and the constants are called const0, const1, ..., const15.
const7 contains -1.
const5 is used as an enabling flag for the bounds-check subroutine.
const4 contains 4 for bounds-check trap subroutine.
aux0: AuxRegSpec = [aux[0]];
aux1: AuxRegSpec = [aux[1]];
aux2: AuxRegSpec = [aux[2]];
aux3: AuxRegSpec = [aux[3]];
aux4: AuxRegSpec = [aux[4]];
aux5: AuxRegSpec = [aux[5]];
aux6: AuxRegSpec = [aux[6]];
aux14: AuxRegSpec = [aux[14]];
aux15: AuxRegSpec = [aux[15]];
const5: ConstSpec = [const[5]];
const4: ConstSpec = [const[6]];
const7: ConstSpec = [const[7]];
const8: ConstSpec = [const[8]];
const9: ConstSpec = [const[9]];
const10: ConstSpec = [const[10]];
const11: ConstSpec = [const[11]];
All:
PROC = {
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.
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[];
savePC: LONG CARDINAL;
BoundsCheck: Label = GenLabel[];
BCUnexpected: Label = GenLabel[];
enterRJBTest: Label = GenLabel[];
enterRBCTest: Label = GenLabel[];
Test RJxB and RJxBJ opcodes on <a, b>, <b, a>, and <a, a>, where x = G, GE, L, or LE.
GenRJB:
PROC = {
a > b for all calls to RJBTest.
RJBTest:
PROC [a, b:
INT] ~ {
endTest: Label = GenLabel[];
badRJB: Label = GenLabel[];
okRJGBJ0: Label = GenLabel[];
okRJGB0: Label = GenLabel[];
okRJLEBJ1: Label = GenLabel[];
okRJLEB1: Label = GenLabel[];
okRJGEBJ0: Label = GenLabel[];
okRJGEB0: Label = GenLabel[];
okRJGEBJ1: Label = GenLabel[];
okRJGEB1: Label = GenLabel[];
okRJLEBJ0: Label = GenLabel[];
okRJLEB0: Label = GenLabel[];
okRJLBJ0: Label = GenLabel[];
okRJLB0: Label = GenLabel[];
ax: Word ← IntToWord[a];
bx: Word ← IntToWord[b];
drLIQB[bx]; drLIQB[ax];
First, test RJGB and RJGBJ.
drRJGBJ[topSrc, belowSrc, UseLabel8B[okRJGBJ0]]; Pause[]; SetLabel[okRJGBJ0];
drRJGB[topSrc, belowSrc, UseLabel8B[okRJGB0]]; Pause[]; SetLabel[okRJGB0];
Equal arguments should not jump.
drRJGBJ[topSrc, topSrc, UseLabel8B[badRJB]];
drRJGB[topSrc, topSrc, UseLabel8B[badRJB]];
Next, test RJLEB and RJLEBJ.
drRJLEBJ[topSrc, belowSrc, UseLabel8B[badRJB]];
drRJLEB[topSrc, belowSrc, UseLabel8B[badRJB]];
drRJLEBJ[topSrc, topSrc, UseLabel8B[okRJLEBJ1]]; Pause[]; SetLabel[okRJLEBJ1];
drRJLEB[topSrc, topSrc, UseLabel8B[okRJLEB1]]; Pause[]; SetLabel[okRJLEB1];
Thirdly, test RJGEB and RJGEBJ.
drRJGEBJ[topSrc, belowSrc, UseLabel8B[okRJGEBJ0]]; Pause[]; SetLabel[okRJGEBJ0];
drRJGEB[topSrc, belowSrc, UseLabel8B[okRJGEB0]]; Pause[]; SetLabel[okRJGEB0];
drRJGEBJ[topSrc, topSrc, UseLabel8B[okRJGEBJ1]]; Pause[]; SetLabel[okRJGEBJ1];
drRJGEB[topSrc, topSrc, UseLabel8B[okRJGEB1]]; Pause[]; SetLabel[okRJGEB1];
Fourthly, test RJLB and RJLBJ.
drRJLBJ[topSrc, belowSrc, UseLabel8B[badRJB]];
drRJLB[topSrc, belowSrc, UseLabel8B[badRJB]];
drRJLBJ[topSrc, topSrc, UseLabel8B[badRJB]];
drRJLB[popSrc, popSrc, UseLabel8B[badRJB]];
Now reverse the arguments
drLIQB[ax]; drLIQB[bx];
drRJGBJ[topSrc, belowSrc, UseLabel8B[badRJB]];
drRJGB[topSrc, belowSrc, UseLabel8B[badRJB]];
drRJLEBJ[topSrc, belowSrc, UseLabel8B[okRJLEBJ0]]; Pause[]; SetLabel[okRJLEBJ0];
drRJLEB[topSrc, belowSrc, UseLabel8B[okRJLEB0]]; Pause[]; SetLabel[okRJLEB0];
drRJGEBJ[topSrc, belowSrc, UseLabel8B[badRJB]];
drRJGEB[topSrc, belowSrc, UseLabel8B[badRJB]];
drRJLBJ[topSrc, belowSrc, UseLabel8B[okRJLBJ0]]; Pause[]; SetLabel[okRJLBJ0];
drRJLB[popSrc, belowSrcPop, UseLabel8B[okRJLB0]]; Pause[]; SetLabel[okRJLB0];
drJDB[UseLabel16[endTest]];
SetLabel[badRJB]; Pause[];
SetLabel[endTest];
};
SetLabel[enterRJBTest];
RJBTest[ 17777777777B, FIRST[INT]];
RJBTest[ 0B, FIRST[INT]];
RJBTest[-17777777777B, FIRST[INT]];
RJBTest[ 17777777777B, 0B];
RJBTest[ 1B, 0B];
RJBTest[ 0B, -1B];
};
RBC: If Ra < Rb (unsigned) then Rc ← Ra else trap
QBC: If Rs < Rb (unsigned) then Rd ← Rs else trap.
BC: If not Stack[S-1] < Stack[S] (unsigned) then trap; S ← S - 1.
GenRBC:
PROC = {
Test the RBC, QBC, and BC opcodes on the value a and bound b.
RBCTest:
PROC [a, b:
LONG CARDINAL] ~ {
ax: Word ← CardToWord[a];
bx: Word ← CardToWord[b];
RBCok: Label ← GenLabel[];
RBCbad: Label ← GenLabel[];
IF a < b
THEN {
drROR[const5, const0, const0]; --Indicate BC trap not expected.
drLIQB[bx];
drLIQB[ax];
drQBC[pushAtop, reg0];
drRBC[pushDst, reg1, reg0];
drRJEBJ[popSrc, reg1, UseLabel8B[RBCok]];
SetLabel[RBCbad]; Pause[]; SetLabel[RBCok];
drRJNEB[popSrc, reg1, UseLabel8B[RBCbad]];
drEXDIS[];
drLIQB[bx];
drBC[];
drLIQB[ax];
drRJNEB[popSrc, belowSrcPop, UseLabel8B[RBCbad]];
}
ELSE {
drROR[const5, const7, const7]; --Indicate BC trap expected.
drLIQB[bx];
drLIQB[ax];
drQBC[pushAtop, reg0];
Pause[]; Pause[]; --Skipped by trap return
drRBC[pushDst, reg1, reg0];
Pause[]; --Skipped by trap return
drEXDIS[];
drLIQB[bx];
drBC[];
Pause[]; Pause[]; Pause[];
drLIQB[bx];
drRJEBJ[popSrc, belowSrcPop, UseLabel8B[RBCok]];
SetLabel[RBCbad]; Pause[];
SetLabel[RBCok];
drLIQB[ax];
drRJNEB[popSrc, belowSrcPop, UseLabel8B[RBCbad]];
};
};
SetLabel[enterRBCTest];
RBCTest[0, 0];
RBCTest[0, 1];
RBCTest[1, 1];
RBCTest[17777777777B, 17777777777B];
RBCTest[17777777776B, 17777777777B];
RBCTest[37777777777B, 17777777777B];
RBCTest[20000000000B, 1];
RBCTest[20000000000B, 17777777777B];
};
savePC ← GetOutputPC[area];
FillTrap[ALUCondBC, BoundsCheck];
SetOutputPC[savePC];
Begin at PC = userBasePC = 1010000B * 4, L = 1, S = 0 as established in GenDebugger. const0 is in a ROM, so it requires no initialization; const7 is initialized to -1 here; the other constants require no initialization for this diagnostic.
drLIQB[IntToWord[-1]];
drROR[const7, topSrc, popSrc]; --Put -1 in const7.
drLIB[4];
drROR[const4, topSrc, popSrc]; --Put 4 in const4 for BC trap
drROR[const5, const0, const0]; --Indicate BC trap not expected.
GenRJB[];
GenRBC[];
Halt[177777B]; --Terminate here at the end of the program
Trap here with the return PC pointing at an opcode which experienced a bounds check trap; this trap is always enabled, so no special enabling action is necessary. Unless const5 = -1, Pause[] (boounds check unexpected); otherwise, increment PC by 4 and return.
WordAlign[area];
SetLabel[BoundsCheck];
drALS[1]; --ALS[1 - nargs]
drLC5[];
drRJNEB[popSrc, const7, UseLabel8B[BCUnexpected]];
GetYoungestPC[]; --Advance return PC by 4
drRVADD[topDst, const4, topSrc]; --Must not use ADDB here because of Carry
SetYoungestPC[];
drRET[377B]; --RET[nResults - 1]
SetLabel[BCUnexpected]; Pause[];
END.