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
.