1430 lines
23 KiB
C
1430 lines
23 KiB
C
/*
|
|
* C object code improver-- second part
|
|
*/
|
|
|
|
#include "c2.h"
|
|
#define NIL (char *)0
|
|
|
|
unsigned hexa ();
|
|
rmove()
|
|
{
|
|
register struct node *p;
|
|
register char *p1, *p2p;
|
|
static char p2[100];
|
|
register int r;
|
|
register r1, i;
|
|
|
|
if(debug > 1)
|
|
printf("rmove works\n");
|
|
for (p=first.forw; p!=0; p = p->forw) {
|
|
|
|
if(debug > 2){
|
|
printf("rmove works on:");
|
|
dbprint(p);
|
|
}
|
|
switch (p->op) {
|
|
|
|
case LD:
|
|
case LDK:
|
|
dualop(p);
|
|
if(equstr(regs[RT1],regs[RT2])) {
|
|
if(debug > 2)
|
|
puts("elim 1");
|
|
elim(p);
|
|
++redunm;
|
|
break;
|
|
}
|
|
ld1:
|
|
if (( r = findrand(regs[RT2],regt[RT2])) >= 0 && regt[r]==regt[RT2])
|
|
if( r == isreg(regs[RT1]) && regt[r]==regt[RT1]) {
|
|
elim(p);
|
|
if(debug > 2)
|
|
puts("elim 2");
|
|
++redunm;
|
|
break;
|
|
}
|
|
|
|
if((r = findrand(regs[RT1],regt[RT1])) >= 0 && regt[r]==regt[RT1])
|
|
if(r==isreg(regs[RT2]) && regt[r]==regt[RT2]) {
|
|
if(debug > 2)
|
|
puts("elim 3");
|
|
elim(p);
|
|
++redunm;
|
|
break;
|
|
}
|
|
|
|
clr:
|
|
if((r=isreg(regs[RT1]))>=0 && regp[r]!=0 && regt[r]==regt[RT1]){
|
|
if(debug > 2)
|
|
puts("elim 4");
|
|
if(!teil(regs[RT1],regs[RT2]))
|
|
elim(regp[r]);
|
|
clrr(r,regt[RT1]);
|
|
if(isreg(ccloc)==(r))
|
|
clrcc();
|
|
}
|
|
|
|
if ((p->op==CLR||equstr(regs[RT2],"#0")) && p->subop != LONG
|
|
&& isreg(regs[RT1])>=0) {
|
|
p->op = XOR;
|
|
regs[RT2][0] = ',';
|
|
i = 0;
|
|
do
|
|
regs[RT2][i+1] = regs[RT1][i];
|
|
while(regs[RT1][i++]);
|
|
p->code = copy(2,regs[RT1],regs[RT2]);
|
|
nchange++;
|
|
break;
|
|
}
|
|
|
|
if(p->op==LD && p->subop==LONG && r >= 2 && r < 7 &&
|
|
p->forw && (p->forw->op==ADD || p->forw->op==INC)
|
|
&& p->forw->subop==0 &&
|
|
p->forw->forw && p->forw->forw->op==LD) {
|
|
/* ldl rri,FP; add r(i+1),#ddd; ldx r(x)i,@rri */
|
|
/* ldl rri,FP; inc r(i+1),#ddd; ldx r(x)i,@rri */
|
|
i = isreg(regs[RT2]);
|
|
if(i>=0 && i<=14 && regc=='r') {
|
|
dualop(p->forw);
|
|
r1 = isreg(regs[RT1]);
|
|
if(r1 == (r+1) && regs[RT2][0] == '#') {
|
|
p2p = p2;
|
|
*p2p++ = ',';
|
|
if(i==12)
|
|
p1 = "FP(";
|
|
else if(i==14)
|
|
p1 = "SP(";
|
|
else if(i==10)
|
|
p1 = "rr10(";
|
|
else
|
|
p1 = "rrx(";
|
|
while(*p2p++ = *p1++);
|
|
if(i < 10)
|
|
*(p2p-3) = i + '0';
|
|
p2p--;
|
|
p1 = regs[RT2];
|
|
while(*p2p++ = *p1++);
|
|
*(p2p-1) = ')';
|
|
*p2p = 0;
|
|
dualop(p->forw->forw);
|
|
r1 = isreg(regs[RT1]);
|
|
if(r1==r || r1 == (r+1)){
|
|
elim(p);
|
|
elim(p->forw);
|
|
p = p->forw->forw;
|
|
p->code = copy(2,regs[RT1],p2);
|
|
if(debug>2) {
|
|
printf("neu erzeugt: ");
|
|
dbprint(p);
|
|
}
|
|
nchange++;
|
|
p = p->back;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
dualop(p);
|
|
if(p->op != LDK) {
|
|
repladdr(p, 0);
|
|
dualop(p);
|
|
}
|
|
mfldil:
|
|
r = isreg(ccloc);
|
|
r1 = isreg(regs[RT1]);
|
|
if(r<0 && r1<0 || r==r1 && ccloct==regt[RT1] ||
|
|
ccloct=='r' && r==(r1 & ~01) ||
|
|
regt[RT1]=='r' && r1==(r & ~01))
|
|
clrcc();
|
|
r = isreg(regs[RT2]);
|
|
dest(regs[RT1],regt[RT1]);
|
|
if(r1 < 0)
|
|
source(regs[RT1],regt[RT1]);
|
|
source(regs[RT2], regt[RT2]);
|
|
if (r >= 0)
|
|
if (r1 >= 0)
|
|
if(r1 < r)
|
|
savereg(r1,regs[RT2],regt[RT2],p);
|
|
else
|
|
savereg(r1, regs[r],regt[r], p);
|
|
else { if(regs[r][0]==0)
|
|
savereg(r, regs[RT1],regt[RT1], NIL);
|
|
else
|
|
savereg(r+NREG, regs[RT1],regt[RT1], NIL);
|
|
}
|
|
else
|
|
if (r1 >= 0)
|
|
savereg(r1, regs[RT2], regt[RT2], p);
|
|
else
|
|
setcon(regs[RT2], regs[RT1], regt[RT1]);
|
|
break;
|
|
|
|
case INC:
|
|
case DEC:
|
|
case SET:
|
|
case RES:
|
|
case SRL:
|
|
case SLL:
|
|
case ASR:
|
|
case ASL:
|
|
dualop(p);
|
|
if(p->op==INC && equstr(regs[RT1],"SP") && p->forw
|
|
&& p->forw->op==PUSH && regs[RT2][0]=='#') {
|
|
dualop(p->forw);
|
|
if(regs[RT2][0]!='r' && regs[RT2][0]!='#')
|
|
goto ende;
|
|
dualop(p);
|
|
if(regs[RT2][1]=='%')
|
|
r1 = hexa(&(regs[RT2][2]));
|
|
else
|
|
r1 = hexa(&(regs[RT2][1]));
|
|
if(p->forw->subop==LONG && r1>3)
|
|
r1 -= 4;
|
|
else if(r1>1 && p->forw->subop != LONG)
|
|
r1 -= 2;
|
|
else goto ende;
|
|
if(!r1){
|
|
if(debug > 2)
|
|
puts("elim 5");
|
|
elim(p);
|
|
}else
|
|
sprintf(regs[RT2],",#%%%x",r1);
|
|
p->forw->op = LD;
|
|
p->code = copy(2,regs[RT1],regs[RT2]);
|
|
redunm++;
|
|
break;
|
|
}
|
|
ende:
|
|
dualop(p);
|
|
dest(regs[RT1],regt[RT1]);
|
|
source(regs[RT2], regt[RT2]);
|
|
source(regs[RT1], regt[RT1]);
|
|
if(p->op==SET||p->op==RES||p->op==PUSH||p->op==POP)
|
|
clrcc();
|
|
else
|
|
setcc(regs[RT1],regt[RT1]);
|
|
break;
|
|
|
|
case ADD:
|
|
case SUB:
|
|
case OR:
|
|
case XOR:
|
|
case MUL:
|
|
case DIV:
|
|
case SDA:
|
|
case SDL:
|
|
case PUSH:
|
|
case POP:
|
|
dble:
|
|
dualop(p);
|
|
if(p->op==POP && (r=isreg(regs[RT1]))>=0 && regp[r]!=0) {
|
|
if(regt[r]==regt[RT1]) {
|
|
if(debug > 2)
|
|
puts("elim 6");
|
|
elim(regp[r]);
|
|
clrr(r,regt[RT1]);
|
|
if(isreg(ccloc)==r)
|
|
clrcc();
|
|
}
|
|
}
|
|
if(p->op==OR && regs[RT2][0]=='#' && p->subop==0) {
|
|
p1 = regs[RT2] + 1;
|
|
if(*p1 == '%')
|
|
++p1;
|
|
if((i = ispow2a(hexa(p1)))>=0) {
|
|
p->op = SET;
|
|
setadr(p,i);
|
|
clrcc();
|
|
++nchange;
|
|
break;
|
|
}
|
|
}
|
|
if(p->op==XOR &&(r=isreg(regs[RT1]))>=0 &&
|
|
equstr(regs[RT1],regs[RT2])) {
|
|
if(regp[r] && regt[r]==regt[RT1]) {
|
|
if(debug > 2)
|
|
puts("elim 7");
|
|
elim(regp[r]);
|
|
clrr(r,regt[RT1]);
|
|
if(isreg(ccloc)==r)
|
|
clrcc();
|
|
}
|
|
if(regt[r]==regt[RT1] &&
|
|
(regt[r]!='h' && equstr(regs[r],"#0") ||
|
|
regt[r]=='h' && equstr(regh[r],"#0"))
|
|
||regt[r]=='l'&®t[RT1]=='h'&&equstr(regh[r],"#0")
|
|
||regt[r]=='h'&®t[RT1]=='l'&&equstr(regs[r],"#0")){
|
|
if(debug > 2)
|
|
puts("elim 8");
|
|
elim(p);
|
|
++redunm;
|
|
break;
|
|
} else if(regt[RT1]=='h') {
|
|
if(regt[r]!='l')
|
|
clrr(r,'h');
|
|
regh[r][0] = '#';
|
|
regh[r][1] = '0';
|
|
regh[r][2] = 0;
|
|
regp[r] = p;
|
|
} else {
|
|
savereg(r,"#0",regt[RT1], p);
|
|
}
|
|
} else {
|
|
repladdr(p, 0);
|
|
dualop(p);
|
|
dest(regs[RT1],regt[RT1]);
|
|
source(regs[RT2], regt[RT2]);
|
|
source(regs[RT1], regt[RT1]);
|
|
}
|
|
setcc(regs[RT1],regt[RT1]);
|
|
break;
|
|
|
|
case NEG:
|
|
case CLR:
|
|
case COM:
|
|
case SXT:
|
|
singop(p);
|
|
if (p->op==CLR)
|
|
if ((r = isreg(regs[RT1])) >= 0)
|
|
goto clr;
|
|
else
|
|
setcon("#0", regs[RT1], regt[RT1]);
|
|
dest(regs[RT1],regt[RT1]);
|
|
source(regs[RT1],regt[RT1]);
|
|
if(p->op!=CLR && p->op!=SXT)
|
|
setcc(regs[RT1], regt[RT1]);
|
|
break;
|
|
|
|
case TST:
|
|
singop(p);
|
|
tst:
|
|
repladdr(p, 1);
|
|
singop(p);
|
|
if ((ccloct==regt[RT1] && equstr(regs[RT1],ccloc)) ||
|
|
p->forw && p->forw->op > CBR) {
|
|
if(debug > 2)
|
|
puts("elim 9");
|
|
elim(p);
|
|
nrtst++;
|
|
}
|
|
else
|
|
setcc(regs[RT1], regt[RT1]);
|
|
source(regs[RT1], regt[RT1]);
|
|
break;
|
|
|
|
case CMP:
|
|
if(p->forw->op==CBR && (r = p->forw->subop) < JLO) {
|
|
dualop(p);
|
|
if(equstr(regs[RT2],"#0")) {
|
|
if(r == JLT)
|
|
p->forw->subop = MI;
|
|
if(r == JGE)
|
|
p->forw->subop = PL;
|
|
if(p->forw->subop < JLE) {
|
|
p->op = TST;
|
|
regs[RT2][0] = 0;
|
|
p->code = copy(1,regs[RT1]);
|
|
goto tst;
|
|
}
|
|
}
|
|
}
|
|
|
|
case BIT:
|
|
if(p->forw->op > CBR) {
|
|
if(debug > 2)
|
|
puts("elim 10");
|
|
elim(p);
|
|
break;
|
|
}
|
|
|
|
case AND:
|
|
dualop(p);
|
|
if(p->op==AND && regs[RT2][0]=='#' && p->subop==0) {
|
|
p1 = regs[RT2] + 1;
|
|
if(*p1 == '%')
|
|
++p1;
|
|
if ((i = ispow2a(~hexa(p1)))>=0) {
|
|
p->op = RES;
|
|
setadr(p,i);
|
|
clrcc();
|
|
++nchange;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(p->op==AND) {
|
|
if(equstr(regs[RT2],"#%ffff")||equstr(regs[RT2],"#-%1")){
|
|
p->op = TST;
|
|
regs[RT2][0] = 0;
|
|
regt[RT2] = 0;
|
|
p->code = copy(1, regs[RT1]);
|
|
nchange++;
|
|
nsaddr++;
|
|
goto tst;
|
|
} else
|
|
if(equstr(regs[RT2],"#%0")) {
|
|
p->op = CLR;
|
|
regs[RT2][0] = 0;
|
|
regt[RT2] = 0;
|
|
p->code = copy(1, regs[RT1]);
|
|
nchange++;
|
|
nsaddr++;
|
|
goto clr;
|
|
}
|
|
dest(regs[RT1],regt[RT1]);
|
|
}
|
|
if(p->op!=BIT &&(p->op!=CMP || regs[RT2][0]!='#')) {
|
|
repladdr(p, 1);
|
|
dualop(p);
|
|
}
|
|
if(p->op!=AND)
|
|
clrcc();
|
|
else
|
|
setcc(regs[RT1], regt[RT1]);
|
|
source(regs[RT1], regt[RT1]);
|
|
source(regs[RT2], regt[RT2]);
|
|
break;
|
|
|
|
case CBR:
|
|
|
|
if (p->back->op==TST || p->back->op==CMP) {
|
|
if (p->back->op==TST) {
|
|
singop(p->back);
|
|
savereg(RT2, "#0", regt[RT1], p->back);
|
|
} else
|
|
dualop(p->back);
|
|
r = compare(p->subop, findcon(RT1), findcon(RT2));
|
|
if (r==0) {
|
|
if(p->forw->op == CBR ) {
|
|
if(debug > 2)
|
|
puts("elim 11");
|
|
elim(p);
|
|
clrcc();
|
|
} else {
|
|
p->back->back->forw = p->forw;
|
|
p->forw->back = p->back->back;
|
|
clrcc();
|
|
}
|
|
decref(p->ref);
|
|
p = p->back->back;
|
|
nchange++;
|
|
} else if (r>0) {
|
|
p->op += 2;
|
|
p->subop = 0;
|
|
p->back->back->forw = p;
|
|
p->back = p->back->back;
|
|
p = p->back;
|
|
nchange++;
|
|
}
|
|
}
|
|
|
|
case JMP:
|
|
redunbr(p);
|
|
clrp();
|
|
break;
|
|
|
|
case END:
|
|
case EROU:
|
|
case CALL:
|
|
for(r = 0; r<8; ++r)
|
|
if (regp[r]!=0 && regs[r][0]=='r') {
|
|
if(debug > 2)
|
|
puts("elim 12");
|
|
elim(regp[r]);
|
|
if(isreg(ccloc)==r)
|
|
clrcc();
|
|
}
|
|
|
|
default:
|
|
clearreg();
|
|
}
|
|
}
|
|
}
|
|
|
|
jumpsw()
|
|
{
|
|
register struct node *p, *p1;
|
|
register t;
|
|
register struct node *tp;
|
|
register 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) {
|
|
if(debug > 2){
|
|
printf("jumpsw works on:");
|
|
dbprint(p);
|
|
}
|
|
p1 = p->forw;
|
|
if ((p->op == CBR || p1->op == JMP) && p->ref && p1->ref
|
|
&& Abs(p->refc - p->ref->refc) > Abs(p1->refc - p1->ref->refc)) {
|
|
if (p->ref==p1->ref ||p->labno==0 || p1->labno==0)
|
|
continue;
|
|
p->subop = revbr[p->subop];
|
|
tp = p1->ref;
|
|
p1->ref = p->ref;
|
|
p->ref = tp;
|
|
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(debug > 2){
|
|
printf("addsob works on:");
|
|
dbprint(p);
|
|
}
|
|
switch(p->op) {
|
|
case CLR:
|
|
case AND:
|
|
case OR:
|
|
case BIT:
|
|
case RES:
|
|
case SET:
|
|
case CMP:
|
|
case TST:
|
|
case LD:
|
|
case LDK:
|
|
p1 = nonlab(p->forw);
|
|
if(p1 && p1->op==p->op
|
|
&& equstr(p->code,p1->code)){
|
|
if(debug > 2)
|
|
puts("elim 13");
|
|
elim(p);
|
|
p = p->back;
|
|
if(!(p1 = p->forw))
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(p1 && p1->op == TST) {
|
|
switch(p->op) {
|
|
case CLR:
|
|
if(p1->forw && p1->forw->op == CBR
|
|
&& equstr(p->code,p1->code))
|
|
switch (p1->subop) {
|
|
case JNE:
|
|
case JGT:
|
|
case JHI:
|
|
if(debug > 2)
|
|
puts("elim 14");
|
|
elim(p1->forw);
|
|
elim(p1);
|
|
if(!(p1=p->forw))
|
|
return;
|
|
case JEQ:
|
|
case JLOS:
|
|
case JLE:
|
|
p=p1->forw;
|
|
if(debug > 2)
|
|
puts("elim 15");
|
|
elim(p1);
|
|
p->op += 2;
|
|
p->subop=0;
|
|
if(!p)
|
|
return;
|
|
}
|
|
else break;
|
|
|
|
case COM:
|
|
case INC:
|
|
case DEC:
|
|
case NEG:
|
|
if(equstr(p->code,p1->code)) {
|
|
if(debug > 2)
|
|
puts("elim 16");
|
|
elim(p1);
|
|
nrtst++;
|
|
if((p1 = p1->forw) == 0)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (p->op==TST && p1->op > CBR) {
|
|
if(debug > 2)
|
|
puts("elim 17");
|
|
elim(p);
|
|
nrtst++;
|
|
continue;
|
|
}
|
|
|
|
if (p->op==DEC && isreg(p->code)>=0
|
|
&& p1->op==CBR && p1->subop==JNE) {
|
|
if (p->refc < p1->ref->refc)
|
|
continue;
|
|
if (toofar(p1))
|
|
continue;
|
|
dualop(p);
|
|
p->code = copy(1,regs[RT1]);
|
|
p->labno = p1->labno;
|
|
p->op = DJNZ;
|
|
p->subop = 0;
|
|
p1->forw->back = p;
|
|
p->forw = p1->forw;
|
|
nsob++;
|
|
}
|
|
}
|
|
}
|
|
|
|
toofar(ap)
|
|
struct node *ap;
|
|
{
|
|
register struct node *p, *p1;
|
|
register len;
|
|
|
|
p = ap;
|
|
for(p1 = first.forw; p1 != p ; p1 = p1->forw)
|
|
if (p1 == p->ref)
|
|
break;
|
|
|
|
if(p1 == p->ref) {
|
|
p = p1;
|
|
p1 = ap;
|
|
} else
|
|
p1 = p->ref;
|
|
len = 0;
|
|
for (p = p->forw; p && p!=p1; p = p->forw)
|
|
len += ilen(p);
|
|
if (len < 256)
|
|
return(0);
|
|
return(1);
|
|
}
|
|
|
|
ilen(p)
|
|
register struct node *p;
|
|
{
|
|
if (p->op == 0)
|
|
return(0);
|
|
|
|
switch (p->op) {
|
|
case LABEL:
|
|
case DLABEL:
|
|
case CP:
|
|
case EROU:
|
|
case EVEN:
|
|
case CODE:
|
|
case BSS:
|
|
case CD:
|
|
case CMT:
|
|
return(0);
|
|
|
|
|
|
case SRL:
|
|
case SLL:
|
|
case ASR:
|
|
case ASL:
|
|
case SDA:
|
|
case LDI:
|
|
case LDD:
|
|
return(4);
|
|
|
|
case LDK:
|
|
case DJNZ:
|
|
return(2);
|
|
|
|
default:
|
|
dualop(p);
|
|
switch(p->op) {
|
|
case BIT:
|
|
case RES:
|
|
case SET:
|
|
case INC:
|
|
case DEC:
|
|
return(2 + adrlen(regs[RT1]));
|
|
|
|
case LD:
|
|
case CMP:
|
|
case ADD:
|
|
case SUB:
|
|
case MUL:
|
|
case DIV:
|
|
if(p->subop==LONG && regs[RT2][0]=='#')
|
|
return(6);
|
|
|
|
default:
|
|
return(2 + adrlen(regs[RT1]) + adrlen(regs[RT2]));
|
|
}
|
|
}
|
|
}
|
|
|
|
adrlen(s)
|
|
register char *s;
|
|
{
|
|
if (*s == 0)
|
|
return(0);
|
|
if (*s=='r' || *s=='S' && *(s+1)=='P')
|
|
return(0);
|
|
if (*s=='r' || *s=='F' && *(s+1)=='P')
|
|
return(0);
|
|
if (*s=='r' || *s=='s' && *(s+1)=='p')
|
|
return(0);
|
|
if (*s=='r' || *s=='f' && *(s+1)=='p')
|
|
return(0);
|
|
if (*s=='(' && (*(s+1)=='r' || *(s+1)=='F' || *(s+1)=='f'))
|
|
return(0);
|
|
if (*s=='@')
|
|
return(0);
|
|
if (*s=='|')
|
|
return(2);
|
|
return(4);
|
|
}
|
|
|
|
Abs(x)
|
|
{
|
|
return(x<0? -x: x);
|
|
}
|
|
|
|
equop(ap1, p2)
|
|
struct node *ap1;
|
|
register struct node *p2;
|
|
{
|
|
register char *cp1, *cp2;
|
|
register struct node *p1;
|
|
|
|
p1 = ap1;
|
|
if (p1->op!=p2->op || p1->subop!=p2->subop)
|
|
return(0);
|
|
if (p1->op!=p2->op || p1->subop!=p2->subop)
|
|
return(0);
|
|
if (p1->op>0 && p1->op<LD)
|
|
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(p)
|
|
register struct node *p;
|
|
{
|
|
if(debug > 2){
|
|
printf("decref works on:");
|
|
dbprint(p);
|
|
}
|
|
if (--p->refc <= 0) {
|
|
if(debug > 2)
|
|
puts("elim 18");
|
|
nrlab++;
|
|
elim(p);
|
|
}
|
|
}
|
|
|
|
struct node *
|
|
nonlab(p)
|
|
register struct node *p;
|
|
{
|
|
while (p && p->op==LABEL)
|
|
p = p->forw;
|
|
return(p);
|
|
}
|
|
|
|
char *
|
|
alloc(n)
|
|
register n;
|
|
{
|
|
register char *p;
|
|
|
|
n++;
|
|
n &= ~01;
|
|
if (lasta+n >= lastr) {
|
|
if (addrseg == 9) {
|
|
fprintf(stderr, "lpopt: out of space\n");
|
|
exit(1);
|
|
}
|
|
addrseg++;
|
|
if(address[addrseg] == (char *)0) {
|
|
lasta = (char *)malloc(0xfff8);
|
|
address[addrseg] = lasta;
|
|
lastr = lasta + 0xfff8;
|
|
}
|
|
}
|
|
p = lasta;
|
|
lasta += n;
|
|
return(p);
|
|
}
|
|
|
|
clearreg()
|
|
{
|
|
register int i;
|
|
|
|
for (i=0; i<FREG; i++) {
|
|
regs[i][0] = '\0';
|
|
regt[i] = 0;
|
|
regp[i] = 0;
|
|
}
|
|
conloc[0] = 0;
|
|
conloct = 0;
|
|
conval[0] = 0;
|
|
convalt = 0;
|
|
clrcc();
|
|
for(i = 0; i < 8; i++)
|
|
regh[i][0] = 0;
|
|
}
|
|
|
|
savereg(ai, as, at, ap)
|
|
register ai;
|
|
register struct node *ap;
|
|
char *as;
|
|
char at;
|
|
{
|
|
register char *p, *s, *sp;
|
|
|
|
sp = p = regs[ai];
|
|
s = as;
|
|
clrr(ai,at);
|
|
regt[ai] = at;
|
|
regp[ai] = ap;
|
|
|
|
while (*p++ = *s) {
|
|
if (s[0]=='(' && regnum(s+1) != 14 ) {
|
|
*sp = 0;
|
|
return;
|
|
}
|
|
if (*s++ == ',')
|
|
break;
|
|
}
|
|
*--p = '\0';
|
|
}
|
|
|
|
dest(as, at)
|
|
char *as;
|
|
char at;
|
|
{
|
|
register char *s;
|
|
register int i, j, j1;
|
|
char *s1 = "rr10";
|
|
|
|
s = as;
|
|
if ((j = isreg(s)) >= 0) {
|
|
clregrr(j,at);
|
|
clrr(j,at);
|
|
clrr(j+NREG,at);
|
|
j1 = j & ~1;
|
|
if(j1 < 10) {
|
|
s1[2] = j1 + '0';
|
|
s1[3] = 0;
|
|
} else {
|
|
s1[2] = '1';
|
|
s1[3] = j1 - 10 + '0';
|
|
}
|
|
} else
|
|
s1[3] = '4';
|
|
for (i = 0; i < FREG; i++) {
|
|
if(j>=0 && j==isreg(regs[i]))
|
|
clrr(i,at);
|
|
else if(equstr(s,regs[i])||equstr(s1,regs[i]))
|
|
clrr(i,at);
|
|
else if(teil(s,regs[i])|| teil(s1,regs[i]))
|
|
clrr(i,at);
|
|
else if(teil(regs[i],s)|| teil(regs[i],s1))
|
|
clrr(i,at);
|
|
|
|
}
|
|
if ((i = findrand(s,at)) >= 0)
|
|
if(regt[i]==at)
|
|
clrr(i,at);
|
|
while (*s) {
|
|
if ((*s=='(' && (*(s+1)!='F' || *(s+2)!='P' || *(s+1)!='f'
|
|
|| *(s+2)!='p' || *(s+1)!='s')) || *s++=='@') {
|
|
for (i=0; i<FREG; i++) {
|
|
if (regs[i][0] != '#' && regs[i][0] != 'r')
|
|
clrr(i,at);
|
|
conloc[0] = 0;
|
|
conloct = 0;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
source(as, at)
|
|
char *as;
|
|
char at;
|
|
{
|
|
register char *s;
|
|
register int i;
|
|
|
|
s = as;
|
|
if ((i = isreg(s)) >= 0) {
|
|
regp[i] = 0;
|
|
regp[i+NREG] = 0;
|
|
if((i & 1) && regt[i-1]=='r') {
|
|
regp[i-1] = 0;
|
|
regp[i+NREG-1] = 0;
|
|
}
|
|
if(at=='r' || at=='q') {
|
|
regp[i+1] = 0;
|
|
regp[i+1 + NREG] = 0;
|
|
}
|
|
if(at=='q') {
|
|
regp[i+2] = 0;
|
|
regp[i+3] = 0;
|
|
regp[i+2 + NREG] = 0;
|
|
regp[i+3 + NREG] = 0;
|
|
}
|
|
} else
|
|
if(*s=='@' && (i = isreg(++s))>=0) {
|
|
regp[i] = 0;
|
|
regp[i+NREG] = 0;
|
|
}
|
|
else {
|
|
while(*s && *s!='(')
|
|
++s;
|
|
if(*s && *s=='(' && (i = regnum(++s))>=0) {
|
|
regp[i] = 0;
|
|
regp[i+NREG] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
singop(ap)
|
|
struct node *ap;
|
|
{
|
|
register char *p1, *p2;
|
|
|
|
p1 = ap->code;
|
|
p2 = regs[RT1];
|
|
while (*p2++ = *p1++);
|
|
settyp(RT1,ap);
|
|
regs[RT2][0] = 0;
|
|
regt[RT2] = 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++;
|
|
settyp(RT1,ap);
|
|
*p2++ = 0;
|
|
p2 = regs[RT2];
|
|
*p2 = 0;
|
|
if (*p1++ !=',') {
|
|
regt[RT2] = 0;
|
|
return;
|
|
}
|
|
while (*p2++ = *p1++);
|
|
settyp(RT2,ap);
|
|
}
|
|
|
|
findrand(as, at)
|
|
char *as;
|
|
char at;
|
|
{
|
|
register int i, j;
|
|
|
|
if(*as==0)
|
|
return(-1);
|
|
/*
|
|
if((i = isreg(as))>=0 && (j = isreg(regs[i]))>=0){
|
|
if(j>i && regt[j]==regt[i])
|
|
return ( j );
|
|
else
|
|
return(-1);
|
|
}
|
|
*/
|
|
for (i = 0; i < FREG; i++) {
|
|
if (equstr(regs[i], as)) {
|
|
if(regt[i] != at)
|
|
continue;
|
|
if((regt[i & ~01] == 'r' && at != 'r') ||
|
|
(regt[i & ~03] == 'q' && at != 'q'))
|
|
continue;
|
|
else
|
|
return(i);
|
|
}
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
isreg(as)
|
|
char *as;
|
|
{
|
|
register char *s;
|
|
|
|
s = as;
|
|
if(s==0 || (*s)==0)
|
|
return(-1);
|
|
return(regnum(s));
|
|
}
|
|
|
|
check()
|
|
{
|
|
register struct node *p, *lp;
|
|
|
|
lp = &first;
|
|
for (p=first.forw; p!=0; p = p->forw) {
|
|
if (p->back != lp)
|
|
abort();
|
|
lp = p;
|
|
}
|
|
}
|
|
|
|
|
|
repladdr(p, f)
|
|
register f;
|
|
struct node *p;
|
|
{
|
|
register r, i;
|
|
register r1, r2;
|
|
register char *p1, *p2;
|
|
static char rt1[50], rt2[50];
|
|
|
|
if(debug > 2){
|
|
printf("repladdr works on:");
|
|
dbprint(p);
|
|
}
|
|
if (f)
|
|
r = findrand(regs[RT1], regt[RT1]);
|
|
else
|
|
r = -1;
|
|
r1 = findrand(regs[RT2], regt[RT2]);
|
|
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 && (regs[r][0]==0 || regt[r]==regt[RT1]) &&
|
|
((r2 = isreg(regs[RT1]))<0 || r2<r && regt[r2]==regt[RT1])) {
|
|
rt1[0] = 'r';
|
|
i = 1;
|
|
if(regt[RT1] != 0)
|
|
rt1[i++] = regt[RT1];
|
|
if( r > 9 ) {
|
|
rt1[i++] = '1';
|
|
rt1[i++] = r - 10 + '0';
|
|
}else
|
|
rt1[i++] = r + '0';
|
|
rt1[i] = 0;
|
|
nsaddr++;
|
|
nchange++;
|
|
}
|
|
if (r1>=0 && (regs[r1][0]==0 || regt[r1]==regt[RT2]) &&
|
|
((r2 = isreg(regs[RT2]))<0 ||r2<r1 && regt[r2]==regt[RT2])) {
|
|
rt2[1] = 'r';
|
|
i = 2;
|
|
if (regt[RT2] != 0)
|
|
rt2[i++] = regt[RT2];
|
|
if ( r1 > 9 ) {
|
|
rt2[i++] = '1';
|
|
rt2[i++] = r1 - 10 + '0';
|
|
} else
|
|
rt2[i++] = r1 + '0';
|
|
rt2[i] = 0;
|
|
nsaddr++;
|
|
nchange++;
|
|
}
|
|
p->code = copy(2, rt1, rt2);
|
|
if(debug > 2)
|
|
printf("repladdr liefert '%s'\n",p->code);
|
|
}
|
|
}
|
|
|
|
redunbr(p)
|
|
register struct node *p;
|
|
{
|
|
register struct node *p1;
|
|
register char *ap1;
|
|
register char *ap2;
|
|
|
|
if ((p1 = p->ref) == 0)
|
|
return;
|
|
p1 = nonlab(p1);
|
|
if (p1->op==TST) {
|
|
singop(p1);
|
|
savereg(RT2, "#0", regt[RT1], p1);
|
|
} 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)>0 && p1->labno) {
|
|
nredunj++;
|
|
nchange++;
|
|
decref(p->ref);
|
|
p->ref = p1->ref;
|
|
p->labno = p1->labno;
|
|
p->ref->refc++;
|
|
}
|
|
}
|
|
|
|
char *
|
|
findcon(i)
|
|
register i;
|
|
{
|
|
register char *p;
|
|
register r;
|
|
|
|
p = regs[i];
|
|
if (*p=='#')
|
|
return(p);
|
|
if ((r = isreg(p)) >= 0 && regt[r]==regt[i])
|
|
return(regs[r]);
|
|
if (equstr(p, conloc) && conloct==regt[i])
|
|
return(conval);
|
|
return(p);
|
|
}
|
|
|
|
compare(oper, cp1, cp2)
|
|
register oper;
|
|
char *cp1, *cp2;
|
|
{
|
|
register unsigned n1, n2;
|
|
|
|
if (*cp1++ != '#' || *cp2++ != '#')
|
|
return(-1);
|
|
n2 = hexa(cp2);
|
|
n1 = hexa(cp1);
|
|
do {
|
|
if (*cp1++ != *cp2)
|
|
return(-1);
|
|
} while (*cp2++);
|
|
switch(oper) {
|
|
|
|
case JEQ:
|
|
return(n1 == n2);
|
|
case JNE:
|
|
return(n1 != n2);
|
|
case JLE:
|
|
return((int)n1 <= (int)n2);
|
|
case JGE:
|
|
return((int)n1 >= (int)n2);
|
|
case JLT:
|
|
return((int)n1 < (int)n2);
|
|
case JGT:
|
|
return((int)n1 > (int)n2);
|
|
case JLO:
|
|
return(n1 < n2);
|
|
case JHI:
|
|
return(n1 > n2);
|
|
case JLOS:
|
|
return(n1 <= n2);
|
|
case JHIS:
|
|
return(n1 >= n2);
|
|
case PL:
|
|
return((int)n1 >= 0);
|
|
case MI:
|
|
return((int)n1 < 0);
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
setcon(ar1, ar2, t)
|
|
char *ar1, *ar2;
|
|
char t;
|
|
{
|
|
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++);
|
|
conloct = t;
|
|
convalt = t;
|
|
}
|
|
|
|
equstr(ap1, ap2)
|
|
char *ap1, *ap2;
|
|
{
|
|
register char *p1, *p2;
|
|
|
|
p1 = ap1;
|
|
p2 = ap2;
|
|
if(!p1) {
|
|
if(!p2)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
if(*p1 == '#' && *p2 == '#') {
|
|
if(*++p1 =='%')
|
|
++p1;
|
|
if(*++p2 =='%')
|
|
++p2;
|
|
}
|
|
do {
|
|
if (*p1++ != *p2)
|
|
return(0);
|
|
} while (*p2++);
|
|
return(1);
|
|
}
|
|
|
|
setcc(ap, t)
|
|
char *ap;
|
|
char t;
|
|
{
|
|
register char *p, *p1;
|
|
|
|
p = ap;
|
|
ccloct = t;
|
|
if (!natural(p)) {
|
|
clrcc();
|
|
return;
|
|
}
|
|
p1 = ccloc;
|
|
while (*p1++ = *p++);
|
|
}
|
|
|
|
clrcc()
|
|
{
|
|
ccloc[0] = 0;
|
|
ccloct = 0;
|
|
}
|
|
|
|
natural(ap)
|
|
char *ap;
|
|
{
|
|
register char *p;
|
|
|
|
p = ap;
|
|
if (*p == '@' || *p == '(')
|
|
return(0);
|
|
while (*p++);
|
|
p--;
|
|
if ( *--p ==')' && *--p != 'P')
|
|
return(0);
|
|
return(1);
|
|
}
|
|
|
|
unsigned
|
|
hexa(cp)
|
|
char *cp;
|
|
{
|
|
unsigned register n;
|
|
n = 0;
|
|
while(*cp >= '0' && *cp <= '9' || *cp >= 'a' && *cp <= 'f') {
|
|
n <<= 4;
|
|
if(*cp < 'a')
|
|
n += *cp++ - '0';
|
|
else
|
|
n += *cp++ - 'W';
|
|
}
|
|
return(n);
|
|
}
|
|
|
|
elim(p)
|
|
register struct node *p;
|
|
{
|
|
if(debug){
|
|
printf("elim works on:");
|
|
dbprint(p);
|
|
}
|
|
p->back->forw = p->forw;
|
|
p->forw->back = p->back;
|
|
nchange++;
|
|
}
|
|
|
|
regnum(r)
|
|
char *r;
|
|
{
|
|
if (*r != 'r' && *r != 'F' && *r != 'f' && *r != 'S' && *r!='s')
|
|
return(-1);
|
|
regc = 0;
|
|
|
|
if (*r =='S' && *(r+1) == 'P' && *(r+2) == 0) {
|
|
regc = 'r';
|
|
return(14);
|
|
}
|
|
|
|
if (*r =='s' && *(r+1) == 'p' && *(r+2) == 0)
|
|
return(15);
|
|
|
|
if (*r =='F' && *(r+1) == 'P' && *(r+2) == 0) {
|
|
regc = 'r';
|
|
return(12);
|
|
}
|
|
|
|
if (*r =='f' && *(r+1) == 'p' && *(r+2) == 0)
|
|
return(13);
|
|
|
|
if(*r++ != 'r')
|
|
return(-1);
|
|
if(*r == 'l' || *r== 'r' || *r == 'h' || *r == 'q')
|
|
regc = *r++;
|
|
|
|
if(*(r+1) >= '0' && *(r+1) <= '5' && *r == '1') {
|
|
r++;
|
|
if(*(r+1) == 0)
|
|
return(10 + *r++ - '0');
|
|
else
|
|
return(-1);
|
|
|
|
}
|
|
else if(*r >= '0' && *r <= '9' && *(r+1) == 0)
|
|
return(*r++ - '0');
|
|
return(-1);
|
|
|
|
}
|
|
|
|
settyp(a,ap)
|
|
register a;
|
|
register struct node *ap;
|
|
{
|
|
if(regs[a][0] == 'r' && regs[a][1] > '9')
|
|
regt[a] = regs[a][1];
|
|
else if (ap->subop==LONG)
|
|
regt[a] = 'r';
|
|
else if (ap->subop==BYTE)
|
|
regt[a] = 'l';
|
|
else regt[a] = 0;
|
|
}
|
|
|
|
clrr(i,at)
|
|
register i;
|
|
char at;
|
|
{
|
|
register j,k;
|
|
k = i&~01;
|
|
j = i&~03;
|
|
|
|
if((i & 1) && regt[i-1]=='r') {
|
|
regs[i-1][0] = 0;
|
|
regt[i-1]=0;
|
|
regp[i-1]=0;
|
|
}
|
|
if(i < 8 && at!='l')
|
|
regh[i][0] = 0;
|
|
if(regt[j]=='q' || at=='q') {
|
|
regs[j][0] = 0; regt[j] = 0; regp[j] = 0;
|
|
regs[++j][0] = 0; regt[j] = 0; regp[j] = 0;
|
|
regs[++j][0] = 0; regt[j] = 0; regp[j] = 0;
|
|
regs[++j][0] = 0; regt[j] = 0; regp[j] = 0;
|
|
}
|
|
else if (regt[k]=='r' || at=='r') {
|
|
regs[k][0] = 0; regt[k] = 0; regp[k] = 0;
|
|
regs[++k][0] = 0; regt[k] = 0; regp[k] = 0;
|
|
}
|
|
else {
|
|
regs[i][0] = 0;
|
|
regt[i] = 0;
|
|
regp[i] = 0;
|
|
}
|
|
regp[i] = 0;
|
|
}
|
|
|
|
clrp()
|
|
{
|
|
register i;
|
|
for( i=0; i<30; i++)
|
|
regp[i] = 0;
|
|
}
|
|
|
|
ispow2a(a)
|
|
register unsigned a;
|
|
{
|
|
register i;
|
|
if(a>0 && a<=0x8000 && (a&(a-1))==0) {
|
|
for(i = 0; a >>= 1; i++);
|
|
return(i);
|
|
}
|
|
else
|
|
return(-1);
|
|
}
|
|
|
|
setadr(p, i)
|
|
register struct node *p;
|
|
register i;
|
|
{
|
|
static char rt[5];
|
|
regt[RT2] = 0;
|
|
rt[0] = ',';
|
|
rt[1] = '#';
|
|
rt[2] = '%';
|
|
if(i < 10)
|
|
rt[3] = '0' + i;
|
|
else
|
|
rt[3] = 'a' + i - 10;
|
|
rt[4] = 0;
|
|
p->code = copy(2, regs[RT1], rt);
|
|
}
|
|
|
|
/* ist r teilstring in s */
|
|
teil(r,s)
|
|
char *r,*s;
|
|
{
|
|
static char f[5];
|
|
char *fp, *sp, *osp = s;
|
|
int len,i;
|
|
if(equstr(r,s))
|
|
return(0);
|
|
len = strlen(r);
|
|
while((sp = strchr(osp,*r))!=NULL) {
|
|
osp = sp + 1;
|
|
fp = f;
|
|
for(i=0; i < len; i++)
|
|
*fp++ = *sp++;
|
|
*fp = 0;
|
|
if(equstr(f,r))
|
|
return(1);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
clregrr(r, t)
|
|
register r;
|
|
char t;
|
|
{
|
|
char *s1 = "rr10";
|
|
int j1, j;
|
|
|
|
again:
|
|
j1 = r & ~1;
|
|
if(j1 < 10) {
|
|
s1[2] = j1 + '0';
|
|
s1[3] = 0;
|
|
} else {
|
|
s1[2] = '1';
|
|
s1[3] = j1 - 10 + '0';
|
|
}
|
|
for(j = 0; j < NREG; j++)
|
|
if(teil(s1, regs[j]))
|
|
clrr(j, regt[j]);
|
|
if(t == 'q') {
|
|
t = 0;
|
|
r += 2;
|
|
goto again;
|
|
}
|
|
}
|