xref: /inferno-os/utils/ql/noop.c (revision d67b7dad77bb8aa973dad1f7c3ab0c309b114278)
174a4d8c2SCharles.Forsyth #include	"l.h"
274a4d8c2SCharles.Forsyth 
374a4d8c2SCharles.Forsyth void
noops(void)474a4d8c2SCharles.Forsyth noops(void)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth 	Prog *p, *p1, *q, *q1;
774a4d8c2SCharles.Forsyth 	int o, mov, aoffset, curframe, curbecome, maxbecome;
874a4d8c2SCharles.Forsyth 
974a4d8c2SCharles.Forsyth 	/*
1074a4d8c2SCharles.Forsyth 	 * find leaf subroutines
1174a4d8c2SCharles.Forsyth 	 * become sizes
1274a4d8c2SCharles.Forsyth 	 * frame sizes
1374a4d8c2SCharles.Forsyth 	 * strip NOPs
1474a4d8c2SCharles.Forsyth 	 * expand RET
1574a4d8c2SCharles.Forsyth 	 * expand BECOME pseudo
1674a4d8c2SCharles.Forsyth 	 */
1774a4d8c2SCharles.Forsyth 
1874a4d8c2SCharles.Forsyth 	if(debug['v'])
1974a4d8c2SCharles.Forsyth 		Bprint(&bso, "%5.2f noops\n", cputime());
2074a4d8c2SCharles.Forsyth 	Bflush(&bso);
2174a4d8c2SCharles.Forsyth 
2274a4d8c2SCharles.Forsyth 	curframe = 0;
2374a4d8c2SCharles.Forsyth 	curbecome = 0;
2474a4d8c2SCharles.Forsyth 	maxbecome = 0;
2574a4d8c2SCharles.Forsyth 	curtext = 0;
2674a4d8c2SCharles.Forsyth 	q = P;
2774a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
2874a4d8c2SCharles.Forsyth 
2974a4d8c2SCharles.Forsyth 		/* find out how much arg space is used in this TEXT */
3074a4d8c2SCharles.Forsyth 		if(p->to.type == D_OREG && p->to.reg == REGSP)
3174a4d8c2SCharles.Forsyth 			if(p->to.offset > curframe)
3274a4d8c2SCharles.Forsyth 				curframe = p->to.offset;
3374a4d8c2SCharles.Forsyth 
3474a4d8c2SCharles.Forsyth 		switch(p->as) {
3574a4d8c2SCharles.Forsyth 		/* too hard, just leave alone */
3674a4d8c2SCharles.Forsyth 		case ATEXT:
3774a4d8c2SCharles.Forsyth 			if(curtext && curtext->from.sym) {
3874a4d8c2SCharles.Forsyth 				curtext->from.sym->frame = curframe;
3974a4d8c2SCharles.Forsyth 				curtext->from.sym->become = curbecome;
4074a4d8c2SCharles.Forsyth 				if(curbecome > maxbecome)
4174a4d8c2SCharles.Forsyth 					maxbecome = curbecome;
4274a4d8c2SCharles.Forsyth 			}
4374a4d8c2SCharles.Forsyth 			curframe = 0;
4474a4d8c2SCharles.Forsyth 			curbecome = 0;
4574a4d8c2SCharles.Forsyth 
4674a4d8c2SCharles.Forsyth 			q = p;
4774a4d8c2SCharles.Forsyth 			p->mark |= LABEL|LEAF|SYNC;
4874a4d8c2SCharles.Forsyth 			if(p->link)
4974a4d8c2SCharles.Forsyth 				p->link->mark |= LABEL;
5074a4d8c2SCharles.Forsyth 			curtext = p;
5174a4d8c2SCharles.Forsyth 			break;
5274a4d8c2SCharles.Forsyth 
5374a4d8c2SCharles.Forsyth 		case ANOR:
5474a4d8c2SCharles.Forsyth 			q = p;
5574a4d8c2SCharles.Forsyth 			if(p->to.type == D_REG)
5674a4d8c2SCharles.Forsyth 				if(p->to.reg == REGZERO)
5774a4d8c2SCharles.Forsyth 					p->mark |= LABEL|SYNC;
5874a4d8c2SCharles.Forsyth 			break;
5974a4d8c2SCharles.Forsyth 
6074a4d8c2SCharles.Forsyth 		case ALWAR:
6174a4d8c2SCharles.Forsyth 		case ASTWCCC:
6274a4d8c2SCharles.Forsyth 		case AECIWX:
6374a4d8c2SCharles.Forsyth 		case AECOWX:
6474a4d8c2SCharles.Forsyth 		case AEIEIO:
6574a4d8c2SCharles.Forsyth 		case AICBI:
6674a4d8c2SCharles.Forsyth 		case AISYNC:
6774a4d8c2SCharles.Forsyth 		case ATLBIE:
6874a4d8c2SCharles.Forsyth 		case ADCBF:
6974a4d8c2SCharles.Forsyth 		case ADCBI:
7074a4d8c2SCharles.Forsyth 		case ADCBST:
7174a4d8c2SCharles.Forsyth 		case ADCBT:
7274a4d8c2SCharles.Forsyth 		case ADCBTST:
7374a4d8c2SCharles.Forsyth 		case ADCBZ:
7474a4d8c2SCharles.Forsyth 		case ASYNC:
7574a4d8c2SCharles.Forsyth 		case ATW:
7674a4d8c2SCharles.Forsyth 		case AWORD:
7774a4d8c2SCharles.Forsyth 		case ARFI:
7874a4d8c2SCharles.Forsyth 		case ARFCI:
7974a4d8c2SCharles.Forsyth 			q = p;
8074a4d8c2SCharles.Forsyth 			p->mark |= LABEL|SYNC;
8174a4d8c2SCharles.Forsyth 			continue;
8274a4d8c2SCharles.Forsyth 
8374a4d8c2SCharles.Forsyth 		case AMOVW:
8474a4d8c2SCharles.Forsyth 			q = p;
8574a4d8c2SCharles.Forsyth 			switch(p->from.type) {
8674a4d8c2SCharles.Forsyth 			case D_MSR:
8774a4d8c2SCharles.Forsyth 			case D_SREG:
8874a4d8c2SCharles.Forsyth 			case D_SPR:
8974a4d8c2SCharles.Forsyth 			case D_FPSCR:
9074a4d8c2SCharles.Forsyth 			case D_CREG:
9174a4d8c2SCharles.Forsyth 			case D_DCR:
9274a4d8c2SCharles.Forsyth 				p->mark |= LABEL|SYNC;
9374a4d8c2SCharles.Forsyth 			}
9474a4d8c2SCharles.Forsyth 			switch(p->to.type) {
9574a4d8c2SCharles.Forsyth 			case D_MSR:
9674a4d8c2SCharles.Forsyth 			case D_SREG:
9774a4d8c2SCharles.Forsyth 			case D_SPR:
9874a4d8c2SCharles.Forsyth 			case D_FPSCR:
9974a4d8c2SCharles.Forsyth 			case D_CREG:
10074a4d8c2SCharles.Forsyth 			case D_DCR:
10174a4d8c2SCharles.Forsyth 				p->mark |= LABEL|SYNC;
10274a4d8c2SCharles.Forsyth 			}
10374a4d8c2SCharles.Forsyth 			continue;
10474a4d8c2SCharles.Forsyth 
10574a4d8c2SCharles.Forsyth 		case AFABS:
10674a4d8c2SCharles.Forsyth 		case AFABSCC:
10774a4d8c2SCharles.Forsyth 		case AFADD:
10874a4d8c2SCharles.Forsyth 		case AFADDCC:
10974a4d8c2SCharles.Forsyth 		case AFCTIW:
11074a4d8c2SCharles.Forsyth 		case AFCTIWCC:
11174a4d8c2SCharles.Forsyth 		case AFCTIWZ:
11274a4d8c2SCharles.Forsyth 		case AFCTIWZCC:
11374a4d8c2SCharles.Forsyth 		case AFDIV:
11474a4d8c2SCharles.Forsyth 		case AFDIVCC:
11574a4d8c2SCharles.Forsyth 		case AFMADD:
11674a4d8c2SCharles.Forsyth 		case AFMADDCC:
11774a4d8c2SCharles.Forsyth 		case AFMOVD:
11874a4d8c2SCharles.Forsyth 		case AFMOVDU:
11974a4d8c2SCharles.Forsyth 		/* case AFMOVDS: */
12074a4d8c2SCharles.Forsyth 		case AFMOVS:
12174a4d8c2SCharles.Forsyth 		case AFMOVSU:
12274a4d8c2SCharles.Forsyth 		/* case AFMOVSD: */
12374a4d8c2SCharles.Forsyth 		case AFMSUB:
12474a4d8c2SCharles.Forsyth 		case AFMSUBCC:
12574a4d8c2SCharles.Forsyth 		case AFMUL:
12674a4d8c2SCharles.Forsyth 		case AFMULCC:
12774a4d8c2SCharles.Forsyth 		case AFNABS:
12874a4d8c2SCharles.Forsyth 		case AFNABSCC:
12974a4d8c2SCharles.Forsyth 		case AFNEG:
13074a4d8c2SCharles.Forsyth 		case AFNEGCC:
13174a4d8c2SCharles.Forsyth 		case AFNMADD:
13274a4d8c2SCharles.Forsyth 		case AFNMADDCC:
13374a4d8c2SCharles.Forsyth 		case AFNMSUB:
13474a4d8c2SCharles.Forsyth 		case AFNMSUBCC:
13574a4d8c2SCharles.Forsyth 		case AFRSP:
13674a4d8c2SCharles.Forsyth 		case AFRSPCC:
13774a4d8c2SCharles.Forsyth 		case AFSUB:
13874a4d8c2SCharles.Forsyth 		case AFSUBCC:
13974a4d8c2SCharles.Forsyth 			q = p;
14074a4d8c2SCharles.Forsyth 			p->mark |= FLOAT;
14174a4d8c2SCharles.Forsyth 			continue;
14274a4d8c2SCharles.Forsyth 
14374a4d8c2SCharles.Forsyth 		case ABL:
14474a4d8c2SCharles.Forsyth 		case ABCL:
14574a4d8c2SCharles.Forsyth 			if(curtext != P)
14674a4d8c2SCharles.Forsyth 				curtext->mark &= ~LEAF;
14774a4d8c2SCharles.Forsyth 
14874a4d8c2SCharles.Forsyth 		case ABC:
14974a4d8c2SCharles.Forsyth 		case ABEQ:
15074a4d8c2SCharles.Forsyth 		case ABGE:
15174a4d8c2SCharles.Forsyth 		case ABGT:
15274a4d8c2SCharles.Forsyth 		case ABLE:
15374a4d8c2SCharles.Forsyth 		case ABLT:
15474a4d8c2SCharles.Forsyth 		case ABNE:
15574a4d8c2SCharles.Forsyth 		case ABR:
15674a4d8c2SCharles.Forsyth 		case ABVC:
15774a4d8c2SCharles.Forsyth 		case ABVS:
15874a4d8c2SCharles.Forsyth 
15974a4d8c2SCharles.Forsyth 			p->mark |= BRANCH;
16074a4d8c2SCharles.Forsyth 			q = p;
16174a4d8c2SCharles.Forsyth 			q1 = p->cond;
16274a4d8c2SCharles.Forsyth 			if(q1 != P) {
16374a4d8c2SCharles.Forsyth 				while(q1->as == ANOP) {
16474a4d8c2SCharles.Forsyth 					q1 = q1->link;
16574a4d8c2SCharles.Forsyth 					p->cond = q1;
16674a4d8c2SCharles.Forsyth 				}
16774a4d8c2SCharles.Forsyth 				if(!(q1->mark & LEAF))
16874a4d8c2SCharles.Forsyth 					q1->mark |= LABEL;
16974a4d8c2SCharles.Forsyth 			} else
17074a4d8c2SCharles.Forsyth 				p->mark |= LABEL;
17174a4d8c2SCharles.Forsyth 			q1 = p->link;
17274a4d8c2SCharles.Forsyth 			if(q1 != P)
17374a4d8c2SCharles.Forsyth 				q1->mark |= LABEL;
17474a4d8c2SCharles.Forsyth 			continue;
17574a4d8c2SCharles.Forsyth 
17674a4d8c2SCharles.Forsyth 		case AFCMPO:
17774a4d8c2SCharles.Forsyth 		case AFCMPU:
17874a4d8c2SCharles.Forsyth 			q = p;
17974a4d8c2SCharles.Forsyth 			p->mark |= FCMP|FLOAT;
18074a4d8c2SCharles.Forsyth 			continue;
18174a4d8c2SCharles.Forsyth 
18274a4d8c2SCharles.Forsyth 		case ARETURN:
18374a4d8c2SCharles.Forsyth 			/* special form of RETURN is BECOME */
18474a4d8c2SCharles.Forsyth 			if(p->from.type == D_CONST)
18574a4d8c2SCharles.Forsyth 				if(p->from.offset > curbecome)
18674a4d8c2SCharles.Forsyth 					curbecome = p->from.offset;
18774a4d8c2SCharles.Forsyth 
18874a4d8c2SCharles.Forsyth 			q = p;
18974a4d8c2SCharles.Forsyth 			if(p->link != P)
19074a4d8c2SCharles.Forsyth 				p->link->mark |= LABEL;
19174a4d8c2SCharles.Forsyth 			continue;
19274a4d8c2SCharles.Forsyth 
19374a4d8c2SCharles.Forsyth 		case ANOP:
19474a4d8c2SCharles.Forsyth 			q1 = p->link;
19574a4d8c2SCharles.Forsyth 			q->link = q1;		/* q is non-nop */
19674a4d8c2SCharles.Forsyth 			q1->mark |= p->mark;
19774a4d8c2SCharles.Forsyth 			continue;
19874a4d8c2SCharles.Forsyth 
19974a4d8c2SCharles.Forsyth 		default:
20074a4d8c2SCharles.Forsyth 			q = p;
20174a4d8c2SCharles.Forsyth 			continue;
20274a4d8c2SCharles.Forsyth 		}
20374a4d8c2SCharles.Forsyth 	}
20474a4d8c2SCharles.Forsyth 	if(curtext && curtext->from.sym) {
20574a4d8c2SCharles.Forsyth 		curtext->from.sym->frame = curframe;
20674a4d8c2SCharles.Forsyth 		curtext->from.sym->become = curbecome;
20774a4d8c2SCharles.Forsyth 		if(curbecome > maxbecome)
20874a4d8c2SCharles.Forsyth 			maxbecome = curbecome;
20974a4d8c2SCharles.Forsyth 	}
21074a4d8c2SCharles.Forsyth 
21174a4d8c2SCharles.Forsyth 	if(debug['b'])
21274a4d8c2SCharles.Forsyth 		print("max become = %d\n", maxbecome);
21374a4d8c2SCharles.Forsyth 	xdefine("ALEFbecome", STEXT, maxbecome);
21474a4d8c2SCharles.Forsyth 
21574a4d8c2SCharles.Forsyth 	curtext = 0;
21674a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
21774a4d8c2SCharles.Forsyth 		switch(p->as) {
21874a4d8c2SCharles.Forsyth 		case ATEXT:
21974a4d8c2SCharles.Forsyth 			curtext = p;
22074a4d8c2SCharles.Forsyth 			break;
22174a4d8c2SCharles.Forsyth 
22274a4d8c2SCharles.Forsyth 		case ABL:	/* ABCL? */
22374a4d8c2SCharles.Forsyth 			if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
22474a4d8c2SCharles.Forsyth 				o = maxbecome - curtext->from.sym->frame;
22574a4d8c2SCharles.Forsyth 				if(o <= 0)
22674a4d8c2SCharles.Forsyth 					break;
22774a4d8c2SCharles.Forsyth 				/* calling a become or calling a variable */
22874a4d8c2SCharles.Forsyth 				if(p->to.sym == S || p->to.sym->become) {
22974a4d8c2SCharles.Forsyth 					curtext->to.offset += o;
23074a4d8c2SCharles.Forsyth 					if(debug['b']) {
23174a4d8c2SCharles.Forsyth 						curp = p;
23274a4d8c2SCharles.Forsyth 						print("%D calling %D increase %d\n",
23374a4d8c2SCharles.Forsyth 							&curtext->from, &p->to, o);
23474a4d8c2SCharles.Forsyth 					}
23574a4d8c2SCharles.Forsyth 				}
23674a4d8c2SCharles.Forsyth 			}
23774a4d8c2SCharles.Forsyth 			break;
23874a4d8c2SCharles.Forsyth 		}
23974a4d8c2SCharles.Forsyth 	}
24074a4d8c2SCharles.Forsyth 
24174a4d8c2SCharles.Forsyth 	curtext = P;
24274a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
24374a4d8c2SCharles.Forsyth 		o = p->as;
24474a4d8c2SCharles.Forsyth 		switch(o) {
24574a4d8c2SCharles.Forsyth 		case ATEXT:
24674a4d8c2SCharles.Forsyth 			mov = AMOVW;
24774a4d8c2SCharles.Forsyth 			aoffset = 0;
24874a4d8c2SCharles.Forsyth 			curtext = p;
24974a4d8c2SCharles.Forsyth 			autosize = p->to.offset + 4;
25074a4d8c2SCharles.Forsyth 			if((p->mark & LEAF) && autosize <= 4)
25174a4d8c2SCharles.Forsyth 				autosize = 0;
25274a4d8c2SCharles.Forsyth 			else
25374a4d8c2SCharles.Forsyth 				if(autosize & 4)
25474a4d8c2SCharles.Forsyth 					autosize += 4;
25574a4d8c2SCharles.Forsyth 			p->to.offset = autosize - 4;
25674a4d8c2SCharles.Forsyth 
25774a4d8c2SCharles.Forsyth 			q = p;
25874a4d8c2SCharles.Forsyth 			if(autosize) {
25974a4d8c2SCharles.Forsyth 				/* use MOVWU to adjust R1 when saving R31, if autosize is small */
26074a4d8c2SCharles.Forsyth 				if(!(curtext->mark & LEAF) && autosize >= -BIG && autosize <= BIG) {
26174a4d8c2SCharles.Forsyth 					mov = AMOVWU;
26274a4d8c2SCharles.Forsyth 					aoffset = -autosize;
26374a4d8c2SCharles.Forsyth 				} else {
26474a4d8c2SCharles.Forsyth 					q = prg();
26574a4d8c2SCharles.Forsyth 					q->as = AADD;
26674a4d8c2SCharles.Forsyth 					q->line = p->line;
26774a4d8c2SCharles.Forsyth 					q->from.type = D_CONST;
26874a4d8c2SCharles.Forsyth 					q->from.offset = -autosize;
26974a4d8c2SCharles.Forsyth 					q->to.type = D_REG;
27074a4d8c2SCharles.Forsyth 					q->to.reg = REGSP;
27174a4d8c2SCharles.Forsyth 
27274a4d8c2SCharles.Forsyth 					q->link = p->link;
27374a4d8c2SCharles.Forsyth 					p->link = q;
27474a4d8c2SCharles.Forsyth 				}
27574a4d8c2SCharles.Forsyth 			} else
27674a4d8c2SCharles.Forsyth 			if(!(curtext->mark & LEAF)) {
27774a4d8c2SCharles.Forsyth 				if(debug['v'])
27874a4d8c2SCharles.Forsyth 					Bprint(&bso, "save suppressed in: %s\n",
27974a4d8c2SCharles.Forsyth 						curtext->from.sym->name);
28074a4d8c2SCharles.Forsyth 				curtext->mark |= LEAF;
28174a4d8c2SCharles.Forsyth 			}
28274a4d8c2SCharles.Forsyth 
28374a4d8c2SCharles.Forsyth 			if(curtext->mark & LEAF) {
28474a4d8c2SCharles.Forsyth 				if(curtext->from.sym)
28574a4d8c2SCharles.Forsyth 					curtext->from.sym->type = SLEAF;
28674a4d8c2SCharles.Forsyth 				break;
28774a4d8c2SCharles.Forsyth 			}
28874a4d8c2SCharles.Forsyth 
28974a4d8c2SCharles.Forsyth 			q1 = prg();
29074a4d8c2SCharles.Forsyth 			q1->as = mov;
29174a4d8c2SCharles.Forsyth 			q1->line = p->line;
29274a4d8c2SCharles.Forsyth 			q1->from.type = D_REG;
29374a4d8c2SCharles.Forsyth 			q1->from.reg = REGTMP;
29474a4d8c2SCharles.Forsyth 			q1->to.type = D_OREG;
29574a4d8c2SCharles.Forsyth 			q1->to.offset = aoffset;
29674a4d8c2SCharles.Forsyth 			q1->to.reg = REGSP;
29774a4d8c2SCharles.Forsyth 
29874a4d8c2SCharles.Forsyth 			q1->link = q->link;
29974a4d8c2SCharles.Forsyth 			q->link = q1;
30074a4d8c2SCharles.Forsyth 
30174a4d8c2SCharles.Forsyth 			q1 = prg();
30274a4d8c2SCharles.Forsyth 			q1->as = AMOVW;
30374a4d8c2SCharles.Forsyth 			q1->line = p->line;
30474a4d8c2SCharles.Forsyth 			q1->from.type = D_SPR;
30574a4d8c2SCharles.Forsyth 			q1->from.offset = D_LR;
30674a4d8c2SCharles.Forsyth 			q1->to.type = D_REG;
30774a4d8c2SCharles.Forsyth 			q1->to.reg = REGTMP;
30874a4d8c2SCharles.Forsyth 
30974a4d8c2SCharles.Forsyth 			q1->link = q->link;
31074a4d8c2SCharles.Forsyth 			q->link = q1;
31174a4d8c2SCharles.Forsyth 			break;
31274a4d8c2SCharles.Forsyth 
31374a4d8c2SCharles.Forsyth 		case ARETURN:
31474a4d8c2SCharles.Forsyth 			if(p->from.type == D_CONST)
31574a4d8c2SCharles.Forsyth 				goto become;
31674a4d8c2SCharles.Forsyth 			if(curtext->mark & LEAF) {
31774a4d8c2SCharles.Forsyth 				if(!autosize) {
31874a4d8c2SCharles.Forsyth 					p->as = ABR;
31974a4d8c2SCharles.Forsyth 					p->from = zprg.from;
32074a4d8c2SCharles.Forsyth 					p->to.type = D_SPR;
32174a4d8c2SCharles.Forsyth 					p->to.offset = D_LR;
32274a4d8c2SCharles.Forsyth 					p->mark |= BRANCH;
32374a4d8c2SCharles.Forsyth 					break;
32474a4d8c2SCharles.Forsyth 				}
32574a4d8c2SCharles.Forsyth 
32674a4d8c2SCharles.Forsyth 				p->as = AADD;
32774a4d8c2SCharles.Forsyth 				p->from.type = D_CONST;
32874a4d8c2SCharles.Forsyth 				p->from.offset = autosize;
32974a4d8c2SCharles.Forsyth 				p->to.type = D_REG;
33074a4d8c2SCharles.Forsyth 				p->to.reg = REGSP;
33174a4d8c2SCharles.Forsyth 
33274a4d8c2SCharles.Forsyth 				q = prg();
33374a4d8c2SCharles.Forsyth 				q->as = ABR;
33474a4d8c2SCharles.Forsyth 				q->line = p->line;
33574a4d8c2SCharles.Forsyth 				q->to.type = D_SPR;
33674a4d8c2SCharles.Forsyth 				q->to.offset = D_LR;
33774a4d8c2SCharles.Forsyth 				q->mark |= BRANCH;
33874a4d8c2SCharles.Forsyth 
33974a4d8c2SCharles.Forsyth 				q->link = p->link;
34074a4d8c2SCharles.Forsyth 				p->link = q;
34174a4d8c2SCharles.Forsyth 				break;
34274a4d8c2SCharles.Forsyth 			}
34374a4d8c2SCharles.Forsyth 
34474a4d8c2SCharles.Forsyth 			p->as = AMOVW;
34574a4d8c2SCharles.Forsyth 			p->from.type = D_OREG;
34674a4d8c2SCharles.Forsyth 			p->from.offset = 0;
34774a4d8c2SCharles.Forsyth 			p->from.reg = REGSP;
34874a4d8c2SCharles.Forsyth 			p->to.type = D_REG;
34974a4d8c2SCharles.Forsyth 			p->to.reg = REGTMP;
35074a4d8c2SCharles.Forsyth 
35174a4d8c2SCharles.Forsyth 			q = prg();
35274a4d8c2SCharles.Forsyth 			q->as = AMOVW;
35374a4d8c2SCharles.Forsyth 			q->line = p->line;
35474a4d8c2SCharles.Forsyth 			q->from.type = D_REG;
35574a4d8c2SCharles.Forsyth 			q->from.reg = REGTMP;
35674a4d8c2SCharles.Forsyth 			q->to.type = D_SPR;
35774a4d8c2SCharles.Forsyth 			q->to.offset = D_LR;
35874a4d8c2SCharles.Forsyth 
35974a4d8c2SCharles.Forsyth 			q->link = p->link;
36074a4d8c2SCharles.Forsyth 			p->link = q;
36174a4d8c2SCharles.Forsyth 			p = q;
36274a4d8c2SCharles.Forsyth 
36374a4d8c2SCharles.Forsyth 			if(autosize) {
36474a4d8c2SCharles.Forsyth 				q = prg();
36574a4d8c2SCharles.Forsyth 				q->as = AADD;
36674a4d8c2SCharles.Forsyth 				q->line = p->line;
36774a4d8c2SCharles.Forsyth 				q->from.type = D_CONST;
36874a4d8c2SCharles.Forsyth 				q->from.offset = autosize;
36974a4d8c2SCharles.Forsyth 				q->to.type = D_REG;
37074a4d8c2SCharles.Forsyth 				q->to.reg = REGSP;
37174a4d8c2SCharles.Forsyth 
37274a4d8c2SCharles.Forsyth 				q->link = p->link;
37374a4d8c2SCharles.Forsyth 				p->link = q;
37474a4d8c2SCharles.Forsyth 			}
37574a4d8c2SCharles.Forsyth 
37674a4d8c2SCharles.Forsyth 			q1 = prg();
37774a4d8c2SCharles.Forsyth 			q1->as = ABR;
37874a4d8c2SCharles.Forsyth 			q1->line = p->line;
37974a4d8c2SCharles.Forsyth 			q1->to.type = D_SPR;
38074a4d8c2SCharles.Forsyth 			q1->to.offset = D_LR;
38174a4d8c2SCharles.Forsyth 			q1->mark |= BRANCH;
38274a4d8c2SCharles.Forsyth 
38374a4d8c2SCharles.Forsyth 			q1->link = q->link;
38474a4d8c2SCharles.Forsyth 			q->link = q1;
38574a4d8c2SCharles.Forsyth 			break;
38674a4d8c2SCharles.Forsyth 
38774a4d8c2SCharles.Forsyth 		become:
38874a4d8c2SCharles.Forsyth 			if(curtext->mark & LEAF) {
38974a4d8c2SCharles.Forsyth 
39074a4d8c2SCharles.Forsyth 				q = prg();
39174a4d8c2SCharles.Forsyth 				q->line = p->line;
39274a4d8c2SCharles.Forsyth 				q->as = ABR;
39374a4d8c2SCharles.Forsyth 				q->from = zprg.from;
39474a4d8c2SCharles.Forsyth 				q->to = p->to;
39574a4d8c2SCharles.Forsyth 				q->cond = p->cond;
39674a4d8c2SCharles.Forsyth 				q->link = p->link;
39774a4d8c2SCharles.Forsyth 				q->mark |= BRANCH;
39874a4d8c2SCharles.Forsyth 				p->link = q;
39974a4d8c2SCharles.Forsyth 
40074a4d8c2SCharles.Forsyth 				p->as = AADD;
40174a4d8c2SCharles.Forsyth 				p->from = zprg.from;
40274a4d8c2SCharles.Forsyth 				p->from.type = D_CONST;
40374a4d8c2SCharles.Forsyth 				p->from.offset = autosize;
40474a4d8c2SCharles.Forsyth 				p->to = zprg.to;
40574a4d8c2SCharles.Forsyth 				p->to.type = D_REG;
40674a4d8c2SCharles.Forsyth 				p->to.reg = REGSP;
40774a4d8c2SCharles.Forsyth 
40874a4d8c2SCharles.Forsyth 				break;
40974a4d8c2SCharles.Forsyth 			}
41074a4d8c2SCharles.Forsyth 			q = prg();
41174a4d8c2SCharles.Forsyth 			q->line = p->line;
41274a4d8c2SCharles.Forsyth 			q->as = ABR;
41374a4d8c2SCharles.Forsyth 			q->from = zprg.from;
41474a4d8c2SCharles.Forsyth 			q->to = p->to;
41574a4d8c2SCharles.Forsyth 			q->cond = p->cond;
41674a4d8c2SCharles.Forsyth 			q->mark |= BRANCH;
41774a4d8c2SCharles.Forsyth 			q->link = p->link;
41874a4d8c2SCharles.Forsyth 			p->link = q;
41974a4d8c2SCharles.Forsyth 
42074a4d8c2SCharles.Forsyth 			q = prg();
42174a4d8c2SCharles.Forsyth 			q->line = p->line;
42274a4d8c2SCharles.Forsyth 			q->as = AADD;
42374a4d8c2SCharles.Forsyth 			q->from.type = D_CONST;
42474a4d8c2SCharles.Forsyth 			q->from.offset = autosize;
42574a4d8c2SCharles.Forsyth 			q->to.type = D_REG;
42674a4d8c2SCharles.Forsyth 			q->to.reg = REGSP;
42774a4d8c2SCharles.Forsyth 			q->link = p->link;
42874a4d8c2SCharles.Forsyth 			p->link = q;
42974a4d8c2SCharles.Forsyth 
43074a4d8c2SCharles.Forsyth 			q = prg();
43174a4d8c2SCharles.Forsyth 			q->line = p->line;
43274a4d8c2SCharles.Forsyth 			q->as = AMOVW;
43374a4d8c2SCharles.Forsyth 			q->line = p->line;
43474a4d8c2SCharles.Forsyth 			q->from.type = D_REG;
43574a4d8c2SCharles.Forsyth 			q->from.reg = REGTMP;
43674a4d8c2SCharles.Forsyth 			q->to.type = D_SPR;
43774a4d8c2SCharles.Forsyth 			q->to.offset = D_LR;
43874a4d8c2SCharles.Forsyth 			q->link = p->link;
43974a4d8c2SCharles.Forsyth 			p->link = q;
44074a4d8c2SCharles.Forsyth 
44174a4d8c2SCharles.Forsyth 			p->as = AMOVW;
44274a4d8c2SCharles.Forsyth 			p->from = zprg.from;
44374a4d8c2SCharles.Forsyth 			p->from.type = D_OREG;
44474a4d8c2SCharles.Forsyth 			p->from.offset = 0;
44574a4d8c2SCharles.Forsyth 			p->from.reg = REGSP;
44674a4d8c2SCharles.Forsyth 			p->to = zprg.to;
44774a4d8c2SCharles.Forsyth 			p->to.type = D_REG;
44874a4d8c2SCharles.Forsyth 			p->to.reg = REGTMP;
44974a4d8c2SCharles.Forsyth 
45074a4d8c2SCharles.Forsyth 			break;
45174a4d8c2SCharles.Forsyth 		}
45274a4d8c2SCharles.Forsyth 	}
45374a4d8c2SCharles.Forsyth 
45474a4d8c2SCharles.Forsyth 	if(debug['Q'] == 0)
45574a4d8c2SCharles.Forsyth 		return;
45674a4d8c2SCharles.Forsyth 
45774a4d8c2SCharles.Forsyth 	curtext = P;
45874a4d8c2SCharles.Forsyth 	q = P;		/* p - 1 */
45974a4d8c2SCharles.Forsyth 	q1 = firstp;	/* top of block */
46074a4d8c2SCharles.Forsyth 	o = 0;		/* count of instructions */
46174a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p1) {
46274a4d8c2SCharles.Forsyth 		p1 = p->link;
46374a4d8c2SCharles.Forsyth 		o++;
46474a4d8c2SCharles.Forsyth 		if(p->mark & NOSCHED){
46574a4d8c2SCharles.Forsyth 			if(q1 != p){
46674a4d8c2SCharles.Forsyth 				sched(q1, q);
46774a4d8c2SCharles.Forsyth 			}
46874a4d8c2SCharles.Forsyth 			for(; p != P; p = p->link){
46974a4d8c2SCharles.Forsyth 				if(!(p->mark & NOSCHED))
47074a4d8c2SCharles.Forsyth 					break;
47174a4d8c2SCharles.Forsyth 				q = p;
47274a4d8c2SCharles.Forsyth 			}
47374a4d8c2SCharles.Forsyth 			p1 = p;
47474a4d8c2SCharles.Forsyth 			q1 = p;
47574a4d8c2SCharles.Forsyth 			o = 0;
47674a4d8c2SCharles.Forsyth 			continue;
47774a4d8c2SCharles.Forsyth 		}
47874a4d8c2SCharles.Forsyth 		if(p->mark & (LABEL|SYNC)) {
47974a4d8c2SCharles.Forsyth 			if(q1 != p)
48074a4d8c2SCharles.Forsyth 				sched(q1, q);
48174a4d8c2SCharles.Forsyth 			q1 = p;
48274a4d8c2SCharles.Forsyth 			o = 1;
48374a4d8c2SCharles.Forsyth 		}
48474a4d8c2SCharles.Forsyth 		if(p->mark & (BRANCH|SYNC)) {
48574a4d8c2SCharles.Forsyth 			sched(q1, p);
48674a4d8c2SCharles.Forsyth 			q1 = p1;
48774a4d8c2SCharles.Forsyth 			o = 0;
48874a4d8c2SCharles.Forsyth 		}
48974a4d8c2SCharles.Forsyth 		if(o >= NSCHED) {
49074a4d8c2SCharles.Forsyth 			sched(q1, p);
49174a4d8c2SCharles.Forsyth 			q1 = p1;
49274a4d8c2SCharles.Forsyth 			o = 0;
49374a4d8c2SCharles.Forsyth 		}
49474a4d8c2SCharles.Forsyth 		q = p;
49574a4d8c2SCharles.Forsyth 	}
49674a4d8c2SCharles.Forsyth }
49774a4d8c2SCharles.Forsyth 
49874a4d8c2SCharles.Forsyth void
addnop(Prog * p)49974a4d8c2SCharles.Forsyth addnop(Prog *p)
50074a4d8c2SCharles.Forsyth {
50174a4d8c2SCharles.Forsyth 	Prog *q;
50274a4d8c2SCharles.Forsyth 
50374a4d8c2SCharles.Forsyth 	q = prg();
504*d67b7dadSforsyth 	q->as = AOR;
50574a4d8c2SCharles.Forsyth 	q->line = p->line;
50674a4d8c2SCharles.Forsyth 	q->from.type = D_REG;
50774a4d8c2SCharles.Forsyth 	q->from.reg = REGZERO;
50874a4d8c2SCharles.Forsyth 	q->to.type = D_REG;
50974a4d8c2SCharles.Forsyth 	q->to.reg = REGZERO;
51074a4d8c2SCharles.Forsyth 
51174a4d8c2SCharles.Forsyth 	q->link = p->link;
51274a4d8c2SCharles.Forsyth 	p->link = q;
51374a4d8c2SCharles.Forsyth }
514