eliminate confusion between "file" and "./file"
[unix-history] / usr / src / old / pcc / c2.tahoe / c22.c
CommitLineData
bcaf9154 1#ifndef lint
cdb206a9 2static char sccsid[] = "@(#)c22.c 1.7 (Berkeley/CCI) %G%";
bcaf9154
SL
3#endif
4
5/*
6 * C object code improver-- third part
7 */
8
9#include "c2.h"
10#include <stdio.h>
11#include <ctype.h>
12
13rmove()
14{
15 register struct node *p;
16 register int r, r1;
17
18 clearreg();
19 for (p=first.forw; p!=0; p = p->forw) {
20 if (debug) {
21 printf("Regs: ");
22 for (r=0; r<=NREG; r++)
23 if (regs[r][0]) {
24 r1=regs[r][0];
25 printf("%d: %d%d %s\n", r, r1&0xF, r1>>4, regs[r]+1);
26 }
27 printf("-\n");
28 }
29 switch (p->op) {
30
31 case CVT:
32 case MOVZ:
33 splitrand(p);
34 repladdr(p);
35 r = isreg(regs[RT1]);
36 r1 = isreg(regs[RT2]);
37 dest(regs[RT2],p->subop, 1);
38 if (r>=0 && r1>=0) {
39 p->op = MOV; p->subop = LONG;
40 p->pop = 0;
41 nchange++;
42 goto case_mov;
43 }
44 if(p->op == CVT) {
45 if (r1>=0) savereg(r1, regs[RT1], p->subop);
46 } else
47 ccloc[0] = 0;
48 break;
49
50 case MOV:
51 case_mov:
52 splitrand(p);
53 if ((r = findrand(regs[RT1],p->subop)) >= 0) {
54 if (r == isreg(regs[RT2]))
55 if(p->forw->op!=CBR) {
56 delnode(p); redunm++; nchange++; break;
57 } else {
58 p->op=TST; p->pop=0;
59 while(*p->code++ != ',');
60 redunm++; nchange++;
61 goto case_tst;
62 }
63 }
64 repladdr(p);
65 r = isreg(regs[RT1]);
66 r1 = isreg(regs[RT2]);
67 dest(regs[RT2],p->subop, 1);
864f1f35
SL
68 if ((regs[ACC][0]) && equstr(regs[RT2],regs[ACC]+1))
69 *(short *)(regs[ACC]) = 0;
bcaf9154
SL
70 if (r>=0) {
71 if (r1>=0) {
72 if (r == r1 && p->forw->op!=CBR) {
864f1f35
SL
73 delnode(p); redunm++; nchange++;
74 break;
bcaf9154
SL
75 }
76 if(regs[r][0])
77 savereg(r1, regs[r]+1, p->subop);
864f1f35
SL
78 } else
79 savereg(r, regs[RT2], p->subop);
80 } else if (r1>=0)
81 savereg(r1, regs[RT1], p->subop);
82 else
83 setcon(regs[RT1], regs[RT2], p->subop);
bcaf9154
SL
84 break;
85
86/* .rx,.wx or .rx,.rx,.wx */
87 case ADD:
88 case SUB:
89 case AND:
90 case OR:
91 case XOR:
92 case MUL:
93 case DIV:
94#ifdef EMOD
95 case EDIV:
96 case EMOD:
97#endif EMOD
98 case SHAL:
99 case SHAR:
100 case SHL:
101 case SHR:
102 case ADDA:
103 case SUBA:
104/* .rx,.wx */
105 case MFPR:
106 case COM:
107 case NEG:
108 splitrand(p);
109 repladdr(p);
110 dest(lastrand,p->subop, p->op!=ADDA && p->op!=SUBA);
111 break;
112
113/* .mx or .wx */
114 case STF:
115 if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) {
116 delnode(p);
117 nst++; nchange++; break;
118 }
119 savereg(ACC, p->code, p->subop);
bcaf9154
SL
120 case INC:
121 case DEC:
122 case CVFL:
123 dest(p->code,p->subop, 1);
864f1f35
SL
124 break;
125
126 case CLR:
127 dest(p->code,p->subop, 1);
128 if ((regs[ACC][0]) && equstr(p->code,regs[ACC]+1))
129 *(short *)(regs[ACC]) = 0;
130 if ((r = isreg(p->code)) < 0)
131 setcon("$0", p->code, p->subop);
132 else
133 savereg(r, "$0", p->subop);
bcaf9154
SL
134 break;
135
136/* .rx */
137 case LDF:
138 if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) {
139 delnode(p);
140 nld++; nchange++; break;
141 }
142 savereg(ACC, p->code, p->subop);
143 goto case_tst;
144 case LNF:
145 if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) {
146 p->op = NEGF; p->pop = 0; p->code = 0;
147 regs[ACC][0] = 0;
148 break;
149 }
150 case CVLF:
151 case LDFD:
152 case ADDF:
153 case SUBF:
154 case MULF:
155 case DIVF:
156 regs[ACC][0] = 0;
157 case TST:
158 case_tst:
159 case PUSH:
160 splitrand(p);
161 lastrand=regs[RT1+1]; /* fool repladdr into doing 1 operand */
162 repladdr(p);
163 lastrand=regs[RT1];
164 if (p->op==TST && equstr(lastrand, ccloc+1)
165 && ((0xf&(ccloc[0]>>4))==p->subop || equtype(ccloc[0],p->subop))) {
166 delnode(p); nrtst++; nchange++; break;
167 }
168 if (p->op==PUSH && p->subop!=LONG &&
169 (isreg(lastrand)>=0 || *lastrand=='$')) {
170 p->subop = LONG;
171 p->pop = 0;
172 nchange++;
173 }
174 if (p->op==TST || p->op==PUSH)
175 setcc(lastrand,p->subop);
176 break;
177
178/* .rx,.rx,.rx */
179 case PROBE:
180 case CASE:
181/* .rx,.rx */
182 case MTPR:
183 case CALLS:
184 case CALLF:
185 case CMP:
186 case BIT:
187 case CMPF:
188 case CMPF2:
189 splitrand(p);
190 /* fool repladdr into doing right number of operands */
191 lastrand=byondrd(p);
192 if (p->op==CALLF || p->op==CALLS) clearreg();
193 else repladdr(p);
194 case TSTF:
195 ccloc[0]=0;
196 case PUSHD:
197 break;
198
199/* acc only */
200 case CVDF:
201 case NEGF:
202 case SINF:
203 case COSF:
204 case ATANF:
205 case LOGF:
206 case SQRTF:
207 case EXPF:
208 regs[ACC][0] = 0;
209 break;
210
211#ifndef EMOD
212/* .rx,.rx,.wx,.wx */
213 case EDIV:
214 splitrand(p);
215 lastrand = regs[RT3];
216 repladdr(p);
217 dest(regs[RT3], p->subop, 1);
218 dest(regs[RT4], p->subop, 0);
219 break;
220#endif EMOD
221
222/* .rx,.rx,.rx,wx */
223 case EMUL:
224 splitrand(p);
225 lastrand = regs[RT4];
226 repladdr(p);
227 dest(regs[RT4],QUAD, 1); /* fourth operand is a quad */
228 break;
229 case CBR:
230 if (p->subop>=JBC) {
231 splitrand(p);
232 lastrand=regs[RT3]; /* 2 operands can be optimized */
233 repladdr(p);
234 ccloc[0] = 0;
235 } else
236 reduncbr(p);
237 break;
238
239 case JBR:
240 redunbr(p);
241
242 default:
243 clearreg();
244 }
245 }
246}
247
248jumpsw()
249{
250 register struct node *p, *p1, *pt;
251 register int t, nj;
252
253 t = 0;
254 nj = 0;
255 for (p=first.forw; p!=0; p = p->forw)
256 p->seq = ++t;
257 for (p=first.forw; p!=0; p = p1) {
258 p1 = p->forw;
259 if (p->op == CBR && p1->op==JBR && p->ref && p1->ref
260 && abs(p->seq - p->ref->seq) > abs(p1->seq - p1->ref->seq)) {
261 if (p->ref==p1->ref)
262 continue;
263 p->subop = revbr[p->subop];
264 p->pop=0;
265 pt = p1->ref;
266 p1->ref = p->ref;
267 p->ref = pt;
268 t = p1->labno;
269 p1->labno = p->labno;
270 p->labno = t;
271#ifdef COPYCODE
272 if (p->labno == 0) {
273 pt = (struct node *)p1->code; p1->code = p->code; p->code = (char *)pt;
274 }
275#endif
276 nrevbr++;
277 nj++;
278 }
279 }
280 return(nj);
281}
282
283addaob()
284{
285 register struct node *p, *p1, *p2, *p3;
286
287 for (p = &first; (p1 = p->forw)!=0; p = p1) {
288 if (p->op==INC && p->subop==LONG) {
289 if (p1->op==LABEL && p1->refc==1 && p1->forw->op==CMP && p1->forw->subop==LONG
290 && (p2=p1->forw->forw)->op==CBR && p2->subop==JLE
291 && (p3=p2->ref->back)->op==JBR && p3->subop==0 && p3->ref==p1
292 && p3->forw->op==LABEL && p3->forw==p2->ref) {
293 /* change INC LAB: CMP to LAB: INC CMP */
294 p->back->forw=p1; p1->back=p->back;
295 p->forw=p1->forw; p1->forw->back=p;
296 p->back=p1; p1->forw=p;
297 p1=p->forw;
298 /* adjust beginning value by 1 */
299 p2=alloc(sizeof first); p2->op = DEC; p2->subop = LONG;
300 p2->pop=0;
301 p2->forw=p3; p2->back=p3->back; p3->back->forw=p2;
302 p3->back=p2; p2->code=p->code; p2->labno=0;
303 }
304 if (p1->op==CMP && p1->subop==LONG &&
305 (p2=p1->forw)->op==CBR && p2->forw->op!=CBR) {
306 register char *cp1,*cp2;
307 splitrand(p1); if (!equstr(p->code,regs[RT1])) continue;
e6c8f4f3
SL
308 if ((p2->subop==JLE || p2->subop==JLT) &&
309 checkaobdisp(p2)){
bcaf9154
SL
310 if (p2->subop==JLE) p->op = AOBLEQ; else p->op = AOBLSS; p->subop = 0;
311 cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++); /* limit */
312 cp2=regs[RT2]; cp1=p->code; while (*cp2++= *cp1++); /* index */
313 p->pop=0; newcode(p);
314 p->labno = p2->labno; delnode(p2); delnode(p1); naob++;
315 }
316 }
317 }
318 }
319}
320
321ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */
322 register int log;
323 if (n==0 || n&(n-1)) return(-1); log=0;
324 for (;;) {n >>= 1; if (n==0) return(log); ++log; if (n== -1) return(log);}
325}
326
327equop(p1, p2)
328register struct node *p1, *p2;
329{
330 register char *cp1, *cp2;
331
332 if (p1->op != p2->op || p1->subop != p2->subop)
333 return(0);
cdb206a9
DS
334 if (p1->op == NIL && p1->subop == 0 && p1->pop != p2->pop)
335 return(0);
864f1f35 336 if (p1->op != NIL && ord(p1->op) < ord(MOV))
bcaf9154 337 return(0);
cdb206a9
DS
338 switch (p1->op) {
339 case EROU: case JSW: case TEXT: case DATA:
340 case BSS: case ALIGN: case WGEN: case END:
341 /* sufficient? */
342 return(0);
343 }
bcaf9154
SL
344 if (p1->op==MOVA && p1->labno!=p2->labno) return(0);
345 cp1 = p1->code;
346 cp2 = p2->code;
347 if (cp1==0 && cp2==0)
348 return(1);
349 if (cp1==0 || cp2==0)
350 return(0);
351 while (*cp1 == *cp2++)
352 if (*cp1++ == 0)
353 return(1);
354 return(0);
355}
356
357delnode(p) register struct node *p; {
358 p->back->forw = p->forw;
359 p->forw->back = p->back;
360}
361
362decref(p)
363register struct node *p;
364{
365 if (p && --p->refc <= 0) {
366 nrlab++; nchange++;
367 delnode(p);
368 }
369}
370
371struct node *
372nonlab(ap)
373struct node *ap;
374{
375 register struct node *p;
376
377 p = ap;
378 while (p && p->op==LABEL)
379 p = p->forw;
380 return(p);
381}
382
383clearuse() {
384 register struct node **i;
e6c8f4f3 385 for (i=uses+NREG; i>uses;) *--i=0;
bcaf9154
SL
386 useacc = 0;
387}
388
389clearreg() {
390 register char **i;
391 for (i=regs+NREG+1; i>regs;){ **--i=0; **i=0; }
392 conloc[0] = 0; ccloc[0] = 0;
393}
394
395savereg(ai, s, type)
396register char *s;
397{
398 register char *p, *sp;
399
400 sp = p = regs[ai];
401 /* if any indexing, must be parameter or local */
402 /* indirection (as in "*-4(fp)") is ok, however */
403 *p++ = type;
404 if (*s=='*' || *s=='$')
405 *p++ = *s++;
406 if (natural(s))
407 strcpy(p, s);
408 else {*sp = 0; return;}
409}
410
411dest(s,type, ccflg)
412register char *s;
413{
414 register int i;
415
416 if ((i = isreg(s)) >= 0) {
417 *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
418 if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF) || type==QUAD)
419 *(short *)(regs[i+1]) = 0;
420 }
421 for (i=NREG; --i>=0;)
422 if (regs[i][1]=='*' && equstr(s, regs[i]+2))
423 *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */
424 while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */
425 *(short *)(regs[i]) = 0;
426
427 if (!natural(s)) {/* wild store, everything except constants vanishes */
428 for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0;
429 conloc[0] = 0; ccloc[0] = 0;
430 } else {
431 if(ccflg)setcc(s,type); /* natural destinations set condition codes */
432 if (equstr(s, conloc))
433 conloc[0] = 0;
434 }
435}
436
437splitrand(p) struct node *p; {
438/* separate operands at commas, set up 'regs' and 'lastrand' */
439register char *p1, *p2; register char **preg;
440
441 preg=regs+RT1;
442 if (p1=p->code) while (*p1) {
443 lastrand=p2= *preg++;
444 while (*p1) if (','==(*p2++= *p1++)) {--p2; break;}
445 *p2=0;
446 }
447 while (preg<(regs+RT1+5)) *(*preg++)=0;
448}
449
450compat(have, want)
451register int have, want;
452{
453 register int hsrc, hdst;
454 extern int bitsize[];
455
456 if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
457 hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;
458 if (want>=QUAD)
459 return(bitsize[hdst]==bitsize[want] && bitsize[hsrc]==bitsize[want]);
460 return(hsrc==want && hdst>=want && hdst<QUAD);
461}
462
463equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}
464
465findrand(as, type)
466char *as;
467{
468 register char **i;
469 for (i = regs+NREG; --i>=regs;) {
470 if (**i && equstr(*i+1, as) && compat(**i,type))
471 return(i-regs);
472 }
473 return(-1);
474}
475
476isreg(s)
477register char *s;
478{
479 if (*s++!='r' || !isdigit(*s++)) return(-1);
480 if (*s==0) return(*--s-'0');
481 if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0');
482 return(-1);
483}
484
485/*
486check()
487{
488 register struct node *p, *lp;
489
490 lp = &first;
491 for (p=first.forw; p!=0; p = p->forw) {
492 if (p->back != lp)
493 abort(-1);
494 lp = p;
495 }
496}
497*/
498
499newcode(p) struct node *p; {
500 register char *p1,*p2,**preg;
501
502 preg=regs+RT1; p2=line;
503 while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';}
504 *--p2=0;
505 p->code=copy(line);
506}
507
508repladdr(p)
509struct node *p;
510{
511 register int r;
512 register char *p1;
513 register char **preg;
514 register int nrepl;
515
516 preg=regs+RT1; nrepl=0;
517 while (lastrand!=(p1= *preg++))
518 if (0<=(r=findrand(p1,p->subop))) {
519 *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0;
520 nchange++; nrepl++; nsaddr++;
521 }
522 if (nrepl) newcode(p);
523}
524
525/* conditional branches which are never/always taken */
526reduncbr(p)
527register struct node *p;
528{
529 register struct node *p1;
530 register char *ap1, *ap2;
531
532 p1 = p->back;
533 if (p1->op==CMP) {
534 splitrand(p1);
535 ap1 = findcon(regs[RT1], p1->subop);
536 ap2 = findcon(regs[RT2], p1->subop);
537 } else {
538 if(!ccloc[0])
539 return;
540 ap1 = findcon(ccloc+1, ccloc[0]);
541 ap2 = "$0";
542 }
543 switch (compare(p->subop, ap1, ap2)) {
544 case 0: /* branch never taken */
545 delnode(p);
546 nredunj++;
547 nchange++;
548 decref(p->ref);
549 if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) {
550 delnode(p1);
551 nrtst++;
552 }
553 break;
554 case 1: /* branch always taken */
555 p->op = JBR;
556 p->subop = 0;
557 p->pop = 0;
558 nchange++;
559 if(nonlab(p->ref)->op!=CBR && (p1->op==TST || p1->op==CMP)) {
560 delnode(p1);
561 nrtst++;
562 }
563 }
564}
565
566/* a jump to a redundant compare (start of a 'for') */
567redunbr(p)
568register struct node *p;
569{
570 register struct node *p1;
571 register char *ap1, *ap2;
572
573 if ((p1 = p->ref) == 0)
574 return;
575 p1 = nonlab(p1);
576 if (p1->op==TST || p1->op==CMP)
577 splitrand(p1);
578 else
579 return;
580 if (p1->forw->op==CBR) {
581 ap1 = findcon(regs[RT1], p1->subop);
582 if (p1->op==TST)
583 ap2 = "$0";
584 else
585 ap2 = findcon(regs[RT2], p1->subop);
586 p1 = p1->forw;
587 if (compare(p1->subop, ap1, ap2) > 0) {
588 nredunj++;
589 nchange++;
590 decref(p->ref);
591 p->ref = p1->ref;
592 p->labno = p1->labno;
593#ifdef COPYCODE
594 if (p->labno == 0)
595 p->code = p1->code;
596 if (p->ref)
597#endif
598 p->ref->refc++;
599 }
600 } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) &&
601 equtype(ccloc[0],p1->subop)) {
602 p1=insertl(p1->forw); decref(p->ref); p->ref=p1;
603 nrtst++; nchange++;
604 }
605}
606
607char *
608findcon(p, type)
609 register char *p;
610{
611 register int r;
612
613 if (*p=='$')
614 return(p);
615 if ((r = isreg(p)) >= 0 && compat(regs[r][0],type))
616 return(regs[r]+1);
9117f705 617 if (equstr(p, conloc) && equtype(conloc[0], type))
bcaf9154
SL
618 return(conval+1);
619 return(p);
620}
621
622/* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */
623compare(op, acp1, acp2)
624char *acp1, *acp2;
625{
626 register char *cp1, *cp2;
627 register int n1, n2, sign;
628
629 cp1 = acp1;
630 cp2 = acp2;
631 if (*cp1++ != '$' || *cp2++ != '$')
632 return(-1);
633 n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;}
634 while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';}
635 n1 *= sign;
636 n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;}
637 while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';}
638 n2 *= sign;
639 if (*cp1=='+')
640 cp1++;
641 if (*cp2=='+')
642 cp2++;
643 do {
644 if (*cp1++ != *cp2)
645 return(-1);
646 } while (*cp2++);
647 switch(op) {
648
649 case JEQ:
650 return(n1 == n2);
651 case JNE:
652 return(n1 != n2);
653 case JLE:
654 return(n1 <= n2);
655 case JGE:
656 return(n1 >= n2);
657 case JLT:
658 return(n1 < n2);
659 case JGT:
660 return(n1 > n2);
661 case JLO:
662 return((unsigned)n1 < (unsigned)n2);
663 case JHI:
664 return((unsigned)n1 > (unsigned)n2);
665 case JLOS:
666 return((unsigned)n1 <= (unsigned)n2);
667 case JHIS:
668 return((unsigned)n1 >= (unsigned)n2);
669 }
670 return(-1);
671}
672
673setcon(cv, cl, type)
674register char *cv, *cl;
675{
676 register char *p;
677
678 if (*cv != '$')
679 return;
680 if (!natural(cl))
681 return;
682 p = conloc;
683 while (*p++ = *cl++);
684 p = conval;
685 *p++ = type;
686 while (*p++ = *cv++);
687}
688
689setcc(ap,type)
690char *ap;
691{
692 register char *p, *p1;
693
694 p = ap;
695 if (!natural(p)) {
696 ccloc[0] = 0;
697 return;
698 }
699 p1 = ccloc;
700 *p1++ = type;
701 while (*p1++ = *p++);
702}
703
704indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
705 while (*p) if (*p++=='[') return(1);
706 return(0);
707}
708
709natural(p)
710register char *p;
711{/* 1->simple local, parameter, global, or register; 0->otherwise */
712
713 if (*p=='*' || *p=='(' || *p=='$')
714 return(0);
715 while (*p++);
716 p--;
717 if (*--p==']' || *p==')' &&
718 !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1'))
719 return(0);
720 return(1);
721}
722
723/*
724** Tell if an argument is most likely static.
725*/
726
727isstatic(cp)
728register char *cp;
729{
730 if (*cp == '_' || *cp == 'L')
731 return (1);
732 return (0);
733}
e6c8f4f3
SL
734
735
736checkaobdisp(p)
737register struct node *p;
738{
739register struct node *q;
740register int i;
741
742
743if (!aobflag) return(1);
744/* backward search */
745 i = 0;
746 q = p;
747 while (i++ < MAXAOBDISP && ((q= q->back) !=&first))
748 {
749 if (p->ref == q)
750 return(1);
751 }
752
753/* forward search */
754 i = 0;
755 q = p;
756 while (i++ < MAXAOBDISP && ((q= q->forw) !=0))
757 {
758 if (p->ref == q)
759 return(1);
760 }
761 return(0);
762}
763
764
765struct intleavetab intltab[] = {
766 ADDF, FLOAT, 1,
767 ADDF, DOUBLE, 1,
768 SUBF, FLOAT, 1,
769 SUBF, DOUBLE, 1,
770 MULF, FLOAT, 1,
771 MULF, DOUBLE, 1,
772 DIVF, FLOAT, 1,
773 DIVF, DOUBLE, 1,
774 SINF, FLOAT, 1,
775 COSF, FLOAT, 1,
776 ATANF, FLOAT, 1,
777 LOGF, FLOAT, 1,
778 SQRTF, FLOAT, 1,
779 EXPF, FLOAT, 1,
780 LDF, FLOAT, 0,
781 LDF, DOUBLE, 0,
782 LNF, FLOAT, 0,
783 LNF, DOUBLE, 0,
784 STF, FLOAT, 0,
785 CMPF, FLOAT, 0,
786 CMPF, DOUBLE, 0,
787 CMPF2, FLOAT, 0,
788 TSTF, FLOAT, 0,
789 TSTF, DOUBLE, 0,
790 PUSHD, DOUBLE, 0,
791 CVLF, U(LONG,FLOAT), 0,
792 CVFL, U(FLOAT,LONG), 0,
793 LDFD, U(FLOAT,DOUBLE),0,
794 CVDF, U(DOUBLE,FLOAT),0,
795 NEGF, FLOAT, 0,
864f1f35 796 NIL, 0, 0};
e6c8f4f3
SL
797
798interleave()
799{
800 register struct node *p, *p1;
801
802 register struct intleavetab *t;
803 register int r;
804 int count;
805 for (p= first.forw; p!=0; p = p->forw){
806 count = 0;
864f1f35 807 for (t =intltab; t->op != NIL; t++){
e6c8f4f3
SL
808 if (t->op == p->op && t->subop == p->subop){
809 count = t->intleavect;
810 break;
811 }
812 }
813 if (count < 1) continue;
814 p1 = p->forw;
815 clearuse();
816 clearreg();
817 while ((p1 != 0) && (p1->op != CBR) &&
818 (p1->subop == FLOAT || p1->subop == DOUBLE ||
819 ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )||
820 ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT))
821 {
822 if (((r = isreg(p1->code)) >= 0)){
823 uses[r] = p1;
824 if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) ||
825 ((p->subop&0xF)==DOUBLE))
826 uses[r+1] = p1;
827 }
828 else checkreg(p1,p1->code);
829 p1 = p1->forw;
830
831 }
832 if (p1 == 0) return;
833 if (!(sideeffect(p, p1)))
834 insertblk(p,p1);
835 }
836
837}
838
839
840insertblk(p, p1)
841struct node *p, *p1;
842{
843 p1->back->forw = p1->forw;
844 p1->forw->back = p1->back;
845 p1->forw = p->forw;
846 p->forw->back = p1;
847 p->forw = p1;
848 p1->back = p;
849}
850
864f1f35 851OpCode termop[] = {
e6c8f4f3
SL
852 JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT,
853 CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR,
854 MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET,
864f1f35
SL
855 LCOMM, COMM, NIL
856};
e6c8f4f3
SL
857
858sideeffect(p,p1)
859struct node *p, *p1;
860{
861 register struct node *q;
862 register int r;
864f1f35 863 register OpCode *t;
e6c8f4f3
SL
864 register char *cp;
865 int i;
866
864f1f35 867 if (p1->op == NIL) return(1); /* special instructions */
e6c8f4f3 868
864f1f35 869 for (t = termop; *t!=NIL; t++){
e6c8f4f3
SL
870 if (*t == p1->op) return(1);
871 }
872 if ((p1->forw != NULL) && (p1->forw->op == CBR))
873 return(1);
874 splitrand(p1);
875 r = isreg(lastrand);
876 if (uses[r] && r >= 0 ) return(1);
877 if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) &&
878 (uses[r])) return(1);
879
880 for (q = p1->back ; q!=p; q=q->back)
881 {
882 if ((p1->op == PUSH || p1->op == PUSHA) &&
883 (q->op == PUSHD || q->op == PUSH || q->op == PUSHA))
884 return(1); /* keep args in order */
885 if (((i = strlen(q->code)) >= 5 && /* cvdl -(sp); pushl r0*/
886 (strcmp(q->code+i-5,"-(sp)") == 0 )) ||
887 (strcmp(lastrand,"-(sp)") == 0)) return(1);
888 if (equstr(q->code, lastrand))
889 return(1);
890 if (q->op == STF || q->op == CVFL || q->op == CVLF)
891 {
892 if (equstr(q->code, regs[RT1])) return(1);
864f1f35 893 if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV)
e6c8f4f3
SL
894 if (equstr(q->code, regs[RT2]))
895 return(1);
896 /* handle the case std -56(fp) pushl -60(fp) pushl
897 -56(fp);
898 */
899 if ((p1->forw != NULL) && (q->op == STF) &&
900 (q->subop == DOUBLE)){
901 if (!strncmp(q->code,p1->forw->code,strlen(q->code)))
902 return(1);
903 }
904 }
905 }
906 return(0);
907}
908checkreg(p,s)
909struct node *p;
910char *s;
911{
912char *cp2;
913register int r;
914 /* check for (r),[r] */
915 do if (*s=='(' || *s=='[') {/* get register number */
916 char t;
917 cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0;
918 if ((r=isreg(cp2)) >= 0) {
919 uses[r]=p;
920 }
921 *s=t;
922 } while (*++s);
923}