<> <> <> <> <> <> <> <> <> <> <> <> <> <> <> DIRECTORY DragOpsCross, DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; GenBasics: CEDAR PROGRAM IMPORTS DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport = BEGIN OPEN DragOpsCrossUtils, HandCoding, HandCodingPseudos, HandCodingSupport; Word: TYPE = DragOpsCross.Word; ZerosWord: Word = DragOpsCross.ZerosWord; bytesPerWord: CARDINAL = DragOpsCross.bytesPerWord; wordsPerPage: CARDINAL = DragOpsCross.wordsPerPage; globalBase: LONG CARDINAL; globalBaseWord: Word; initialPages: INT _ 64; gAllocPtr: NAT = 2; All: PROC = { FillTrap: PROC [tx: DragOpsCross.TrapIndex, dest: Label] = { oldPC: LONG CARDINAL = GetOutputPC[area]; SetOutputPC[DragOpsCrossUtils.TrapIndexToBytePC[tx]]; drJDB[UseLabel16[dest]]; SetOutputPC[oldPC]; }; FillXop: PROC [inst: DragOpsCross.Inst, dest: Label] = { oldPC: LONG CARDINAL = GetOutputPC[area]; SetOutputPC[DragOpsCrossUtils.XopToBytePC[inst]]; drJDB[UseLabel16[dest]]; SetOutputPC[oldPC]; }; area: Area = GetCurrentArea[]; start: Label = GenLabel[]; dummy: Label = GenLabel[]; startUser: Label = GenLabel[]; initL: Label = GenLabel[]; procSetVectorConstant: Label = GenLabel[]; procMoveVector: Label = GenLabel[]; procAllocVector: Label = GenLabel[]; globalBase _ ReserveData[initialPages*wordsPerPage] / bytesPerWord; globalBaseWord _ CardToWord[globalBase]; SetLabel[start]; <> <> drLIB[1]; drROR[c: const1, a: const0, b: popSrc]; drRVADD[c: const2, a: const1, b: const1]; drRVADD[c: const3, a: const2, b: const1]; drRVADD[c: const4, a: const3, b: const1]; drRVSUB[c: constN2, a: const0, b: const2]; drRVSUB[c: constN1, a: const0, b: const1]; drLIDB[100000B]; drROR[c: constNSI, a: const0, b: popSrc]; drLC1[]; drSHL[FieldDescriptorToCard[[insert: FALSE, mask: 32, shift: 31]]]; drROR[c: constNI, a: const0, b: popSrc]; drLIQB[globalBaseWord]; drROR[c: global, a: const0, b: topSrc]; -- the base of global data drDUP[]; drADDDB[wordsPerPage]; -- don't allocate in the first page drWSB[gAllocPtr]; -- set the allocation pointer FOR i: NAT IN [1..15] DO drROR[c: [aux[i]], a: const0, b: const0]; ENDLOOP; drLFC[UseLabel16[initL]]; <> drASL[255]; <> drLIB[16]; drLFC[UseLabel16[procAllocVector]]; drROR[process, const0, popSrc]; <> drLIB[16]; drLFC[UseLabel16[procAllocVector]]; drROR[processor, const0, popSrc]; <> drJDB[UseLabel16[startUser]]; GenSetVectorConstant[procSetVectorConstant]; GenMoveVector[procMoveVector]; GenAllocVector[procAllocVector]; GenMultiply[]; GenDivide[]; ProcedureEntry[initL, 0]; drLC1[]; SetYoungestL[]; -- L _ 1 on return drLIB[128-16-1]; -- spLimit is set with room for 17 overflow words (just in case) SetSPLimit[]; ProcedureExit[0]; WordAlign[area]; SetLabel[startUser]; <> MakeLabelGlobal["Basics.ExitToGenStack", startUser]; FillTrap[ResetTrap, start]; }; GenSetVectorConstant: PROC [entryLabel: Label] = { addrLocal: RegSpec = reg0; lenLocal: RegSpec = reg1; wordLocal: RegSpec = reg2; finishLabel: Label = GenLabel[]; ProcedureEntry[entryLabel, 3]; MakeLabelGlobal["Basics.SetVectorConstant", entryLabel]; drLRn[lenLocal]; drRJLBJ[left: topSrc, right: const4, dist: UseLabel8B[finishLabel]]; {loopLabel: Label = GenLabelHere[]; exitLabel: Label = GenLabel[]; drSUBB[4]; drWRI[wordLocal, addrLocal, 0]; drWRI[wordLocal, addrLocal, 1]; drWRI[wordLocal, addrLocal, 2]; drWRI[wordLocal, addrLocal, 3]; drRVADD[c: addrLocal, a: addrLocal, b: const4]; drRJGEBJ[left: topSrc, right: const4, dist: UseLabel8B[loopLabel]]; SetLabel[finishLabel]; drRJLEB[left: topSrc, right: const0, dist: UseLabel8B[exitLabel]]; drWRI[wordLocal, addrLocal, 0]; drRJLEB[left: topSrc, right: const1, dist: UseLabel8B[exitLabel]]; drWRI[wordLocal, addrLocal, 1]; drRJLEB[left: topSrc, right: const2, dist: UseLabel8B[exitLabel]]; drWRI[wordLocal, addrLocal, 2]; SetLabel[exitLabel]; }; ProcedureExit[0]; }; GenMoveVector: PROC [entryLabel: Label] = { srcLocal: RegSpec = reg0; lenLocal: RegSpec = reg1; dstLocal: RegSpec = reg2; finishLabel: Label = GenLabel[]; ProcedureEntry[entryLabel, 3]; MakeLabelGlobal["Basics.MoveVector", entryLabel]; drLRn[lenLocal]; drRJLBJ[left: topSrc, right: const4, dist: UseLabel8B[finishLabel]]; {loopLabel: Label = GenLabelHere[]; exitLabel: Label = GenLabel[]; drSUBB[4]; drLRIn[srcLocal, 0]; drLRIn[srcLocal, 1]; drLRIn[srcLocal, 2]; drLRIn[srcLocal, 3]; drRVADD[c: srcLocal, a: srcLocal, b: const4]; drSRIn[dstLocal, 3]; drSRIn[dstLocal, 2]; drSRIn[dstLocal, 1]; drSRIn[dstLocal, 0]; drRVADD[c: dstLocal, a: dstLocal, b: const4]; drRJGEBJ[left: topSrc, right: const4, dist: UseLabel8B[loopLabel]]; SetLabel[finishLabel]; drRJLEB[left: topSrc, right: const0, dist: UseLabel8B[exitLabel]]; drLRIn[srcLocal, 0]; drSRIn[dstLocal, 0]; drRJLEB[left: topSrc, right: const1, dist: UseLabel8B[exitLabel]]; drLRIn[srcLocal, 1]; drSRIn[dstLocal, 1]; drRJLEB[left: topSrc, right: const2, dist: UseLabel8B[exitLabel]]; drLRIn[srcLocal, 2]; drSRIn[dstLocal, 2]; SetLabel[exitLabel]; }; ProcedureExit[0]; }; GenAllocVector: PROC [entryLabel: Label] = { lenLocal: RegSpec = reg0; G: RegSpec = reg1; ProcedureEntry[entryLabel, 1]; MakeLabelGlobal["Basics.AllocVector", entryLabel]; drLIQB[globalBaseWord]; drLRIn[G, gAllocPtr]; drRVADD[pushDst, lenLocal, topSrc]; drSRIn[G, gAllocPtr]; drSRn[lenLocal]; ProcedureExit[1]; }; <> GenMultiply: PROC [] = { accum: RegSpec = reg0; -- initially holds X, will hold return value entryLabel: Label = GenLabel[]; exitLabel: Label = GenLabel[]; exit0Label: Label = GenLabel[]; positiveLabel: Label = GenLabel[]; ProcedureEntry[entryLabel, 2]; MakeLabelGlobal["Basics.MixedMultiply", entryLabel]; <> SetLabel[positiveLabel]; drLIB[17B]; drLIB[3*15+1]; drLRn[accum]; drROR[accum, const0, const0]; { localY: RegSpec = reg1; -- holds Y mask: RegSpec = reg2; -- holds 17B as a mask width: RegSpec = reg3; -- holds 3*15+1 as the table width localX: RegSpec = reg4; -- holds X loopEntry: Label = GenLabel[]; loopTop: Label = GenLabel[]; drJB[UseLabel8A[loopEntry]]; SetLabel[loopTop]; drRADD[localY, localY, localY]; drRADD[localY, localY, localY]; drRADD[localY, localY, localY]; drRADD[localY, localY, localY]; SetLabel[loopEntry]; drRAND[pushDst, mask, localX]; drRSUB[pushDst, width, topSrc]; drQSUB[topAtop, belowSrc]; drRSUB[belowDst, popSrc, belowSrc]; drJS[]; THROUGH [0..15) DO drRADD[accum, accum, localY]; ENDLOOP; ExtractField[first: 0, bits: 32-4]; drRJNEBJ[left: topSrc, right: const0, dist: UseLabel8B[loopTop]]; ProcedureExit[1]; }; { < FIRST[INT] we negate X, multiply, and negate the result. For X = FIRST[INT] we test for Y = 0 (return 0) and Y = 1 (return X), otherwise we always overflow. NOTE: we also make sure that if both numbers are positive that we place the smaller number in X and the larger number in Y.>> otherLabel: Label = GenLabel[]; specialLabel: Label = GenLabel[]; negateLabel: Label = GenLabel[]; negXlabel: Label = GenLabel[]; ProcedureEntry[otherLabel, 2]; MakeLabelGlobal["Basics.IntMultiply", otherLabel]; <> drRJGB[left: const0, right: reg0, dist: UseLabel8B[negXlabel]]; <> drRJGB[left: const0, right: reg1, dist: UseLabel8B[positiveLabel]]; <= 0 & Y < 0, just branch to the positive entry>> drRJGEB[left: topSrc, right: belowSrc, dist: UseLabel8B[positiveLabel]]; <= 0 & Y >= 0 & X <= Y, just branch to the positive entry>> <> drRXOR[topDst, topSrc, belowSrc]; drRXOR[belowDst, topSrc, belowSrc]; drRXOR[topDst, topSrc, belowSrc]; drJB[UseLabel8A[positiveLabel]]; SetLabel[negXlabel]; drLRn[reg0]; drRJEB[left: popSrc, right: constNI, dist: UseLabel8B[specialLabel]]; <> drRSUB[reg0, const0, reg0]; <> drLFC[UseLabel16[entryLabel]]; <> SetLabel[negateLabel]; drRSUB[reg0, const0, reg0]; <> ProcedureExit[1]; SetLabel[specialLabel]; <> drRJEB[left: topSrc, right: const1, dist: UseLabel8B[exitLabel]]; < the identity>> drRJNEB[left: topSrc, right: const0, dist: UseLabel8B[negateLabel]]; < negate (to get overflow) & return>> }; SetLabel[exit0Label]; drROR[reg0, const0, const0]; <> SetLabel[exitLabel]; ProcedureExit[1]; { thinCardLabel: Label = GenLabel[]; fatCardLabel: Label = GenLabel[]; lo: RegSpec = reg0; -- holds lo-order result word hi: RegSpec = reg1; -- holds hi-order result word yLo: RegSpec = reg2; -- holds lo-order part of Y yHi: RegSpec = reg3; -- holds hi-order part of Y localX: RegSpec = reg4; -- holds X ProcedureEntry[fatCardLabel, 2]; MakeLabelGlobal["Basics.FatCardMultiply", fatCardLabel]; <> drLRn[reg1]; -- push Y drLC0[]; -- init hi-order part of Y drLRn[reg0]; -- push X drROR[hi, const0, const0]; drROR[lo, const0, const0]; { loopEntry: Label = GenLabel[]; loopTop: Label = GenLabel[]; noAddLabel: Label = GenLabel[]; drRJNEBJ[left: topSrc, right: const0, dist: UseLabel8B[loopEntry]]; ProcedureExit[1]; SetLabel[loopTop]; drRUADD[yLo, yLo, yLo]; drRUADD[yHi, yHi, yHi]; SetLabel[loopEntry]; drQAND[pushA1, localX]; drJEBB[0, UseLabel8B[noAddLabel]]; drRUADD[lo, lo, yLo]; drRUADD[hi, hi, yHi]; SetLabel[noAddLabel]; ExtractField[first: 0, bits: 31]; drRJNEBJ[left: topSrc, right: const0, dist: UseLabel8B[loopTop]]; }; ProcedureExit[2]; <> ProcedureEntry[thinCardLabel, 2]; MakeLabelGlobal["Basics.CardMultiply", thinCardLabel]; drLFC[UseLabel16[fatCardLabel]]; drRJEBJ[left: topSrc, right: const0, dist: UseLabel8B[exitLabel]]; <> <> drRADD[pushDst, constNI, constNI]; ProcedureExit[1]; }; }; GenDivide: PROC = { <> <<>> entryLabel: Label = GenLabel[]; exitLabel: Label = GenLabel[]; faultLabel: Label = GenLabel[]; quotient: RegSpec = reg0; -- initially holds X, will hold return value localY: RegSpec = reg1; localX: RegSpec = reg2; compY: RegSpec = reg3; temp: RegSpec = reg4; mask: RegSpec = reg5; ProcedureEntry[entryLabel, 2]; MakeLabelGlobal["Basics.CardDivide", entryLabel]; <> drRJEB[left: topSrc, right: const0, dist: UseLabel8B[faultLabel]]; drRJEB[left: topSrc, right: const1, dist: UseLabel8B[exitLabel]]; <> drLRn[quotient]; drROR[quotient, const0, const0]; drRXOR[pushDst, localY, constNI]; drRXOR[pushDst, localX, constNI]; drRJLB[left: popSrc, right: belowSrc, dist: UseLabel8B[exitLabel]]; <> drLC1[]; drRXOR[pushDst, const0, constNI]; { <> <> <> <> <> label0: Label = GenLabel[]; label1: Label = GenLabel[]; drJB[UseLabel8A[label1]]; SetLabel[label0]; ExtractField[first: 0, bits: 32-4]; drRVADD[localX, localX, localX]; drRVADD[localX, localX, localX]; drRVADD[localX, localX, localX]; drRVADD[localX, localX, localX]; SetLabel[label1]; drLRn[localX]; ExtractField[first: 0, bits: 4]; drJEBBJ[0, UseLabel8B[label0]]; }; { <> <> <> <> <> <> setupLabel: Label = GenLabelHere[]; ExtractField[first: 0, bits: 31]; drRUADD[localX, localX, localX]; drRUADD[pushDst, const0, const0]; drJEBB[0, UseLabel8B[setupLabel]]; }; { <> <> <> <> <= y THEN {>> <> <> <<};>> <> <> <> <<>> noSubLabel: Label = GenLabel[]; loopLabel: Label = GenLabelHere[]; drRUADD[localX, localX, localX]; drRUADD[temp, temp, temp]; drRXOR[pushDst, temp, constNI]; drRJLB[left: popSrc, right: compY, dist: UseLabel8B[noSubLabel]]; drRVSUB[temp, temp, localY]; drRVADD[quotient, quotient, mask]; SetLabel[noSubLabel]; ExtractField[first: 0, bits: 31]; drRJNEBJ[left: topSrc, right: const0, dist: UseLabel8B[loopLabel]]; }; SetLabel[exitLabel]; ProcedureExit[1]; SetLabel[faultLabel]; Halt[277B]; ProcedureExit[1]; }; END.