SECTION "CG4" GET "CGHDR" // MAKE ANY LVALUES ADDRESSABLE - IE GET THEM // INTO A REGISTER LET GETVALUE(A) BE IF H1!A=K.LVLOC | H1!A=K.LVGLOB | H1!A=K.LVLAB DO MOVETOINDEXR(A) // MOVE A SS ITEM INTO AN INDEX REGISTER AND SHIFT // IT LEFT FOR USE WITH CGRV AND MOVETOINDEXRSH(A) = VALOF $( LET K,N,R = H1!A,H2!A,? LET KM = K=K.LOC -> K.MLOC, K=K.LAB -> K.MLAB, K=K.GLOB -> K.MGLOB, K.NONE UNLESS KM=K.NONE DO $( R := LOOKINREGS(KM,N) IF R>=0 DO UNLESS (SETR(R) & V.RI)=0 RESULTIS R $) R := MOVETOINDEXR(A) GENSHIFT(F.SHL, 1, K.REG, R) SETINFO(R,KM,N) RESULTIS R $) // MOVE A SS ITEM INTO ANY REGISTER // PREFERABLY IN SET S AND MOVETOANYR(A,S) = VALOF $( LET K,N,R = H1!A,H2!A,? IF K=K.REG RESULTIS N R := LOOKINFREEREGS(K,N) IF R>=0 DO $( H1!A,H2!A := K.REG,R RESULTIS R $) RESULTIS MOVETOR(A,NEXTRSET(-1,S)) $) // CHANGE R TO BIT STRING SET FORMAT AND SETR(R) = 1<<R // MOVE ARGUMENT TO AN INDEX REGISTER (BX OR SI) AND MOVETOINDEXR(A) = VALOF $(M LET K,N = H1!A, H2!A LET T1, T2 = -1, -1 IF K=K.REG & (N=R.SI | N=R.BX) RESULTIS N IF REG.K!R.SI=K & REG.N!R.SI=N & ISFREE(R.SI) DO T1 := R.SI IF REG.K!R.BX=K & REG.N!R.BX=N & ISFREE(R.BX) DO T2 := R.BX UNLESS T1=-1 & T2=-1 DO $( LET T= T2=-1 -> T1, T2 H1!A, H2!A := K.REG, T RESULTIS T $) RESULTIS MOVETOR(A, (ISFREE(R.BX)->R.BX, ISFREE(R.SI)->R.SI, R.BX)) $)M // MOVE A SS ITEM INTO A GIVEN REGISTER AND MOVETOR(A,R) = VALOF $( FREEREG(R,A) GENMOV(H1!A,H2!A,K.REG,R) H1!A,H2!A := K.REG,R RESULTIS R $) // LOOK FOR THE VALUE OF AN ITEM (K,N) IN THE // REGISTERS; THE REGISTER WILL NOT BE MODIFIED AND LOOKINREGS(K,N) = VALOF $( FOR R=R0 TO R4 DO IF REG.K!R=K & REG.N!R=N RESULTIS R RESULTIS -1 $) // LOOK FOR THE VALUE OF AN ITEM (K,N) IN THE // FREE REGISTERS; THE REGISTER MAY BE MODIFIED AND LOOKINFREEREGS(K,N) = VALOF $( FOR R=R0 TO R4 DO IF REG.K!R=K & REG.N!R=N & ISFREE(R) RESULTIS R RESULTIS -1 $) // ALLOCATE THE NEXT REGISTER (EXCEPT X); // FREE IT IF REQUIRED AND NEXTR(X) = VALOF $( FOR R=R0 TO R4 DO UNLESS R=X DO IF REG.K!R=K.NONE & ISFREE(R) RESULTIS R FOR R=R0 TO R4 DO UNLESS R=X DO IF ISFREE(R) RESULTIS R FOR T=TEMPV TO ARG1 BY 3 DO $( LET R=REGUSEDBY(T) UNLESS R=X IF R>=0 DO $( FREEREG(R,0) RESULTIS R $) $) $) //TRY AND ALLOCATE THE NEXT REGISTER FROM THE GIVEN SET AND NEXTRSET(X, E) = VALOF $( FOR R = R0 TO R4 DO UNLESS R=X DO IF REG.K!R=K.NONE & ISFREE(R) & INSET(E, R) RESULTIS R FOR R = R0 TO R4 DO UNLESS R=X DO IF ISFREE(R) & INSET(E, R) RESULTIS R RESULTIS NEXTR(X) $) AND NEXTRFORCESET(X, E) = VALOF $( FOR R = R0 TO R4 DO UNLESS R=X DO IF REG.K!R=K.NONE & ISFREE(R) & INSET(E, R) RESULTIS R FOR R = R0 TO R4 DO UNLESS R=X DO IF ISFREE(R) & INSET(E, R) RESULTIS R IF (SETR(X) NEQV E)=0 DO CGERROR("SET MEMBER %N EXCLUDED", TRUE, X) IF E=0 DO CGERROR("EMPTY SET", TRUE) FOR T=TEMPV TO ARG1 BY 3 DO $( LET R = REGUSEDBY(T) UNLESS R=X IF R>=0 & INSET(E, R) DO $( FREEREG(R, 0) RESULTIS R $) $) FOR R = R0 TO R4 DO UNLESS R=X DO IF INSET(E,R) DO $( FREEREG(R, 0) RESULTIS R $) CGERROR("FALL OUT NEXTRFSET %N", TRUE, E) $) AND INSET(SET, R) = ((SET>>R)&1)=1 // FIND WHICH REGISTER, IF ANY, IS USED BY // AN SS ITEM AND REGUSEDBY(A) = VALOF $( LET K=H1!A IF K=K.REG RESULTIS H2!A IF K=K.XBX | K=K.XSI RESULTIS K-K.ROFF RESULTIS -1 $) AND ISFREE(R) = VALOF $( FOR T=TEMPV TO ARG1 BY 3 DO IF REGUSEDBY(T)=R RESULTIS FALSE RESULTIS TRUE $) // FREE REGISTER R BY STORING THE VALUES OF // ALL SS ITEMS (EXCEPT X) THAT DEPEND UPON IT AND FREEREG(R,X) BE FOR T=TEMPV TO ARG1 BY 3 DO UNLESS T=X DO IF REGUSEDBY(T)=R DO STORET(T) // STORE THE VALUE OF AN SS ITEM IN ITS TRUE // STACK LOCATION AND STORET(A) BE UNLESS H1!A=K.LOC & H2!A=H3!A DO // CHECK REDUNDANT $( GETVALUE(A) UNLESS H1!A=K.REG | H1!A=K.NUMB DO MOVETOANYR(A, V.XX) GENMOV(H1!A,H2!A,K.LOC,H3!A) H1!A := K.LOC H2!A := H3!A $) // LOAD AN ITEM (K,N) ONTO THE SS AND LOADT(K, N) BE $( CGPENDINGOP(V.XX) ARG2 := ARG1 ARG1 := ARG1 + 3 IF H3+ARG1-TEMPT>=0 DO CGERROR("SIM STACK OVF", TRUE) H1!ARG1,H2!ARG1,H3!ARG1 := K,N,SSP SSP := SSP + 1 IF MAXSSP<SSP DO MAXSSP := SSP $) // REPLACE THE TOP TWO SS ITEMS BY (K,N) AND LOSE1(K, N) BE $( SSP := SSP - 1 TEST ARG2=TEMPV THEN $( H1!ARG2,H2!ARG2 := K.LOC,SSP-2 H3!ARG2 := SSP-2 $) ELSE $( ARG1 := ARG2 ARG2 := ARG2-3 $) H1!ARG1, H2!ARG1, H3!ARG1 := K,N,SSP-1 $) AND CGBYTEAP(OP) BE $(1 CGPENDINGOP(V.XX) $( LET S = MOVETOINDEXRSH(ARG2) LET I = H2!ARG1 LET BYT.M, BYT.V = ?, ? LET RST = ? UNLESS H1!ARG1=K.NUMB DO $( FREEREG(S,ARG2) GETVALUE(ARG1) CGPLUS(ARG1,K.REG,S) I := 0 $) FORMADDR(S+K.ROFF, I) BYT.M, BYT.V := ADDR.M, ADDR.V RST := S=R.BX->"BX","SI" TEST OP=S.GETBYTE THEN $( LET R = NEXTRFORCESET(S,V.R80) LET TN = TRANR(R) GENRS(F.XOR, R, K.REG, R) CHECKBREFS(5) //*<3032 LISTL("MOV %S,%N(%S)", STRINGRB(TN), I, RST) /*3032>*/ CODEB((F.MOVRTRM & #376) | 2) CODEB(CONSB2(TN, BYT.M, BYT.V)) CODEDISP(BYT.M, BYT.V) LOSE1(K.REG,R) $) OR $( LET R, TN = ?, ? TEST ARG2=TEMPV DO $( R := NEXTRFORCESET(S, V.R80) TN := TRANR(R) GENMOV(K.LOC, SSP-3, K.REG, R) $) OR $( LET ARG3 = ARG2-3 TEST H1!ARG3=K.REG & INSET(V.R80, H2!ARG3) DO R := H2!ARG3 OR R := NEXTRFORCESET(S, V.R80) TN := TRANR(R) MOVETOR(ARG3, R) $) CHECKBREFS(5) //*<3032 LISTL("MOV %N(%S),%S", I, RST, STRINGRB(TN)) /*3032>*/ CODEB(F.MOVRTRM & #376) CODEB(CONSB2(TN, BYT.M, BYT.V)) CODEDISP(BYT.M, BYT.V) FORGETVARS() STACK(SSP-3) $) $) $)1 AND CGSTIND() BE $( CGRV() UNLESS H1!ARG2=K.REG | H1!ARG2=K.NUMB DO $( LET R = NEXTR((H2!ARG1)-K.ROFF) MOVETOR(ARG2, R) $) GENMOV(H1!ARG2,H2!ARG2,H1!ARG1,H2!ARG1) FORGETVARS() STACK(SSP-2) $) // STORE THE TOP ITEM OF THE SS IN (K,N) AND STOREIN(K, N) BE $(1 LET B = (H1!ARG1=K & H2!ARG1=N) -> 1, (H1!ARG2=K & H2!ARG2=N) -> 2, 0 LET ARG = B=2 -> ARG1,ARG2 LET NUM = B=2 & H1!ARG=K.NUMB LET KK = H2!ARG LET SW = FALSE LET PENDOP = PENDINGOP IF B=0 GOTO GENCASE PENDINGOP := S.NONE SWITCHON PENDOP INTO $(2 DEFAULT: GENCASE: PENDINGOP := PENDOP CGPENDINGOP(V.XX) CASE S.NONE: GETVALUE(ARG1) UNLESS H1!ARG1=K.REG | (H1!ARG1=K.NUMB & H2!ARG1~=0) DO MOVETOANYR(ARG1, V.XX) GENMOV(H1!ARG1,H2!ARG1,K,N) STACK(SSP-1) RETURN CASE S.NEG: SW := TRUE CASE S.NOT: UNLESS B=1 GOTO GENCASE GEND(SW -> F.NEG, F.NOT, K, N) STACK(SSP-1) RETURN CASE S.PLUS: GETVALUE(ARG) CGPLUS(ARG, K, N) ENDCASE CASE S.MINUS: GETVALUE(ARG) CGMINUS(ARG, K, N) IF B=1 DO GEND(F.NEG,K, N) ENDCASE CASE S.LOGOR: SW := TRUE CASE S.LOGAND: GETVALUE(ARG) CGLOGORANDNEQV(SW->F.OR,F.AND, ARG, K, N) ENDCASE CASE S.EQV: SW := TRUE CASE S.NEQV: GETVALUE(ARG) CGLOGORANDNEQV(F.XOR,ARG, K, N) IF SW DO GEND(F.NOT, K, N) ENDCASE CASE S.MULT: IF H1!ARG=K.NUMB DO IF KK=2 | KK=4 DO $( FOR I = 1 TO KK/2 DO GENSHIFT(F.SHL,1,K,N) ENDCASE $) GOTO GENCASE CASE S.LSHIFT: SW := TRUE CASE S.RSHIFT: UNLESS B=2 GOTO GENCASE IF NUM DO IF 0<=KK<=3 DO $( FOR I = 1 TO KK DO GENSHIFT(SW->F.SHL,F.SHR,1,K,N) ENDCASE $) MOVETOR(ARG1, R.CX) GENSHIFT(SW->F.SHL,F.SHR,0,K,N) ENDCASE $)2 STACK(SSP-2) $)1 .