<> <> <> DIRECTORY DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; GenTrapTest: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; expected: AuxRegSpec = [aux[10]]; ifuOvflCallDepth: AuxRegSpec = [aux[11]]; underflowHandler: AuxRegSpec = [aux[12]]; stackPos: AuxRegSpec = [aux[13]]; Other: TYPE = {none, stackUnderflow}; StackedStatusToWord: PROC [ s: DragOpsCross.StackedStatusWord, sense: {normal, complemented} _ normal ] RETURNS [ w: DragOpsCross.Word ] = TRUSTED BEGIN w _ LOOPHOLE[s]; IF sense = complemented THEN w _ DragOpsCrossUtils.DragNot[w]; END; 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; GenGetLAndStatus: PROC RETURNS [ getLAndStatus: Label ] = BEGIN -- Effect: [S+1] _ DragOpsCross.StackedStatusWord; S _ S+1 getLAndStatus _ GenLabelHere[]; drLIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; ProcedureExit[rets: 1, dontChangeSP: TRUE]; END; GenGetS: PROC RETURNS [ getS: Label ] = BEGIN -- Effect: [S+1] _ S; S _ S+1 ProcedureEntry[label: getS _ GenLabel[], args: 1]; -- L _ S drLFC[UseLabel16[getLAndStatus]]; drLIB[DragOpsCrossUtils.WordToCard[StackedStatusToWord[[lBase: 0FFH]]]]; drAND[]; ProcedureExit[rets: 2]; END; GenLSUnderflowKernel: PROC RETURNS [ lsUnderflowKernel: Label ] = BEGIN underflowTrap, fwdLabel0: Label; lsUnderflowKernel _ GenLabelHere[]; drLIB[DragOpsCross.TrapIndex[ALUCondFalse].ORD]; -- one frame on IFU stack drROR[c: expected, a: const0, b: popSrc]; 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 to EU stack top 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; GenTrapsOn: PROC RETURNS [ trapsOn: Label ] = BEGIN trapsOn _ GenLabelHere[]; drLIQB[StackedStatusToWord[[trapsEnabled: TRUE], complemented]]; drLIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; drAND[]; drLIQB[StackedStatusToWord[[trapsEnabled: TRUE]]]; drOR[]; drSIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; ProcedureExit[rets: 0, dontChangeSP: TRUE]; END; GenXOPTrap: PROC RETURNS [ xopTrap: Label ] = BEGIN -- Checks fault type and S, and returns to successor of xop fwdLabel0: Label; xopTrap _ GenLabelHere[]; drRJEBJ[left: popSrc, right: expected, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[22]; -- this xop 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 fwdLabel0: Label; kfcTrap _ GenLabelHere[]; drRJEBJ[left: popSrc, right: expected, dist: UseLabel8B[fwdLabel0 _ GenLabel[]]]; Halt[24]; -- this kfc wasn't expected SetLabel[fwdLabel0]; CheckStack[haltCode: 25]; drLIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; drSIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; <<.. something innocuous that's illegal in user mode>> drLIB[DragOpsCross.TrapIndex[ALUCondFalse].ORD]; drROR[c: expected, a: const0, b: popSrc]; ProcedureExit[rets: 0, dontChangeSP: 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. 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: 0]; drRADD[c: pushDst, a: const0, b: const0]; -- saved carry, Reg0 drLIP[DragOpsCross.ProcessorRegister[euField].ORD]; -- saved field control, Reg1 CheckStack[haltCode: 3, delta: 2]; 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]; 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, getTrapStatusMasks: 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]; drDUP[]; -- make space for results, fill with ST drDUP[]; drDUP[]; drDUP[]; ProcedureEntry[label: GenLabel[], args: 2]; -- ST in Reg0, Reg1 drRADD[c: pushDst, a: const0, b: const0]; -- saved carry, Reg2 CheckStack[haltCode: 5, delta: 5]; GetYoungestPC[]; drSRn[reg0]; -- Reg0 _ PC of offending instruction drLIQB[UseLabel32[fwdLabel0 _ GenLabel[]]]; SetYoungestPC[]; -- move caller's PC to within our trap handler drLFC[UseLabel16[getTrapStatusMasks _ GenLabel[]]]; drLIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; drOR[]; drAND[]; drSIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; <<.. make caller allowed to trap if and only if we are>> ProcedureExit[rets: 3]; SetLabel[getTrapStatusMasks]; drLIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; drLIQB[StackedStatusToWord[[trapsEnabled: TRUE], complemented]]; drOR[]; drDUP[]; drLIQB[StackedStatusToWord[[trapsEnabled: TRUE]]]; drAND[]; ProcedureExit[rets: 2, dontChangeSP: TRUE]; SetLabel[fwdLabel0]; drRUADD[c: topDst, a: popSrc, b: constN1]; -- restore carry, toss result drSRn[reg0]; -- Reg0 _ ST drSRn[reg1]; -- Reg1 _ PC of offending instruction ProcedureExit[rets: 2]; -- returns PC of offending instruction on top END; GenReschedTrap: PROC RETURNS [ reschedTrap: Label ] = BEGIN reschedTrap _ GenLabel[]; ProcedureEntry[label: reschedTrap, args: 1]; ProcedureExit[rets: 0]; 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; getLAndStatus: Label = GenGetLAndStatus[]; getS: Label = GenGetS[]; trapsOn: Label = GenTrapsOn[]; lsUnderflowKernel: Label = GenLSUnderflowKernel[]; 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[MemAccessFault]; FillTrap[IOAccessFault]; 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]; -- gets here in kernel mode with traps off <> <<.. done by ROM cells these days, I'm told.>> 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[lsUnderflowKernel]]; <> <<>> drLFC[UseLabel16[trapsOn]]; <> <<>> 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[]; -- ignore copied stack top <> <<>> 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]; -- stack top + 20 = 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[]; -- ignore copied stack top <<>> <<>> <> <<>> 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[]; -- ignore copied stack top <<>> <> <<>> 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[trapsOn]]; -- underflow handler sends control w/ traps off <> <<>> 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: x077b]; drDIS[]; OutputByte[NIL, CardToByte[77B]]; -- 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]; -- succeeds because I'm still in kernel mode drJDB[UseLabel16[fwdLabel0 _ GenLabel[]]]; bwdLabel0 _ GenLabelHere[]; -- subroutine executed from kernel mode that returns to user mode drLIQB[StackedStatusToWord[[userMode: TRUE, trapsEnabled: TRUE], complemented]]; drLIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; drAND[]; drLIQB[StackedStatusToWord[[userMode: TRUE, trapsEnabled: TRUE]]]; drOR[]; drSIP[DragOpsCross.ProcessorRegister[ifuYoungestL].ORD]; ProcedureExit[rets: 0, dontChangeSP: TRUE]; SetLabel[fwdLabel0]; drLFC[UseLabel16[bwdLabel0]]; <<>> <> <<>> 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[willBeXOP: dKFC]; drKFC[]; -- make sure we can get to kernel mode and back 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 faux page! SetLabel[faultingPC]; }; END.