xref: /csrg-svn/old/pcc/c2.tahoe/c22.c (revision 29775)
1 #ifndef lint
2 static char sccsid[] = "@(#)c22.c	1.6 (Berkeley/CCI) 08/14/86";
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 
13 rmove()
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);
68 		if ((regs[ACC][0]) && equstr(regs[RT2],regs[ACC]+1))
69 			*(short *)(regs[ACC]) = 0;
70 		if (r>=0) {
71 			if (r1>=0) {
72 				if (r == r1 && p->forw->op!=CBR) {
73 					delnode(p); redunm++; nchange++;
74 					break;
75 				}
76 				if(regs[r][0])
77 					savereg(r1, regs[r]+1, p->subop);
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);
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);
120 	case INC:
121 	case DEC:
122 	case CVFL:
123 		dest(p->code,p->subop, 1);
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);
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 
248 jumpsw()
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 
283 addaob()
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;
308 			if ((p2->subop==JLE || p2->subop==JLT) &&
309 			    checkaobdisp(p2)){
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 
321 ispow2(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 
327 equop(p1, p2)
328 register struct node *p1, *p2;
329 {
330 	register char *cp1, *cp2;
331 
332 	if (p1->op != p2->op || p1->subop != p2->subop)
333 		return(0);
334 	if (p1->op != NIL && ord(p1->op) < ord(MOV))
335 		return(0);
336 	if (p1->op==MOVA && p1->labno!=p2->labno) return(0);
337 	cp1 = p1->code;
338 	cp2 = p2->code;
339 	if (cp1==0 && cp2==0)
340 		return(1);
341 	if (cp1==0 || cp2==0)
342 		return(0);
343 	while (*cp1 == *cp2++)
344 		if (*cp1++ == 0)
345 			return(1);
346 	return(0);
347 }
348 
349 delnode(p) register struct node *p; {
350 	p->back->forw = p->forw;
351 	p->forw->back = p->back;
352 }
353 
354 decref(p)
355 register struct node *p;
356 {
357 	if (p && --p->refc <= 0) {
358 		nrlab++; nchange++;
359 		delnode(p);
360 	}
361 }
362 
363 struct node *
364 nonlab(ap)
365 struct node *ap;
366 {
367 	register struct node *p;
368 
369 	p = ap;
370 	while (p && p->op==LABEL)
371 		p = p->forw;
372 	return(p);
373 }
374 
375 clearuse() {
376 	register struct node **i;
377 	for (i=uses+NREG; i>uses;) *--i=0;
378 	useacc = 0;
379 }
380 
381 clearreg() {
382 	register char **i;
383 	for (i=regs+NREG+1; i>regs;){ **--i=0; **i=0; }
384 	conloc[0] = 0; ccloc[0] = 0;
385 }
386 
387 savereg(ai, s, type)
388 register char *s;
389 {
390 	register char *p, *sp;
391 
392 	sp = p = regs[ai];
393 	/* if any indexing, must be parameter or local */
394 	/* indirection (as in "*-4(fp)") is ok, however */
395 	*p++ = type;
396 	if (*s=='*' || *s=='$')
397 		*p++ = *s++;
398 	if (natural(s))
399 		strcpy(p, s);
400 	else {*sp = 0; return;}
401 }
402 
403 dest(s,type, ccflg)
404 register char *s;
405 {
406 	register int i;
407 
408 	if ((i = isreg(s)) >= 0) {
409 		*(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
410 		if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF) || type==QUAD)
411 			*(short *)(regs[i+1]) = 0;
412 	}
413 	for (i=NREG; --i>=0;)
414 		if (regs[i][1]=='*' && equstr(s, regs[i]+2))
415 			*(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */
416 	while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */
417 		*(short *)(regs[i]) = 0;
418 
419 	if (!natural(s)) {/* wild store, everything except constants vanishes */
420 		for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0;
421 		conloc[0] = 0; ccloc[0] = 0;
422 	} else {
423 		if(ccflg)setcc(s,type); /* natural destinations set condition codes */
424 		if (equstr(s, conloc))
425 			conloc[0] = 0;
426 	}
427 }
428 
429 splitrand(p) struct node *p; {
430 /* separate operands at commas, set up 'regs' and 'lastrand' */
431 register char *p1, *p2; register char **preg;
432 
433 	preg=regs+RT1;
434 	if (p1=p->code) while (*p1) {
435 		lastrand=p2= *preg++;
436 		while (*p1) if (','==(*p2++= *p1++)) {--p2; break;}
437 		*p2=0;
438 	}
439 	while (preg<(regs+RT1+5)) *(*preg++)=0;
440 }
441 
442 compat(have, want)
443 register int have, want;
444 {
445 	register int hsrc, hdst;
446 	extern int bitsize[];
447 
448 	if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
449 	hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;
450 	if (want>=QUAD)
451 		return(bitsize[hdst]==bitsize[want] && bitsize[hsrc]==bitsize[want]);
452 	return(hsrc==want && hdst>=want && hdst<QUAD);
453 }
454 
455 equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}
456 
457 findrand(as, type)
458 char *as;
459 {
460 	register char **i;
461 	for (i = regs+NREG; --i>=regs;) {
462 		if (**i && equstr(*i+1, as) && compat(**i,type))
463 			return(i-regs);
464 	}
465 	return(-1);
466 }
467 
468 isreg(s)
469 register char *s;
470 {
471 	if (*s++!='r' || !isdigit(*s++)) return(-1);
472 	if (*s==0) return(*--s-'0');
473 	if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0');
474 	return(-1);
475 }
476 
477 /*
478 check()
479 {
480 	register struct node *p, *lp;
481 
482 	lp = &first;
483 	for (p=first.forw; p!=0; p = p->forw) {
484 		if (p->back != lp)
485 			abort(-1);
486 		lp = p;
487 	}
488 }
489 */
490 
491 newcode(p) struct node *p; {
492 	register char *p1,*p2,**preg;
493 
494 	preg=regs+RT1; p2=line;
495 	while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';}
496 	*--p2=0;
497 	p->code=copy(line);
498 }
499 
500 repladdr(p)
501 struct node *p;
502 {
503 	register int r;
504 	register char *p1;
505 	register char **preg;
506 	register int nrepl;
507 
508 	preg=regs+RT1; nrepl=0;
509 	while (lastrand!=(p1= *preg++))
510 		if (0<=(r=findrand(p1,p->subop))) {
511 			*p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0;
512 			nchange++; nrepl++; nsaddr++;
513 		}
514 	if (nrepl) newcode(p);
515 }
516 
517 /* conditional branches which are never/always taken */
518 reduncbr(p)
519 register struct node *p;
520 {
521 	register struct node *p1;
522 	register char *ap1, *ap2;
523 
524 	p1 = p->back;
525 	if (p1->op==CMP) {
526 		splitrand(p1);
527 		ap1 = findcon(regs[RT1], p1->subop);
528 		ap2 = findcon(regs[RT2], p1->subop);
529 	} else {
530 		if(!ccloc[0])
531 			return;
532 		ap1 = findcon(ccloc+1, ccloc[0]);
533 		ap2 = "$0";
534 	}
535 	switch (compare(p->subop, ap1, ap2)) {
536 	case 0:		/* branch never taken */
537 		delnode(p);
538 		nredunj++;
539 		nchange++;
540 		decref(p->ref);
541 		if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) {
542 			delnode(p1);
543 			nrtst++;
544 		}
545 		break;
546 	case 1:		/* branch always taken */
547 		p->op = JBR;
548 		p->subop = 0;
549 		p->pop = 0;
550 		nchange++;
551 		if(nonlab(p->ref)->op!=CBR && (p1->op==TST || p1->op==CMP)) {
552 			delnode(p1);
553 			nrtst++;
554 		}
555 	}
556 }
557 
558 /* a jump to a redundant compare (start of a 'for') */
559 redunbr(p)
560 register struct node *p;
561 {
562 	register struct node *p1;
563 	register char *ap1, *ap2;
564 
565 	if ((p1 = p->ref) == 0)
566 		return;
567 	p1 = nonlab(p1);
568 	if (p1->op==TST || p1->op==CMP)
569 		splitrand(p1);
570 	else
571 		return;
572 	if (p1->forw->op==CBR) {
573 		ap1 = findcon(regs[RT1], p1->subop);
574 		if (p1->op==TST)
575 			ap2 = "$0";
576 		else
577 			ap2 = findcon(regs[RT2], p1->subop);
578 		p1 = p1->forw;
579 		if (compare(p1->subop, ap1, ap2) > 0) {
580 			nredunj++;
581 			nchange++;
582 			decref(p->ref);
583 			p->ref = p1->ref;
584 			p->labno = p1->labno;
585 #ifdef COPYCODE
586 			if (p->labno == 0)
587 				p->code = p1->code;
588 			if (p->ref)
589 #endif
590 				p->ref->refc++;
591 		}
592 	} else if (p1->op==TST && equstr(regs[RT1],ccloc+1) &&
593 			equtype(ccloc[0],p1->subop)) {
594 		p1=insertl(p1->forw); decref(p->ref); p->ref=p1;
595 		nrtst++; nchange++;
596 	}
597 }
598 
599 char *
600 findcon(p, type)
601 	register char *p;
602 {
603 	register int r;
604 
605 	if (*p=='$')
606 		return(p);
607 	if ((r = isreg(p)) >= 0 && compat(regs[r][0],type))
608 		return(regs[r]+1);
609 	if (equstr(p, conloc) && equtype(conloc[0], type))
610 		return(conval+1);
611 	return(p);
612 }
613 
614 /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */
615 compare(op, acp1, acp2)
616 char *acp1, *acp2;
617 {
618 	register char *cp1, *cp2;
619 	register int n1, n2, sign;
620 
621 	cp1 = acp1;
622 	cp2 = acp2;
623 	if (*cp1++ != '$' || *cp2++ != '$')
624 		return(-1);
625 	n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;}
626 	while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';}
627 	n1 *= sign;
628 	n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;}
629 	while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';}
630 	n2 *= sign;
631 	if (*cp1=='+')
632 		cp1++;
633 	if (*cp2=='+')
634 		cp2++;
635 	do {
636 		if (*cp1++ != *cp2)
637 			return(-1);
638 	} while (*cp2++);
639 	switch(op) {
640 
641 	case JEQ:
642 		return(n1 == n2);
643 	case JNE:
644 		return(n1 != n2);
645 	case JLE:
646 		return(n1 <= n2);
647 	case JGE:
648 		return(n1 >= n2);
649 	case JLT:
650 		return(n1 < n2);
651 	case JGT:
652 		return(n1 > n2);
653 	case JLO:
654 		return((unsigned)n1 < (unsigned)n2);
655 	case JHI:
656 		return((unsigned)n1 > (unsigned)n2);
657 	case JLOS:
658 		return((unsigned)n1 <= (unsigned)n2);
659 	case JHIS:
660 		return((unsigned)n1 >= (unsigned)n2);
661 	}
662 	return(-1);
663 }
664 
665 setcon(cv, cl, type)
666 register char *cv, *cl;
667 {
668 	register char *p;
669 
670 	if (*cv != '$')
671 		return;
672 	if (!natural(cl))
673 		return;
674 	p = conloc;
675 	while (*p++ = *cl++);
676 	p = conval;
677 	*p++ = type;
678 	while (*p++ = *cv++);
679 }
680 
681 setcc(ap,type)
682 char *ap;
683 {
684 	register char *p, *p1;
685 
686 	p = ap;
687 	if (!natural(p)) {
688 		ccloc[0] = 0;
689 		return;
690 	}
691 	p1 = ccloc;
692 	*p1++ = type;
693 	while (*p1++ = *p++);
694 }
695 
696 indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
697 	while (*p) if (*p++=='[') return(1);
698 	return(0);
699 }
700 
701 natural(p)
702 register char *p;
703 {/* 1->simple local, parameter, global, or register; 0->otherwise */
704 
705 	if (*p=='*' || *p=='(' || *p=='$')
706 		return(0);
707 	while (*p++);
708 	p--;
709 	if (*--p==']' || *p==')' &&
710 	 !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1'))
711 		return(0);
712 	return(1);
713 }
714 
715 /*
716 ** Tell if an argument is most likely static.
717 */
718 
719 isstatic(cp)
720 register char	*cp;
721 {
722 	if (*cp == '_' || *cp == 'L')
723 		return (1);
724 	return (0);
725 }
726 
727 
728 checkaobdisp(p)
729 register struct node *p;
730 {
731 register struct node *q;
732 register int i;
733 
734 
735 if (!aobflag) return(1);
736 /*  backward search */
737 	i = 0;
738 	q = p;
739 	while (i++ < MAXAOBDISP && ((q= q->back) !=&first))
740 	{
741 		if (p->ref == q)
742 		   return(1);
743 	}
744 
745 /*  forward search */
746 	i = 0;
747 	q = p;
748 	while (i++ < MAXAOBDISP && ((q= q->forw) !=0))
749 	{
750 		if (p->ref == q)
751 		   return(1);
752 	}
753 	return(0);
754 }
755 
756 
757 struct intleavetab intltab[] = {
758 	ADDF,	FLOAT,		1,
759 	ADDF,	DOUBLE,		1,
760 	SUBF,	FLOAT,		1,
761 	SUBF,	DOUBLE,		1,
762 	MULF,	FLOAT,		1,
763 	MULF,	DOUBLE,		1,
764 	DIVF,	FLOAT,		1,
765 	DIVF,	DOUBLE,		1,
766 	SINF,	FLOAT,		1,
767 	COSF,	FLOAT,		1,
768 	ATANF,	FLOAT,		1,
769 	LOGF,	FLOAT,		1,
770 	SQRTF,	FLOAT,		1,
771 	EXPF,	FLOAT,		1,
772 	LDF,	FLOAT,		0,
773 	LDF,	DOUBLE,		0,
774 	LNF,	FLOAT,		0,
775 	LNF,	DOUBLE,		0,
776 	STF,	FLOAT,		0,
777 	CMPF,	FLOAT,		0,
778 	CMPF,	DOUBLE,		0,
779 	CMPF2,	FLOAT,		0,
780 	TSTF,	FLOAT,		0,
781 	TSTF,	DOUBLE,		0,
782 	PUSHD,	DOUBLE,		0,
783 	CVLF,	U(LONG,FLOAT),	0,
784 	CVFL,	U(FLOAT,LONG),	0,
785 	LDFD,	U(FLOAT,DOUBLE),0,
786 	CVDF,	U(DOUBLE,FLOAT),0,
787 	NEGF,	FLOAT,		0,
788 	NIL,	0,		0};
789 
790 interleave()
791 {
792 	register struct node *p, *p1;
793 
794 	register struct intleavetab *t;
795 	register int r;
796 	int count;
797 	for (p= first.forw; p!=0; p = p->forw){
798 		count = 0;
799 		for  (t =intltab; t->op != NIL; t++){
800 			if (t->op == p->op && t->subop == p->subop){
801 			count = t->intleavect;
802 			break;
803 			}
804 		}
805 		if (count < 1) continue;
806 		p1 = p->forw;
807 		clearuse();
808 		clearreg();
809 		while ((p1 != 0) && (p1->op != CBR) &&
810 		      (p1->subop == FLOAT || p1->subop == DOUBLE ||
811 	              ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )||
812 	              ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT))
813 		{
814 			if (((r = isreg(p1->code)) >= 0)){
815 			uses[r] = p1;
816 			if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) ||
817 		           ((p->subop&0xF)==DOUBLE))
818 				uses[r+1] = p1;
819 			}
820 			else checkreg(p1,p1->code);
821 			p1 = p1->forw;
822 
823 		}
824 		if (p1 == 0) return;
825 		if (!(sideeffect(p, p1)))
826 			insertblk(p,p1);
827 	}
828 
829 }
830 
831 
832 insertblk(p, p1)
833 struct node *p, *p1;
834 {
835 	p1->back->forw = p1->forw;
836 	p1->forw->back = p1->back;
837 	p1->forw = p->forw;
838 	p->forw->back = p1;
839 	p->forw = p1;
840 	p1->back = p;
841 }
842 
843 OpCode termop[] = {
844 	JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT,
845 	CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR,
846 	MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET,
847 	LCOMM, COMM, NIL
848 };
849 
850 sideeffect(p,p1)
851 struct node *p, *p1;
852 {
853 	register struct node *q;
854 	register int r;
855 	register OpCode *t;
856 	register char *cp;
857 	int i;
858 
859 	if (p1->op == NIL) return(1);  /*  special instructions */
860 
861 	for (t = termop; *t!=NIL; t++){
862 		if (*t == p1->op) return(1);
863 	}
864 	if ((p1->forw != NULL) && (p1->forw->op == CBR))
865 		return(1);
866 	splitrand(p1);
867 	r = isreg(lastrand);
868 	if (uses[r] &&  r >= 0 ) return(1);
869 	if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) &&
870 	   (uses[r]))  return(1);
871 
872 	for (q = p1->back ; q!=p; q=q->back)
873 	{
874 		if ((p1->op == PUSH || p1->op == PUSHA) &&
875 		    (q->op == PUSHD || q->op == PUSH || q->op == PUSHA))
876 		     return(1); 		     /* keep args in order */
877 		if (((i = strlen(q->code)) >= 5 &&    /* cvdl -(sp); pushl r0*/
878 		    (strcmp(q->code+i-5,"-(sp)") == 0 )) ||
879 		    (strcmp(lastrand,"-(sp)") == 0)) return(1);
880 		if (equstr(q->code, lastrand))
881 		    return(1);
882 		if (q->op == STF || q->op == CVFL || q->op == CVLF)
883 		   {
884 		    if (equstr(q->code, regs[RT1])) return(1);
885 		if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV)
886 		    if (equstr(q->code, regs[RT2]))
887 		       return(1);
888 		/*  handle the case  std -56(fp) pushl -60(fp) pushl
889 		    -56(fp);
890 		*/
891 		if ((p1->forw != NULL) &&  (q->op == STF) &&
892 		(q->subop == DOUBLE)){
893 		if (!strncmp(q->code,p1->forw->code,strlen(q->code)))
894 			return(1);
895 		}
896 		}
897 	}
898 	return(0);
899 }
900 checkreg(p,s)
901 struct node *p;
902 char *s;
903 {
904 char *cp2;
905 register int r;
906 	/* check for (r),[r] */
907 	do if (*s=='(' || *s=='[') {/* get register number */
908 		char t;
909 		cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0;
910 		if ((r=isreg(cp2)) >= 0)  {
911 			uses[r]=p;
912 		}
913 		*s=t;
914 	} while (*++s);
915 }
916