DIRECTORY Basics, BasicTime, DragonProcessOffsets, DragOpsCross, DragOpsCrossProcess, DragOpsCrossUtils, HandCoding, HandCodingSupport, HandCodingPseudos, IO, LizardHeart, LizardTweaker, ViewerIO; GenArithTest: CEDAR PROGRAM IMPORTS Basics, BasicTime, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport, IO, LizardHeart, LizardTweaker, ViewerIO = BEGIN OPEN DragonProcessOffsets, HandCoding, HandCodingSupport, HandCodingPseudos; CARD: TYPE = LONG CARDINAL; STREAM: TYPE = IO.STREAM; Word: TYPE = DragOpsCross.Word; LongMult: PROC [x,y: CARD] RETURNS [lo,hi: CARD _ 0] = { yLo: CARD _ y; yHi: CARD _ 0; IF x # 0 THEN DO IF Basics.LowHalf[x] MOD 2 = 1 THEN { lo _ lo + yLo; IF lo < yLo THEN hi _ hi + 1; hi _ hi + yHi; }; x _ Basics.DoubleShiftRight[[lc[x]], 1].lc; IF x = 0 THEN EXIT; yHi _ yHi + yHi; IF LOOPHOLE[yLo, INT] < 0 THEN yHi _ yHi + 1; yLo _ yLo + yLo; ENDLOOP; }; GenMulTest: PROC [enter: Label] = { intMulLabel: Label = GetGlobalLabel["Basics.IntMultiply"]; fatMulLabel: Label = GetGlobalLabel["Basics.FatCardMultiply"]; innerIntCase: PROC [x, y: INT] = { okLabel: Label = GenLabel[]; drLIQB[DragOpsCrossUtils.IntToWord[x]]; drLIQB[DragOpsCrossUtils.IntToWord[y]]; HandCodingSupport.OQBcommon[x060B, DragOpsCrossUtils.IntToWord[0]]; drDFC[UseLabel32[intMulLabel]]; HandCodingSupport.OQBcommon[x060B, DragOpsCrossUtils.IntToWord[1]]; drLIQB[DragOpsCrossUtils.IntToWord[x*y]]; drRJEBJ[left: popSrc, right: popSrc, dist: UseLabel8B[okLabel]]; Halt[whichHalt _ whichHalt + 1]; SetLabel[okLabel]; }; innerFatCase: PROC [x, y: CARD] = { okLabel: Label = GenLabel[]; drLIQB[DragOpsCrossUtils.CardToWord[x]]; drLIQB[DragOpsCrossUtils.CardToWord[y]]; HandCodingSupport.OQBcommon[x060B, DragOpsCrossUtils.IntToWord[0]]; drDFC[UseLabel32[fatMulLabel]]; HandCodingSupport.OQBcommon[x060B, DragOpsCrossUtils.IntToWord[2]]; drLIQB[DragOpsCrossUtils.CardToWord[LongMult[x, y].hi]]; drRJEBJ[left: popSrc, right: popSrc, dist: UseLabel8B[okLabel]]; Halt[whichHalt _ whichHalt + 1]; drLIQB[DragOpsCrossUtils.CardToWord[LongMult[x, y].lo]]; drRJEBJ[left: popSrc, right: popSrc, dist: UseLabel8B[okLabel]]; Halt[whichHalt _ whichHalt + 1]; SetLabel[okLabel]; }; ProcedureEntry[enter, 0]; MakeLabelGlobal["ArithTest.MulTest", enter]; HandCodingSupport.OQBcommon[x060B, DragOpsCrossUtils.IntToWord[-1]]; innerIntCase[37, 401]; innerIntCase[-156, 4]; innerIntCase[123456, 10101]; innerIntCase[LAST[INT] / 78563, 78563]; innerIntCase[LAST[INT] / 78563, -78563]; innerIntCase[LAST[CARDINAL], LAST[INTEGER]]; innerIntCase[FIRST[INT], 0]; innerIntCase[FIRST[INT], 1]; innerIntCase[2, LAST[INT] / 2]; innerIntCase[LAST[INT] / 2, 2]; HandCodingSupport.OQBcommon[x060B, DragOpsCrossUtils.IntToWord[-1]]; innerFatCase[37, 401]; innerFatCase[156, 4]; innerFatCase[123456, 10101]; innerFatCase[LAST[CARD] / 78563, 78563]; innerFatCase[LAST[CARD] / 2, 2]; innerFatCase[LAST[CARD], 0]; innerFatCase[LAST[CARD], 1]; innerFatCase[LAST[CARD], LAST[CARD]]; ProcedureExit[0]; }; GenDivTest: PROC [enter: Label] = { cardDivLabel: Label = GetGlobalLabel["Basics.CardDivide"]; innerCardCase: PROC [x, y: CARD] = { okLabel: Label = GenLabel[]; drLIQB[DragOpsCrossUtils.CardToWord[x]]; drLIQB[DragOpsCrossUtils.CardToWord[y]]; HandCodingSupport.OQBcommon[x060B, DragOpsCrossUtils.IntToWord[0]]; drDFC[UseLabel32[cardDivLabel]]; HandCodingSupport.OQBcommon[x060B, DragOpsCrossUtils.IntToWord[3]]; drLIQB[DragOpsCrossUtils.CardToWord[x/y]]; drRJEBJ[left: popSrc, right: popSrc, dist: UseLabel8B[okLabel]]; Halt[whichHalt _ whichHalt + 1]; SetLabel[okLabel]; }; ProcedureEntry[enter, 0]; MakeLabelGlobal["ArithTest.DivTest", enter]; HandCodingSupport.OQBcommon[x060B, DragOpsCrossUtils.IntToWord[-1]]; innerCardCase[5, 2]; innerCardCase[37, 401]; innerCardCase[401, 37]; innerCardCase[17*17, 17]; innerCardCase[17*17+3, 17]; innerCardCase[123456, 10101]; innerCardCase[LAST[CARD], 78563]; innerCardCase[LAST[CARD], 1]; innerCardCase[LAST[CARD] / 2, 2]; ProcedureExit[0]; }; All: PROC = { startLabel: Label = GenLabelHere[]; mulTestLabel: Label = GenLabel[]; divTestLabel: Label = GenLabel[]; testLabel: Label = GenLabel[]; MakeLabelGlobal["ArithTest.All", startLabel]; EnableTraps[]; -- to detect stack overflow drASL[255]; drRUADD[pushDst, constNI, constNI]; drRUADD[pushDst, constN1, constN1]; drRUADD[pushDst, const0, const0]; drASL[255]; drRUADD[pushDst, constN1, constN1]; drRUADD[pushDst, const0, const0]; drASL[255]; drRUADD[pushDst, constNI, constNI]; drRUADD[pushDst, const1, const1]; drRUADD[pushDst, const0, const0]; drASL[255]; drRUADD[pushDst, constNI, constNI]; drRUSUB[pushDst, constN1, constN1]; drRUADD[pushDst, const0, const0]; drASL[255]; drRUADD[pushDst, constNI, constNI]; drRUSUB[pushDst, const1, const0]; drRUADD[pushDst, const0, const0]; drASL[255]; drRUADD[pushDst, constNI, constNI]; drRSUB[pushDst, const1, const0]; drRUADD[pushDst, const0, const0]; drJDB[UseLabel16[testLabel]]; GenMulTest[mulTestLabel]; GenDivTest[divTestLabel]; SetLabel[testLabel]; drLFC[UseLabel16[mulTestLabel]]; drLFC[UseLabel16[divTestLabel]]; Halt[0]; LizardTweaker.Register[x060B, HandleCode]; out _ ViewerIO.CreateViewerStreams[name: "GenArithTest.log"].out; IO.PutF1[out, "\nOpcode handler registered at %g.\n", [time[BasicTime.Now[]]] ]; }; whichHalt: NAT _ 100; lastX: Word _ DragOpsCross.ZerosWord; lastY: Word _ DragOpsCross.ZerosWord; lastCycle: INT _ 0; out: STREAM _ NIL; HandleCode: LizardTweaker.OpcodeHandler = { ri: INT = DragOpsCrossUtils.WordToInt[rest]; SELECT ri FROM -1 => { IF out # NIL THEN IO.PutRope[out, "\n"]; }; 0 => { regS: DragOpsCross.ProcessorRegister = LizardHeart.WordToReg[processor.regs[ifuS]]; regSm: DragOpsCross.ProcessorRegister = LizardHeart.StackPlus[regS, 255]; lastCycle _ processor.stats.cycles; lastX _ processor.regs[regSm]; lastY _ processor.regs[regS]; }; 1 => { regS: DragOpsCross.ProcessorRegister _ LizardHeart.WordToReg[processor.regs[ifuS]]; delta: INT _ processor.stats.cycles - lastCycle; result: Word _ processor.regs[regS]; lastCycle _ processor.stats.cycles; IF out # NIL THEN { IO.PutF1[out, "%g cycles for IntegerMultiply\n", [integer[delta]] ]; IO.PutF1[out, " X: %g", [integer[DragOpsCrossUtils.WordToInt[lastX]]] ]; IO.PutF1[out, ", Y: %g", [integer[DragOpsCrossUtils.WordToInt[lastY]]] ]; IO.PutF1[out, ", Z: %g\n", [integer[DragOpsCrossUtils.WordToInt[result]]] ]; }; }; 2 => { regS: DragOpsCross.ProcessorRegister _ LizardHeart.WordToReg[processor.regs[ifuS]]; regSm: DragOpsCross.ProcessorRegister = LizardHeart.StackPlus[regS, 255]; delta: INT _ processor.stats.cycles - lastCycle; lo: Word _ processor.regs[regSm]; hi: Word _ processor.regs[regS]; lastCycle _ processor.stats.cycles; IF out # NIL THEN { IO.PutF[out, "%g cycles for FatMultiply\n", [integer[delta]] ]; IO.PutF[out, " X: %bB (%g)", [cardinal[DragOpsCrossUtils.WordToCard[lastX]]], [integer[DragOpsCrossUtils.WordToInt[lastX]]] ]; IO.PutF[out, ", Y: %bB (%g)\n", [cardinal[DragOpsCrossUtils.WordToCard[lastY]]], [integer[DragOpsCrossUtils.WordToInt[lastY]]] ]; IO.PutF[out, " lo: %bB (%g)", [cardinal[DragOpsCrossUtils.WordToCard[lo]]], [integer[DragOpsCrossUtils.WordToInt[lo]]] ]; IO.PutF[out, ", hi: %bB (%g)\n", [cardinal[DragOpsCrossUtils.WordToCard[hi]]], [integer[DragOpsCrossUtils.WordToInt[hi]]] ]; }; }; 3 => { regS: DragOpsCross.ProcessorRegister _ LizardHeart.WordToReg[processor.regs[ifuS]]; delta: INT _ processor.stats.cycles - lastCycle; result: Word _ processor.regs[regS]; lastCycle _ processor.stats.cycles; IF out # NIL THEN { IO.PutF1[out, "%g cycles for Q _ CardDivide[X, Y]\n", [integer[delta]] ]; IO.PutF1[out, " X: %g", [cardinal[DragOpsCrossUtils.WordToCard[lastX]]] ]; IO.PutF1[out, ", Y: %g", [cardinal[DragOpsCrossUtils.WordToCard[lastY]]] ]; IO.PutF1[out, ", Q: %g\n", [cardinal[DragOpsCrossUtils.WordToCard[result]]] ]; }; }; ENDCASE; }; END. šGenArithTest.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) January 28, 1986 2:23:45 pm PST This uses the same algorithm as FatCardMultiply Double precision add Double precision add [data: REF ANY, processor: LizardHeart.Processor, inst: DragOpsCross.Inst, rest: DragOpsCross.Word] RETURNS [normal: BOOL _ FALSE] Capture the cycle count and the two registers on top of the stack. Capture the cycle count and the two registers on top of the stack. Capture the top stack register & the delta of cycles. Capture the top stack registers & the delta of cycles. Capture the top stack register & the delta of cycles. Κ δ–81.25 in leftMargin 1.25 in rightMargin 6.0 in lineLength˜codešœ™Kšœ Οmœ7™BK™3—K˜šΟk ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšž˜Kšœ ˜ Kšœ˜Kšœ ˜ K˜—šœž ˜KšžœXžœ$˜ˆKšœžœžœH˜TK˜K–20 sp tabStopsšžœžœžœžœ˜K–20 sp tabStopsšžœžœžœžœ˜K–20 sp tabStopsšœžœ˜K–20 sp tabStops˜–20 sp tabStopsš Οnœžœžœžœ žœ ˜8K–20 sp tabStopsšœ/™/K–20 sp tabStopsšœžœ˜K–20 sp tabStopsšœžœ˜–20 sp tabStopsšžœžœž˜–20 sp tabStopsšžœžœžœ˜%K–20 sp tabStopsšœ™K–20 sp tabStopsšœ˜K–20 sp tabStopsšžœ žœ ˜K–20 sp tabStopsšœ˜K–20 sp tabStops˜—K–20 sp tabStopsšœ+˜+K–20 sp tabStopsšžœžœžœ˜K–20 sp tabStopsšœ™K–20 sp tabStopsšœ˜K–20 sp tabStopsšžœžœžœžœ˜-K–20 sp tabStops˜K–20 sp tabStopsšžœ˜—K–20 sp tabStops˜—K–20 sp tabStops˜–20 sp tabStopsšŸ œžœ˜#K–20 sp tabStopsšœ:˜:K–20 sp tabStopsšœ>˜>–20 sp tabStopsšœžœžœ˜"K˜Kšœ'˜'Kšœ'˜'KšœC˜CKšœ˜KšœC˜CKšœ)˜)Kšœ@˜@Kšœ ˜ K˜K–20 sp tabStops˜—–20 sp tabStopsšœžœžœ˜#K˜Kšœ(˜(Kšœ(˜(KšœC˜CKšœ˜KšœC˜CKšœ8˜8Kšœ@˜@Kšœ ˜ Kšœ8˜8Kšœ@˜@Kšœ ˜ K˜K–20 sp tabStops˜—K–20 sp tabStopsšœ˜Kšœ,˜,K˜KšœD˜DKšœ˜Kšœ˜Kšœ˜Kšœ žœžœ˜'Kšœ žœžœ˜(Kš œ žœžœžœžœ˜,Kšœ žœžœ˜Kšœ žœžœ˜Kšœžœžœ˜Kšœ žœžœ ˜K˜KšœD˜DKšœ˜Kšœ˜Kšœ˜Kšœ žœžœ˜(Kšœ žœžœ ˜ Kšœ žœžœ˜Kšœ žœžœ˜Kš œ žœžœžœžœ˜%K˜K˜K–20 sp tabStops˜K–20 sp tabStops˜—–20 sp tabStopsšŸ œžœ˜#K–20 sp tabStopsšœ:˜:–20 sp tabStopsšœžœžœ˜$K˜Kšœ(˜(Kšœ(˜(KšœC˜CKšœ ˜ KšœC˜CKšœ*˜*Kšœ@˜@Kšœ ˜ K˜K–20 sp tabStops˜—K–20 sp tabStopsšœ˜Kšœ,˜,K˜KšœD˜DKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœžœžœ ˜!Kšœžœžœ˜Kšœžœžœ ˜!K˜K˜K–20 sp tabStops˜K–20 sp tabStops˜—šŸœžœ˜ K˜K˜#Kšœ!˜!Kšœ!˜!K˜K˜K˜-K˜KšœΟc˜+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˜K˜K˜Kšœ ˜ Kšœ ˜ K˜K˜K˜Kšœ*˜*KšœA˜AKšžœN˜PK˜K˜—K–20 sp tabStopsšœ žœ˜K•StartOfExpansion† -- [data: REF ANY, processor: LizardHeart.Processor, inst: DragOpsCross.Inst, rest: DragOpsCross.Word] RETURNS [normal: BOOL _ FALSE]šœ%˜%K–† -- [data: REF ANY, processor: LizardHeart.Processor, inst: DragOpsCross.Inst, rest: DragOpsCross.Word] RETURNS [normal: BOOL _ FALSE]šœ%˜%Kšœ žœ˜Kšœžœžœ˜K˜šœ+˜+KšΠck‚™‚Kšœžœ%˜,šžœž˜˜KšœC™CKšžœžœžœžœ˜(K˜—˜KšœC™CKšœS˜SKšœI˜IKšœ#˜#Kšœ˜Kšœ˜K˜—˜Kšœ6™6KšœS˜SKšœžœ&˜0Kšœ$˜$Kšœ#˜#šžœžœžœ˜KšžœB˜DKšžœI˜KKšžœG˜IKšžœJ˜LK˜K˜—K˜—˜Kšœ7™7KšœS˜SKšœI˜IKšœžœ&˜0Kšœ!˜!Kšœ ˜ Kšœ#˜#šžœžœžœ˜Kšžœ=˜?Kšžœ˜Kšžœ˜Kšžœz˜|Kšžœz˜|K˜—K˜—˜Kšœ6™6KšœS˜SKšœžœ&˜0Kšœ$˜$Kšœ#˜#šžœžœžœ˜KšžœG˜IKšžœK˜MKšžœI˜KKšžœL˜NK˜—K˜—Kšžœ˜—K˜K˜—Kšžœ˜—K˜—…— -