// BNCG3.bcpl - BCPL Compiler // Nova Code Generator, Stack and Register maintainance routines // Copyright Xerox Corporation 1980 // Last modified on Fri 27 Oct 72 2202.15 by jec. get "bncgx" let Initstack(ssp) be [ arg3 = argvec; arg2 = arg3 + argsize; arg1 = arg2 + argsize SSP = ssp Setarg(arg3, LOCAL, 0, SSP-3, SSP-3, 0) Setarg(arg2, LOCAL, 0, SSP-2, SSP-2, 0) Setarg(arg1, LOCAL, 0, SSP-1, SSP-1, 0) ] and Push(t, r, l) be [ arg3 = arg2; arg2 = arg1; arg1 = arg1 + argsize if arg1 ge argvec + argvecsize do CGreport(2) Setarg(arg1, t, r, l, SSP, 0) SSP = SSP + 1 ] and SetName(n) be [ name!arg1 = n ] and Pop1() be [ SSP = SSP - 1 test arg3 eq argvec then [ Setarg(arg1, type!arg2, ref!arg2, loc!arg2, pos!arg2, name!arg2) Setarg(arg2, type!arg3, ref!arg3, loc!arg3, pos!arg3, name!arg3) Setarg(arg3, LOCAL, 0, SSP-3, SSP-3 , 0) ] or [ arg1 = arg2; arg2 = arg3; arg3 = arg3 - argsize ] ] and Pop2() be [ Pop1(); Pop1() ] and Setarg(arg, t, r, l, p, n) be [ type!arg, ref!arg, loc!arg, pos!arg, name!arg = t, r, l, p, n ] and Copyarg(arga, argb) be [ Setarg(argb, type!arga, ref!arga, loc!arga, pos!arga, name!arga) ] and SetSSP(ssp) be [ if ssp eq SSP return test ssp ls SSP then while ssp ls SSP do [ if arg3 eq argvec & ssp ls SSP-3 do [ Initstack(ssp); break ] Pop1() ] or while ssp gr SSP do [ if ssp gr SSP+3 do [ Clearstack(ssp-1); Initstack(ssp); break ] Push(LOCAL, 0, SSP) ] ] and Clearstack(ssp) be [ let arg = argvec until arg gr arg1 % pos!arg gr ssp do [ CGstoreintemp(arg) arg = arg + argsize ] ] and freeac() = valof [ let arg = argvec let a1, a2 = 0, 0 until arg gr arg1 do [ if type!arg eq AC do test a1 eq 0 then a1 = arg or test a2 eq 0 then a2 = arg or CGreport(-2) arg = arg + argsize ] if a2 eq 0 do test a1 eq 0 then resultis 0 or resultis (loc!a1 eq 0 ? 1, 0) let ac = loc!a1 CGstoreintemp(a1) resultis ac ] and Clearac(ac) be [ let arg = argvec until arg gr arg1 do [ if type!arg eq AC & loc!arg eq ac do [ CGstoreintemp(arg); return ] arg = arg + argsize ] ] and CGload(reg, arg) be [ test type!arg eq NUMBER then [ let n = loc!arg test n eq 0 then [ CGae(Isub, reg, reg) if SWCode do WriteS(" (0)") ] or test n eq 1 then [ CGae(Isubzl, reg, reg) if SWCode do WriteS(" (1)") ] or test n eq #100000 then [ CGae(Isubzr, reg, reg) if SWCode do WriteS(" (100000)") ] or test n eq #177777 then [ CGae(Iadc, reg, reg) if SWCode do WriteS(" (177777)") ] or test n eq #177776 then [ CGae(Iadczl, reg, reg) if SWCode do WriteS(" (177776)") ] or test n eq #077777 then [ CGae(Iadczr, reg, reg) if SWCode do WriteS(" (77777)") ] or CGlda(reg, arg) ] or [ CGlda(reg, arg) ] type!arg, ref!arg, loc!arg = (reg eq X ? XR, AC), 0, reg ] and CGstore(reg, arg) be [ CGsta(reg, arg) ] and CGstoreintemp(arg) be CGstoreintempN(arg, pos!arg) and CGstoreintempN(arg, N) be [ if type!arg eq LOCAL & ref!arg eq 0 & loc!arg eq N return CGloadreg(arg) let ac = loc!arg type!arg, ref!arg, loc!arg, name!arg = LOCAL, 0, N, 0 CGstore(ac, arg) ] and CGloadac(arg) be [ unless type!arg eq AC do CGload(freeac(), arg) ] and CGloadreg(arg) be [ unless type!arg eq AC do CGload(X, arg) ] and CGloadxr(arg) be [ test type!arg eq AC then CGae(Imov, loc!arg, X) or CGload(X, arg) type!arg, ref!arg, loc!arg = XR, 0, X ] and CGloadac0(arg) be [ test type!arg eq AC then unless loc!arg eq 0 do [ Clearac(0) CGae(Imov, loc!arg, 0) loc!arg = 0 ] or [ Clearac(0) CGload(0, arg) ] ] and CGloadac1(arg) be [ test type!arg eq AC then unless loc!arg eq 1 do [ Clearac(1) CGae(Imov, loc!arg, 1) loc!arg = 1 ] or [ Clearac(1) CGload(1, arg) ] ] and CGload01() be [ if type!arg2 eq AC & type!arg1 eq AC do [ unless loc!arg2 eq 0 & loc!arg1 eq 1 do [ CGae(Imov, 0, X) CGae(Imov, 1, 0) CGae(Imov, X, 1) ] loc!arg2, loc!arg1 = 0, 1 return ] test type!arg1 eq AC ifnot [ CGloadac0(arg2); CGloadac1(arg1) ] ifso [ CGloadac1(arg1); CGloadac0(arg2) ] ] and CGloadboth() be [ CGloadac(arg2) CGloadac(arg1) ]