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; 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]; 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 ำ 1984, 1985, 1987 by Xerox Corporation. All rights reserved. Russ Atkinson (RRA) March 19, 1987 11:20:31 am PST McCreight October 27, 1986 4:29:08 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. ส Ž˜codešœ™KšœH™HK™2K™)—˜šฯk ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kš˜Kšœ ˜ Kšœ˜Kšœ ˜ K˜——šฯn œœ˜KšœYœ&˜ˆKšœœœH˜TK˜K–20 sp tabStopsšœœœœ˜K–20 sp tabStopsšœœ˜K–20 sp tabStops˜–20 sp tabStopsš žœœœœ œ ˜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šœ ˜ 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š œœœVœ œœ™‚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˜—…—V,ฎ