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
.