xref: /plan9/sys/src/cmd/5l/noop.c (revision 9b7bf7df4595c26f1e9b67beb0c6e44c9876fb05)
17dd7cddfSDavid du Colombier #include	"l.h"
27dd7cddfSDavid du Colombier 
39a747e4fSDavid du Colombier static	Sym*	sym_div;
49a747e4fSDavid du Colombier static	Sym*	sym_divu;
59a747e4fSDavid du Colombier static	Sym*	sym_mod;
69a747e4fSDavid du Colombier static	Sym*	sym_modu;
79a747e4fSDavid du Colombier 
87dd7cddfSDavid du Colombier void
noops(void)97dd7cddfSDavid du Colombier noops(void)
107dd7cddfSDavid du Colombier {
117dd7cddfSDavid du Colombier 	Prog *p, *q, *q1;
127dd7cddfSDavid du Colombier 	int o, curframe, curbecome, maxbecome;
137dd7cddfSDavid du Colombier 
147dd7cddfSDavid du Colombier 	/*
157dd7cddfSDavid du Colombier 	 * find leaf subroutines
167dd7cddfSDavid du Colombier 	 * become sizes
177dd7cddfSDavid du Colombier 	 * frame sizes
187dd7cddfSDavid du Colombier 	 * strip NOPs
197dd7cddfSDavid du Colombier 	 * expand RET
207dd7cddfSDavid du Colombier 	 * expand BECOME pseudo
217dd7cddfSDavid du Colombier 	 */
227dd7cddfSDavid du Colombier 
237dd7cddfSDavid du Colombier 	if(debug['v'])
247dd7cddfSDavid du Colombier 		Bprint(&bso, "%5.2f noops\n", cputime());
257dd7cddfSDavid du Colombier 	Bflush(&bso);
267dd7cddfSDavid du Colombier 
277dd7cddfSDavid du Colombier 	curframe = 0;
287dd7cddfSDavid du Colombier 	curbecome = 0;
297dd7cddfSDavid du Colombier 	maxbecome = 0;
307dd7cddfSDavid du Colombier 	curtext = 0;
317dd7cddfSDavid du Colombier 
327dd7cddfSDavid du Colombier 	q = P;
337dd7cddfSDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
347dd7cddfSDavid du Colombier 
357dd7cddfSDavid du Colombier 		/* find out how much arg space is used in this TEXT */
367dd7cddfSDavid du Colombier 		if(p->to.type == D_OREG && p->to.reg == REGSP)
377dd7cddfSDavid du Colombier 			if(p->to.offset > curframe)
387dd7cddfSDavid du Colombier 				curframe = p->to.offset;
397dd7cddfSDavid du Colombier 
407dd7cddfSDavid du Colombier 		switch(p->as) {
417dd7cddfSDavid du Colombier 		case ATEXT:
427dd7cddfSDavid du Colombier 			if(curtext && curtext->from.sym) {
437dd7cddfSDavid du Colombier 				curtext->from.sym->frame = curframe;
447dd7cddfSDavid du Colombier 				curtext->from.sym->become = curbecome;
457dd7cddfSDavid du Colombier 				if(curbecome > maxbecome)
467dd7cddfSDavid du Colombier 					maxbecome = curbecome;
477dd7cddfSDavid du Colombier 			}
487dd7cddfSDavid du Colombier 			curframe = 0;
497dd7cddfSDavid du Colombier 			curbecome = 0;
507dd7cddfSDavid du Colombier 
517dd7cddfSDavid du Colombier 			p->mark |= LEAF;
527dd7cddfSDavid du Colombier 			curtext = p;
537dd7cddfSDavid du Colombier 			break;
547dd7cddfSDavid du Colombier 
557dd7cddfSDavid du Colombier 		case ARET:
567dd7cddfSDavid du Colombier 			/* special form of RET is BECOME */
577dd7cddfSDavid du Colombier 			if(p->from.type == D_CONST)
587dd7cddfSDavid du Colombier 				if(p->from.offset > curbecome)
597dd7cddfSDavid du Colombier 					curbecome = p->from.offset;
607dd7cddfSDavid du Colombier 			break;
617dd7cddfSDavid du Colombier 
627dd7cddfSDavid du Colombier 		case ADIV:
637dd7cddfSDavid du Colombier 		case ADIVU:
647dd7cddfSDavid du Colombier 		case AMOD:
657dd7cddfSDavid du Colombier 		case AMODU:
667dd7cddfSDavid du Colombier 			q = p;
677dd7cddfSDavid du Colombier 			if(prog_div == P)
687dd7cddfSDavid du Colombier 				initdiv();
697dd7cddfSDavid du Colombier 			if(curtext != P)
707dd7cddfSDavid du Colombier 				curtext->mark &= ~LEAF;
717dd7cddfSDavid du Colombier 			continue;
727dd7cddfSDavid du Colombier 
737dd7cddfSDavid du Colombier 		case ANOP:
747dd7cddfSDavid du Colombier 			q1 = p->link;
757dd7cddfSDavid du Colombier 			q->link = q1;		/* q is non-nop */
767dd7cddfSDavid du Colombier 			q1->mark |= p->mark;
777dd7cddfSDavid du Colombier 			continue;
787dd7cddfSDavid du Colombier 
797dd7cddfSDavid du Colombier 		case ABL:
807dd7cddfSDavid du Colombier 			if(curtext != P)
817dd7cddfSDavid du Colombier 				curtext->mark &= ~LEAF;
827dd7cddfSDavid du Colombier 
837dd7cddfSDavid du Colombier 		case ABCASE:
847dd7cddfSDavid du Colombier 		case AB:
857dd7cddfSDavid du Colombier 
867dd7cddfSDavid du Colombier 		case ABEQ:
877dd7cddfSDavid du Colombier 		case ABNE:
887dd7cddfSDavid du Colombier 		case ABCS:
897dd7cddfSDavid du Colombier 		case ABHS:
907dd7cddfSDavid du Colombier 		case ABCC:
917dd7cddfSDavid du Colombier 		case ABLO:
927dd7cddfSDavid du Colombier 		case ABMI:
937dd7cddfSDavid du Colombier 		case ABPL:
947dd7cddfSDavid du Colombier 		case ABVS:
957dd7cddfSDavid du Colombier 		case ABVC:
967dd7cddfSDavid du Colombier 		case ABHI:
977dd7cddfSDavid du Colombier 		case ABLS:
987dd7cddfSDavid du Colombier 		case ABGE:
997dd7cddfSDavid du Colombier 		case ABLT:
1007dd7cddfSDavid du Colombier 		case ABGT:
1017dd7cddfSDavid du Colombier 		case ABLE:
1027dd7cddfSDavid du Colombier 
1037dd7cddfSDavid du Colombier 			q1 = p->cond;
1047dd7cddfSDavid du Colombier 			if(q1 != P) {
1057dd7cddfSDavid du Colombier 				while(q1->as == ANOP) {
1067dd7cddfSDavid du Colombier 					q1 = q1->link;
1077dd7cddfSDavid du Colombier 					p->cond = q1;
1087dd7cddfSDavid du Colombier 				}
1097dd7cddfSDavid du Colombier 			}
1107dd7cddfSDavid du Colombier 			break;
1117dd7cddfSDavid du Colombier 		}
1127dd7cddfSDavid du Colombier 		q = p;
1137dd7cddfSDavid du Colombier 	}
1147dd7cddfSDavid du Colombier 
1157dd7cddfSDavid du Colombier 	if(curtext && curtext->from.sym) {
1167dd7cddfSDavid du Colombier 		curtext->from.sym->frame = curframe;
1177dd7cddfSDavid du Colombier 		curtext->from.sym->become = curbecome;
1187dd7cddfSDavid du Colombier 		if(curbecome > maxbecome)
1197dd7cddfSDavid du Colombier 			maxbecome = curbecome;
1207dd7cddfSDavid du Colombier 	}
1217dd7cddfSDavid du Colombier 
1227dd7cddfSDavid du Colombier 	if(debug['b'])
1237dd7cddfSDavid du Colombier 		print("max become = %d\n", maxbecome);
1247dd7cddfSDavid du Colombier 	xdefine("ALEFbecome", STEXT, maxbecome);
1257dd7cddfSDavid du Colombier 
1267dd7cddfSDavid du Colombier 	curtext = 0;
1277dd7cddfSDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
1287dd7cddfSDavid du Colombier 		switch(p->as) {
1297dd7cddfSDavid du Colombier 		case ATEXT:
1307dd7cddfSDavid du Colombier 			curtext = p;
1317dd7cddfSDavid du Colombier 			break;
1327dd7cddfSDavid du Colombier 		case ABL:
1337dd7cddfSDavid du Colombier 			if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
1347dd7cddfSDavid du Colombier 				o = maxbecome - curtext->from.sym->frame;
1357dd7cddfSDavid du Colombier 				if(o <= 0)
1367dd7cddfSDavid du Colombier 					break;
1377dd7cddfSDavid du Colombier 				/* calling a become or calling a variable */
1387dd7cddfSDavid du Colombier 				if(p->to.sym == S || p->to.sym->become) {
1397dd7cddfSDavid du Colombier 					curtext->to.offset += o;
1407dd7cddfSDavid du Colombier 					if(debug['b']) {
1417dd7cddfSDavid du Colombier 						curp = p;
1427dd7cddfSDavid du Colombier 						print("%D calling %D increase %d\n",
1437dd7cddfSDavid du Colombier 							&curtext->from, &p->to, o);
1447dd7cddfSDavid du Colombier 					}
1457dd7cddfSDavid du Colombier 				}
1467dd7cddfSDavid du Colombier 			}
1477dd7cddfSDavid du Colombier 			break;
1487dd7cddfSDavid du Colombier 		}
1497dd7cddfSDavid du Colombier 	}
1507dd7cddfSDavid du Colombier 
1517dd7cddfSDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
1527dd7cddfSDavid du Colombier 		o = p->as;
1537dd7cddfSDavid du Colombier 		switch(o) {
1547dd7cddfSDavid du Colombier 		case ATEXT:
1557dd7cddfSDavid du Colombier 			curtext = p;
1567dd7cddfSDavid du Colombier 			autosize = p->to.offset + 4;
1577dd7cddfSDavid du Colombier 			if(autosize <= 4)
1587dd7cddfSDavid du Colombier 			if(curtext->mark & LEAF) {
1597dd7cddfSDavid du Colombier 				p->to.offset = -4;
1607dd7cddfSDavid du Colombier 				autosize = 0;
1617dd7cddfSDavid du Colombier 			}
1627dd7cddfSDavid du Colombier 
16359cc4ca5SDavid du Colombier 			if(!autosize && !(curtext->mark & LEAF)) {
16459cc4ca5SDavid du Colombier 				if(debug['v'])
16559cc4ca5SDavid du Colombier 					Bprint(&bso, "save suppressed in: %s\n",
16659cc4ca5SDavid du Colombier 						curtext->from.sym->name);
16759cc4ca5SDavid du Colombier 				Bflush(&bso);
16859cc4ca5SDavid du Colombier 				curtext->mark |= LEAF;
16959cc4ca5SDavid du Colombier 			}
17059cc4ca5SDavid du Colombier 
17159cc4ca5SDavid du Colombier 			if(curtext->mark & LEAF) {
17259cc4ca5SDavid du Colombier 				if(curtext->from.sym)
17359cc4ca5SDavid du Colombier 					curtext->from.sym->type = SLEAF;
17459cc4ca5SDavid du Colombier #ifdef optimise_time
1757dd7cddfSDavid du Colombier 				if(autosize) {
1767dd7cddfSDavid du Colombier 					q = prg();
1777dd7cddfSDavid du Colombier 					q->as = ASUB;
1787dd7cddfSDavid du Colombier 					q->line = p->line;
1797dd7cddfSDavid du Colombier 					q->from.type = D_CONST;
1807dd7cddfSDavid du Colombier 					q->from.offset = autosize;
1817dd7cddfSDavid du Colombier 					q->to.type = D_REG;
1827dd7cddfSDavid du Colombier 					q->to.reg = REGSP;
1837dd7cddfSDavid du Colombier 
1847dd7cddfSDavid du Colombier 					q->link = p->link;
1857dd7cddfSDavid du Colombier 					p->link = q;
1867dd7cddfSDavid du Colombier 				}
1877dd7cddfSDavid du Colombier 				break;
18859cc4ca5SDavid du Colombier #else
18959cc4ca5SDavid du Colombier 				if(!autosize)
19059cc4ca5SDavid du Colombier 					break;
19159cc4ca5SDavid du Colombier #endif
1927dd7cddfSDavid du Colombier 			}
1937dd7cddfSDavid du Colombier 
1947dd7cddfSDavid du Colombier 			q1 = prg();
1957dd7cddfSDavid du Colombier 			q1->as = AMOVW;
19659cc4ca5SDavid du Colombier 			q1->scond |= C_WBIT;
1977dd7cddfSDavid du Colombier 			q1->line = p->line;
1987dd7cddfSDavid du Colombier 			q1->from.type = D_REG;
1997dd7cddfSDavid du Colombier 			q1->from.reg = REGLINK;
2007dd7cddfSDavid du Colombier 			q1->to.type = D_OREG;
20159cc4ca5SDavid du Colombier 			q1->to.offset = -autosize;
2027dd7cddfSDavid du Colombier 			q1->to.reg = REGSP;
2037dd7cddfSDavid du Colombier 
20459cc4ca5SDavid du Colombier 			q1->link = p->link;
20559cc4ca5SDavid du Colombier 			p->link = q1;
2067dd7cddfSDavid du Colombier 			break;
2077dd7cddfSDavid du Colombier 
2087dd7cddfSDavid du Colombier 		case ARET:
2097dd7cddfSDavid du Colombier 			nocache(p);
2107dd7cddfSDavid du Colombier 			if(p->from.type == D_CONST)
2117dd7cddfSDavid du Colombier 				goto become;
2127dd7cddfSDavid du Colombier 			if(curtext->mark & LEAF) {
2137dd7cddfSDavid du Colombier 				if(!autosize) {
2147dd7cddfSDavid du Colombier 					p->as = AB;
2157dd7cddfSDavid du Colombier 					p->from = zprg.from;
2167dd7cddfSDavid du Colombier 					p->to.type = D_OREG;
2177dd7cddfSDavid du Colombier 					p->to.offset = 0;
2187dd7cddfSDavid du Colombier 					p->to.reg = REGLINK;
2197dd7cddfSDavid du Colombier 					break;
2207dd7cddfSDavid du Colombier 				}
2217dd7cddfSDavid du Colombier 
22259cc4ca5SDavid du Colombier #ifdef optimise_time
2237dd7cddfSDavid du Colombier 				p->as = AADD;
2247dd7cddfSDavid du Colombier 				p->from.type = D_CONST;
2257dd7cddfSDavid du Colombier 				p->from.offset = autosize;
2267dd7cddfSDavid du Colombier 				p->to.type = D_REG;
2277dd7cddfSDavid du Colombier 				p->to.reg = REGSP;
2287dd7cddfSDavid du Colombier 
2297dd7cddfSDavid du Colombier 				q = prg();
2307dd7cddfSDavid du Colombier 				q->as = AB;
23159cc4ca5SDavid du Colombier 				q->scond = p->scond;
2327dd7cddfSDavid du Colombier 				q->line = p->line;
2337dd7cddfSDavid du Colombier 				q->to.type = D_OREG;
2347dd7cddfSDavid du Colombier 				q->to.offset = 0;
2357dd7cddfSDavid du Colombier 				q->to.reg = REGLINK;
2367dd7cddfSDavid du Colombier 
2377dd7cddfSDavid du Colombier 				q->link = p->link;
2387dd7cddfSDavid du Colombier 				p->link = q;
23959cc4ca5SDavid du Colombier 
2407dd7cddfSDavid du Colombier 				break;
24159cc4ca5SDavid du Colombier #endif
2427dd7cddfSDavid du Colombier 			}
2437dd7cddfSDavid du Colombier 			p->as = AMOVW;
24459cc4ca5SDavid du Colombier 			p->scond |= C_PBIT;
2457dd7cddfSDavid du Colombier 			p->from.type = D_OREG;
24659cc4ca5SDavid du Colombier 			p->from.offset = autosize;
2477dd7cddfSDavid du Colombier 			p->from.reg = REGSP;
2487dd7cddfSDavid du Colombier 			p->to.type = D_REG;
24959cc4ca5SDavid du Colombier 			p->to.reg = REGPC;
2507dd7cddfSDavid du Colombier 			break;
2517dd7cddfSDavid du Colombier 
2527dd7cddfSDavid du Colombier 		become:
2537dd7cddfSDavid du Colombier 			if(curtext->mark & LEAF) {
2547dd7cddfSDavid du Colombier 
25559cc4ca5SDavid du Colombier 				if(!autosize) {
25659cc4ca5SDavid du Colombier 					p->as = AB;
25759cc4ca5SDavid du Colombier 					p->from = zprg.from;
25859cc4ca5SDavid du Colombier 					break;
25959cc4ca5SDavid du Colombier 				}
26059cc4ca5SDavid du Colombier 
26159cc4ca5SDavid du Colombier #ifdef optimise_time
2627dd7cddfSDavid du Colombier 				q = prg();
26359cc4ca5SDavid du Colombier 				q->scond = p->scond;
2647dd7cddfSDavid du Colombier 				q->line = p->line;
2657dd7cddfSDavid du Colombier 				q->as = AB;
2667dd7cddfSDavid du Colombier 				q->from = zprg.from;
2677dd7cddfSDavid du Colombier 				q->to = p->to;
2687dd7cddfSDavid du Colombier 				q->cond = p->cond;
2697dd7cddfSDavid du Colombier 				q->link = p->link;
2707dd7cddfSDavid du Colombier 				p->link = q;
2717dd7cddfSDavid du Colombier 
2727dd7cddfSDavid du Colombier 				p->as = AADD;
2737dd7cddfSDavid du Colombier 				p->from = zprg.from;
2747dd7cddfSDavid du Colombier 				p->from.type = D_CONST;
2757dd7cddfSDavid du Colombier 				p->from.offset = autosize;
2767dd7cddfSDavid du Colombier 				p->to = zprg.to;
2777dd7cddfSDavid du Colombier 				p->to.type = D_REG;
2787dd7cddfSDavid du Colombier 				p->to.reg = REGSP;
2797dd7cddfSDavid du Colombier 
2807dd7cddfSDavid du Colombier 				break;
28159cc4ca5SDavid du Colombier #endif
2827dd7cddfSDavid du Colombier 			}
2837dd7cddfSDavid du Colombier 			q = prg();
28459cc4ca5SDavid du Colombier 			q->scond = p->scond;
2857dd7cddfSDavid du Colombier 			q->line = p->line;
2867dd7cddfSDavid du Colombier 			q->as = AB;
2877dd7cddfSDavid du Colombier 			q->from = zprg.from;
2887dd7cddfSDavid du Colombier 			q->to = p->to;
2897dd7cddfSDavid du Colombier 			q->cond = p->cond;
2907dd7cddfSDavid du Colombier 			q->link = p->link;
2917dd7cddfSDavid du Colombier 			p->link = q;
2927dd7cddfSDavid du Colombier 
2937dd7cddfSDavid du Colombier 			p->as = AMOVW;
29459cc4ca5SDavid du Colombier 			p->scond |= C_PBIT;
2957dd7cddfSDavid du Colombier 			p->from = zprg.from;
2967dd7cddfSDavid du Colombier 			p->from.type = D_OREG;
29759cc4ca5SDavid du Colombier 			p->from.offset = autosize;
2987dd7cddfSDavid du Colombier 			p->from.reg = REGSP;
2997dd7cddfSDavid du Colombier 			p->to = zprg.to;
3007dd7cddfSDavid du Colombier 			p->to.type = D_REG;
3017dd7cddfSDavid du Colombier 			p->to.reg = REGLINK;
3027dd7cddfSDavid du Colombier 
3037dd7cddfSDavid du Colombier 			break;
3047dd7cddfSDavid du Colombier 
305*9b7bf7dfSDavid du Colombier 		/*
306*9b7bf7dfSDavid du Colombier 		 * 5c code generation for unsigned -> double made the
307*9b7bf7dfSDavid du Colombier 		 * unfortunate assumption that single and double floating
308*9b7bf7dfSDavid du Colombier 		 * point registers are aliased - true for emulated 7500
309*9b7bf7dfSDavid du Colombier 		 * but not for vfp.  Now corrected, but this test is
310*9b7bf7dfSDavid du Colombier 		 * insurance against old 5c compiled code in libraries.
311*9b7bf7dfSDavid du Colombier 		 */
312*9b7bf7dfSDavid du Colombier 		case AMOVWD:
313*9b7bf7dfSDavid du Colombier 			if((q = p->link) != P && q->as == ACMP)
314*9b7bf7dfSDavid du Colombier 			if((q = q->link) != P && q->as == AMOVF)
315*9b7bf7dfSDavid du Colombier 			if((q1 = q->link) != P && q1->as == AADDF)
316*9b7bf7dfSDavid du Colombier 			if(q1->to.type == D_FREG && q1->to.reg == p->to.reg) {
317*9b7bf7dfSDavid du Colombier 				q1->as = AADDD;
318*9b7bf7dfSDavid du Colombier 				q1 = prg();
319*9b7bf7dfSDavid du Colombier 				q1->scond = q->scond;
320*9b7bf7dfSDavid du Colombier 				q1->line = q->line;
321*9b7bf7dfSDavid du Colombier 				q1->as = AMOVFD;
322*9b7bf7dfSDavid du Colombier 				q1->from = q->to;
323*9b7bf7dfSDavid du Colombier 				q1->to = q1->from;
324*9b7bf7dfSDavid du Colombier 				q1->link = q->link;
325*9b7bf7dfSDavid du Colombier 				q->link = q1;
326*9b7bf7dfSDavid du Colombier 			}
327*9b7bf7dfSDavid du Colombier 			break;
328*9b7bf7dfSDavid du Colombier 
3297dd7cddfSDavid du Colombier 		case ADIV:
3307dd7cddfSDavid du Colombier 		case ADIVU:
3317dd7cddfSDavid du Colombier 		case AMOD:
3327dd7cddfSDavid du Colombier 		case AMODU:
3337dd7cddfSDavid du Colombier 			if(debug['M'])
3347dd7cddfSDavid du Colombier 				break;
3357dd7cddfSDavid du Colombier 			if(p->from.type != D_REG)
3367dd7cddfSDavid du Colombier 				break;
3377dd7cddfSDavid du Colombier 			if(p->to.type != D_REG)
3387dd7cddfSDavid du Colombier 				break;
3397dd7cddfSDavid du Colombier 			q1 = p;
3407dd7cddfSDavid du Colombier 
3417dd7cddfSDavid du Colombier 			/* MOV a,4(SP) */
3427dd7cddfSDavid du Colombier 			q = prg();
3437dd7cddfSDavid du Colombier 			q->link = p->link;
3447dd7cddfSDavid du Colombier 			p->link = q;
3457dd7cddfSDavid du Colombier 			p = q;
3467dd7cddfSDavid du Colombier 
3477dd7cddfSDavid du Colombier 			p->as = AMOVW;
3487dd7cddfSDavid du Colombier 			p->line = q1->line;
3497dd7cddfSDavid du Colombier 			p->from.type = D_REG;
3507dd7cddfSDavid du Colombier 			p->from.reg = q1->from.reg;
3517dd7cddfSDavid du Colombier 			p->to.type = D_OREG;
3527dd7cddfSDavid du Colombier 			p->to.reg = REGSP;
3537dd7cddfSDavid du Colombier 			p->to.offset = 4;
3547dd7cddfSDavid du Colombier 
3557dd7cddfSDavid du Colombier 			/* MOV b,REGTMP */
3567dd7cddfSDavid du Colombier 			q = prg();
3577dd7cddfSDavid du Colombier 			q->link = p->link;
3587dd7cddfSDavid du Colombier 			p->link = q;
3597dd7cddfSDavid du Colombier 			p = q;
3607dd7cddfSDavid du Colombier 
3617dd7cddfSDavid du Colombier 			p->as = AMOVW;
3627dd7cddfSDavid du Colombier 			p->line = q1->line;
3637dd7cddfSDavid du Colombier 			p->from.type = D_REG;
3647dd7cddfSDavid du Colombier 			p->from.reg = q1->reg;
3657dd7cddfSDavid du Colombier 			if(q1->reg == NREG)
3667dd7cddfSDavid du Colombier 				p->from.reg = q1->to.reg;
3677dd7cddfSDavid du Colombier 			p->to.type = D_REG;
3687dd7cddfSDavid du Colombier 			p->to.reg = REGTMP;
3697dd7cddfSDavid du Colombier 			p->to.offset = 0;
3707dd7cddfSDavid du Colombier 
3717dd7cddfSDavid du Colombier 			/* CALL appropriate */
3727dd7cddfSDavid du Colombier 			q = prg();
3737dd7cddfSDavid du Colombier 			q->link = p->link;
3747dd7cddfSDavid du Colombier 			p->link = q;
3757dd7cddfSDavid du Colombier 			p = q;
3767dd7cddfSDavid du Colombier 
3777dd7cddfSDavid du Colombier 			p->as = ABL;
3787dd7cddfSDavid du Colombier 			p->line = q1->line;
3797dd7cddfSDavid du Colombier 			p->to.type = D_BRANCH;
3807dd7cddfSDavid du Colombier 			p->cond = p;
3817dd7cddfSDavid du Colombier 			switch(o) {
3827dd7cddfSDavid du Colombier 			case ADIV:
3837dd7cddfSDavid du Colombier 				p->cond = prog_div;
3849a747e4fSDavid du Colombier 				p->to.sym = sym_div;
3857dd7cddfSDavid du Colombier 				break;
3867dd7cddfSDavid du Colombier 			case ADIVU:
3877dd7cddfSDavid du Colombier 				p->cond = prog_divu;
3889a747e4fSDavid du Colombier 				p->to.sym = sym_divu;
3897dd7cddfSDavid du Colombier 				break;
3907dd7cddfSDavid du Colombier 			case AMOD:
3917dd7cddfSDavid du Colombier 				p->cond = prog_mod;
3929a747e4fSDavid du Colombier 				p->to.sym = sym_mod;
3937dd7cddfSDavid du Colombier 				break;
3947dd7cddfSDavid du Colombier 			case AMODU:
3957dd7cddfSDavid du Colombier 				p->cond = prog_modu;
3969a747e4fSDavid du Colombier 				p->to.sym = sym_modu;
3977dd7cddfSDavid du Colombier 				break;
3987dd7cddfSDavid du Colombier 			}
3997dd7cddfSDavid du Colombier 
4007dd7cddfSDavid du Colombier 			/* MOV REGTMP, b */
4017dd7cddfSDavid du Colombier 			q = prg();
4027dd7cddfSDavid du Colombier 			q->link = p->link;
4037dd7cddfSDavid du Colombier 			p->link = q;
4047dd7cddfSDavid du Colombier 			p = q;
4057dd7cddfSDavid du Colombier 
4067dd7cddfSDavid du Colombier 			p->as = AMOVW;
4077dd7cddfSDavid du Colombier 			p->line = q1->line;
4087dd7cddfSDavid du Colombier 			p->from.type = D_REG;
4097dd7cddfSDavid du Colombier 			p->from.reg = REGTMP;
4107dd7cddfSDavid du Colombier 			p->from.offset = 0;
4117dd7cddfSDavid du Colombier 			p->to.type = D_REG;
4127dd7cddfSDavid du Colombier 			p->to.reg = q1->to.reg;
4137dd7cddfSDavid du Colombier 
4147dd7cddfSDavid du Colombier 			/* ADD $8,SP */
4157dd7cddfSDavid du Colombier 			q = prg();
4167dd7cddfSDavid du Colombier 			q->link = p->link;
4177dd7cddfSDavid du Colombier 			p->link = q;
4187dd7cddfSDavid du Colombier 			p = q;
4197dd7cddfSDavid du Colombier 
4207dd7cddfSDavid du Colombier 			p->as = AADD;
4217dd7cddfSDavid du Colombier 			p->from.type = D_CONST;
4227dd7cddfSDavid du Colombier 			p->from.reg = NREG;
4237dd7cddfSDavid du Colombier 			p->from.offset = 8;
4247dd7cddfSDavid du Colombier 			p->reg = NREG;
4257dd7cddfSDavid du Colombier 			p->to.type = D_REG;
4267dd7cddfSDavid du Colombier 			p->to.reg = REGSP;
4277dd7cddfSDavid du Colombier 
4287dd7cddfSDavid du Colombier 			/* SUB $8,SP */
4297dd7cddfSDavid du Colombier 			q1->as = ASUB;
4307dd7cddfSDavid du Colombier 			q1->from.type = D_CONST;
4317dd7cddfSDavid du Colombier 			q1->from.offset = 8;
4327dd7cddfSDavid du Colombier 			q1->from.reg = NREG;
4337dd7cddfSDavid du Colombier 			q1->reg = NREG;
4347dd7cddfSDavid du Colombier 			q1->to.type = D_REG;
4357dd7cddfSDavid du Colombier 			q1->to.reg = REGSP;
4367dd7cddfSDavid du Colombier 			break;
4377dd7cddfSDavid du Colombier 		}
4387dd7cddfSDavid du Colombier 	}
4397dd7cddfSDavid du Colombier }
4407dd7cddfSDavid du Colombier 
441375daca8SDavid du Colombier static void
sigdiv(char * n)442375daca8SDavid du Colombier sigdiv(char *n)
443375daca8SDavid du Colombier {
444375daca8SDavid du Colombier 	Sym *s;
445375daca8SDavid du Colombier 
446375daca8SDavid du Colombier 	s = lookup(n, 0);
447375daca8SDavid du Colombier 	if(s->type == STEXT){
448375daca8SDavid du Colombier 		if(s->sig == 0)
449375daca8SDavid du Colombier 			s->sig = SIGNINTERN;
450375daca8SDavid du Colombier 	}
451375daca8SDavid du Colombier 	else if(s->type == 0 || s->type == SXREF)
452375daca8SDavid du Colombier 		s->type = SUNDEF;
453375daca8SDavid du Colombier }
454375daca8SDavid du Colombier 
455375daca8SDavid du Colombier void
divsig(void)456375daca8SDavid du Colombier divsig(void)
457375daca8SDavid du Colombier {
458375daca8SDavid du Colombier 	sigdiv("_div");
459375daca8SDavid du Colombier 	sigdiv("_divu");
460375daca8SDavid du Colombier 	sigdiv("_mod");
461375daca8SDavid du Colombier 	sigdiv("_modu");
462375daca8SDavid du Colombier }
463375daca8SDavid du Colombier 
464375daca8SDavid du Colombier static void
sdiv(Sym * s)4659a747e4fSDavid du Colombier sdiv(Sym *s)
4669a747e4fSDavid du Colombier {
467375daca8SDavid du Colombier 	if(s->type == 0 || s->type == SXREF){
468375daca8SDavid du Colombier 		/* undefsym(s); */
469375daca8SDavid du Colombier 		s->type = SXREF;
470375daca8SDavid du Colombier 		if(s->sig == 0)
471375daca8SDavid du Colombier 			s->sig = SIGNINTERN;
472375daca8SDavid du Colombier 		s->subtype = SIMPORT;
473375daca8SDavid du Colombier 	}
474375daca8SDavid du Colombier 	else if(s->type != STEXT)
4756b6b9ac8SDavid du Colombier 		diag("undefined: %s", s->name);
4769a747e4fSDavid du Colombier }
4779a747e4fSDavid du Colombier 
4787dd7cddfSDavid du Colombier void
initdiv(void)4797dd7cddfSDavid du Colombier initdiv(void)
4807dd7cddfSDavid du Colombier {
4817dd7cddfSDavid du Colombier 	Sym *s2, *s3, *s4, *s5;
4827dd7cddfSDavid du Colombier 	Prog *p;
4837dd7cddfSDavid du Colombier 
484375daca8SDavid du Colombier 	if(prog_div != P)
4859a747e4fSDavid du Colombier 		return;
486375daca8SDavid du Colombier 	sym_div = s2 = lookup("_div", 0);
487375daca8SDavid du Colombier 	sym_divu = s3 = lookup("_divu", 0);
488375daca8SDavid du Colombier 	sym_mod = s4 = lookup("_mod", 0);
489375daca8SDavid du Colombier 	sym_modu = s5 = lookup("_modu", 0);
490375daca8SDavid du Colombier 	if(dlm) {
491375daca8SDavid du Colombier 		sdiv(s2); if(s2->type == SXREF) prog_div = UP;
492375daca8SDavid du Colombier 		sdiv(s3); if(s3->type == SXREF) prog_divu = UP;
493375daca8SDavid du Colombier 		sdiv(s4); if(s4->type == SXREF) prog_mod = UP;
494375daca8SDavid du Colombier 		sdiv(s5); if(s5->type == SXREF) prog_modu = UP;
4959a747e4fSDavid du Colombier 	}
4967dd7cddfSDavid du Colombier 	for(p = firstp; p != P; p = p->link)
4977dd7cddfSDavid du Colombier 		if(p->as == ATEXT) {
4987dd7cddfSDavid du Colombier 			if(p->from.sym == s2)
4997dd7cddfSDavid du Colombier 				prog_div = p;
5007dd7cddfSDavid du Colombier 			if(p->from.sym == s3)
5017dd7cddfSDavid du Colombier 				prog_divu = p;
5027dd7cddfSDavid du Colombier 			if(p->from.sym == s4)
5037dd7cddfSDavid du Colombier 				prog_mod = p;
5047dd7cddfSDavid du Colombier 			if(p->from.sym == s5)
5057dd7cddfSDavid du Colombier 				prog_modu = p;
5067dd7cddfSDavid du Colombier 		}
5077dd7cddfSDavid du Colombier 	if(prog_div == P) {
5086b6b9ac8SDavid du Colombier 		diag("undefined: %s", s2->name);
5097dd7cddfSDavid du Colombier 		prog_div = curtext;
5107dd7cddfSDavid du Colombier 	}
5117dd7cddfSDavid du Colombier 	if(prog_divu == P) {
5126b6b9ac8SDavid du Colombier 		diag("undefined: %s", s3->name);
5137dd7cddfSDavid du Colombier 		prog_divu = curtext;
5147dd7cddfSDavid du Colombier 	}
5157dd7cddfSDavid du Colombier 	if(prog_mod == P) {
5166b6b9ac8SDavid du Colombier 		diag("undefined: %s", s4->name);
5177dd7cddfSDavid du Colombier 		prog_mod = curtext;
5187dd7cddfSDavid du Colombier 	}
5197dd7cddfSDavid du Colombier 	if(prog_modu == P) {
5206b6b9ac8SDavid du Colombier 		diag("undefined: %s", s5->name);
5217dd7cddfSDavid du Colombier 		prog_modu = curtext;
5227dd7cddfSDavid du Colombier 	}
5237dd7cddfSDavid du Colombier }
5247dd7cddfSDavid du Colombier 
5257dd7cddfSDavid du Colombier void
nocache(Prog * p)5267dd7cddfSDavid du Colombier nocache(Prog *p)
5277dd7cddfSDavid du Colombier {
5287dd7cddfSDavid du Colombier 	p->optab = 0;
5297dd7cddfSDavid du Colombier 	p->from.class = 0;
5307dd7cddfSDavid du Colombier 	p->to.class = 0;
5317dd7cddfSDavid du Colombier }
532