DIRECTORY DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; GenTrapTest: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; expected: AuxRegSpec = aux10; ifuOvflCallDepth: AuxRegSpec = aux11; underflowHandler: AuxRegSpec = aux12; stackPos: AuxRegSpec = aux13; Other: TYPE = {none, stackUnderflow}; All: PROC = { MarkStack: PROC = { -- 6 bytes drLFC[UseLabel16[getS]]; -- get the current EU stack position drROR[c: stackPos, a: const0, b: popSrc]; }; CheckStack: PROC [haltCode: NAT, delta: INT _ 0] = { drLFC[UseLabel16[getS]]; -- get the current EU stack position IF delta # 0 THEN { drADDB[IF delta>0 THEN 128-delta ELSE -delta]; drLIB[07FH]; drAND[]; }; drRJEBJ[left: popSrc, right: stackPos, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[haltCode]; -- stack misadjusted SetLabel[fwdLabel0]; }; Expect: PROC [ willBeXOP: DragOpsCross.Inst _ dLIQB -- never an XOP --, willBeTrap: DragOpsCross.TrapIndex _ ALUCondFalse -- never a trap --, willBeOther: Other _ none ] = BEGIN IF (willBeXOP # dLIQB) OR (willBeOther # none) OR (willBeTrap # ALUCondFalse) THEN MarkStack[]; -- 6 bytes PushExpected[xop: willBeXOP, trap: willBeTrap, other: willBeOther]; -- 2 bytes if trap drROR[c: expected, a: const0, b: popSrc]; -- 3 bytes END; PushExpected: PROC [xop: DragOpsCross.Inst _ dLIQB -- not a real xop --, trap: DragOpsCross.TrapIndex _ ALUCondFalse -- not a real trap --, other: Other _ none -- not a real other -- ] = BEGIN SELECT TRUE FROM xop # dLIQB => drLIDB[256+xop.ORD]; other # none => drLIDB[512+other.ORD]; ENDCASE => drLIB[trap.ORD]; -- 2 bytes END; Check: PROC [ wasXOP, willBeXOP: DragOpsCross.Inst _ dLIQB -- never an XOP --, wasTrap, willBeTrap: DragOpsCross.TrapIndex _ ALUCondFalse -- never a trap -- , wasOther, willBeOther: Other _ none -- never a trap -- , wasFailCode: CARDINAL _ 1 ] = BEGIN fwdLabel0: Label; PushExpected[xop: wasXOP, trap: wasTrap, other: wasOther]; drRJEBJ[left: popSrc, right: expected, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[wasFailCode]; SetLabel[fwdLabel0]; Expect[willBeXOP: willBeXOP, willBeTrap: willBeTrap, willBeOther: willBeOther]; END; GenGetS: PROC RETURNS [ getS: Label ] = BEGIN -- Effect: [S+1] _ S; S _ S+1 getS _ GenLabel[]; ProcedureEntry[label: getS, args: 1]; -- L _ S GetL[]; ProcedureExit[rets: 2]; END; GenLSEnaKernel: PROC RETURNS [ lsEnaKernel: Label ] = BEGIN underflowTrap, fwdLabel0: Label; lsEnaKernel _ GenLabelHere[]; drLIB[DragOpsCross.TrapIndex[ALUCondFalse].ORD]; -- one frame on IFU stack drROR[c: expected, a: const0, b: popSrc]; drLIB[LOOPHOLE[DragOpsCross.IFUStatusRec[userMode: FALSE, trapsEnabled: FALSE, reschedule: FALSE], LONG CARDINAL]]; drSIP[DragOpsCross.ProcessorRegister[ifuStatus].ORD]; drLIB[sLimitValue]; drDUP[]; drSIP[DragOpsCross.ProcessorRegister[ifuSLimit].ORD]; drLIP[DragOpsCross.ProcessorRegister[ifuSLimit].ORD]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[5]; -- couldn't set SPLimit SetLabel[fwdLabel0]; GetEldestPC[]; -- pops IFU stack drSFC[]; -- returns to caller with underflow handler on stack underflowTrap _ GenLabelHere[]; -- no frames on stack PushExpected[other: stackUnderflow]; drRJEBJ[left: popSrc, right: expected, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[6]; -- this fault wasn't expected SetLabel[fwdLabel0]; drLFC[UseLabel16[getS]]; drRJEBJ[left: popSrc, right: stackPos, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[7]; -- stack misadjusted SetLabel[fwdLabel0]; drLIB[DragOpsCross.TrapIndex[ALUCondFalse].ORD]; drROR[c: expected, a: const0, b: popSrc]; drROR[c: pushDst, a: const0, b: underflowHandler]; drSFC[]; drJB[UseLabel8A[underflowTrap]]; END; GenXOPTrap: PROC RETURNS [ xopTrap: Label ] = BEGIN -- Checks fault type and S, and returns to successor of faulting instr. fwdLabel0: Label; xopTrap _ GenLabelHere[]; drRJEBJ[left: popSrc, right: expected, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[22]; -- this trap wasn't expected SetLabel[fwdLabel0]; CheckStack[haltCode: 23]; drLIB[DragOpsCross.TrapIndex[ALUCondFalse].ORD]; drROR[c: expected, a: const0, b: popSrc]; ProcedureExit[rets: 0, dontChangeSP: TRUE]; END; GenKFCTrap: PROC RETURNS [ kfcTrap: Label ] = BEGIN kfcTrap _ GenLabel[]; ProcedureEntry[label: kfcTrap, args: 2]; -- saved IFU status, Reg0; trap#, Reg1 drLFC[UseLabel16[xopTrap]]; ProcedureExit[rets: 0, enableTraps: TRUE]; END; GenStandardTrap: PROC RETURNS [ standardTrap: Label ] = BEGIN -- Checks fault type and S, pushes PC of faulting instr on S, and returns to successor of faulting instr. resumeStatus: DragOpsCross.IFUStatusRec = [ trapsEnabled: TRUE, rescheduleKeep: TRUE ]; fwdLabel0: Label; opLengthTable: Label = GenLabel[]; standardTrap _ GenLabelHere[]; drRJEBJ[left: popSrc, right: expected, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[2]; -- this trap wasn't expected SetLabel[fwdLabel0]; drLIB[DragOpsCross.TrapIndex[ALUCondFalse].ORD]; drROR[c: expected, a: const0, b: popSrc]; ProcedureEntry[label: GenLabel[], args: 1]; -- saved IFU status, Reg0 drRADD[c: pushDst, a: const0, b: const0]; -- saved carry, Reg1 drLIP[DragOpsCross.ProcessorRegister[euField].ORD]; -- saved field control, Reg2 CheckStack[haltCode: 3, delta: 3]; GetYoungestPC[]; -- read PC of offending instruction from IFU stack drDUP[]; drDUP[]; drSHL[FieldDescriptorToCard[[mask: 5, shift: 3]]]; drFSDB[FieldDescriptorToCard[[]]]; drSHR[FieldDescriptorToCard[[mask: 30, shift: 32-2]]]; drRB[0]; drRFU[c: topDst, a: topSrc, b: const0]; drSHR[FieldDescriptorToCard[[mask: 5, shift: 32-27]]]; drLIB[(7 -- three bits of opcode -- )*DragOpsCross.bytesPerWord]; drAND[]; -- byte offset in opLengthTable drLIQB[UseLabel32[opLengthTable]]; -- byte address of opLengthTable drADD[]; drSHR[FieldDescriptorToCard[[mask: 30, shift: 32-2]]]; -- byte to word address drRB[0]; -- read length table for trapping op drADD[]; -- add to trap PC SetYoungestPC[]; -- adjust PC on IFU stack drFSDB[0]; -- restore field control from stack top drRUADD[c: topDst, a: popSrc, b: constN1]; -- restore carry from stack top, toss result ProcedureExit[rets: 0, enableTraps: TRUE]; WordAlign[area]; SetLabel[opLengthTable]; -- gleaned from DragOpsCross OutputWord[area, IntToWord[1]]; -- 000 => 1 byte OutputWord[area, IntToWord[5]]; -- 001 => 5 bytes OutputWord[area, IntToWord[1]]; -- 01- => 1 byte OutputWord[area, IntToWord[1]]; -- 01- => 1 byte OutputWord[area, IntToWord[2]]; -- 10- => 2 bytes OutputWord[area, IntToWord[2]]; -- 10- => 2 bytes OutputWord[area, IntToWord[3]]; -- 11- => 3 bytes OutputWord[area, IntToWord[3]]; -- 11- => 3 bytes END; GenCallerTrap: PROC RETURNS [ callerTrap: Label ] = BEGIN -- Checks fault type and S, and returns to caller of faulting instr with two results: PC of faulting instr on top, and stack top next. fwdLabel0: Label; callerTrap _ GenLabelHere[]; drRJEBJ[left: popSrc, right: expected, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[4]; -- this fault wasn't expected SetLabel[fwdLabel0]; drLIB[DragOpsCross.TrapIndex[ALUCondFalse].ORD]; drROR[c: expected, a: const0, b: popSrc]; ProcedureEntry[label: GenLabel[], args: 2]; -- stack top, Reg0; saved IFU status, Reg1 drLRn[reg1]; -- saved IFU status, Reg2 drRADD[c: pushDst, a: const0, b: const0]; -- saved carry, Reg3 drLRn[reg0]; -- stack top, Reg4 CheckStack[haltCode: 5, delta: 4]; GetYoungestPC[]; -- PC of offending instruction, Reg5 drLIQB[UseLabel32[fwdLabel0 _ GenLabel[]]]; SetYoungestPC[]; ProcedureExit[rets: 6]; SetLabel[fwdLabel0]; drSRn[reg1]; drSRn[reg0]; drRUADD[c: topDst, a: popSrc, b: constN1]; -- restore carry, toss result ProcedureExit[rets: 2, enableTraps: TRUE]; END; GenReschedTrap: PROC RETURNS [ reschedTrap: Label ] = BEGIN resumeStatusAnd: DragOpsCross.IFUStatusRec = [ userMode: TRUE, trapsEnabled: TRUE ]; -- clears reschedule reschedTrap _ GenLabel[]; ProcedureEntry[label: reschedTrap, args: 1]; drLIQB[LOOPHOLE[resumeStatusAnd]]; drAND[]; ProcedureExit[rets: 0, enableTraps: TRUE]; END; FillTrap: PROC [ trap: DragOpsCross.TrapIndex, label: Label _ NIL ] = BEGIN oldPC: LONG CARDINAL = GetOutputPC[]; IF label = NIL THEN label _ standardTrap; SetOutputPC[DragOpsCrossUtils.TrapIndexToBytePC[trap]]; PushExpected[trap: trap]; -- push the trap number drJDB[UseLabel16[label]]; -- go to trap handler SetOutputPC[oldPC]; END; FillXOP: PROC [ inst: DragOpsCross.Inst, label: Label ] = BEGIN oldPC: LONG CARDINAL = GetOutputPC[]; SetOutputPC[DragOpsCrossUtils.XopToBytePC[inst]]; PushExpected[xop: inst]; -- push the xop number drJDB[UseLabel16[label]]; -- go to trap handler SetOutputPC[oldPC]; END; area: Area = GetCurrentArea[]; curPC: CARD; sLimitValue: [0..128) = 16; getS: Label = GenGetS[]; lsEnaKernel: Label = GenLSEnaKernel[]; standardTrap: Label = GenStandardTrap[]; callerTrap: Label = GenCallerTrap[]; xopTrap: Label = GenXOPTrap[]; kfcTrap: Label = GenKFCTrap[]; reschedTrap: Label = GenReschedTrap[]; data: Label = GenLabel[]; dataA: Label = GenLabel[]; SFCITarget: Label = GenLabel[]; start: Label = GenLabel[]; fwdLabel0, fwdLabel1, fwdLabel2, bwdLabel0, bwdLabel1: Label; ifuPageFaultTest1: Label = GenLabel[]; ifuFirstIncompleteInstruction1: Label = GenLabel[]; faultingPC: Label = GenLabel[]; FillTrap[IFUPageFaultTrap, callerTrap]; FillTrap[EUPageFault, callerTrap]; FillTrap[IFUStackOverflowTrap]; FillTrap[EUStackOverflowTrap, callerTrap]; FillTrap[ALUCondOver]; FillTrap[ModeFault]; FillTrap[AddressCheckFault]; FillTrap[RescheduleTrap, reschedTrap]; FillTrap[ResetTrap, start]; FOR inst: DragOpsCross.Inst IN DragOpsCross.Inst DO FillXOP[inst: inst, label: (IF inst=dKFC THEN kfcTrap ELSE xopTrap)]; ENDLOOP; WHILE GetOutputPC[area] MOD 4*DragOpsCross.bytesPerWord # 0 DO OutputByte[area, CardToByte[0]]; ENDLOOP; SetLabel[data]; [] _ ReserveData[words: 16]; SetLabel[dataA]; THROUGH [0..3) DO OutputWord[area, IntToWord[0]] ENDLOOP; THROUGH [0..3) DO OutputByte[area, CardToByte[0]] ENDLOOP; drLIQB[UseLabel32[SFCITarget]]; SetLabel[start]; drLIB[1]; drROR[c: const1, a: const0, b: popSrc]; drRADD[c: pushDst, a: const0, b: const0]; -- clear carry drDIS[]; drRSUB[c: constN1, a: const0, b: const1]; drRADD[c: constN2, a: constN1, b: constN1]; drLC1[]; drLIQB[CardToWord[FieldDescriptorToCard[[insert: FALSE, mask: 32, shift: 31]]]]; drFSDB[0]; -- initialize field unit control drRFU[c: constNI, a: popSrc, b: const0]; drLFC[UseLabel16[lsEnaKernel]]; EnableTraps[]; drRADD[c: pushDst, a: const0, b: const0]; -- clear carry drDIS[]; drRADD[c: pushDst, a: constNI, b: const0]; -- shouldn't overflow drDIS[]; Check[willBeTrap: ALUCondOver]; drRADD[c: pushDst, a: constNI, b: constN1]; -- should overflow Check[wasFailCode: 101]; drRADD[c: pushDst, a: const0, b: const0]; -- find out what carry was drJEBBJ[lit: 0, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[102]; -- carry wasn't clear SetLabel[fwdLabel0]; drRUADD[c: pushDst, a: constN1, b: constN1]; -- set carry drDIS[]; drRADD[c: pushDst, a: constNI, b: constN1]; -- shouldn't overflow drDIS[]; drRUADD[c: pushDst, a: constN1, b: constN1]; -- set carry drDIS[]; Check[willBeTrap: ALUCondOver]; drRADD[c: pushDst, a: constNI, b: constN2]; Check[wasFailCode: 111]; drRADD[c: pushDst, a: const0, b: const0]; -- find out what carry was drJEBBJ[lit: 1, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[112]; -- carry wasn't set SetLabel[fwdLabel0]; MarkStack[]; drRJEBJ[left: const0, right: const0, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; drDIS[]; Halt[113]; bwdLabel0 _ GenLabelHere[]; drDIS[]; Halt[114]; SetLabel[fwdLabel0]; drRJNEBJ[left: const0, right: const0, dist: UseLabel8B[bwdLabel0]]; drRJEB[left: const0, right: const0, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; drDIS[]; Halt[115]; bwdLabel0 _ GenLabelHere[]; drDIS[]; Halt[116]; SetLabel[fwdLabel0]; drRJNEB[left: const0, right: const0, dist: UseLabel8B[bwdLabel0]]; drJ1[]; CheckStack[haltCode: 117]; drLFC[UseLabel16[ifuPageFaultTest1]]; Check[wasFailCode: 105]; drLIQB[UseLabel32[ifuFirstIncompleteInstruction1]]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[121]; -- trap PC wasn't right SetLabel[fwdLabel0]; drDIS[]; -- discard second result from trap handler drLFC[UseLabel16[fwdLabel0 _ GenLabel[]]]; Check[]; drJDB[UseLabel16[fwdLabel1 _ GenLabel[]]]; SetLabel[fwdLabel0]; drLIB[0]; drSIP[DragOpsCross.ProcessorRegister[euMAR].ORD]; -- clear euMAR drLIQB[UseLabel32[ifuFirstIncompleteInstruction1]]; drSHR[FieldDescriptorToCard[[mask: 30, shift: 32-2]]]; -- byte to word address Check[willBeTrap: EUPageFault]; WHILE GetOutputPC[area] MOD DragOpsCross.bytesPerWord # 3 DO drJ1[]; ENDLOOP; bwdLabel0 _ GenLabelHere[]; drRB[20]; -- generates page fault, sets euMAR to faulting address drRADD[c: pushDst, a: constNI, b: constNI]; -- generates arithmetic overflow Halt[131]; -- should never get here SetLabel[fwdLabel1]; drLIQB[UseLabel32[bwdLabel0]]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[132]; -- trap PC wasn't right SetLabel[fwdLabel0]; drLIB[20]; -- form address that faulted drADD[]; drLIP[DragOpsCross.ProcessorRegister[euMAR].ORD]; -- compare against euMAR drRJEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[133]; -- euMAR wasn't right SetLabel[fwdLabel0]; drLIQB[UseLabel32[dataA]]; drSHR[FieldDescriptorToCard[[mask: 30, shift: 32-2]]]; -- byte to word address drDUP[]; drLIB[4]; drWSB[0]; -- force prior reject drADDB[4]; drSFCI[]; -- force reject within SFCI Check[]; drJDB[UseLabel16[fwdLabel0 _ GenLabel[]]]; SetLabel[SFCITarget]; drLIQB[UseLabel32[faultingPC]]; -- as if there were a data word here drSHR[FieldDescriptorToCard[[mask: 30, shift: 32-2]]]; -- byte to word address Check[willBeTrap: EUPageFault]; bwdLabel0 _ GenLabelHere[]; drSFCI[]; -- generates page fault, sets euMAR to faulting address drRADD[c: pushDst, a: constNI, b: constNI]; -- generates arithmetic overflow Halt[134]; SetLabel[fwdLabel0]; drLIQB[UseLabel32[bwdLabel0]]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[132]; -- trap PC wasn't right SetLabel[fwdLabel0]; drDIS[]; -- faulting address drLFC[UseLabel16[fwdLabel0 _ GenLabel[]]]; drJDB[UseLabel16[fwdLabel1 _ GenLabel[]]]; ProcedureEntry[label: fwdLabel0, args: 0]; drLIQB[UseLabel32[data]]; drSHR[FieldDescriptorToCard[[mask: 30, shift: 32-2]]]; -- byte to word address drLIB[1]; drSRIn[reg0, 0]; drLIB[2]; -- proposed new value drLIB[1]; -- proposed old value MarkStack[]; drCST[0]; -- should succeed drJEBBJ[lit: 1, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; -- sampled value Halt[141]; SetLabel[fwdLabel0]; CheckStack[haltCode: 142]; drLRIn[reg0, 0]; drJEBBJ[lit: 2, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[143]; SetLabel[fwdLabel0]; drDIS[]; drDIS[]; drLIB[3]; -- proposed new value drLIB[1]; -- proposed old value drCST[0]; -- should fail drJEBBJ[lit: 2, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; -- sampled value Halt[144]; SetLabel[fwdLabel0]; CheckStack[haltCode: 145]; drLRIn[reg0, 0]; drJEBBJ[lit: 2, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[146]; SetLabel[fwdLabel0]; drDIS[]; drDIS[]; drDIS[]; drLIQB[UseLabel32[ifuFirstIncompleteInstruction1]]; drSHR[FieldDescriptorToCard[[mask: 30, shift: 32-2]]]; -- byte to word address drLIB[3]; -- proposed new value drLIB[1]; -- proposed old value Check[willBeTrap: EUPageFault]; WHILE GetOutputPC[area] MOD DragOpsCross.bytesPerWord # DragOpsCross.bytesPerWord-1 DO drJ1[]; ENDLOOP; bwdLabel0 _ GenLabelHere[]; drCST[20]; -- generates page fault drRADD[c: pushDst, a: constNI, b: constNI]; -- generates arithmetic overflow Halt[147]; -- should never get here SetLabel[fwdLabel1]; Check[wasFailCode: 148]; drLIQB[UseLabel32[bwdLabel0]]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[149]; -- trap PC wasn't right SetLabel[fwdLabel0]; drDIS[]; -- discard second result from trap handler drLFC[UseLabel16[fwdLabel0 _ GenLabel[]]]; drJDB[UseLabel16[fwdLabel1 _ GenLabel[]]]; ProcedureEntry[label: fwdLabel0, args: 0]; drLFC[UseLabel16[fwdLabel0 _ GenLabel[]]]; drSRn[reg1]; -- PC of offender drSRn[reg0]; -- last successfully pushed value ProcedureExit[rets: 2]; SetLabel[fwdLabel0]; Check[willBeTrap: EUStackOverflowTrap]; drLIB[sLimitValue-1]; drROR[c: stackPos, a: const0, b: popSrc]; drLIB[0]; bwdLabel0 _ GenLabelHere[]; FOR i: [0..32) IN [0..32) DO drLIB[2*(i+1)]; ENDLOOP; Halt[151]; -- should have trapped on EU overflow by now SetLabel[fwdLabel1]; Check[]; drLIQB[UseLabel32[bwdLabel0]]; drRVSUB[c: belowDst, a: belowSrc, b: popSrc]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[152]; -- trap PC didn't agree with topmost value SetLabel[fwdLabel0]; drLIQB[UseLabel32[fwdLabel0 _ GenLabel[]]]; drROR[c: underflowHandler, a: const0, b: popSrc]; Check[willBeOther: stackUnderflow]; ProcedureExit[rets: 0, dontChangeSP: TRUE]; SetLabel[fwdLabel0]; Check[wasFailCode: 161]; drLFC[UseLabel16[fwdLabel0 _ GenLabel[]]]; drJDB[UseLabel16[fwdLabel1 _ GenLabel[]]]; ProcedureEntry[label: fwdLabel0, args: 0]; drLIB[0]; Check[willBeTrap: IFUStackOverflowTrap]; drLFC[UseLabel16[fwdLabel0 _ GenLabel[]]]; bwdLabel0 _ GenLabelHere[]; -- IFU PC address at which to stop ProcedureExit[rets: 0]; fwdLabel2 _ GenLabel[]; FOR i: [0..16) IN [0..16) DO SetLabel[fwdLabel0]; drLFC[UseLabel16[fwdLabel0 _ GenLabel[]]]; drJDB[UseLabel16[fwdLabel2]]; ENDLOOP; SetLabel[fwdLabel0]; Halt[171]; -- too deep SetLabel[fwdLabel2]; drLIQB[UseLabel32[bwdLabel0]]; -- IFU stack PC address at which to stop bwdLabel1 _ GenLabelHere[]; drRVADD[c: reg0, a: reg0, b: const1]; -- pull most of the calls off the stack GetYoungestPC[]; drRJEB[left: popSrc, right: belowSrc, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; drLIQB[UseLabel32[bwdLabel1]]; SetYoungestPC[]; ProcedureExit[rets: 0, dontChangeSP: TRUE]; SetLabel[fwdLabel0]; drDIS[]; Check[wasFailCode: 181]; drLRn[reg0]; drROR[c: ifuOvflCallDepth, a: popSrc, b: const0]; ProcedureExit[rets: 0, dontChangeSP: TRUE]; SetLabel[fwdLabel1]; Check[willBeXOP: VAL[1B]]; OutputByte[NIL, CardToByte[1B]]; -- one-byte XOP Check[]; drLIQB[CardToWord[12345678H]]; drDUP[]; -- get stack to depth it will have after XOP pushes argument word Check[willBeXOP: x065B]; drDIS[]; OutputByte[NIL, CardToByte[65B]]; -- five-byte XOP OutputAlphaBetaGammaDelta[NIL, CardToWord[12345678H]]; -- this gets pushed Check[]; drRJEBJ[left: popSrc, right: belowSrcPop, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[191]; SetLabel[fwdLabel0]; drLIB[0FEH]; drSIP[07FH]; drLIQB[LOOPHOLE[DragOpsCross.IFUStatusRec[userMode: TRUE, trapsEnabled: TRUE]]]; drLFC[UseLabel16[fwdLabel0 _ GenLabel[]]]; HandCodingSupport.OIcommon[dJ5]; -- jump around two-instruction routine SetLabel[fwdLabel0]; drALS[0]; -- one argument drRETK[0FFH]; drLIB[1]; -- for the store, which should never happen Check[willBeTrap: ModeFault]; drSIP[07FH]; Check[]; drDIS[]; -- the 1 above drLIP[07FH]; drDIS[]; Check[willBeTrap: ModeFault]; drLIP[DragOpsCross.ProcessorRegister[ifuEldestPC].ORD]; Check[willBeTrap: ModeFault]; drROR[c: const1, a: const0, b: const0]; Check[willBeTrap: ModeFault]; drROR[c: [aux[0]], a: const0, b: const0]; Check[]; drROR[c: [aux[15]], a: const0, b: const0]; Halt[0FFFFH]; -- end of test curPC _ GetOutputPC[area]; SetOutputPC[curPC+((2*DragOpsCross.bytesPerPage-15-(curPC MOD DragOpsCross.bytesPerPage)) MOD DragOpsCross.bytesPerPage), area]; SetLabel[ifuPageFaultTest1]; Expect[willBeTrap: IFUPageFaultTrap]; -- 11 bytes SetLabel[ifuFirstIncompleteInstruction1]; OutputByte[area, CardToByte[DragOpsCross.Inst[dLIQB].ORD]]; -- 4 bytes in this page OutputByte[area, CardToByte[1]]; OutputByte[area, CardToByte[2]]; OutputByte[area, CardToByte[3]]; -- Aprez moi, le fault de page! SetLabel[faultingPC]; }; END. xGenTrapTest.mesa written by McCreight, 28 Sept 85 McCreight, February 26, 1986 4:03:00 pm PST The register expected is used to indicate which trap is expected, and stackPos indicates where the stack should be when the trap strikes. Main line code sets them, and trap routines check and reset them. M A I N L I N E C O D E Set up data area Align to quadword boundary .. it would be nice if there were a way of generating a byte-address and word-address data word Set up some constant registers Set up L and SLimit registers and turn on traps in kernel mode. Test addition without and with overflow, with carry clear. Test addition without and with overflow, with carry set. Test variants of conditional jumps Test IFU page faulting. Test EU page faulting. Align with respect to word boundary Test SFCI with rejects Test conditional store Align to last byte in a word Test S register limiting. Limits as a drLIB instruction tries to increment from sLimitValue-1 to sLimitValue Test manual IFU stack entry and underflow. Test IFU stack overflow. drJEBBJ[lit: 10, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[182]; -- reg0 holds actual number SetLabel[fwdLabel0]; Test mode-independent XOP's Switch to user mode Try several kernel-mode instructions Address-independent protection violations trap to ModeFault End of test Instruction sequence for IFU page fault test... Κ˜šœ™Jšœ ™ Icode™+—J˜šΟk ˜ Kšœ ˜ K˜Kšœ ˜ Kšœ˜Kšœ˜K˜—šœ œ˜KšœD˜KKšœœœE˜QK˜Kšœ˜Kšœ%˜%Kšœ%˜%Kšœ˜K˜Kšœœ˜%K˜K˜šΟnœœ˜ KšœΛ™ΛK™—˜šž œœΟc ˜JšœŸ$˜=Jšœ)˜)J˜J˜—šž œœ œ œ ˜4˜JšœŸ$˜=šœ œ˜Jšœœ œ œ ˜.Jšœ ˜ Jšœ˜Jšœ˜—JšœQ˜QJšœŸ˜$J˜—Jšœ Οi œ˜J˜˜J˜——šžœœ(Ÿœ4Ÿœ˜«Jš˜Jš œœœœŸ ˜jJšœDŸ˜VJšœ*Ÿ ˜4Jšœ˜J˜J˜—š ž œœ!Ÿœ.ŸœŸœ˜ΊJš˜šœœ˜Jšœœ˜#Jšœ!œ˜&JšœœŸ ˜&—Jšœ˜J˜J˜—š žœœ0Ÿœ=Ÿœ'Ÿœœ˜υJš˜J˜˜Jšœ:˜:JšœQ˜QJšœ˜J˜—šœ   œ˜JšœO˜OJ˜—Jšœ˜J˜J˜—šžœœœ˜'JšœŸ˜#J˜šΟbœ˜šœ&Ÿ˜.J˜J˜J˜——Jšœ˜J˜J˜—šžœœœ˜5Jš˜Jšœ ˜ J˜Jš‘ œ˜˜Jšœ+œŸ˜JJšœ)˜)Jš œœ%œœœœœ˜sKšœ0œ˜5J˜J˜Jšœ0œ˜5Jšœ0œ˜5JšœT˜TJšœ Ÿ˜ J˜—šœ   œ˜JšœŸ˜ Jšœ Ÿ4˜=J˜—šœ Ÿ˜5Jšœ$˜$JšœQ˜QJšœ Ÿ˜&J˜—šœ   œ˜Jšœ˜JšœQ˜QJšœ Ÿ˜—J˜šœ   œ˜Jšœ+œ˜0Jšœ)˜)Jšœ2˜2J˜Jšœ ˜ J˜—Jšœ˜J˜J˜—šž œœœ‘œ˜-JšœŸG˜MJ˜J˜š‘œ˜JšœQ˜QJšœ Ÿ˜&J˜—šœ   œ˜Jšœ˜Jšœ+œ˜0Jšœ)˜)Jšœ%œ˜+J˜—Jšœ˜J˜J˜—šž œœœ‘œ˜-Jš˜Jšœ˜J˜šœ‘œ Ÿ&˜OJšœ˜Jšœ$œ˜*J˜—Jšœ˜J˜J˜—šžœœœ‘œ˜7JšœŸi˜oJšœ:œœ˜WJšœ˜J˜"J˜š‘ œ˜JšœQ˜QJšœ Ÿ˜%J˜—šœ   œ˜Jšœ+œ˜0Jšœ)˜)—J˜šœ,Ÿ˜EJšœ*Ÿ˜>Jšœ.œŸ˜PJ˜Jšœ"˜"J˜JšœŸ2˜CJ˜J˜J˜2J˜"J˜6J˜J˜'J˜6Jšœ Ÿœ˜AJšœ Ÿ˜(Jšœ#Ÿ ˜CJ˜Jšœ7Ÿ˜NJšœ Ÿ$˜-Jšœ Ÿ˜JšœŸ˜*Jšœ Ÿ'˜2Jšœ+Ÿ,˜WJšœ$œ˜*J˜—J˜šœ ‘ œŸ˜5Jšœ Ÿ˜0Jšœ Ÿ˜1Jšœ Ÿ˜0Jšœ Ÿ˜0Jšœ Ÿ˜1Jšœ Ÿ˜1Jšœ Ÿ˜1Jšœ Ÿ˜1—Jšœ˜J˜J˜—šž œœœ‘œ˜3JšœŸ†˜ŒJ˜J˜š‘ œ˜JšœQ˜QJšœ Ÿ˜&J˜—šœ   œ˜Jšœ+œ˜0Jšœ)˜)—J˜šœ,Ÿ*˜VJšœ Ÿ˜&Jšœ*Ÿ˜>Jšœ Ÿ˜J˜Jšœ"˜"J˜JšœŸ$˜5Jšœ+˜+J˜Jšœ˜J˜—šœ   œ˜Jšœ ˜ Jšœ ˜ Jšœ+Ÿ˜HJšœ$œ˜*J˜—Jšœ˜J˜J˜—šžœœœ˜5Jš˜šœ,˜,Jšœ œœŸ˜<—Jš‘ œ˜J˜šœ‘ œ ˜,Jšœœ˜"Jšœ˜Jšœ$œ˜*—Jšœ˜J˜J˜—šžœœ0œ˜EJš˜Jšœœœ˜%Jšœ œœ˜)J˜7JšœŸ˜1JšœŸ˜/J˜Jšœ˜J˜J˜—šžœœ,˜9Jš˜Jšœœœ˜%J˜1JšœŸ˜/JšœŸ˜/J˜Jšœ˜J˜J˜—Jšœ™J˜J˜Jšœœ˜ J˜J˜J˜J˜J˜&J˜(Jšœ$˜$Jšœ˜J˜J˜&J˜J˜J˜J˜J˜J˜=J˜&J˜3J˜J˜Jšœ'˜'Jšœ"˜"Jšœ˜Jšœ*˜*J˜J˜Jšœ˜Jšœ&˜&Jšœ˜J˜šœœ˜3Jšœœ œ œ ˜EJšœ˜—J˜šœ™™šœœ!˜>J™J˜ Jšœ˜J˜——šœ ‘œ˜J˜—šœ ‘œ˜Jšœœ œ˜9Jšœœ!œ˜:šœ˜J™_—J˜—J˜—šœ™J™šœ ‘œ˜J˜1Jšœ*Ÿ˜8J˜J˜)J˜+Jšœ˜Jšœ1œ˜PJšœ Ÿ ˜+J˜(—J˜—šœ?™?™J˜J˜J˜——šœ:™:™Jšœ*Ÿ˜8J˜Jšœ+Ÿ˜@J˜J˜Jšœ,Ÿ˜>J˜Jšœ*Ÿ˜DJ˜:Jšœ Ÿ˜ J˜—Jšœ   œ˜J˜—šœ8™8™Jšœ-Ÿ ˜9J˜Jšœ,Ÿ˜AJ˜Jšœ-Ÿ ˜9J˜J˜Jšœ+˜+J˜Jšœ*Ÿ˜DJšœ:˜:Jšœ Ÿ˜J˜—šœ   œ˜J˜——™"™Jšœ ˜ JšœO˜OJšœ˜Jšœ ˜ —J˜š  œ˜Jšœ˜Jšœ ˜ J˜—šœ   œ˜JšœC˜CJšœN˜NJšœ˜Jšœ ˜ J˜—š  œ˜Jšœ˜Jšœ ˜ J˜—šœ   œ˜JšœB˜BJ˜J˜J˜J˜——™™J˜%J˜J˜3JšœT˜TJšœ Ÿ˜"J˜—šœ   œ˜Jšœ Ÿ*˜3J˜——™™Jšœ*˜*J˜Jšœ*˜*J˜—šœ   œ˜Jšœ ˜ Jšœ,œŸ˜@Jšœ3˜3Jšœ7Ÿ˜NJ˜J˜—šœœ˜Jšœ˜J˜—Jšœ˜šœ œ ˜J˜šœ   œ˜Jšœ*˜*Jšœ˜J˜—šœ˜J˜——šœ   œ˜Jšœ Ÿ ˜J˜J˜—šœ   œ˜JšœŸ(˜GJ˜—š  œ˜Jšœ&Ÿ'˜MJ˜JšœP˜PJšœ˜J˜Jšœ%œ˜+J˜—šœ   œ˜J˜Jšœ˜J˜ Jšœ1˜1Jšœ;™;Jšœ Ÿ™&J˜—šœ   œ™Jšœ%œ˜+J˜—Jšœ   œ˜J˜—šœ™™Jšœœ˜Jšœ œŸ˜0J˜J˜Jšœ ŸA˜JJšœ˜J˜Jšœ œŸ˜2JšœœŸ˜JJ˜JšœT˜TJ˜ J˜—Jšœ   œ˜J˜—šœ™™Jšœ ˜ Jšœ ˜ Jšœœ%œœ˜PJšœ*˜*šœ!Ÿ&˜GJšœ   œ˜Kšœ Ÿ˜K˜ —J™——™$™Jšœ Ÿ+˜5šœ˜Jšœ;™;—J˜ Jšœ˜Jšœ Ÿ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ2œ˜7Jšœ˜J˜'Jšœ˜Jšœ)˜)J˜Jšœ*˜*J˜J™——šœ ™ ™JšœŸ˜J˜J˜——J™/˜J˜Jšœ:œœ#˜€J˜šœ ‘œ˜Jšœ&Ÿ ˜1—J˜šœ ‘œ˜)Jšœ5œŸ˜SJšœ ˜ Jšœ ˜ Jšœ!Ÿ˜@J˜—Jšœ ‘ œ˜—J˜J˜J˜—Jšœ˜J˜J˜J˜——…—Mήgf