BSD 4_3_Reno development
[unix-history] / .ref-fdb8e4aac282b72d4670aa3a26d9bba07afc7e6f / usr / src / old / pcc / c2.tahoe / c22.c
CommitLineData
bcaf9154 1#ifndef lint
1346e8b5 2static char sccsid[] = "@(#)c22.c 1.9 (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]);
2532ae25 37 dest(regs[RT2],p->subop, p->op!=CVT || r<0);
bcaf9154
SL
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;
1346e8b5 603 p->labno=p1->labno;
bcaf9154
SL
604 nrtst++; nchange++;
605 }
606}
607
608char *
609findcon(p, type)
610 register char *p;
611{
612 register int r;
613
614 if (*p=='$')
615 return(p);
616 if ((r = isreg(p)) >= 0 && compat(regs[r][0],type))
617 return(regs[r]+1);
9117f705 618 if (equstr(p, conloc) && equtype(conloc[0], type))
bcaf9154
SL
619 return(conval+1);
620 return(p);
621}
622
623/* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */
624compare(op, acp1, acp2)
625char *acp1, *acp2;
626{
627 register char *cp1, *cp2;
628 register int n1, n2, sign;
629
630 cp1 = acp1;
631 cp2 = acp2;
632 if (*cp1++ != '$' || *cp2++ != '$')
633 return(-1);
634 n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;}
635 while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';}
636 n1 *= sign;
637 n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;}
638 while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';}
639 n2 *= sign;
640 if (*cp1=='+')
641 cp1++;
642 if (*cp2=='+')
643 cp2++;
644 do {
645 if (*cp1++ != *cp2)
646 return(-1);
647 } while (*cp2++);
648 switch(op) {
649
650 case JEQ:
651 return(n1 == n2);
652 case JNE:
653 return(n1 != n2);
654 case JLE:
655 return(n1 <= n2);
656 case JGE:
657 return(n1 >= n2);
658 case JLT:
659 return(n1 < n2);
660 case JGT:
661 return(n1 > n2);
662 case JLO:
663 return((unsigned)n1 < (unsigned)n2);
664 case JHI:
665 return((unsigned)n1 > (unsigned)n2);
666 case JLOS:
667 return((unsigned)n1 <= (unsigned)n2);
668 case JHIS:
669 return((unsigned)n1 >= (unsigned)n2);
670 }
671 return(-1);
672}
673
674setcon(cv, cl, type)
675register char *cv, *cl;
676{
677 register char *p;
678
679 if (*cv != '$')
680 return;
681 if (!natural(cl))
682 return;
683 p = conloc;
684 while (*p++ = *cl++);
685 p = conval;
686 *p++ = type;
687 while (*p++ = *cv++);
688}
689
690setcc(ap,type)
691char *ap;
692{
693 register char *p, *p1;
694
695 p = ap;
696 if (!natural(p)) {
697 ccloc[0] = 0;
698 return;
699 }
700 p1 = ccloc;
701 *p1++ = type;
702 while (*p1++ = *p++);
703}
704
705indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
706 while (*p) if (*p++=='[') return(1);
707 return(0);
708}
709
710natural(p)
711register char *p;
712{/* 1->simple local, parameter, global, or register; 0->otherwise */
713
714 if (*p=='*' || *p=='(' || *p=='$')
715 return(0);
716 while (*p++);
717 p--;
718 if (*--p==']' || *p==')' &&
719 !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1'))
720 return(0);
721 return(1);
722}
723
724/*
725** Tell if an argument is most likely static.
726*/
727
728isstatic(cp)
729register char *cp;
730{
731 if (*cp == '_' || *cp == 'L')
732 return (1);
733 return (0);
734}
e6c8f4f3
SL
735
736
737checkaobdisp(p)
738register struct node *p;
739{
740register struct node *q;
741register int i;
742
743
744if (!aobflag) return(1);
745/* backward search */
746 i = 0;
747 q = p;
748 while (i++ < MAXAOBDISP && ((q= q->back) !=&first))
749 {
750 if (p->ref == q)
751 return(1);
752 }
753
754/* forward search */
755 i = 0;
756 q = p;
757 while (i++ < MAXAOBDISP && ((q= q->forw) !=0))
758 {
759 if (p->ref == q)
760 return(1);
761 }
762 return(0);
763}
764
765
766struct intleavetab intltab[] = {
767 ADDF, FLOAT, 1,
768 ADDF, DOUBLE, 1,
769 SUBF, FLOAT, 1,
770 SUBF, DOUBLE, 1,
771 MULF, FLOAT, 1,
772 MULF, DOUBLE, 1,
773 DIVF, FLOAT, 1,
774 DIVF, DOUBLE, 1,
775 SINF, FLOAT, 1,
776 COSF, FLOAT, 1,
777 ATANF, FLOAT, 1,
778 LOGF, FLOAT, 1,
779 SQRTF, FLOAT, 1,
780 EXPF, FLOAT, 1,
781 LDF, FLOAT, 0,
782 LDF, DOUBLE, 0,
783 LNF, FLOAT, 0,
784 LNF, DOUBLE, 0,
785 STF, FLOAT, 0,
786 CMPF, FLOAT, 0,
787 CMPF, DOUBLE, 0,
788 CMPF2, FLOAT, 0,
789 TSTF, FLOAT, 0,
790 TSTF, DOUBLE, 0,
791 PUSHD, DOUBLE, 0,
792 CVLF, U(LONG,FLOAT), 0,
793 CVFL, U(FLOAT,LONG), 0,
794 LDFD, U(FLOAT,DOUBLE),0,
795 CVDF, U(DOUBLE,FLOAT),0,
796 NEGF, FLOAT, 0,
864f1f35 797 NIL, 0, 0};
e6c8f4f3
SL
798
799interleave()
800{
801 register struct node *p, *p1;
802
803 register struct intleavetab *t;
804 register int r;
805 int count;
806 for (p= first.forw; p!=0; p = p->forw){
807 count = 0;
864f1f35 808 for (t =intltab; t->op != NIL; t++){
e6c8f4f3
SL
809 if (t->op == p->op && t->subop == p->subop){
810 count = t->intleavect;
811 break;
812 }
813 }
814 if (count < 1) continue;
815 p1 = p->forw;
816 clearuse();
817 clearreg();
818 while ((p1 != 0) && (p1->op != CBR) &&
819 (p1->subop == FLOAT || p1->subop == DOUBLE ||
820 ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )||
821 ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT))
822 {
823 if (((r = isreg(p1->code)) >= 0)){
824 uses[r] = p1;
825 if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) ||
826 ((p->subop&0xF)==DOUBLE))
827 uses[r+1] = p1;
828 }
829 else checkreg(p1,p1->code);
830 p1 = p1->forw;
831
832 }
833 if (p1 == 0) return;
834 if (!(sideeffect(p, p1)))
835 insertblk(p,p1);
836 }
837
838}
839
840
841insertblk(p, p1)
842struct node *p, *p1;
843{
844 p1->back->forw = p1->forw;
845 p1->forw->back = p1->back;
846 p1->forw = p->forw;
847 p->forw->back = p1;
848 p->forw = p1;
849 p1->back = p;
850}
851
864f1f35 852OpCode termop[] = {
e6c8f4f3
SL
853 JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT,
854 CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR,
855 MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET,
864f1f35
SL
856 LCOMM, COMM, NIL
857};
e6c8f4f3
SL
858
859sideeffect(p,p1)
860struct node *p, *p1;
861{
862 register struct node *q;
863 register int r;
864f1f35 864 register OpCode *t;
e6c8f4f3
SL
865 register char *cp;
866 int i;
867
864f1f35 868 if (p1->op == NIL) return(1); /* special instructions */
e6c8f4f3 869
864f1f35 870 for (t = termop; *t!=NIL; t++){
e6c8f4f3
SL
871 if (*t == p1->op) return(1);
872 }
873 if ((p1->forw != NULL) && (p1->forw->op == CBR))
874 return(1);
875 splitrand(p1);
876 r = isreg(lastrand);
877 if (uses[r] && r >= 0 ) return(1);
878 if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) &&
879 (uses[r])) return(1);
880
881 for (q = p1->back ; q!=p; q=q->back)
882 {
883 if ((p1->op == PUSH || p1->op == PUSHA) &&
884 (q->op == PUSHD || q->op == PUSH || q->op == PUSHA))
885 return(1); /* keep args in order */
886 if (((i = strlen(q->code)) >= 5 && /* cvdl -(sp); pushl r0*/
887 (strcmp(q->code+i-5,"-(sp)") == 0 )) ||
888 (strcmp(lastrand,"-(sp)") == 0)) return(1);
889 if (equstr(q->code, lastrand))
890 return(1);
891 if (q->op == STF || q->op == CVFL || q->op == CVLF)
892 {
893 if (equstr(q->code, regs[RT1])) return(1);
864f1f35 894 if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV)
e6c8f4f3
SL
895 if (equstr(q->code, regs[RT2]))
896 return(1);
897 /* handle the case std -56(fp) pushl -60(fp) pushl
898 -56(fp);
899 */
900 if ((p1->forw != NULL) && (q->op == STF) &&
901 (q->subop == DOUBLE)){
902 if (!strncmp(q->code,p1->forw->code,strlen(q->code)))
903 return(1);
904 }
905 }
906 }
907 return(0);
908}
909checkreg(p,s)
910struct node *p;
911char *s;
912{
913char *cp2;
914register int r;
915 /* check for (r),[r] */
916 do if (*s=='(' || *s=='[') {/* get register number */
917 char t;
918 cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0;
919 if ((r=isreg(cp2)) >= 0) {
920 uses[r]=p;
921 }
922 *s=t;
923 } while (*++s);
924}