GenAcker.mesa
Copyright Ó 1984, 1986, 1987 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) May 18, 1987 4:33:42 pm PDT
DIRECTORY
DragonProcessOffsets,
DragOpsCross,
DragOpsCrossProcess,
DragOpsCrossUtils,
HandCoding,
HandCodingSupport,
HandCodingPseudos;
GenAcker: CEDAR PROGRAM
IMPORTS HandCoding, HandCodingSupport, HandCodingPseudos
= BEGIN OPEN DragonProcessOffsets, HandCoding, HandCodingSupport, HandCodingPseudos;
Word: TYPE = DragOpsCross.Word;
useStats: BOOLTRUE;
GenAck: PROC [enter: Label] = {
area: HandCodingSupport.Area ← HandCodingSupport.GetCurrentArea[];
globalFrameLabel: Label ← HandCodingPseudos.GenDataLabel[area, 64];
gDepth: NAT = 4;
gMaxDepth: NAT = 5;
gCalls: NAT = 6;
This is the assembly level code for:
Ack: PROC [x,y: INT] RETURNS [ans: INT] = {
IF useStats THEN {
calls ← calls + 1;
depth ← depth + 1;
IF depth > maxDepth THEN maxDepth ← depth;
};
SELECT TRUE FROM
x = 0 => ans ← 1;
y = 0 => ans ← IF x = 1 THEN 2 ELSE x+2;
ENDCASE => ans ← Ack[Ack[x-1, y], y-1];
IF useStats THEN
depth ← depth - 1;
};
rX: RegSpec = reg0;
rY: RegSpec = reg1;
rG: RegSpec = reg2;
rAns: RegSpec = reg3;
returnLabel: Label = GenLabel[];
ProcedureEntry[enter, 2];
MakeLabelGlobal["Acker.Ack", enter];
PushWordAddr[area, globalFrameLabel];
drLC0[];
IF useStats THEN {
elseLabel: Label = GenLabel[];
drLRIn[rG, gCalls];
drADDB[1];
drSRIn[rG, gCalls];
drLRIn[rG, gDepth];
drADDB[1];
drSRIn[rG, gDepth];
drLRIn[rG, gDepth];
drLRIn[rG, gMaxDepth];
drRJLEBJ[popSrc, popSrc, UseLabel8B[elseLabel]];
drLRIn[rG, gDepth];
drSRIn[rG, gMaxDepth];
SetLabel[elseLabel];
};
{elseLabel: Label = GenLabel[];
drLRn[rX];
drJNEBBJ[0, UseLabel8B[elseLabel]];
MoveReg[rAns, const1];
drJB[UseLabel8A[returnLabel]];
SetLabel[elseLabel];
};
{elseLabel: Label = GenLabel[];
drLRn[rY];
drJNEBBJ[0, UseLabel8B[elseLabel]];
{innerElseLabel: Label = GenLabel[];
drLRn[rX];
drJNEBB[1, UseLabel8B[innerElseLabel]];
MoveReg[rAns, const2];
drJB[UseLabel8A[returnLabel]];
SetLabel[innerElseLabel];
drRADD[rAns, rX, const2];
drJB[UseLabel8A[returnLabel]];
};
SetLabel[elseLabel];
};
drRSUB[pushDst, rX, const1];
drLRn[rY];
drLFC[UseLabel16[enter]];
drRSUB[pushDst, rY, const1];
drLFC[UseLabel16[enter]];
drSRn[rAns];
SetLabel[returnLabel];
IF useStats THEN {
drLRIn[rG, gDepth];
drSUBB[1];
drSRIn[rG, gDepth];
};
MoveReg[reg0, rAns];
ProcedureExit[1];
};
All: PROC = {
GenAcker.All[] is a procedure that gets called by LizardTool to generate the code when GenAcker.bcd is loaded and started.
startLabel: Label = GenLabelHere[];
enterRecurse: Label = GenLabel[];
testLabel: Label = GenLabel[];
MakeLabelGlobal["Acker.Start", startLabel];
drASL[255]; -- ensure that stack is empty, regardless of where it was
drJDB[UseLabel16[testLabel]];
GenAck[enterRecurse];
SetLabel[testLabel];
drLIB[11];
drLIB[2];
drLFC[UseLabel16[enterRecurse]];
Halt[0];
};
END.