xref: /plan9/sys/src/cmd/kl/noop.c (revision 6b6b9ac8b0b103b1e30e4d019522a78c950fce74)
13e12c5d1SDavid du Colombier #include	"l.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier void
noops(void)43e12c5d1SDavid du Colombier noops(void)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 	Prog *p, *p1, *q, *q1;
7219b2ee8SDavid du Colombier 	int o, curframe, curbecome, maxbecome;
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier 	/*
10219b2ee8SDavid du Colombier 	 * find leaf subroutines
11219b2ee8SDavid du Colombier 	 * become sizes
12219b2ee8SDavid du Colombier 	 * frame sizes
13219b2ee8SDavid du Colombier 	 * strip NOPs
14219b2ee8SDavid du Colombier 	 * expand RET
15219b2ee8SDavid du Colombier 	 * expand BECOME pseudo
163e12c5d1SDavid du Colombier 	 */
173e12c5d1SDavid du Colombier 
183e12c5d1SDavid du Colombier 	if(debug['v'])
193e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f noops\n", cputime());
203e12c5d1SDavid du Colombier 	Bflush(&bso);
213e12c5d1SDavid du Colombier 
22219b2ee8SDavid du Colombier 	curframe = 0;
23219b2ee8SDavid du Colombier 	curbecome = 0;
24219b2ee8SDavid du Colombier 	maxbecome = 0;
25219b2ee8SDavid du Colombier 	curtext = 0;
263e12c5d1SDavid du Colombier 	q = P;
273e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
28219b2ee8SDavid du Colombier 
29219b2ee8SDavid du Colombier 		/* find out how much arg space is used in this TEXT */
30219b2ee8SDavid du Colombier 		if(p->to.type == D_OREG && p->to.reg == REGSP)
31219b2ee8SDavid du Colombier 			if(p->to.offset > curframe)
32219b2ee8SDavid du Colombier 				curframe = p->to.offset;
33219b2ee8SDavid du Colombier 
343e12c5d1SDavid du Colombier 		switch(p->as) {
353e12c5d1SDavid du Colombier 		/* too hard, just leave alone */
363e12c5d1SDavid du Colombier 		case ATEXT:
37219b2ee8SDavid du Colombier 			if(curtext && curtext->from.sym) {
38219b2ee8SDavid du Colombier 				curtext->from.sym->frame = curframe;
39219b2ee8SDavid du Colombier 				curtext->from.sym->become = curbecome;
40219b2ee8SDavid du Colombier 				if(curbecome > maxbecome)
41219b2ee8SDavid du Colombier 					maxbecome = curbecome;
42219b2ee8SDavid du Colombier 			}
43219b2ee8SDavid du Colombier 			curframe = 0;
44219b2ee8SDavid du Colombier 			curbecome = 0;
45219b2ee8SDavid du Colombier 
463e12c5d1SDavid du Colombier 			q = p;
473e12c5d1SDavid du Colombier 			p->mark |= LABEL|LEAF|SYNC;
483e12c5d1SDavid du Colombier 			if(p->link)
493e12c5d1SDavid du Colombier 				p->link->mark |= LABEL;
503e12c5d1SDavid du Colombier 			curtext = p;
513e12c5d1SDavid du Colombier 			break;
523e12c5d1SDavid du Colombier 
533e12c5d1SDavid du Colombier 		case AORN:
543e12c5d1SDavid du Colombier 			q = p;
553e12c5d1SDavid du Colombier 			if(p->to.type == D_REG)
563e12c5d1SDavid du Colombier 				if(p->to.reg == REGZERO)
573e12c5d1SDavid du Colombier 					p->mark |= LABEL|SYNC;
583e12c5d1SDavid du Colombier 			break;
593e12c5d1SDavid du Colombier 
603e12c5d1SDavid du Colombier 		case AUNIMP:
613e12c5d1SDavid du Colombier 		case ATAS:
623e12c5d1SDavid du Colombier 		case ASWAP:
633e12c5d1SDavid du Colombier 		case ATA:
643e12c5d1SDavid du Colombier 		case ATCC:
653e12c5d1SDavid du Colombier 		case ATCS:
663e12c5d1SDavid du Colombier 		case ATE:
673e12c5d1SDavid du Colombier 		case ATG:
683e12c5d1SDavid du Colombier 		case ATGE:
693e12c5d1SDavid du Colombier 		case ATGU:
703e12c5d1SDavid du Colombier 		case ATL:
713e12c5d1SDavid du Colombier 		case ATLE:
723e12c5d1SDavid du Colombier 		case ATLEU:
733e12c5d1SDavid du Colombier 		case ATN:
743e12c5d1SDavid du Colombier 		case ATNE:
753e12c5d1SDavid du Colombier 		case ATNEG:
763e12c5d1SDavid du Colombier 		case ATPOS:
773e12c5d1SDavid du Colombier 		case ATVC:
783e12c5d1SDavid du Colombier 		case ATVS:
793e12c5d1SDavid du Colombier 		case AWORD:
803e12c5d1SDavid du Colombier 			q = p;
813e12c5d1SDavid du Colombier 			p->mark |= LABEL|SYNC;
823e12c5d1SDavid du Colombier 			continue;
833e12c5d1SDavid du Colombier 
843e12c5d1SDavid du Colombier 		case AFABSD:
853e12c5d1SDavid du Colombier 		case AFABSF:
863e12c5d1SDavid du Colombier 		case AFABSX:
873e12c5d1SDavid du Colombier 		case AFADDD:
883e12c5d1SDavid du Colombier 		case AFADDF:
893e12c5d1SDavid du Colombier 		case AFADDX:
903e12c5d1SDavid du Colombier 		case AFDIVD:
913e12c5d1SDavid du Colombier 		case AFDIVF:
923e12c5d1SDavid du Colombier 		case AFDIVX:
933e12c5d1SDavid du Colombier 		case AFMOVD:
943e12c5d1SDavid du Colombier 		case AFMOVDF:
953e12c5d1SDavid du Colombier 		case AFMOVDW:
963e12c5d1SDavid du Colombier 		case AFMOVDX:
973e12c5d1SDavid du Colombier 		case AFMOVF:
983e12c5d1SDavid du Colombier 		case AFMOVFD:
993e12c5d1SDavid du Colombier 		case AFMOVFW:
1003e12c5d1SDavid du Colombier 		case AFMOVFX:
1013e12c5d1SDavid du Colombier 		case AFMOVWD:
1023e12c5d1SDavid du Colombier 		case AFMOVWF:
1033e12c5d1SDavid du Colombier 		case AFMOVWX:
1043e12c5d1SDavid du Colombier 		case AFMOVX:
1053e12c5d1SDavid du Colombier 		case AFMOVXD:
1063e12c5d1SDavid du Colombier 		case AFMOVXF:
1073e12c5d1SDavid du Colombier 		case AFMOVXW:
1083e12c5d1SDavid du Colombier 		case AFMULD:
1093e12c5d1SDavid du Colombier 		case AFMULF:
1103e12c5d1SDavid du Colombier 		case AFMULX:
1113e12c5d1SDavid du Colombier 		case AFNEGD:
1123e12c5d1SDavid du Colombier 		case AFNEGF:
1133e12c5d1SDavid du Colombier 		case AFNEGX:
1143e12c5d1SDavid du Colombier 		case AFSQRTD:
1153e12c5d1SDavid du Colombier 		case AFSQRTF:
1163e12c5d1SDavid du Colombier 		case AFSQRTX:
1173e12c5d1SDavid du Colombier 		case AFSUBD:
1183e12c5d1SDavid du Colombier 		case AFSUBF:
1193e12c5d1SDavid du Colombier 		case AFSUBX:
1203e12c5d1SDavid du Colombier 			q = p;
1213e12c5d1SDavid du Colombier 			p->mark |= FLOAT;
1223e12c5d1SDavid du Colombier 			continue;
1233e12c5d1SDavid du Colombier 
1243e12c5d1SDavid du Colombier 		case AMUL:
1253e12c5d1SDavid du Colombier 		case ADIV:
1263e12c5d1SDavid du Colombier 		case ADIVL:
1273e12c5d1SDavid du Colombier 		case AMOD:
1283e12c5d1SDavid du Colombier 		case AMODL:
1293e12c5d1SDavid du Colombier 			q = p;
1303e12c5d1SDavid du Colombier 			if(!debug['M']) {
1313e12c5d1SDavid du Colombier 				if(prog_mul == P)
1323e12c5d1SDavid du Colombier 					initmuldiv();
1333e12c5d1SDavid du Colombier 				if(curtext != P)
1343e12c5d1SDavid du Colombier 					curtext->mark &= ~LEAF;
1353e12c5d1SDavid du Colombier 			}
1363e12c5d1SDavid du Colombier 			continue;
1373e12c5d1SDavid du Colombier 
1383e12c5d1SDavid du Colombier 		case AJMPL:
1393e12c5d1SDavid du Colombier 			if(curtext != P)
1403e12c5d1SDavid du Colombier 				curtext->mark &= ~LEAF;
1413e12c5d1SDavid du Colombier 
1423e12c5d1SDavid du Colombier 		case AJMP:
1433e12c5d1SDavid du Colombier 
1443e12c5d1SDavid du Colombier 		case ABA:
1453e12c5d1SDavid du Colombier 		case ABN:
1463e12c5d1SDavid du Colombier 		case ABE:
1473e12c5d1SDavid du Colombier 		case ABNE:
1483e12c5d1SDavid du Colombier 		case ABLE:
1493e12c5d1SDavid du Colombier 		case ABG:
1503e12c5d1SDavid du Colombier 		case ABL:
1513e12c5d1SDavid du Colombier 		case ABGE:
1523e12c5d1SDavid du Colombier 		case ABLEU:
1533e12c5d1SDavid du Colombier 		case ABGU:
1543e12c5d1SDavid du Colombier 		case ABCS:
1553e12c5d1SDavid du Colombier 		case ABCC:
1563e12c5d1SDavid du Colombier 		case ABNEG:
1573e12c5d1SDavid du Colombier 		case ABPOS:
1583e12c5d1SDavid du Colombier 		case ABVC:
1593e12c5d1SDavid du Colombier 		case ABVS:
1603e12c5d1SDavid du Colombier 
1613e12c5d1SDavid du Colombier 		case AFBN:
1623e12c5d1SDavid du Colombier 		case AFBO:
1633e12c5d1SDavid du Colombier 		case AFBE:
1643e12c5d1SDavid du Colombier 		case AFBLG:
1653e12c5d1SDavid du Colombier 		case AFBG:
1663e12c5d1SDavid du Colombier 		case AFBLE:
1673e12c5d1SDavid du Colombier 		case AFBGE:
1683e12c5d1SDavid du Colombier 		case AFBL:
1693e12c5d1SDavid du Colombier 		case AFBNE:
1703e12c5d1SDavid du Colombier 		case AFBUE:
1713e12c5d1SDavid du Colombier 		case AFBA:
1723e12c5d1SDavid du Colombier 		case AFBU:
1733e12c5d1SDavid du Colombier 		case AFBUG:
1743e12c5d1SDavid du Colombier 		case AFBULE:
1753e12c5d1SDavid du Colombier 		case AFBUGE:
1763e12c5d1SDavid du Colombier 		case AFBUL:
1773e12c5d1SDavid du Colombier 			p->mark |= BRANCH;
1783e12c5d1SDavid du Colombier 			q = p;
1793e12c5d1SDavid du Colombier 			q1 = p->cond;
1803e12c5d1SDavid du Colombier 			if(q1 != P) {
1813e12c5d1SDavid du Colombier 				while(q1->as == ANOP) {
1823e12c5d1SDavid du Colombier 					q1 = q1->link;
1833e12c5d1SDavid du Colombier 					p->cond = q1;
1843e12c5d1SDavid du Colombier 				}
1853e12c5d1SDavid du Colombier 				if(!(q1->mark & LEAF))
1863e12c5d1SDavid du Colombier 					q1->mark |= LABEL;
1873e12c5d1SDavid du Colombier 			} else
1883e12c5d1SDavid du Colombier 				p->mark |= LABEL;
1893e12c5d1SDavid du Colombier 			q1 = p->link;
1903e12c5d1SDavid du Colombier 			if(q1 != P)
1913e12c5d1SDavid du Colombier 				q1->mark |= LABEL;
1923e12c5d1SDavid du Colombier 			continue;
1933e12c5d1SDavid du Colombier 
1943e12c5d1SDavid du Colombier 		case AFCMPD:
1953e12c5d1SDavid du Colombier 		case AFCMPED:
1963e12c5d1SDavid du Colombier 		case AFCMPEF:
1973e12c5d1SDavid du Colombier 		case AFCMPEX:
1983e12c5d1SDavid du Colombier 		case AFCMPF:
1993e12c5d1SDavid du Colombier 		case AFCMPX:
2003e12c5d1SDavid du Colombier 			q = p;
2013e12c5d1SDavid du Colombier 			p->mark |= FCMP|FLOAT;
2023e12c5d1SDavid du Colombier 			continue;
2033e12c5d1SDavid du Colombier 
2043e12c5d1SDavid du Colombier 		case ARETURN:
205219b2ee8SDavid du Colombier 			/* special form of RETURN is BECOME */
206219b2ee8SDavid du Colombier 			if(p->from.type == D_CONST)
207219b2ee8SDavid du Colombier 				if(p->from.offset > curbecome)
208219b2ee8SDavid du Colombier 					curbecome = p->from.offset;
209219b2ee8SDavid du Colombier 
2103e12c5d1SDavid du Colombier 			q = p;
2113e12c5d1SDavid du Colombier 			if(p->link != P)
2123e12c5d1SDavid du Colombier 				p->link->mark |= LABEL;
2133e12c5d1SDavid du Colombier 			continue;
2143e12c5d1SDavid du Colombier 
2153e12c5d1SDavid du Colombier 		case ANOP:
2163e12c5d1SDavid du Colombier 			q1 = p->link;
2173e12c5d1SDavid du Colombier 			q->link = q1;		/* q is non-nop */
2183e12c5d1SDavid du Colombier 			q1->mark |= p->mark;
2193e12c5d1SDavid du Colombier 			continue;
2203e12c5d1SDavid du Colombier 
2213e12c5d1SDavid du Colombier 		default:
2223e12c5d1SDavid du Colombier 			q = p;
2233e12c5d1SDavid du Colombier 			continue;
2243e12c5d1SDavid du Colombier 		}
2253e12c5d1SDavid du Colombier 	}
226219b2ee8SDavid du Colombier 	if(curtext && curtext->from.sym) {
227219b2ee8SDavid du Colombier 		curtext->from.sym->frame = curframe;
228219b2ee8SDavid du Colombier 		curtext->from.sym->become = curbecome;
229219b2ee8SDavid du Colombier 		if(curbecome > maxbecome)
230219b2ee8SDavid du Colombier 			maxbecome = curbecome;
231219b2ee8SDavid du Colombier 	}
232219b2ee8SDavid du Colombier 
233219b2ee8SDavid du Colombier 	if(debug['b'])
234219b2ee8SDavid du Colombier 		print("max become = %d\n", maxbecome);
235219b2ee8SDavid du Colombier 	xdefine("ALEFbecome", STEXT, maxbecome);
236219b2ee8SDavid du Colombier 
237219b2ee8SDavid du Colombier 	curtext = 0;
238219b2ee8SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
239219b2ee8SDavid du Colombier 		switch(p->as) {
240219b2ee8SDavid du Colombier 		case ATEXT:
241219b2ee8SDavid du Colombier 			curtext = p;
242219b2ee8SDavid du Colombier 			break;
243219b2ee8SDavid du Colombier 
244219b2ee8SDavid du Colombier 		case AJMPL:
245219b2ee8SDavid du Colombier 			if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
246219b2ee8SDavid du Colombier 				o = maxbecome - curtext->from.sym->frame;
247219b2ee8SDavid du Colombier 				if(o <= 0)
248219b2ee8SDavid du Colombier 					break;
249219b2ee8SDavid du Colombier 				/* calling a become or calling a variable */
250219b2ee8SDavid du Colombier 				if(p->to.sym == S || p->to.sym->become) {
251219b2ee8SDavid du Colombier 					curtext->to.offset += o;
252219b2ee8SDavid du Colombier 					if(debug['b']) {
253219b2ee8SDavid du Colombier 						curp = p;
254219b2ee8SDavid du Colombier 						print("%D calling %D increase %d\n",
255219b2ee8SDavid du Colombier 							&curtext->from, &p->to, o);
256219b2ee8SDavid du Colombier 					}
257219b2ee8SDavid du Colombier 				}
258219b2ee8SDavid du Colombier 			}
259219b2ee8SDavid du Colombier 			break;
260219b2ee8SDavid du Colombier 		}
261219b2ee8SDavid du Colombier 	}
2623e12c5d1SDavid du Colombier 
2633e12c5d1SDavid du Colombier 	curtext = P;
2643e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
2653e12c5d1SDavid du Colombier 		o = p->as;
2663e12c5d1SDavid du Colombier 		switch(o) {
2673e12c5d1SDavid du Colombier 		case ATEXT:
2683e12c5d1SDavid du Colombier 			curtext = p;
2693e12c5d1SDavid du Colombier 			autosize = p->to.offset + 4;
2703e12c5d1SDavid du Colombier 			if((p->mark & LEAF) && autosize <= 4)
2713e12c5d1SDavid du Colombier 				autosize = 0;
2723e12c5d1SDavid du Colombier 			else
2733e12c5d1SDavid du Colombier 				if(autosize & 4)
2743e12c5d1SDavid du Colombier 					autosize += 4;
2753e12c5d1SDavid du Colombier 			p->to.offset = autosize - 4;
2763e12c5d1SDavid du Colombier 
2773e12c5d1SDavid du Colombier 			q = p;
2783e12c5d1SDavid du Colombier 			if(autosize) {
2793e12c5d1SDavid du Colombier 				q = prg();
2803e12c5d1SDavid du Colombier 				q->as = ASUB;
2813e12c5d1SDavid du Colombier 				q->line = p->line;
2823e12c5d1SDavid du Colombier 				q->from.type = D_CONST;
2833e12c5d1SDavid du Colombier 				q->from.offset = autosize;
2843e12c5d1SDavid du Colombier 				q->to.type = D_REG;
2853e12c5d1SDavid du Colombier 				q->to.reg = REGSP;
2863e12c5d1SDavid du Colombier 
2873e12c5d1SDavid du Colombier 				q->link = p->link;
2883e12c5d1SDavid du Colombier 				p->link = q;
2893e12c5d1SDavid du Colombier 			} else
2903e12c5d1SDavid du Colombier 			if(!(curtext->mark & LEAF)) {
2913e12c5d1SDavid du Colombier 				if(debug['v'])
2923e12c5d1SDavid du Colombier 					Bprint(&bso, "save suppressed in: %s\n",
2933e12c5d1SDavid du Colombier 						curtext->from.sym->name);
2943e12c5d1SDavid du Colombier 				curtext->mark |= LEAF;
2953e12c5d1SDavid du Colombier 			}
2963e12c5d1SDavid du Colombier 
2973e12c5d1SDavid du Colombier 			if(curtext->mark & LEAF) {
2983e12c5d1SDavid du Colombier 				if(curtext->from.sym)
2993e12c5d1SDavid du Colombier 					curtext->from.sym->type = SLEAF;
3003e12c5d1SDavid du Colombier 				break;
3013e12c5d1SDavid du Colombier 			}
3023e12c5d1SDavid du Colombier 
3033e12c5d1SDavid du Colombier 			q1 = prg();
3043e12c5d1SDavid du Colombier 			q1->as = AMOVW;
3053e12c5d1SDavid du Colombier 			q1->line = p->line;
3063e12c5d1SDavid du Colombier 			q1->from.type = D_REG;
3073e12c5d1SDavid du Colombier 			q1->from.reg = REGLINK;
3083e12c5d1SDavid du Colombier 			q1->to.type = D_OREG;
3093e12c5d1SDavid du Colombier 			q1->from.offset = 0;
3103e12c5d1SDavid du Colombier 			q1->to.reg = REGSP;
3113e12c5d1SDavid du Colombier 
3123e12c5d1SDavid du Colombier 			q1->link = q->link;
3133e12c5d1SDavid du Colombier 			q->link = q1;
3143e12c5d1SDavid du Colombier 			break;
3153e12c5d1SDavid du Colombier 
3163e12c5d1SDavid du Colombier 		case AMUL:
3173e12c5d1SDavid du Colombier 		case ADIV:
3183e12c5d1SDavid du Colombier 		case ADIVL:
3193e12c5d1SDavid du Colombier 		case AMOD:
3203e12c5d1SDavid du Colombier 		case AMODL:
3213e12c5d1SDavid du Colombier 			if(debug['M'])
3223e12c5d1SDavid du Colombier 				break;
3233e12c5d1SDavid du Colombier 			if(p->from.type != D_REG)
3243e12c5d1SDavid du Colombier 				break;
3253e12c5d1SDavid du Colombier 			if(p->to.type != D_REG)
3263e12c5d1SDavid du Colombier 				break;
3273e12c5d1SDavid du Colombier 			q1 = p;
3283e12c5d1SDavid du Colombier 
3293e12c5d1SDavid du Colombier 			/* MOV a,4(SP) */
3303e12c5d1SDavid du Colombier 			q = prg();
3313e12c5d1SDavid du Colombier 			q->link = p->link;
3323e12c5d1SDavid du Colombier 			p->link = q;
3333e12c5d1SDavid du Colombier 			p = q;
3343e12c5d1SDavid du Colombier 
3353e12c5d1SDavid du Colombier 			p->as = AMOVW;
3363e12c5d1SDavid du Colombier 			p->line = q1->line;
3373e12c5d1SDavid du Colombier 			p->from.type = D_REG;
3383e12c5d1SDavid du Colombier 			p->from.reg = q1->from.reg;
3393e12c5d1SDavid du Colombier 			p->to.type = D_OREG;
3403e12c5d1SDavid du Colombier 			p->to.reg = REGSP;
3413e12c5d1SDavid du Colombier 			p->to.offset = 4;
3423e12c5d1SDavid du Colombier 
3433e12c5d1SDavid du Colombier 			/* MOV b,REGTMP */
3443e12c5d1SDavid du Colombier 			q = prg();
3453e12c5d1SDavid du Colombier 			q->link = p->link;
3463e12c5d1SDavid du Colombier 			p->link = q;
3473e12c5d1SDavid du Colombier 			p = q;
3483e12c5d1SDavid du Colombier 
3493e12c5d1SDavid du Colombier 			p->as = AMOVW;
3503e12c5d1SDavid du Colombier 			p->line = q1->line;
3513e12c5d1SDavid du Colombier 			p->from.type = D_REG;
3523e12c5d1SDavid du Colombier 			p->from.reg = q1->reg;
3533e12c5d1SDavid du Colombier 			if(q1->reg == NREG)
3543e12c5d1SDavid du Colombier 				p->from.reg = q1->to.reg;
3553e12c5d1SDavid du Colombier 			p->to.type = D_REG;
3563e12c5d1SDavid du Colombier 			p->to.reg = REGTMP;
3573e12c5d1SDavid du Colombier 			p->to.offset = 0;
3583e12c5d1SDavid du Colombier 
3593e12c5d1SDavid du Colombier 			/* CALL appropriate */
3603e12c5d1SDavid du Colombier 			q = prg();
3613e12c5d1SDavid du Colombier 			q->link = p->link;
3623e12c5d1SDavid du Colombier 			p->link = q;
3633e12c5d1SDavid du Colombier 			p = q;
3643e12c5d1SDavid du Colombier 
3653e12c5d1SDavid du Colombier 			p->as = AJMPL;
3663e12c5d1SDavid du Colombier 			p->line = q1->line;
3673e12c5d1SDavid du Colombier 			p->to.type = D_BRANCH;
3683e12c5d1SDavid du Colombier 			p->cond = p;
3693e12c5d1SDavid du Colombier 			p->mark |= BRANCH;
3703e12c5d1SDavid du Colombier 			switch(o) {
3713e12c5d1SDavid du Colombier 			case AMUL:
3723e12c5d1SDavid du Colombier 				p->cond = prog_mul;
3733e12c5d1SDavid du Colombier 				break;
3743e12c5d1SDavid du Colombier 			case ADIV:
3753e12c5d1SDavid du Colombier 				p->cond = prog_div;
3763e12c5d1SDavid du Colombier 				break;
3773e12c5d1SDavid du Colombier 			case ADIVL:
3783e12c5d1SDavid du Colombier 				p->cond = prog_divl;
3793e12c5d1SDavid du Colombier 				break;
3803e12c5d1SDavid du Colombier 			case AMOD:
3813e12c5d1SDavid du Colombier 				p->cond = prog_mod;
3823e12c5d1SDavid du Colombier 				break;
3833e12c5d1SDavid du Colombier 			case AMODL:
3843e12c5d1SDavid du Colombier 				p->cond = prog_modl;
3853e12c5d1SDavid du Colombier 				break;
3863e12c5d1SDavid du Colombier 			}
3873e12c5d1SDavid du Colombier 
3883e12c5d1SDavid du Colombier 			/* MOV REGTMP, b */
3893e12c5d1SDavid du Colombier 			q = prg();
3903e12c5d1SDavid du Colombier 			q->link = p->link;
3913e12c5d1SDavid du Colombier 			p->link = q;
3923e12c5d1SDavid du Colombier 			p = q;
3933e12c5d1SDavid du Colombier 
3943e12c5d1SDavid du Colombier 			p->as = AMOVW;
3953e12c5d1SDavid du Colombier 			p->line = q1->line;
3963e12c5d1SDavid du Colombier 			p->from.type = D_REG;
3973e12c5d1SDavid du Colombier 			p->from.reg = REGTMP;
3983e12c5d1SDavid du Colombier 			p->from.offset = 0;
3993e12c5d1SDavid du Colombier 			p->to.type = D_REG;
4003e12c5d1SDavid du Colombier 			p->to.reg = q1->to.reg;
4013e12c5d1SDavid du Colombier 
4023e12c5d1SDavid du Colombier 			/* ADD $8,SP */
4033e12c5d1SDavid du Colombier 			q = prg();
4043e12c5d1SDavid du Colombier 			q->link = p->link;
4053e12c5d1SDavid du Colombier 			p->link = q;
4063e12c5d1SDavid du Colombier 			p = q;
4073e12c5d1SDavid du Colombier 
4083e12c5d1SDavid du Colombier 			p->as = AADD;
4093e12c5d1SDavid du Colombier 			p->from.type = D_CONST;
4103e12c5d1SDavid du Colombier 			p->from.reg = NREG;
4113e12c5d1SDavid du Colombier 			p->from.offset = 8;
4123e12c5d1SDavid du Colombier 			p->reg = NREG;
4133e12c5d1SDavid du Colombier 			p->to.type = D_REG;
4143e12c5d1SDavid du Colombier 			p->to.reg = REGSP;
4153e12c5d1SDavid du Colombier 
4163e12c5d1SDavid du Colombier 			/* SUB $8,SP */
4173e12c5d1SDavid du Colombier 			q1->as = ASUB;
4183e12c5d1SDavid du Colombier 			q1->from.type = D_CONST;
4193e12c5d1SDavid du Colombier 			q1->from.offset = 8;
4203e12c5d1SDavid du Colombier 			q1->from.reg = NREG;
4213e12c5d1SDavid du Colombier 			q1->reg = NREG;
4223e12c5d1SDavid du Colombier 			q1->to.type = D_REG;
4233e12c5d1SDavid du Colombier 			q1->to.reg = REGSP;
4243e12c5d1SDavid du Colombier 			break;
4253e12c5d1SDavid du Colombier 
4263e12c5d1SDavid du Colombier 		case ARETURN:
427219b2ee8SDavid du Colombier 			if(p->from.type == D_CONST)
428219b2ee8SDavid du Colombier 				goto become;
4293e12c5d1SDavid du Colombier 			if(curtext->mark & LEAF) {
4303e12c5d1SDavid du Colombier 				if(!autosize) {
4313e12c5d1SDavid du Colombier 					p->as = AJMP;
4323e12c5d1SDavid du Colombier 					p->from = zprg.from;
4333e12c5d1SDavid du Colombier 					p->to.type = D_OREG;
4343e12c5d1SDavid du Colombier 					p->to.offset = 8;
4353e12c5d1SDavid du Colombier 					p->to.reg = REGLINK;
4363e12c5d1SDavid du Colombier 					p->mark |= BRANCH;
4373e12c5d1SDavid du Colombier 					break;
4383e12c5d1SDavid du Colombier 				}
4393e12c5d1SDavid du Colombier 
4403e12c5d1SDavid du Colombier 				p->as = AADD;
4413e12c5d1SDavid du Colombier 				p->from.type = D_CONST;
4423e12c5d1SDavid du Colombier 				p->from.offset = autosize;
4433e12c5d1SDavid du Colombier 				p->to.type = D_REG;
4443e12c5d1SDavid du Colombier 				p->to.reg = REGSP;
4453e12c5d1SDavid du Colombier 
4463e12c5d1SDavid du Colombier 				q = prg();
4473e12c5d1SDavid du Colombier 				q->as = AJMP;
4483e12c5d1SDavid du Colombier 				q->line = p->line;
4493e12c5d1SDavid du Colombier 				q->to.type = D_OREG;
4503e12c5d1SDavid du Colombier 				q->to.offset = 8;
4513e12c5d1SDavid du Colombier 				q->to.reg = REGLINK;
4523e12c5d1SDavid du Colombier 				q->mark |= BRANCH;
4533e12c5d1SDavid du Colombier 
4543e12c5d1SDavid du Colombier 				q->link = p->link;
4553e12c5d1SDavid du Colombier 				p->link = q;
4563e12c5d1SDavid du Colombier 				break;
4573e12c5d1SDavid du Colombier 			}
4583e12c5d1SDavid du Colombier 
4593e12c5d1SDavid du Colombier 			p->as = AMOVW;
4603e12c5d1SDavid du Colombier 			p->from.type = D_OREG;
4613e12c5d1SDavid du Colombier 			p->from.offset = 0;
4623e12c5d1SDavid du Colombier 			p->from.reg = REGSP;
4633e12c5d1SDavid du Colombier 			p->to.type = D_REG;
4643e12c5d1SDavid du Colombier 			p->to.reg = REGRET+1;
4653e12c5d1SDavid du Colombier 
4663e12c5d1SDavid du Colombier 			q = p;
4673e12c5d1SDavid du Colombier 			if(autosize) {
4683e12c5d1SDavid du Colombier 				q = prg();
4693e12c5d1SDavid du Colombier 				q->as = AADD;
4703e12c5d1SDavid du Colombier 				q->line = p->line;
4713e12c5d1SDavid du Colombier 				q->from.type = D_CONST;
4723e12c5d1SDavid du Colombier 				q->from.offset = autosize;
4733e12c5d1SDavid du Colombier 				q->to.type = D_REG;
4743e12c5d1SDavid du Colombier 				q->to.reg = REGSP;
4753e12c5d1SDavid du Colombier 
4763e12c5d1SDavid du Colombier 				q->link = p->link;
4773e12c5d1SDavid du Colombier 				p->link = q;
4783e12c5d1SDavid du Colombier 			}
4793e12c5d1SDavid du Colombier 
4803e12c5d1SDavid du Colombier 			q1 = prg();
4813e12c5d1SDavid du Colombier 			q1->as = AJMP;
4823e12c5d1SDavid du Colombier 			q1->line = p->line;
4833e12c5d1SDavid du Colombier 			q1->to.type = D_OREG;
4843e12c5d1SDavid du Colombier 			q1->to.offset = 8;
4853e12c5d1SDavid du Colombier 			q1->to.reg = REGRET+1;
4863e12c5d1SDavid du Colombier 			q1->mark |= BRANCH;
4873e12c5d1SDavid du Colombier 
4883e12c5d1SDavid du Colombier 			q1->link = q->link;
4893e12c5d1SDavid du Colombier 			q->link = q1;
4903e12c5d1SDavid du Colombier 			break;
491219b2ee8SDavid du Colombier 
492219b2ee8SDavid du Colombier 		become:
493219b2ee8SDavid du Colombier 			if(curtext->mark & LEAF) {
494219b2ee8SDavid du Colombier 
495219b2ee8SDavid du Colombier 				q = prg();
496219b2ee8SDavid du Colombier 				q->line = p->line;
497219b2ee8SDavid du Colombier 				q->as = AJMP;
498219b2ee8SDavid du Colombier 				q->from = zprg.from;
499219b2ee8SDavid du Colombier 				q->to = p->to;
500219b2ee8SDavid du Colombier 				q->cond = p->cond;
501219b2ee8SDavid du Colombier 				q->link = p->link;
502219b2ee8SDavid du Colombier 				q->mark |= BRANCH;
503219b2ee8SDavid du Colombier 				p->link = q;
504219b2ee8SDavid du Colombier 
505219b2ee8SDavid du Colombier 				p->as = AADD;
506219b2ee8SDavid du Colombier 				p->from = zprg.from;
507219b2ee8SDavid du Colombier 				p->from.type = D_CONST;
508219b2ee8SDavid du Colombier 				p->from.offset = autosize;
509219b2ee8SDavid du Colombier 				p->to = zprg.to;
510219b2ee8SDavid du Colombier 				p->to.type = D_REG;
511219b2ee8SDavid du Colombier 				p->to.reg = REGSP;
512219b2ee8SDavid du Colombier 
513219b2ee8SDavid du Colombier 				break;
514219b2ee8SDavid du Colombier 			}
515219b2ee8SDavid du Colombier 			q = prg();
516219b2ee8SDavid du Colombier 			q->line = p->line;
517219b2ee8SDavid du Colombier 			q->as = AJMP;
518219b2ee8SDavid du Colombier 			q->from = zprg.from;
519219b2ee8SDavid du Colombier 			q->to = p->to;
520219b2ee8SDavid du Colombier 			q->cond = p->cond;
521219b2ee8SDavid du Colombier 			q->mark |= BRANCH;
522219b2ee8SDavid du Colombier 			q->link = p->link;
523219b2ee8SDavid du Colombier 			p->link = q;
524219b2ee8SDavid du Colombier 
525219b2ee8SDavid du Colombier 			q = prg();
526219b2ee8SDavid du Colombier 			q->line = p->line;
527219b2ee8SDavid du Colombier 			q->as = AADD;
528219b2ee8SDavid du Colombier 			q->from.type = D_CONST;
529219b2ee8SDavid du Colombier 			q->from.offset = autosize;
530219b2ee8SDavid du Colombier 			q->to.type = D_REG;
531219b2ee8SDavid du Colombier 			q->to.reg = REGSP;
532219b2ee8SDavid du Colombier 			q->link = p->link;
533219b2ee8SDavid du Colombier 			p->link = q;
534219b2ee8SDavid du Colombier 
535219b2ee8SDavid du Colombier 			p->as = AMOVW;
536219b2ee8SDavid du Colombier 			p->from = zprg.from;
537219b2ee8SDavid du Colombier 			p->from.type = D_OREG;
538219b2ee8SDavid du Colombier 			p->from.offset = 0;
539219b2ee8SDavid du Colombier 			p->from.reg = REGSP;
540219b2ee8SDavid du Colombier 			p->to = zprg.to;
541219b2ee8SDavid du Colombier 			p->to.type = D_REG;
542219b2ee8SDavid du Colombier 			p->to.reg = REGLINK;
543219b2ee8SDavid du Colombier 
544219b2ee8SDavid du Colombier 			break;
5453e12c5d1SDavid du Colombier 		}
5463e12c5d1SDavid du Colombier 	}
5473e12c5d1SDavid du Colombier 
5483e12c5d1SDavid du Colombier 	curtext = P;
5493e12c5d1SDavid du Colombier 	q = P;		/* p - 1 */
5503e12c5d1SDavid du Colombier 	q1 = firstp;	/* top of block */
5513e12c5d1SDavid du Colombier 	o = 0;		/* count of instructions */
5523e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p1) {
5533e12c5d1SDavid du Colombier 		p1 = p->link;
5543e12c5d1SDavid du Colombier 		o++;
555219b2ee8SDavid du Colombier 		if(p->mark & NOSCHED){
556219b2ee8SDavid du Colombier 			if(q1 != p){
557219b2ee8SDavid du Colombier 				sched(q1, q);
558219b2ee8SDavid du Colombier 			}
559219b2ee8SDavid du Colombier 			for(; p != P; p = p->link){
560219b2ee8SDavid du Colombier 				if(!(p->mark & NOSCHED))
561219b2ee8SDavid du Colombier 					break;
562219b2ee8SDavid du Colombier 				q = p;
563219b2ee8SDavid du Colombier 			}
564219b2ee8SDavid du Colombier 			p1 = p;
565219b2ee8SDavid du Colombier 			q1 = p;
566219b2ee8SDavid du Colombier 			o = 0;
567219b2ee8SDavid du Colombier 			continue;
568219b2ee8SDavid du Colombier 		}
5693e12c5d1SDavid du Colombier 		if(p->mark & (LABEL|SYNC)) {
5703e12c5d1SDavid du Colombier 			if(q1 != p)
5713e12c5d1SDavid du Colombier 				sched(q1, q);
5723e12c5d1SDavid du Colombier 			q1 = p;
5733e12c5d1SDavid du Colombier 			o = 1;
5743e12c5d1SDavid du Colombier 		}
5753e12c5d1SDavid du Colombier 		if(p->mark & (BRANCH|SYNC)) {
5763e12c5d1SDavid du Colombier 			sched(q1, p);
5773e12c5d1SDavid du Colombier 			q1 = p1;
5783e12c5d1SDavid du Colombier 			o = 0;
5793e12c5d1SDavid du Colombier 		}
5803e12c5d1SDavid du Colombier 		if(o >= NSCHED) {
5813e12c5d1SDavid du Colombier 			sched(q1, p);
5823e12c5d1SDavid du Colombier 			q1 = p1;
5833e12c5d1SDavid du Colombier 			o = 0;
5843e12c5d1SDavid du Colombier 		}
5853e12c5d1SDavid du Colombier 		q = p;
5863e12c5d1SDavid du Colombier 	}
5873e12c5d1SDavid du Colombier }
5883e12c5d1SDavid du Colombier 
5893e12c5d1SDavid du Colombier void
addnop(Prog * p)5903e12c5d1SDavid du Colombier addnop(Prog *p)
5913e12c5d1SDavid du Colombier {
5923e12c5d1SDavid du Colombier 	Prog *q;
5933e12c5d1SDavid du Colombier 
5943e12c5d1SDavid du Colombier 	q = prg();
5953e12c5d1SDavid du Colombier 	q->as = AORN;
5963e12c5d1SDavid du Colombier 	q->line = p->line;
5973e12c5d1SDavid du Colombier 	q->from.type = D_REG;
5983e12c5d1SDavid du Colombier 	q->from.reg = REGZERO;
5993e12c5d1SDavid du Colombier 	q->to.type = D_REG;
6003e12c5d1SDavid du Colombier 	q->to.reg = REGZERO;
6013e12c5d1SDavid du Colombier 
6023e12c5d1SDavid du Colombier 	q->link = p->link;
6033e12c5d1SDavid du Colombier 	p->link = q;
6043e12c5d1SDavid du Colombier }
6053e12c5d1SDavid du Colombier 
6063e12c5d1SDavid du Colombier void
initmuldiv(void)6073e12c5d1SDavid du Colombier initmuldiv(void)
6083e12c5d1SDavid du Colombier {
6093e12c5d1SDavid du Colombier 	Sym *s1, *s2, *s3, *s4, *s5;
6103e12c5d1SDavid du Colombier 	Prog *p;
6113e12c5d1SDavid du Colombier 
6123e12c5d1SDavid du Colombier 	s1 = lookup("_mul", 0);
6133e12c5d1SDavid du Colombier 	s2 = lookup("_div", 0);
6143e12c5d1SDavid du Colombier 	s3 = lookup("_divl", 0);
6153e12c5d1SDavid du Colombier 	s4 = lookup("_mod", 0);
6163e12c5d1SDavid du Colombier 	s5 = lookup("_modl", 0);
6173e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link)
6183e12c5d1SDavid du Colombier 		if(p->as == ATEXT) {
6193e12c5d1SDavid du Colombier 			if(p->from.sym == s1)
6203e12c5d1SDavid du Colombier 				prog_mul = p;
6213e12c5d1SDavid du Colombier 			if(p->from.sym == s2)
6223e12c5d1SDavid du Colombier 				prog_div = p;
6233e12c5d1SDavid du Colombier 			if(p->from.sym == s3)
6243e12c5d1SDavid du Colombier 				prog_divl = p;
6253e12c5d1SDavid du Colombier 			if(p->from.sym == s4)
6263e12c5d1SDavid du Colombier 				prog_mod = p;
6273e12c5d1SDavid du Colombier 			if(p->from.sym == s5)
6283e12c5d1SDavid du Colombier 				prog_modl = p;
6293e12c5d1SDavid du Colombier 		}
6303e12c5d1SDavid du Colombier 	if(prog_mul == P) {
631*6b6b9ac8SDavid du Colombier 		diag("undefined: %s", s1->name);
6323e12c5d1SDavid du Colombier 		prog_mul = curtext;
6333e12c5d1SDavid du Colombier 	}
6343e12c5d1SDavid du Colombier 	if(prog_div == P) {
635*6b6b9ac8SDavid du Colombier 		diag("undefined: %s", s2->name);
6363e12c5d1SDavid du Colombier 		prog_div = curtext;
6373e12c5d1SDavid du Colombier 	}
6383e12c5d1SDavid du Colombier 	if(prog_divl == P) {
639*6b6b9ac8SDavid du Colombier 		diag("undefined: %s", s3->name);
6403e12c5d1SDavid du Colombier 		prog_divl = curtext;
6413e12c5d1SDavid du Colombier 	}
6423e12c5d1SDavid du Colombier 	if(prog_mod == P) {
643*6b6b9ac8SDavid du Colombier 		diag("undefined: %s", s4->name);
6443e12c5d1SDavid du Colombier 		prog_mod = curtext;
6453e12c5d1SDavid du Colombier 	}
6463e12c5d1SDavid du Colombier 	if(prog_modl == P) {
647*6b6b9ac8SDavid du Colombier 		diag("undefined: %s", s5->name);
6483e12c5d1SDavid du Colombier 		prog_modl = curtext;
6493e12c5d1SDavid du Colombier 	}
6503e12c5d1SDavid du Colombier }
651