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

.