Add original unix v6
This commit is contained in:
+659
@@ -0,0 +1,659 @@
|
||||
#
|
||||
/*
|
||||
* C object code improver-- second part
|
||||
*/
|
||||
|
||||
#include "c2h.c"
|
||||
|
||||
rmove()
|
||||
{
|
||||
register struct node *p;
|
||||
register char *cp;
|
||||
register int r;
|
||||
int r1, flt;
|
||||
|
||||
for (p=first.forw; p!=0; p = p->forw) {
|
||||
if (debug) {
|
||||
for (r=0; r<2*NREG; r++)
|
||||
if (regs[r][0])
|
||||
printf("%d: %s\n", r, regs[r]);
|
||||
printf("-\n");
|
||||
}
|
||||
flt = 0;
|
||||
switch (p->op) {
|
||||
|
||||
case MOVF:
|
||||
case MOVFO:
|
||||
case MOVOF:
|
||||
flt = NREG;
|
||||
|
||||
case MOV:
|
||||
if (p->subop==BYTE)
|
||||
goto badmov;
|
||||
dualop(p);
|
||||
if ((r = findrand(regs[RT1], flt)) >= 0) {
|
||||
if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR) {
|
||||
p->forw->back = p->back;
|
||||
p->back->forw = p->forw;
|
||||
redunm++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
repladdr(p, 0, flt);
|
||||
r = isreg(regs[RT1]);
|
||||
r1 = isreg(regs[RT2]);
|
||||
dest(regs[RT2], flt);
|
||||
if (r >= 0)
|
||||
if (r1 >= 0)
|
||||
savereg(r1+flt, regs[r+flt]);
|
||||
else
|
||||
savereg(r+flt, regs[RT2]);
|
||||
else
|
||||
if (r1 >= 0)
|
||||
savereg(r1+flt, regs[RT1]);
|
||||
else
|
||||
setcon(regs[RT1], regs[RT2]);
|
||||
source(regs[RT1]);
|
||||
setcc(regs[RT2]);
|
||||
continue;
|
||||
|
||||
case ADDF:
|
||||
case SUBF:
|
||||
case DIVF:
|
||||
case MULF:
|
||||
flt = NREG;
|
||||
|
||||
case ADD:
|
||||
case SUB:
|
||||
case BIC:
|
||||
case BIS:
|
||||
case MUL:
|
||||
case DIV:
|
||||
case ASH:
|
||||
badmov:
|
||||
dualop(p);
|
||||
repladdr(p, 0, flt);
|
||||
source(regs[RT1]);
|
||||
dest(regs[RT2], flt);
|
||||
if (p->op==DIV && (r = isreg(regs[RT2])>=0))
|
||||
regs[r+1][0] = 0;
|
||||
ccloc[0] = 0;
|
||||
continue;
|
||||
|
||||
case CLRF:
|
||||
case NEGF:
|
||||
flt = NREG;
|
||||
|
||||
case CLR:
|
||||
case COM:
|
||||
case INC:
|
||||
case DEC:
|
||||
case NEG:
|
||||
case ASR:
|
||||
case ASL:
|
||||
case SXT:
|
||||
singop(p);
|
||||
dest(regs[RT1], flt);
|
||||
if (p->op==CLR && flt==0)
|
||||
if ((r = isreg(regs[RT1])) >= 0)
|
||||
savereg(r, "$0");
|
||||
else
|
||||
setcon("$0", regs[RT1]);
|
||||
setcc(regs[RT1]);
|
||||
continue;
|
||||
|
||||
case TSTF:
|
||||
flt = NREG;
|
||||
|
||||
case TST:
|
||||
singop(p);
|
||||
repladdr(p, 0, flt);
|
||||
source(regs[RT1]);
|
||||
if (equstr(regs[RT1], ccloc)) {
|
||||
p->back->forw = p->forw;
|
||||
p->forw->back = p->back;
|
||||
p = p->back;
|
||||
nrtst++;
|
||||
nchange++;
|
||||
}
|
||||
continue;
|
||||
|
||||
case CMPF:
|
||||
flt = NREG;
|
||||
|
||||
case CMP:
|
||||
case BIT:
|
||||
dualop(p);
|
||||
source(regs[RT1]);
|
||||
source(regs[RT2]);
|
||||
repladdr(p, 1, flt);
|
||||
ccloc[0] = 0;
|
||||
continue;
|
||||
|
||||
case CBR:
|
||||
case CFCC:
|
||||
ccloc[0] = 0;
|
||||
continue;
|
||||
|
||||
case JBR:
|
||||
redunbr(p);
|
||||
|
||||
default:
|
||||
clearreg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jumpsw()
|
||||
{
|
||||
register struct node *p, *p1;
|
||||
register t;
|
||||
int nj;
|
||||
|
||||
t = 0;
|
||||
nj = 0;
|
||||
for (p=first.forw; p!=0; p = p->forw)
|
||||
p->refc = ++t;
|
||||
for (p=first.forw; p!=0; p = p1) {
|
||||
p1 = p->forw;
|
||||
if (p->op == CBR && p1->op==JBR && p->ref && p1->ref
|
||||
&& abs(p->refc - p->ref->refc) > abs(p1->refc - p1->ref->refc)) {
|
||||
p->subop = revbr[p->subop];
|
||||
t = p1->ref;
|
||||
p1->ref = p->ref;
|
||||
p->ref = t;
|
||||
t = p1->labno;
|
||||
p1->labno = p->labno;
|
||||
p->labno = t;
|
||||
nrevbr++;
|
||||
nj++;
|
||||
}
|
||||
}
|
||||
return(nj);
|
||||
}
|
||||
|
||||
addsob()
|
||||
{
|
||||
register struct node *p, *p1;
|
||||
|
||||
for (p = &first; (p1 = p->forw)!=0; p = p1) {
|
||||
if (p->op==DEC && isreg(p->code)>=0
|
||||
&& p1->combop==(CBR|JNE<<8)) {
|
||||
if (p->refc < p1->ref->refc)
|
||||
continue;
|
||||
if (p->refc - p1->ref->refc > 50)
|
||||
continue;
|
||||
p->labno = p1->labno;
|
||||
p->combop = SOB;
|
||||
p1->forw->back = p;
|
||||
p->forw = p1->forw;
|
||||
nsob++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abs(x)
|
||||
{
|
||||
return(x<0? -x: x);
|
||||
}
|
||||
|
||||
equop(ap1, p2)
|
||||
struct node *ap1, *p2;
|
||||
{
|
||||
register char *cp1, *cp2;
|
||||
register struct node *p1;
|
||||
|
||||
p1 = ap1;
|
||||
if (p1->combop != p2->combop)
|
||||
return(0);
|
||||
if (p1->op>0 && p1->op<MOV)
|
||||
return(0);
|
||||
cp1 = p1->code;
|
||||
cp2 = p2->code;
|
||||
if (cp1==0 && cp2==0)
|
||||
return(1);
|
||||
if (cp1==0 || cp2==0)
|
||||
return(0);
|
||||
while (*cp1 == *cp2++)
|
||||
if (*cp1++ == 0)
|
||||
return(1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
decref(ap)
|
||||
{
|
||||
register struct node *p;
|
||||
|
||||
p = ap;
|
||||
if (--p->refc <= 0) {
|
||||
nrlab++;
|
||||
p->back->forw = p->forw;
|
||||
p->forw->back = p->back;
|
||||
}
|
||||
}
|
||||
|
||||
nonlab(ap)
|
||||
struct node *ap;
|
||||
{
|
||||
register struct node *p;
|
||||
|
||||
p = ap;
|
||||
while (p && p->op==LABEL)
|
||||
p = p->forw;
|
||||
return(p);
|
||||
}
|
||||
|
||||
alloc(an)
|
||||
{
|
||||
register int n;
|
||||
register char *p;
|
||||
|
||||
n = an;
|
||||
n++;
|
||||
n =& ~01;
|
||||
if (lasta+n >= lastr) {
|
||||
if (sbrk(2000) == -1) {
|
||||
write(2, "Optimizer: out of space\n", 14);
|
||||
exit(1);
|
||||
}
|
||||
lastr =+ 2000;
|
||||
}
|
||||
p = lasta;
|
||||
lasta =+ n;
|
||||
return(p);
|
||||
}
|
||||
|
||||
clearreg()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i=0; i<2*NREG; i++)
|
||||
regs[i][0] = '\0';
|
||||
conloc[0] = 0;
|
||||
ccloc[0] = 0;
|
||||
}
|
||||
|
||||
savereg(ai, as)
|
||||
char *as;
|
||||
{
|
||||
register char *p, *s, *sp;
|
||||
|
||||
sp = p = regs[ai];
|
||||
s = as;
|
||||
if (source(s))
|
||||
return;
|
||||
while (*p++ = *s) {
|
||||
if (s[0]=='(' && s[1]=='r' && s[2]<'5') {
|
||||
*sp = 0;
|
||||
return;
|
||||
}
|
||||
if (*s++ == ',')
|
||||
break;
|
||||
}
|
||||
*--p = '\0';
|
||||
}
|
||||
|
||||
dest(as, flt)
|
||||
char *as;
|
||||
{
|
||||
register char *s;
|
||||
register int i;
|
||||
|
||||
s = as;
|
||||
if ((i = isreg(s)) >= 0)
|
||||
regs[i+flt][0] = 0;
|
||||
while ((i = findrand(s, flt)) >= 0)
|
||||
regs[i][0] = 0;
|
||||
while (*s) {
|
||||
if ((*s=='(' && (*(s+1)!='r' || *(s+2)!='5')) || *s++=='*') {
|
||||
for (i=flt; i<flt+NREG; i++) {
|
||||
if (regs[i][0] != '$')
|
||||
regs[i][0] = 0;
|
||||
conloc[0] = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
singop(ap)
|
||||
struct node *ap;
|
||||
{
|
||||
register char *p1, *p2;
|
||||
|
||||
p1 = ap->code;
|
||||
p2 = regs[RT1];
|
||||
while (*p2++ = *p1++);
|
||||
regs[RT2][0] = 0;
|
||||
}
|
||||
|
||||
|
||||
dualop(ap)
|
||||
struct node *ap;
|
||||
{
|
||||
register char *p1, *p2;
|
||||
register struct node *p;
|
||||
|
||||
p = ap;
|
||||
p1 = p->code;
|
||||
p2 = regs[RT1];
|
||||
while (*p1 && *p1!=',')
|
||||
*p2++ = *p1++;
|
||||
*p2++ = 0;
|
||||
p2 = regs[RT2];
|
||||
*p2 = 0;
|
||||
if (*p1++ !=',')
|
||||
return;
|
||||
while (*p2++ = *p1++);
|
||||
}
|
||||
|
||||
findrand(as, flt)
|
||||
char *as;
|
||||
{
|
||||
register int i;
|
||||
for (i = flt; i<NREG+flt; i++) {
|
||||
if (equstr(regs[i], as))
|
||||
return(i);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
isreg(as)
|
||||
char *as;
|
||||
{
|
||||
register char *s;
|
||||
|
||||
s = as;
|
||||
if (s[0]=='r' && s[1]>='0' && s[1]<='4' && s[2]==0)
|
||||
return(s[1]-'0');
|
||||
return(-1);
|
||||
}
|
||||
|
||||
check()
|
||||
{
|
||||
register struct node *p, *lp;
|
||||
|
||||
lp = &first;
|
||||
for (p=first.forw; p!=0; p = p->forw) {
|
||||
if (p->back != lp)
|
||||
abort();
|
||||
lp = p;
|
||||
}
|
||||
}
|
||||
|
||||
source(ap)
|
||||
char *ap;
|
||||
{
|
||||
register char *p1, *p2;
|
||||
|
||||
p1 = ap;
|
||||
p2 = p1;
|
||||
if (*p1==0)
|
||||
return(0);
|
||||
while (*p2++);
|
||||
if (*p1=='-' && *(p1+1)=='('
|
||||
|| *p1=='*' && *(p1+1)=='-' && *(p1+2)=='('
|
||||
|| *(p2-2)=='+') {
|
||||
while (*p1 && *p1++!='r');
|
||||
if (*p1>='0' && *p1<='4')
|
||||
regs[*p1 - '0'][0] = 0;
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
repladdr(p, f, flt)
|
||||
struct node *p;
|
||||
{
|
||||
register r;
|
||||
int r1;
|
||||
register char *p1, *p2;
|
||||
static char rt1[50], rt2[50];
|
||||
|
||||
if (f)
|
||||
r1 = findrand(regs[RT2], flt);
|
||||
else
|
||||
r1 = -1;
|
||||
r = findrand(regs[RT1], flt);
|
||||
if (r1 >= NREG)
|
||||
r1 =- NREG;
|
||||
if (r >= NREG)
|
||||
r =- NREG;
|
||||
if (r>=0 || r1>=0) {
|
||||
p2 = regs[RT1];
|
||||
for (p1 = rt1; *p1++ = *p2++;);
|
||||
if (regs[RT2][0]) {
|
||||
p1 = rt2;
|
||||
*p1++ = ',';
|
||||
for (p2 = regs[RT2]; *p1++ = *p2++;);
|
||||
} else
|
||||
rt2[0] = 0;
|
||||
if (r>=0) {
|
||||
rt1[0] = 'r';
|
||||
rt1[1] = r + '0';
|
||||
rt1[2] = 0;
|
||||
nsaddr++;
|
||||
}
|
||||
if (r1>=0) {
|
||||
rt2[1] = 'r';
|
||||
rt2[2] = r1 + '0';
|
||||
rt2[3] = 0;
|
||||
nsaddr++;
|
||||
}
|
||||
p->code = copy(rt1, rt2);
|
||||
}
|
||||
}
|
||||
|
||||
movedat()
|
||||
{
|
||||
register struct node *p1, *p2;
|
||||
struct node *p3;
|
||||
register seg;
|
||||
struct node data;
|
||||
struct node *datp;
|
||||
|
||||
if (first.forw == 0)
|
||||
return;
|
||||
datp = &data;
|
||||
for (p1 = first.forw; p1!=0; p1 = p1->forw) {
|
||||
if (p1->op == DATA) {
|
||||
p2 = p1->forw;
|
||||
while (p2 && p2->op!=TEXT)
|
||||
p2 = p2->forw;
|
||||
if (p2==0)
|
||||
break;
|
||||
p3 = p1->back;
|
||||
p1->back->forw = p2->forw;
|
||||
p2->forw->back = p3;
|
||||
p2->forw = 0;
|
||||
datp->forw = p1;
|
||||
p1->back = datp;
|
||||
p1 = p3;
|
||||
datp = p2;
|
||||
}
|
||||
}
|
||||
if (data.forw) {
|
||||
datp->forw = first.forw;
|
||||
first.forw->back = datp;
|
||||
data.forw->back = &first;
|
||||
first.forw = data.forw;
|
||||
}
|
||||
seg = -1;
|
||||
for (p1 = first.forw; p1!=0; p1 = p1->forw) {
|
||||
if (p1->op==TEXT||p1->op==DATA||p1->op==BSS) {
|
||||
if (p1->op == seg || p1->forw&&p1->forw->op==seg) {
|
||||
p1->back->forw = p1->forw;
|
||||
p1->forw->back = p1->back;
|
||||
p1 = p1->back;
|
||||
continue;
|
||||
}
|
||||
seg = p1->op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
redunbr(ap)
|
||||
struct node *ap;
|
||||
{
|
||||
register struct node *p, *p1;
|
||||
register char *ap1;
|
||||
char *ap2;
|
||||
|
||||
if ((p1 = p->ref) == 0)
|
||||
return;
|
||||
p1 = nonlab(p1);
|
||||
if (p1->op==TST) {
|
||||
singop(p1);
|
||||
savereg(RT2, "$0");
|
||||
} else if (p1->op==CMP)
|
||||
dualop(p1);
|
||||
else
|
||||
return;
|
||||
if (p1->forw->op!=CBR)
|
||||
return;
|
||||
ap1 = findcon(RT1);
|
||||
ap2 = findcon(RT2);
|
||||
p1 = p1->forw;
|
||||
if (compare(p1->subop, ap1, ap2)) {
|
||||
nredunj++;
|
||||
nchange++;
|
||||
decref(p->ref);
|
||||
p->ref = p1->ref;
|
||||
p->labno = p1->labno;
|
||||
p->ref->refc++;
|
||||
}
|
||||
}
|
||||
|
||||
findcon(i)
|
||||
{
|
||||
register char *p;
|
||||
register r;
|
||||
|
||||
p = regs[i];
|
||||
if (*p=='$')
|
||||
return(p);
|
||||
if ((r = isreg(p)) >= 0)
|
||||
return(regs[r]);
|
||||
if (equstr(p, conloc))
|
||||
return(conval);
|
||||
return(p);
|
||||
}
|
||||
|
||||
compare(op, acp1, acp2)
|
||||
char *acp1, *acp2;
|
||||
{
|
||||
register char *cp1, *cp2;
|
||||
register n1;
|
||||
int n2;
|
||||
struct { int i;};
|
||||
|
||||
cp1 = acp1;
|
||||
cp2 = acp2;
|
||||
if (*cp1++ != '$' || *cp2++ != '$')
|
||||
return(0);
|
||||
n1 = 0;
|
||||
while (*cp2 >= '0' && *cp2 <= '7') {
|
||||
n1 =<< 3;
|
||||
n1 =+ *cp2++ - '0';
|
||||
}
|
||||
n2 = n1;
|
||||
n1 = 0;
|
||||
while (*cp1 >= '0' && *cp1 <= '7') {
|
||||
n1 =<< 3;
|
||||
n1 =+ *cp1++ - '0';
|
||||
}
|
||||
if (*cp1=='+')
|
||||
cp1++;
|
||||
if (*cp2=='+')
|
||||
cp2++;
|
||||
do {
|
||||
if (*cp1++ != *cp2)
|
||||
return(0);
|
||||
} while (*cp2++);
|
||||
cp1 = n1;
|
||||
cp2 = n2;
|
||||
switch(op) {
|
||||
|
||||
case JEQ:
|
||||
return(cp1 == cp2);
|
||||
case JNE:
|
||||
return(cp1 != cp2);
|
||||
case JLE:
|
||||
return(cp1.i <= cp2.i);
|
||||
case JGE:
|
||||
return(cp1.i >= cp2.i);
|
||||
case JLT:
|
||||
return(cp1.i < cp2.i);
|
||||
case JGT:
|
||||
return(cp1.i > cp2.i);
|
||||
case JLO:
|
||||
return(cp1 < cp2);
|
||||
case JHI:
|
||||
return(cp1 > cp2);
|
||||
case JLOS:
|
||||
return(cp1 <= cp2);
|
||||
case JHIS:
|
||||
return(cp1 >= cp2);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
setcon(ar1, ar2)
|
||||
char *ar1, *ar2;
|
||||
{
|
||||
register char *cl, *cv, *p;
|
||||
|
||||
cl = ar2;
|
||||
cv = ar1;
|
||||
if (*cv != '$')
|
||||
return;
|
||||
if (!natural(cl))
|
||||
return;
|
||||
p = conloc;
|
||||
while (*p++ = *cl++);
|
||||
p = conval;
|
||||
while (*p++ = *cv++);
|
||||
}
|
||||
|
||||
equstr(ap1, ap2)
|
||||
char *ap1, *ap2;
|
||||
{
|
||||
char *p1, *p2;
|
||||
|
||||
p1 = ap1;
|
||||
p2 = ap2;
|
||||
do {
|
||||
if (*p1++ != *p2)
|
||||
return(0);
|
||||
} while (*p2++);
|
||||
return(1);
|
||||
}
|
||||
|
||||
setcc(ap)
|
||||
char *ap;
|
||||
{
|
||||
register char *p, *p1;
|
||||
|
||||
p = ap;
|
||||
if (!natural(p)) {
|
||||
ccloc[0] = 0;
|
||||
return;
|
||||
}
|
||||
p1 = ccloc;
|
||||
while (*p1++ = *p++);
|
||||
}
|
||||
|
||||
natural(ap)
|
||||
char *ap;
|
||||
{
|
||||
register char *p;
|
||||
|
||||
p = ap;
|
||||
if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(')
|
||||
return(0);
|
||||
while (*p++);
|
||||
p--;
|
||||
if (*--p == '+' || *p ==')' && *--p != '5')
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
Reference in New Issue
Block a user