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];
This is the location where Reset comes to. The registers need initialization.
N.B. const0 is a ROM containing a 0. The IFU needs a literal 0 for several operations, and the consequences of const0 being non-zero are simply too horrible to contemplate. Ergo, we made it impossible.
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]];
We use this method to initialize L to 1
drASL[255];
When there is nothing on the stack, S should be at L-1
drLIB[16]; drLFC[UseLabel16[procAllocVector]]; drROR[process, const0, popSrc];
Allocate a dummy (non-NIL) process object
drLIB[16]; drLFC[UseLabel16[procAllocVector]]; drROR[processor, const0, popSrc];
Allocate a dummy (non-NIL) processor object
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];
Control flow falls through to the next file that gets generated. Typically, GenStack follows GenBasics, and other programs follow GenStack. Note that there should be no frames on the IFU stack when we fall through.
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];
};