DIRECTORY DragonProcessOffsets, DragOpsCross, DragOpsCrossProcess, DragOpsCrossUtils, HandCoding, HandCodingSupport, HandCodingPseudos; GenStackTest: CEDAR PROGRAM IMPORTS HandCoding, HandCodingPseudos = BEGIN OPEN DragonProcessOffsets, HandCoding, HandCodingSupport, HandCodingPseudos; CARD: TYPE = LONG CARDINAL; Word: TYPE = DragOpsCross.Word; depthReg: RegSpec = HandCoding.aux10; GenRecurse: PROC [entry: Label] = { times: RegSpec = reg0; -- this value is also returned size: RegSpec = reg1; current: RegSpec = reg2; ProcedureEntry[entry, 2]; MakeLabelGlobal["StackTest.Recurse", entry]; drLC3[]; -- init current to 3 (words initially on stack) { loopLabel: Label = GenLabelHere[]; drRADD[current, current, const1]; drLRn[current]; drRJLBJ[left: topSrc, right: size, dist: UseLabel8B[loopLabel]]; }; { fiLabel: Label = GenLabel[]; drRJGEB[left: const1, right: times, dist: UseLabel8B[fiLabel]]; drRSUB[pushDst, times, const1]; drLRn[size]; drLFC[UseLabel16[entry]]; {okLabel: Label = GenLabel[]; drRSUB[pushDst, times, const1]; drRJEBJ[left: topSrc, right: popSrc, dist: UseLabel8B[okLabel]]; Halt[1]; SetLabel[okLabel]; drDIS[]; }; SetLabel[fiLabel]; }; ProcedureExit[1]; }; GenEmptyRecurse: PROC [entry: Label] = { exitLabel: Label = GenLabel[]; ProcedureEntry[entry, 0]; MakeLabelGlobal["StackTest.EmptyRecurse", entry]; drRJGEB[left: const0, right: depthReg, dist: UseLabel8B[exitLabel]]; drRVSUB[depthReg, depthReg, const1]; drLFC[UseLabel16[entry]]; drRVADD[depthReg, depthReg, const1]; SetLabel[exitLabel]; ProcedureExit[0]; }; All: PROC = { startLabel: Label = GenLabelHere[]; enterRecurse: Label = GenLabel[]; emptyRecurse: Label = GenLabel[]; testLabel: Label = GenLabel[]; maxDepth: NAT _ 32; MakeLabelGlobal["StackTest.Start", startLabel]; EnableTraps[]; -- to detect stack overflow drJDB[UseLabel16[testLabel]]; GenEmptyRecurse[emptyRecurse]; GenRecurse[enterRecurse]; SetLabel[testLabel]; { okLabel: Label = GenLabel[]; drLIB[maxDepth]; SReg[depthReg]; drLFC[UseLabel16[emptyRecurse]]; drLIB[maxDepth]; drRJEBJ[left: topSrc, right: depthReg, dist: UseLabel8B[okLabel]]; Halt[1]; SetLabel[okLabel]; }; { okLabel: Label = GenLabel[]; drLIB[maxDepth]; drLIB[5]; drLFC[UseLabel16[enterRecurse]]; drLIB[maxDepth]; drRJEBJ[left: topSrc, right: popSrc, dist: UseLabel8B[okLabel]]; Halt[2]; SetLabel[okLabel]; drDIS[]; }; { okLabel: Label = GenLabel[]; drLIB[maxDepth]; drLIB[33]; drLFC[UseLabel16[enterRecurse]]; drLIB[maxDepth]; drRJEBJ[left: topSrc, right: popSrc, dist: UseLabel8B[okLabel]]; Halt[3]; SetLabel[okLabel]; drDIS[]; }; Halt[0]; }; END. ϊGenStackTest.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) February 27, 1986 0:07:05 am PST An unused aux register that keeps track of the frame depth. loop to put extra words on the stack if times > 1, then recurse on times-1 At this point the returned value of times is not what was passed in. This is an indication that the stack management was blown. Test for empty stack frames being properly handled. This will cause various IFU overflow and underflow traps. The depthReg register governs how deep we go. Test for small frames being properly handled. This will exercise the IFU stack overflow handler. Test for large frames being properly handled. This will exercise the EU stack overflow handler. Κ΄–81.25 in leftMargin 1.25 in rightMargin 6.0 in lineLength˜codešœ™Kšœ Οmœ7™BK™4—K˜šΟk ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜K˜—šœž ˜Kšžœ˜%KšœžœžœH˜TK˜K–20 sp tabStopsšžœžœžœžœ˜K–20 sp tabStopsšœžœ˜K–20 sp tabStops˜–20 sp tabStopsšœ%˜%K–20 sp tabStopsšœ;™;—K–20 sp tabStops˜šΟn œžœ˜#K˜KšœΟc˜6K˜K˜K˜Kšœ˜Kšœ,˜,K˜Kšœ  /˜9K˜˜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šœ˜šœ1˜1K˜—K˜DK˜$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šœB˜BK˜K˜Kšœ˜K˜—K˜˜Kšœa™aK˜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˜—…— 4β