SECTION "CG5" GET "CGHDR" LET CGRV() BE $(1 LET R = 0 IF PENDINGOP=S.MINUS & H1!ARG1=K.NUMB DO PENDINGOP, H2!ARG1 := S.PLUS, -H2!ARG1 TEST PENDINGOP=S.PLUS & (H1!ARG1=K.NUMB | H1!ARG2=K.NUMB) THEN $( LET ARG = ARG2 LET N = H2!ARG1 IF H1!ARG2=K.NUMB DO ARG,N := ARG1,H2!ARG2 PENDINGOP := S.NONE R := MOVETOINDEXRSH(ARG) LOSE1(R+K.ROFF,2*N) $) ELSE $( CGPENDINGOP(V.RI) R := MOVETOINDEXRSH(ARG1) H1!ARG1, H2!ARG1 := R+K.ROFF, 0 $) $)1 AND CGSHIFTK(SW,KK,K,N) BE $(1 IF KK=8 DO // TYPE SHOULD BE K.REG IN THE 8080 SET (V.R80) $( TEST SW DO $( GENBYTEXCHG(N); GENCLEARBYTE(N) $) OR $( GENCLEARBYTE(N); GENBYTEXCHG(N) $) RETURN $) GENSHIFT(SW -> F.SHL, F.SHR, 1, K, N) IF KK=2 DO GENSHIFT(SW -> F.SHL, F.SHR, 1, K, N) $)1 AND CGADDK(KK, K, N) BE UNLESS KK=0 DO $(1 IF KK=1 DO $( GENINCDEC(F.INC, K, N); RETURN $) IF KK=-1 DO $( GENINCDEC(F.DEC, K, N); RETURN $) GENKD(F.ADD, KK, K, N) $)1 AND CGPLUS(A,K,N) BE TEST H1!A=K.NUMB THEN CGADDK(H2!A, K, N) OR CGDIADWITHR(F.ADD, A, K, N) AND CGMINUS(A,K,N) BE TEST H1!A=K.NUMB THEN CGADDK(-H2!A, K, N) OR CGDIADWITHR(F.SUB, A, K, N) AND CGLOGORANDNEQV(F, A, K, N) BE TEST H1!A=K.NUMB THEN GENKD(F, H2!A, K, N) OR CGDIADWITHR(F, A, K, N) AND CGGLOBAL(N) BE $(1 EVEN() //*<3032 LISTAT(S.ITEMN, 0) /*3032>*/ CODE(0, 0) FOR I = 1 TO N DO $( LET G = RDGN() LET L = RDL() LET DL = NEXTPARAM() //*<3032 LISTAT(S.ITEMN, G) /*3032>*/ CODE(G, 0) //*<3032 LISTAT(S.ITEML,DL) /*3032>*/ CODE(0, -DL) // GLOBIN DOES RELOCATION CGDATA(S.DATALAB, DL) // LABEL OF DESCRIPTOR CGDATA(S.GLOBAL, L) // THE DESCRIPTOR ITSELF $) //*<3032 LISTAT(S.ITEMN, MAXGN) /*3032>*/ CODE(MAXGN, 0) CGSTATICS() // ITEMS IN DATA SEGMENT $)1 AND CGENTRY(N,L) BE $(1 GENBREFJUMPS(50,0) CGNAME(S.ENTRY,N) SETLAB(L) INCODE := TRUE GENRS(F.ADD, R.BP, K.REG, R.DX) // ADJUST FRAME //*<3032 LISTL("MOV 4(BP),DX") /*3032>*/ CODEB(#X89); CODEB(#X56); CODEB(4) // MOV 4(BP),DX // POP RETURN ADDRESS INTO STACK FRAME //*<3032 LISTL("POP (BP)") LISTL("POP 2(BP)") /*3032>*/ CODEB(#X8F); CODEB(#X46); CODEB(0) // POP (BP) CODEB(#X8F); CODEB(#X46); CODEB(2) // POP 2(BP) IF NAMING DO $( //*<3032 LISTL("MOV 6(BP),SI") /*3032>*/ CODEB(#X89); CODEB(#X76); CODEB(6) $) IF CALLCOUNTING DO INSERTCOUNT() FORGETALL() $)1 AND CGDIADWITHR(F, A, K, N) BE $( LET R = K=K.REG -> N, H1!A=K.REG -> H2!A, -1 IF R=-1 DO R := MOVETOANYR(A, V.XX) TEST K=K.REG DO GENRS(F, R, H1!A, H2!A) OR GENRD(F, R, K, N) $) AND INDCODE(R) = VALOF $( LET IR = TRANR(R)!TABLE -1,-1,-1,7,-1,6,4,5 IF IR=-1 DO CGERROR("REG %N NOT INDXBLE",FALSE,R) RESULTIS IR $) AND TRANR(R) = VALOF $( UNLESS 0<=R<=7 DO CGERROR("INVALID REGISTER %N", TRUE, R) RESULTIS R!TABLE 3,0,1,2,6,5,4,7 $) AND CGSAVE(N) BE $(1 LET NRGS = N-SAVESPACESIZE FOR I = 0 TO NRGS>=3->2,NRGS-1 DO $( GENMOV(K.REG, I, K.LOC, I+SAVESPACESIZE) SETINFO(I, K.LOC, I+SAVESPACESIZE) $) INITSTACK(N) $)1 // FUNCTION OR ROUTINE CALL AND CGAPPLY(OP,K) BE $(1 LET SR0 = K+SAVESPACESIZE LET SR2 = K+SAVESPACESIZE+2 LET L = ? CGPENDINGOP(V.XX) // STORE ARGS 4,5,... STORE(SR2+1, SSP-2) // NOW DEAL WITH NON-ARGS FOR T = TEMPV TO ARG2 BY 3 DO $( IF H3!T>=K BREAK IF REGUSEDBY(T)>=0 DO STORET(T) $) GETVALUE(ARG1) // MOVE ARGS 1-3 TO ARG REGISTERS FOR T = ARG2 TO TEMPV BY -3 DO $( LET S = H3!T LET R = S-SR0 IF S<SR0 BREAK IF S<=SR2 & ISFREE(R) DO MOVETOR(T,R) $) FOR T = ARG2 TO TEMPV BY -3 DO $( LET S = H3!T LET R = S-SR0 IF S<SR0 BREAK IF S<=SR2 DO MOVETOR(T,R) $) // DEAL WITH ARGS NOT IN SS FOR S = SR0 TO SR2 DO $( LET R = S-SR0 IF S>=H3!TEMPV BREAK FREEREG(R,0) GENMOV(K.LOC, S, K.REG, R) $) FREEREG(R.DX, 0) GENMOV(K.NUMB, 2*K, K.REG, R.DX) IF H1!ARG1=K.NUMB DO H2!ARG1 := H2!ARG1*2 FREEREG(R.SI, 0) // SI USED TO HOLD DESCRIPTOR ADDRESS GENMOV(H1!ARG1, H2!ARG1, K.REG, R.SI) GENJ(F.CIS, K.XSI, 0) FORGETALL() STACK(K) IF OP=S.FNAP DO LOADT(K.REG,R0) $)1 AND CGRETURN(OP) BE $(1 CGPENDINGOP(V.R0) IF OP=S.FNRN DO $( MOVETOR(ARG1,R0) STACK(SSP-1) $) // GENERATE ONLY 1 RETURN SEQUENCE // PER SECTION TEST RETURN.SET=0 DO $( RETURN.SET := NEXTPARAM() INCODE := TRUE // BE SAFE CHECKBREFS(7) SETLAB(RETURN.SET) //*<3032 LISTL("MOV SI,4(BP)") /*3032>*/ CODEB(#X8B);CODEB(#X76);CODEB(4) // MOV SI,4(BP) GENRS(F.SUB, R.BP, K.REG, R.SI) // OLD FRAME POINTER //*<3032 LISTL("JIS (BP,SI)") /*3032>*/ CODEB(#XFF); CODEB(#X2A) // JIS (BP,SI) $) OR $( CHECKBREFS(3) GENBRANCH(F.JMP, RETURN.SET) $) INITSTACK(SSP) $)1 // USED FOR OCODE OPERATORS JT AND JF AND CGJUMP(B,L) BE $(1 LET F = CONDBRFN(PENDINGOP) IF F=0 DO $( CGPENDINGOP(V.XX) LOADT(K.NUMB,0) F := F.JNE $) PENDINGOP := S.NONE STORE(0,SSP-3) GETVALUE(ARG1) GETVALUE(ARG2) F := CGCMP(B,F,-1) GENBRANCH(F,L) STACK(SSP-2) IF PROFILING DO INSERTCOUNT() $)1 AND CGCMPF(F) = VALOF SWITCHON F INTO $( CASE F.JL : RESULTIS F.JG CASE F.JGE: RESULTIS F.JLE CASE F.JLE: RESULTIS F.JGE CASE F.JG : RESULTIS F.JL DEFAULT : RESULTIS F $) // XR IS A REGISTER WHICH MUST NOT BE USED! AND CGCMP(B,F,XR) = VALOF $(1 TEST NUMBERIS(0,ARG1) & H1!ARG2=K.REG THEN GENRS(F.OR,H2!ARG2, K.REG,H2!ARG2) ELSE $( TEST NUMBERIS(0,ARG2) & H1!ARG1=K.REG THEN $( GENRS(F.OR,H2!ARG1,K.REG,H2!ARG1) F := CGCMPF(F) $) OR $( TEST H1!ARG1=K.NUMB THEN GENKD(F.CMP, H2!ARG1, H1!ARG2, H2!ARG2) OR $( TEST H1!ARG2=K.NUMB THEN $( GENKD(F.CMP, H2!ARG2, H1!ARG1, H2!ARG1) F := CGCMPF(F) $) OR $( UNLESS H1!ARG1=K.REG | H1!ARG2=K.REG DO MOVETOR(ARG2, NEXTR(XR)) CGDIADWITHR(F.CMP, ARG1, H1!ARG2, H2!ARG2) $) $) $) $) RESULTIS B -> F, F NEQV 1 $)1 .