static char sccsid
[] = "@(#)c20.c 4.11 (Berkeley) 6/23/90";
char firstr
[sizeof (char *)];
{100000L,200000L,300000L,400000L,500000L,600000L,700000L,800000L,900000L,1000000L};
* Cheapo space allocator. Works much like the old one but uses malloc()
* and doesn't clash with stdio. Assumes that no one requests more than
* ALLOCSIZE bytes at a time.
register char *nextb
= * (char **) currentb
;
if (n
== 0) { /* Free everything */
nextb
= * (char **) currentb
;
if ((nextb
= malloc(ALLOCSIZE
)) == NULL
) {
fprintf(stderr
, "Optimizer: out of space\n");
ncore
+= (ALLOCSIZE
/1024);
* (char **) currentb
= nextb
;
* (char **) nextb
= NULL
;
lasta
= nextb
+ sizeof nextb
;
lastr
= nextb
+ ALLOCSIZE
;
register int niter
, maxiter
, isend
;
nflag
= 0; infound
=0; argc
--; argv
++;
while (argc
>0) {/* get flags */
if (**argv
=='+') debug
++;
if ((*argv
)[1]=='i') ioflag
++;
else if ((*argv
)[1]=='f') fflag
++;
if (freopen(*argv
, "r", stdin
) ==NULL
) {
fprintf(stderr
,"C2: can't find %s\n", *argv
);
} else if (freopen(*argv
, "w", stdout
) ==NULL
) {
fprintf(stderr
,"C2: can't create %s\n", *argv
);
} while (nchange
|| jumpsw());
fprintf(stderr
,"%d iterations\n", maxiter
);
fprintf(stderr
,"%d jumps to jumps\n", nbrbr
);
fprintf(stderr
,"%d inst. after jumps\n", iaftbr
);
fprintf(stderr
,"%d jumps to .+1\n", njp1
);
fprintf(stderr
,"%d redundant labels\n", nrlab
);
fprintf(stderr
,"%d cross-jumps\n", nxjump
);
fprintf(stderr
,"%d code motions\n", ncmot
);
fprintf(stderr
,"%d branches reversed\n", nrevbr
);
fprintf(stderr
,"%d redundant moves\n", redunm
);
fprintf(stderr
,"%d simplified addresses\n", nsaddr
);
fprintf(stderr
,"%d loops inverted\n", loopiv
);
fprintf(stderr
,"%d redundant jumps\n", nredunj
);
fprintf(stderr
,"%d common seqs before jmp's\n", ncomj
);
fprintf(stderr
,"%d skips over jumps\n", nskip
);
fprintf(stderr
,"%d sob's added\n", nsob
);
fprintf(stderr
,"%d redundant tst's\n", nrtst
);
fprintf(stderr
,"%d jump on bit\n", nbj
);
fprintf(stderr
,"%d field operations\n", nfield
);
fprintf(stderr
,"%dK core\n", ncore
);
register struct node
*p
, *lastp
;
struct optab
*opp
; register char *cp1
;
static struct optab F77JSW
= {".long", T(JSW
,1)};
if (debug
&& opp
==0) fprintf(stderr
,"? %s\n",line
);
switch (opp
->opcode
&0377) {
if (isdigit(line
[0]) && (p
->labno
=locdef(line
)) ||
(line
[0] == 'L') && (p
->labno
=getnum(line
+1))) {
if (p
->labno
<100000L && isn
<=p
->labno
) isn
=1+p
->labno
;
if (*curlp
!='L' && !locuse(curlp
)) goto std
;
if (opp
->opcode
==T(JBR
,RET
) || opp
->opcode
==T(JBR
,RSB
)) goto std
;
case SOBGEQ
: case SOBGTR
: case AOBLEQ
: case AOBLSS
: case ACB
:
p
->combop
= opp
->opcode
; p
->code
=0; cp1
=curlp
;
if ((!isdigit(*cp1
) || 0==(p
->labno
=locuse(cp1
))) &&
(*cp1
!='L' || 0==(p
->labno
= getnum(cp1
+1)))) {/* jbs, etc.? */
while (*cp1
++); while (*--cp1
!=',' && cp1
!=curlp
);
(!isdigit(*++cp1
) || 0==(p
->labno
=locuse(cp1
))) &&
(*cp1
!='L' || 0==(p
->labno
=getnum(cp1
+1))))
if (isn
<=p
->labno
) isn
=1+p
->labno
;
p
->combop
=opp
->opcode
; p
->code
=0; cp1
=curlp
+1;
if (cp1
[-1]=='L' || isdigit(cp1
[-1])) {
while (*cp1
++!=','); *--cp1
=0;
if (0!=(p
->labno
=locuse(curlp
)) ||
0!=(p
->labno
=getnum(curlp
+1))) p
->code
=copy(cp1
+1);
else {*cp1
=','; p
->code
=copy(curlp
);}
} else {p
->code
=copy(--cp1
); p
->labno
=0;}
printf("%s\n",line
); goto top
;
printf("%s%c",line
,(opp
->opcode
==LABEL
? ':' : '\n'));
if (opp
->opcode
==TEXT
) goto top
;
if (END
==(opp
=getline())->opcode
) {/* dangling .data is bad for you */
lp
=curlp
; while (*lp
++); while (*--lp
!='$'); ncase
=getnum(lp
+1);
if (LABEL
!=(getline())->opcode
) {
fprintf(stderr
, "c2: garbled 'case' instruction\n");
if (WGEN
!=(getline())->opcode
) {
fprintf(stderr
, "c2: garbled 'case' instruction\n");
p
= alloc(sizeof first
); p
->combop
= JSW
; p
->code
= 0;
lp
=curlp
; while(*lp
++!='-'); *--lp
=0; p
->labno
=getnum(curlp
+1);
if (isn
<=p
->labno
) isn
=1+p
->labno
;
p
->forw
= 0; p
->back
= lastp
; lastp
->forw
= p
; lastp
= p
;
static struct optab OPLABEL
={"",LABEL
};
static struct optab OPEND
={"",END
};
while (EOF
!=(c
=getchar()) && isspace(c
));
register c
; int neg
; register long n
;
n
= 0; neg
=0; if (*p
=='-') {++neg
; ++p
;}
while (isdigit(c
= *p
++)) {
c
-= '0'; n
*= 10; if (neg
) n
-= c
; else n
+= c
;
if (!isdigit(p
[0]) || p
[1] != 'f' && p
[1] != 'b' || p
[2]) return(0);
return (lgensym
[p
[0] - '0'] - (p
[1] == 'b'));
if (!isdigit(p
[0]) || p
[1]) return(0);
return (lgensym
[p
[0] - '0']++);
while (t
= t
->forw
) switch (t
->op
) {
printf("L%d:", t
->labno
);
if (t
->pop
==0) {/* must find it */
register struct optab
*p
;
for (p
=optab
; p
->opstring
[0]; ++p
)
if (p
->opcode
==t
->combop
) {t
->pop
=p
; break;}
printf("%s", t
->pop
->opstring
);
if (t
->code
) printf("\t%s", t
->code
);
if (t
->labno
!=0) printf("%cL%d\n",
if (t
->labno
==0) goto std
;
printf("mova%c\tL%d,%s\n","bwlq"[t
->subop
-BYTE
],t
->labno
,t
->code
);
if (t
->subop
!=0) {/* F77JSW */
printf(".long\tL%d\n",t
->labno
); continue;
if (casebas
==0) printf("L%d:\n",casebas
=isn
++);
printf(".word L%d-L%d\n", t
->labno
, casebas
);
if (t
->forw
) if(t
->forw
->op
== CBR
) goto std
;
if (*t
->code
== '$') goto std
;
printf("movl\t%s\n", t
->code
);
if (t
->subop
== DFLOAT
|| t
->subop
== GFLOAT
)
printf("movq\t%s\n", t
->code
);
printf("movo\t%s\n", t
->code
);
register char *p
= ap
, *np
;
onp
= np
= (char *) alloc(n
);
struct optab
*ophash
[OPHS
];
register struct optab
*optp
, **ophp
;
for(i
=NREG
+5;--i
>=0;) regs
[i
] = malloc(C2_ASIZE
);
for (optp
= optab
; optp
->opstring
[0]; optp
++) {
t
=7; i
=0; while (--t
>=0) i
+= i
+optp
->opstring
[t
];
ophp
= &ophash
[i
% OPHS
];
/* fprintf(stderr,"\ncollision: %d %s %s",
/* ophp-1-ophash,optp->opstring,(*(ophp-1))->opstring);
if (ophp
>= &ophash
[OPHS
])
register struct optab
*optp
,**ophp
;
static struct optab OPNULL
={"",0};
for (p
=line
, p2
=tempop
; *p
&& !isspace(*p
); *p2
++= *p
++); *p2
=0; p2
=p
;
while (isspace(*p2
)) ++p2
; curlp
=p2
;
t
=0; while(--p
>=line
) t
+= t
+*p
; ophp
= &ophash
[t
% OPHS
];
if (equstr(tempop
,optp
->opstring
)) return(optp
);
if ((++ophp
) >= &ophash
[OPHS
]) ophp
= ophash
;
register struct node
*p
, *lp
, *tp
;
struct node
*labhash
[LABHS
];
register struct node
**hp
;
for (hp
= labhash
; hp
< &labhash
[LABHS
];)
for (p
= first
.forw
; p
!=0; p
= p
->forw
)
labhash
[p
->labno
% LABHS
] = p
;
for (p
= first
.forw
; p
!=0; p
= p
->forw
) {
if (p
->combop
==JBR
|| p
->op
==CBR
|| p
->op
==JSW
|| p
->op
==JMP
|| p
->op
==SOBGEQ
|| p
->op
==SOBGTR
|| p
->op
==AOBLEQ
|| p
->op
==AOBLSS
|| p
->op
==ACB
|| (p
->op
==MOVA
&& p
->labno
!=0)) {
lp
= labhash
[p
->labno
% LABHS
];
if (lp
==0 || p
->labno
!=lp
->labno
)
for (lp
= first
.forw
; lp
!=0; lp
= lp
->forw
) {
if (lp
->op
==LABEL
&& p
->labno
==lp
->labno
)
for (p
= first
.forw
; p
!=0; p
= p
->forw
)
if (p
->op
==LABEL
&& p
->refc
==0
&& (lp
= nonlab(p
))->op
&& lp
->op
!=JSW
)
register struct node
*p
, *rp
, *p1
;
for (p
= first
.forw
; p
!=0; p
= p
->forw
) {
if ((p
->op
==JBR
||p
->op
==CBR
||p
->op
==JSW
) && p
->ref
) {
if (rp
->op
==JBR
&& rp
->labno
&& p
->labno
!=rp
->labno
) {
if (p
->op
==CBR
&& (p1
= p
->forw
)->combop
==JBR
) {/* combop: RET problems */
if (p
->op
==CBR
&& (p1
= p
->forw
)->combop
==JBR
&&
p
->ref
) {/* combop: RET problems */
p
->subop
= revbr
[p
->subop
];
if (p
->op
==JBR
|| p
->op
==JMP
) {
while (p
->forw
&& p
->forw
->op
!=LABEL
&& p
->forw
->op
!=DLABEL
&& p
->forw
->op
!=EROU
&& p
->forw
->op
!=END
&& p
->forw
->op
!=0 && p
->forw
->op
!=DATA
) {
while (rp
&& rp
->op
==LABEL
) {
register struct node
*p1
;
register struct node
*p2
, *p3
;
while ((p1
= p1
->back
) && p1
->op
==LABEL
);
while ((p2
= p2
->back
) && p2
->op
==LABEL
);
if (!equop(p1
, p2
) || p1
==p2
)
register struct node
*np
;
register struct node
*lp
;
if (np
->back
->op
== LABEL
) {
lp
= alloc(sizeof first
);
register struct node
*p1
, *p2
, *p3
;
/* last clause to avoid infinite loop on partial compiler droppings:
if (p1
->op
!=JBR
|| (p2
= p1
->ref
)==0 || p2
==p1
->forw
)
if ((p2
= p2
->back
) == 0)
if (p2
->op
!=JBR
&& p2
->op
!=JMP
)
if (p3
->op
==JBR
|| p3
->op
==JMP
) {
p2
->back
->forw
= p3
->forw
;
p3
->forw
->back
= p2
->back
;
if ((p3
= p3
->forw
) == 0 || p3
==p1
|| --n
==0)
} while (p3
->op
!=CBR
|| p3
->labno
!=p1
->forw
->labno
);
if ((p1
= p1
->back
) == 0)
p3
->subop
= revbr
[p3
->subop
];
register struct node
*p1
, *p2
, *p3
;
for (p1
= first
.forw
; p1
!=0; p1
= p1
->forw
)
if (p1
->op
==JBR
&& ((p2
= p1
->ref
) && p2
->refc
> 1
|| p1
->subop
==RET
|| p1
->subop
==RSB
))
for (p3
= p1
->forw
; p3
!=0; p3
= p3
->forw
)
if (p3
->op
==JBR
&& p3
->ref
== p2
)
register struct node
*p1
, *p2
, *p3
;
while ((p1
= p1
->back
) && p1
->op
==LABEL
);
p2
->back
->forw
= p2
->forw
;
p2
->forw
->back
= p2
->back
;
p2
->combop
= JBR
; /* to handle RET */