<> <> <> 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]]; <<.. it would be nice if there were a way of generating a byte-address and word-address data word>> <> <<>> 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.