SECTION "CG3"
GET "CGHDR"
// COMPILES CODE TO DEAL WITH ANY PENDING OP
LET CGPENDINGOP(SET) BE
$(1 LET R = -1
LET SW = FALSE
LET PENDOP = PENDINGOP
LET NUM1 = H1!ARG1=K.NUMB
LET KK = H2!ARG1
LET RAND1,RAND2 = ARG1,ARG2
PENDINGOP := S.NONE
SWITCHON PENDOP INTO
$(SW CASE S.ABS:
R := MOVETOANYR(ARG1,SET)
GENRS(F.OR, R, K.REG, R)
CHECKBREFS(6)
//*<3032
LISTL("JGE $+4")
/*3032>*/
CODEB(F.JGE)
CODEB(2)
CASE S.NEG:
SW := TRUE
CASE S.NOT:
R := MOVETOANYR(ARG1, SET)
GEND(SW->F.NEG,F.NOT, K.REG, R)
CASE S.NONE:
RETURN
$)SW
GETVALUE(ARG1)
GETVALUE(ARG2)
IF H1!ARG2=K.NUMB | H1!ARG1=K.REG |
LOOKINFREEREGS(ARG1)>=0 DO
// SWOP OPERANDS FOR SYMETRIC OPS
RAND1,RAND2 := ARG2,ARG1
SWITCHON PENDOP INTO
$(SW DEFAULT:CGERROR("BAD PNDOP %N",FALSE,PENDOP)
RETURN
CASE S.EQ: CASE S.NE:
CASE S.LS: CASE S.GR:
CASE S.LE: CASE S.GE:
// COMPARISONS ARE ARG2 <OP> ARG1
$( LET F = CONDBRFN(PENDOP)
R := NEXTRSET(-1,SET)
GENRS(F.XOR, R, K.REG, R)
F := CGCMP(FALSE,F,R) // EXCLUDE R
CHECKBREFS(6)
//*<3032
LISTL("%S $+4", SF(F))
/*3032>*/
CODEB(F)
CODEB(2)
GEND(F.NOT, K.REG, R)
ENDCASE $)
CASE S.EQV:
SW := TRUE
CASE S.NEQV:
R := MOVETOANYR(ARG2,SET)
CGLOGORANDNEQV(F.XOR, ARG1, K.REG, R)
IF SW DO GEND(F.NOT, K.REG, R)
ENDCASE
CASE S.PLUS:
IF NUM1 & H1!ARG2=K.NUMB DO
$( LOSE1(K.NUMB, KK+H2!ARG2)
RETURN $)
R := MOVETOANYR(RAND2,SET)
CGPLUS(RAND1,K.REG,R)
ENDCASE
CASE S.MINUS:
R := MOVETOANYR(ARG2,SET)
CGMINUS(ARG1,K.REG,R)
ENDCASE
CASE S.MULT:
IF NUMBERIS(2,RAND1) | NUMBERIS(4,RAND1) DO
$( R := MOVETOANYR(RAND2,SET)
FOR I = 1 TO (H2!RAND1)/2 DO
GENSHIFT(F.SHL, 1, K.REG, R)
ENDCASE $)
MOVETOR(RAND2, R.AX)
FREEREG(R.DX, RAND1)
IF H1!RAND1=K.NUMB DO
$( LET R = LOOKINREGS(K.NUMB, H2!RAND1)
IF R<0 DO R := NEXTRFORCESET(R.AX, V.XMULDIV)
MOVETOR(RAND1, R)
$)
FORGET(K.REG, R.DX)
GENMULDIV(F.IMUL, RAND1)
R := R.AX
ENDCASE
CASE S.DIV:
SW := TRUE
CASE S.REM:
FREEREG(R.DX, -1)
MOVETOR(ARG2, R.AX)
FORGET(K.REG, R.DX)
GENF(F.CWD)
IF H1!ARG1=K.NUMB DO
$( LET R = LOOKINREGS(K.NUMB, H2!ARG1)
IF R<0 DO R := NEXTRFORCESET(R.AX, V.XMULDIV)
MOVETOR(ARG1, R)
$)
GENMULDIV(F.IDIV, ARG1)
R := SW -> R.AX, R.DX
ENDCASE
CASE S.LOGOR:
SW := TRUE
CASE S.LOGAND:
R := MOVETOANYR(RAND2,SET)
CGLOGORANDNEQV(SW->F.OR,F.AND,RAND1,K.REG,R)
ENDCASE
CASE S.LSHIFT:
SW := TRUE
CASE S.RSHIFT:
IF NUM1 DO
IF KK=1 | KK=2 | KK=8 DO
$( R := MOVETOANYR(ARG2,SET)
UNLESS KK=8 & ~INSET(V.R80, R) DO
$( CGSHIFTK(SW,KK,K.REG,R)
ENDCASE
$)
$)
MOVETOR(ARG1, R.CX) // SHIFT COUNTER
TEST H1!ARG2=K.REG DO R := H2!ARG2
OR $( R := LOOKINFREEREGS(H1!ARG2, H2!ARG2)
TEST R>=0 DO H1!ARG2, H2!ARG2 := K.REG, R
OR $( R := NEXTRSET(R.CX, SET)
MOVETOR(ARG2, R)
$)
$)
GENSHIFT(SW -> F.SHL, F.SHR,0,K.REG,R)
ENDCASE
$)SW
LOSE1(K.REG, R)
$)1
// GET A SET FOR AN OPERATOR
AND REGSET(P) = VALOF
SWITCHON P INTO
$( DEFAULT: RESULTIS V.XX
CASE S.MULT:
CASE S.DIV:
CASE S.REM: RESULTIS V.AX
CASE S.RV:
CASE S.PUTBYTE:
CASE S.GETBYTE:
RESULTIS V.RI
$)
// COMPILES A GLOBAL CALL FOR OUT OF
// LINE FUNCTIONS
AND CGGLOBCALL(GN) BE
$( CGPENDINGOP(V.R1)
STORE(0,SSP-3)
MOVETOR(ARG2, R0)
MOVETOR(ARG1, R1)
STACK(SSP-2)
FREEREG(R.DX,-1)
GENMOV(K.NUMB, 2*SSP, K.REG, R.DX)
GENMOV(K.GLOB, GN, K.REG, R.SI)
GENJ(F.CIS, K.XSI, 0)
FORGETALL()
$)
AND NUMBERIS(N,A) =
H1!A=K.NUMB & H2!A=N
.