static char sccsid
[] = "@(#)c20.c 1.1 (Berkeley) %G%";
char _sibuf
[BUFSIZ
], _sobuf
[BUFSIZ
];
{100000L,200000L,300000L,400000L,500000L,600000L,700000L,800000L,900000L,1000000L};
n
&= ~(sizeof(char *)-1);
error("Optimizer: out of space\n");
return((struct node
*)p
);
register int niter
, maxiter
, isend
;
nflag
= 0; infound
=0; argc
--; argv
++;
while (argc
>0) {/* get flags */
case 'n': nflag
++; break;
case 'd': debug
++; break;
case 'f': fortflg
++; break;
if (freopen(*argv
, "r", stdin
) ==NULL
)
error("C2: can't find %s\n", *argv
);
setbuf(stdin
,_sibuf
); ++infound
;
} else if (freopen(*argv
, "w", stdout
) ==NULL
)
error("C2: can't create %s\n", *argv
);
lasta
= lastr
= (char *)sbrk(2);
lasta
= firstr
= lastr
= (char *)alloc(0);
} while (nchange
|| jumpsw());
score("iterations", maxiter
);
score("jumps to jumps", nbrbr
);
score("inst. after jumps", iaftbr
);
score("jumps to .+1", njp1
);
score("redundant labels", nrlab
);
score("cross-jumps", nxjump
);
score("code motions", ncmot
);
score("branches reversed", nrevbr
);
score("redundant moves", redunm
);
score("simplified addresses", nsaddr
);
score("loops inverted", loopiv
);
score("redundant jumps", nredunj
);
score("common seqs before jmp's", ncomj
);
score("skips over jumps", nskip
);
score("aob's added", naob
);
score("redundant tst's", nrtst
);
score("jump on bit", nbj
);
score("redundant accumulator stores", nst
);
score("redundant accumulator loads", nld
);
score("K core", ((unsigned)lastr
+01777) >> 10);
fprintf(stderr
, "%d %s\n", n
, s
);
register struct node
*p
, *lastp
;
register struct optab
*op
; register char *cp1
;
static struct optab F77JSW
= {".long", JSW
, 1};
if (debug
&& op
==0) fprintf(stderr
,"? %s\n",line
);
if (isdigit(line
[0]) && (p
->labno
=locdef(line
)) ||
(line
[0] == 'L') && (p
->labno
=getnum(line
+1))) {
p
->op
= LABEL
; p
->subop
= 0;
if (p
->labno
<100000L && isn
<=p
->labno
) isn
=1+p
->labno
;
p
->op
= DLABEL
; p
->subop
= 0;
if (*curlp
!='L' && !locuse(curlp
)) goto std
;
if (op
->opcod
==JBR
&& (op
->subopcod
&0xF)==RET
) goto std
;
case AOBLEQ
: case AOBLSS
:
p
->op
= op
->opcod
; p
->subop
= op
->subopcod
;
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
->op
= op
->opcod
; p
->subop
= op
->subopcod
;
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;}
p
->op
= op
->opcod
; p
->subop
= op
->subopcod
;
if ((cp1
[-1]=='$') && (cp1
[0] == 'L')) {
while (*cp1
++!=','); *--cp1
=0;
p
->labno
= getnum(curlp
+2);
case MOVBLK
: /* used implicitly */
curlp
= "(r0),(r1),(r2)";
printf("%s\n",line
); goto top
;
printf("%s%c",line
,(op
->opcod
==LABEL
? ':' : '\n'));
if (op
->opcod
==TEXT
) goto top
;
if (END
==(op
=getline())->opcod
) {/* dangling .data is bad for you */
p
->op
= op
->opcod
; p
->subop
= op
->subopcod
;
lp
=curlp
; while (*lp
++); while (*--lp
!='$'); ncase
=getnum(lp
+1);
if (ALIGN
!=(getline())->opcod
|| LABEL
!=(getline())->opcod
) caserr();
if (WGEN
!=(getline())->opcod
) caserr();
p
->op
= JSW
; p
->subop
= 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
;
error("C2: improper casel instruction\n");
static struct optab OPLABEL
={"",LABEL
,0};
static struct optab OPEND
={"",END
,0};
while (EOF
!=(c
=getchar()) && isspace(c
));
while((c
=getchar()) != '\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
->opcod
==t
->op
&& p
->subopcod
==t
->subop
) {
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(".align 1\nL%d:\n",casebas
=isn
++);
printf(".word L%d-L%d\n", t
->labno
, casebas
);
register char *p
, *np
, *onp
;
onp
= np
= (char *)alloc(n
);
struct optab
*ophash
[OPHS
];
register struct optab
*optp
, **ophp
;
for(i
=RT1
+5;--i
>=0;) regs
[i
]=(char *)alloc(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,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
, *np
;
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
->op
==JBR
&& p
->subop
==0 || p
->op
==CBR
|| p
->op
==JSW
|| p
->op
==JMP
|| p
->op
==AOBLEQ
|| p
->op
==AOBLSS
|| (p
->op
==MOVA
&& p
->labno
!=0)
|| (p
->op
==MOV
&& 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
)->op
==JBR
&& p1
->subop
==0
p
->subop
= revbr
[p
->subop
];
if (p
->op
==JBR
|| p
->op
==JMP
) {
while ((p1
=p
->forw
)!=0 && p1
->op
!=LABEL
&& p1
->op
!=DLABEL
&& p1
->op
!=EROU
&& p1
->op
!=END
&& p1
->op
!=0 && p1
->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
)
p1
->op
= JBR
; p1
->subop
= 0;
register struct node
*op
;
register struct node
*lp
;
if (op
->back
->op
== LABEL
) {
lp
= alloc(sizeof first
);
lp
->op
= LABEL
; lp
->subop
= 0;
register struct node
*p1
, *p2
, *p3
;
register struct node
*t
, *tl
;
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
&0xF)==RET
))
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
->op
= JBR
; p2
->subop
= 0; /* to handle RET */