// 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