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