// BNCG2.bcpl - BCPL Compiler -- Nova Code Generator, Pure stream processor
// Copyright Xerox Corporation 1980
// Last modified on Wed 01 Nov 72 0041.49 by jec.
// Swinehart, 5-10-77: fast getframe, return -- docase exp
// Paxton, 9-14-78: unsigned compares
// last modified by Butterfield, May 30, 1979 4:32 PM
// - ScanPures ENTRY:, CG(Iifsgetframe) if SWStackStrings - 5/30
// - ScanPures END:, ENTRY:, and ENDFRAME:; SWStackStrings - 5/9/79
get "bncgx"
let ScanPures() be
[pures
Next:
let Op = Readop()
Continue:
CGcheckconstants(0)
switchon Op into
[items
default:
[ Op = CGothers(Op)
test Op eq -1 then goto Next or goto Continue
]
case END:
[ CGoutconstants(#200)
if SWNoxios do
if (PC & #1) ne 0 do
[ CGn(0)
if SWCode do WriteS("//force code to be an even length")
]
if SWCode do WriteS("*n")
if SWStackStrings ne 0 & SWStackStrings ne -1 then CGreport(-5203);
return
]
case PLINE:
[ Curline = ReadN()
if SWList do
[ if SWCode do [ WW($*n); WW($*n) ]
WriteLine(Curline)
]
goto Next
]
case LINE:
[ Curline = ReadN()
goto Next
]
case WSUB:
case BSUB:
case NQUAL:
case WQUAL:
case XQUAL:
case WBQUAL:
case STNQUAL:
case STWQUAL:
case STXQUAL:
case STWBQUAL:
case YQUAL:
case STYQUAL:
[ Op = CGqual(Op)
test Op eq -1 then goto Next or goto Continue
]
case PLUS:
[ Op = CGplus(Op)
test Op eq -1 then goto Next or goto Continue
]
case MINUS: CGsub(); goto Next
case MULT: CGmul(); goto Next
case DIV: CGdiv(); goto Next
case REM: CGrem(); goto Next
case LSHIFT: CGlsh(); goto Next
case RSHIFT: CGrsh(); goto Next
case LOGAND: CGand(); goto Next
case LOGOR: CGior(); goto Next
case EQV: CGeqv(); goto Next
case NEQV: CGxor(); goto Next
case NEG: CGneg(); goto Next
case NOT: CGnot(); goto Next
case EQ:
case NE:
case LS:
case LE:
case GR:
case GE:
case ULS:
case ULE:
case UGR:
case UGE:
[ Op = CGrel(Op)
test Op eq -1 then goto Next or goto Continue
]
case JT:
case JF:
[ Clearstack(SSP-2)
CGloadreg(arg1)
CGtest((Op eq JT ? Iseq0, Isne0), loc!arg1, loc!arg1, ReadL())
Pop1()
goto Next
]
case JUMP:
[ Clearstack(SSP-1)
CGjmp(ReadL())
CGoutconstants(0)
goto Next
]
case LAB:
[ Clearstack(SSP-1)
Initstack(SSP)
CGlabdef(ReadL())
LabelDef = true
goto Next
]
case GOTO:
[ Clearstack(SSP-2)
CGjumpandsave()
Pop1()
Initstack(SSP)
CGoutconstants(0)
goto Next
]
case STACK:
[ SetSSP(ReadN())
goto Next
]
case STORE:
[ Clearstack(SSP-1)
Initstack(SSP)
goto Next
]
case SWITCHLOAD:
[ Clearstack(SSP-2) // store temps
CGloadac0(arg1) // switchon index
CGcheckconstants(#200)
Initstack(SSP-1)
goto Next ]
case SWITCHON:
[ CGswitch()
goto Next
]
case FINISH:
[ CG(Ifinish)
if SWCode do WriteS(" (FINISH)")
CGoutconstants(0)
goto Next
]
case ABORT:
[ CG(Iabort)
if SWCode do WriteS(" (ABORT)")
CGoutconstants(0)
goto Next
]
case RTCALL:
case FNCALL:
case PARAM:
case RTAP:
case FNAP:
[ Op = CGcall(Op)
test Op eq -1 then goto Next or goto Continue
]
case ENTRY:
case LENTRY:
[ let l = ReadL()
let m = ReadL()
Clearstack(SSP-1)
Initstack(SSP)
if SWNoxios do
if (PC & #1) ne 0 do
[ CG(Ijmp + (R lshift 8) + 1)
if SWCode do WriteS("// force even address for static label*n")
]
elabelvec!l = m; eaddrvec!l = PC
unless Op eq ENTRY goto Next
if MaxSSP ls 0 then CGreport(-5201);
if SWStackStrings gr 0 then
[ SWStackStrings = not SWStackStrings; MaxSSP = not MaxSSP; ]
framestack!framestackp = MaxSSP
framestack!(framestackp+1) = MaxVecSSP
framestackp = framestackp + 2
MaxSSP, MaxVecSSP = ReadN(), ReadN()
if MaxSSP ls framespacemin do
MaxSSP = framespacemin //leave frame space for header+two args
// since first 2 args are stored always
if SWCode do
[ WriteS("// frame size is ")
WriteOct(MaxSSP+MaxVecSSP); WriteS(" words (")
WriteOct(MaxSSP); WW($+); WriteOct(MaxVecSSP); WW($))
]
Push(LOCAL, 0, SSPtemp1)
test SWFastFrame then // issue microcode getframe call?
[
CG(SWFastFrame) // switch contains microcode trap instr.
if SWCode do WriteS(" Fast stack frame allocation call")
]
or
[
CGstore(X, arg1)
if SWCode do WriteS(" of last frame is the return address")
]
Pop1()
test SWStackStrings
ifso [ CG(Iifsgetframe); if SWCode do WriteS(" (IFS GETNEWFRAME)") ]
ifnot [ CG(Igetframe); if SWCode do WriteS(" (GETNEWFRAME)") ]
CGn(MaxSSP + MaxVecSSP)
CG(Istoreargs)
if SWCode do WriteS(" (STOREARGS) if more than 3")
Op = Readop()
unless Op eq SAVE do CGreport(-14)
Initstack(ReadN())
Op = Readop()
unless Op eq NUMARGS goto Continue
Push(LOCAL, 0, SSP); SetName(ReadL())
CGstore(0, arg1)
if SWCode do WriteS(" is NUMARGS")
goto Next
]
case ENDFRAME:
[
if SWStackStrings gr 0 then
[
let n = 0; let pc = SWStackStrings;
until pc le 0 do
[ n = n+1; if pc gr Codelimit then pc = pc - Codelimit; pc = Code!pc; ]
if n ge 128 then CGreport(-5202);
let i = 0;
until SWStackStrings le 0 do
[
i = i + 1; pc = SWStackStrings; let tableFlag = 0;
if pc gr Codelimit then [ pc = pc - Codelimit; tableFlag = #200; ]
SWStackStrings = Code!pc; Code!pc = n lshift 8 + tableFlag + i;
]
]
framestackp = framestackp - 2
MaxSSP, MaxVecSSP = framestack!framestackp, framestack!(framestackp+1)
if MaxSSP ls 0 then
[ SWStackStrings = not SWStackStrings; MaxSSP = not MaxSSP; ]
goto Next
]
case RTRN:
case FNRN:
[ if Op eq FNRN do [ CGloadac0(arg1); Pop1() ]
CG(SWFastFrame? SWFastFrame+#400, Ireturn) // procedure call or fast op-code
if SWCode do WriteS(" (RETURN)")
CGoutconstants(0)
Clearstack(SSP-1)
Initstack(SSP)
goto Next
]
case RES:
[ Clearstack(SSP-2)
CGloadac0(arg1)
Pop1()
CGjmp(ReadL())
if SWCode do WriteS("(RESULT IN AC0)")
CGoutconstants(0)
goto Next
]
case RSTACK:
[ SetSSP(ReadN())
Push(AC, 0, 0)
goto Next
]
]items
]pures