xref: /inferno-os/utils/ql/span.c (revision 647adfbc462388549008eda6af62f2e74b260d63)
174a4d8c2SCharles.Forsyth #include	"l.h"
274a4d8c2SCharles.Forsyth #define	r0iszero	1
374a4d8c2SCharles.Forsyth 
474a4d8c2SCharles.Forsyth void
span(void)574a4d8c2SCharles.Forsyth span(void)
674a4d8c2SCharles.Forsyth {
7d67b7dadSforsyth 	Prog *p, *q;
874a4d8c2SCharles.Forsyth 	Sym *setext;
974a4d8c2SCharles.Forsyth 	Optab *o;
10d67b7dadSforsyth 	int m, bflag;
11d67b7dadSforsyth 	long c, otxt;
1274a4d8c2SCharles.Forsyth 
1374a4d8c2SCharles.Forsyth 	if(debug['v'])
1474a4d8c2SCharles.Forsyth 		Bprint(&bso, "%5.2f span\n", cputime());
1574a4d8c2SCharles.Forsyth 	Bflush(&bso);
16d67b7dadSforsyth 
17d67b7dadSforsyth 	bflag = 0;
1874a4d8c2SCharles.Forsyth 	c = INITTEXT;
19d67b7dadSforsyth 	otxt = c;
2074a4d8c2SCharles.Forsyth 	for(p = firstp; p != P; p = p->link) {
2174a4d8c2SCharles.Forsyth 		p->pc = c;
2274a4d8c2SCharles.Forsyth 		o = oplook(p);
2374a4d8c2SCharles.Forsyth 		m = o->size;
2474a4d8c2SCharles.Forsyth 		if(m == 0) {
2574a4d8c2SCharles.Forsyth 			if(p->as == ATEXT) {
2674a4d8c2SCharles.Forsyth 				curtext = p;
2774a4d8c2SCharles.Forsyth 				autosize = p->to.offset + 4;
2874a4d8c2SCharles.Forsyth 				if(p->from3.type == D_CONST) {
2974a4d8c2SCharles.Forsyth 					if(p->from3.offset & 3)
3074a4d8c2SCharles.Forsyth 						diag("illegal origin\n%P", p);
3174a4d8c2SCharles.Forsyth 					if(c > p->from3.offset)
3274a4d8c2SCharles.Forsyth 						diag("passed origin (#%lux)\n%P", c, p);
3374a4d8c2SCharles.Forsyth 					else
3474a4d8c2SCharles.Forsyth 						c = p->from3.offset;
3574a4d8c2SCharles.Forsyth 					p->pc = c;
3674a4d8c2SCharles.Forsyth 				}
3774a4d8c2SCharles.Forsyth 				if(p->from.sym != S)
3874a4d8c2SCharles.Forsyth 					p->from.sym->value = c;
39d67b7dadSforsyth 				/* need passes to resolve branches? */
40d67b7dadSforsyth 				if(c-otxt >= (1L<<15))
41d67b7dadSforsyth 					bflag = c;
42d67b7dadSforsyth 				otxt = c;
4374a4d8c2SCharles.Forsyth 				continue;
4474a4d8c2SCharles.Forsyth 			}
4574a4d8c2SCharles.Forsyth 			if(p->as != ANOP)
4674a4d8c2SCharles.Forsyth 				diag("zero-width instruction\n%P", p);
4774a4d8c2SCharles.Forsyth 			continue;
4874a4d8c2SCharles.Forsyth 		}
4974a4d8c2SCharles.Forsyth 		c += m;
5074a4d8c2SCharles.Forsyth 	}
51d67b7dadSforsyth 
52d67b7dadSforsyth 	/*
53d67b7dadSforsyth 	 * if any procedure is large enough to
54d67b7dadSforsyth 	 * generate a large SBRA branch, then
55d67b7dadSforsyth 	 * generate extra passes putting branches
56d67b7dadSforsyth 	 * around jmps to fix. this is rare.
57d67b7dadSforsyth 	 */
58d67b7dadSforsyth 	while(bflag) {
59d67b7dadSforsyth 		if(debug['v'])
60d67b7dadSforsyth 			Bprint(&bso, "%5.2f span1\n", cputime());
61d67b7dadSforsyth 		bflag = 0;
62d67b7dadSforsyth 		c = INITTEXT;
63d67b7dadSforsyth 		for(p = firstp; p != P; p = p->link) {
64d67b7dadSforsyth 			p->pc = c;
65d67b7dadSforsyth 			o = oplook(p);
66d67b7dadSforsyth 			if((o->type == 16 || o->type == 17) && p->cond) {
67d67b7dadSforsyth 				otxt = p->cond->pc - c;
68d67b7dadSforsyth 				if(otxt < -(1L<<16)+10 || otxt >= (1L<<15)-10) {
69d67b7dadSforsyth 					q = prg();
70d67b7dadSforsyth 					q->link = p->link;
71d67b7dadSforsyth 					p->link = q;
72d67b7dadSforsyth 					q->as = ABR;
73d67b7dadSforsyth 					q->to.type = D_BRANCH;
74d67b7dadSforsyth 					q->cond = p->cond;
75d67b7dadSforsyth 					p->cond = q;
76d67b7dadSforsyth 					q = prg();
77d67b7dadSforsyth 					q->link = p->link;
78d67b7dadSforsyth 					p->link = q;
79d67b7dadSforsyth 					q->as = ABR;
80d67b7dadSforsyth 					q->to.type = D_BRANCH;
81d67b7dadSforsyth 					q->cond = q->link->link;
82d67b7dadSforsyth 					addnop(p->link);
83d67b7dadSforsyth 					addnop(p);
84d67b7dadSforsyth 					bflag = 1;
85d67b7dadSforsyth 				}
86d67b7dadSforsyth 			}
87d67b7dadSforsyth 			m = o->size;
88d67b7dadSforsyth 			if(m == 0) {
89d67b7dadSforsyth 				if(p->as == ATEXT) {
90d67b7dadSforsyth 					curtext = p;
91d67b7dadSforsyth 					autosize = p->to.offset + 4;
92d67b7dadSforsyth 					if(p->from.sym != S)
93d67b7dadSforsyth 						p->from.sym->value = c;
94d67b7dadSforsyth 					continue;
95d67b7dadSforsyth 				}
96d67b7dadSforsyth 				if(p->as != ANOP)
97d67b7dadSforsyth 					diag("zero-width instruction\n%P", p);
98d67b7dadSforsyth 				continue;
99d67b7dadSforsyth 			}
100d67b7dadSforsyth 			c += m;
101d67b7dadSforsyth 		}
102d67b7dadSforsyth 	}
103d67b7dadSforsyth 
104d67b7dadSforsyth 	c = rnd(c, 8);
10574a4d8c2SCharles.Forsyth 
10674a4d8c2SCharles.Forsyth 	setext = lookup("etext", 0);
10774a4d8c2SCharles.Forsyth 	if(setext != S) {
10874a4d8c2SCharles.Forsyth 		setext->value = c;
10974a4d8c2SCharles.Forsyth 		textsize = c - INITTEXT;
11074a4d8c2SCharles.Forsyth 	}
11174a4d8c2SCharles.Forsyth 	if(INITRND)
11274a4d8c2SCharles.Forsyth 		INITDAT = rnd(c, INITRND);
11374a4d8c2SCharles.Forsyth 	if(debug['v'])
11474a4d8c2SCharles.Forsyth 		Bprint(&bso, "tsize = %lux\n", textsize);
11574a4d8c2SCharles.Forsyth 	Bflush(&bso);
11674a4d8c2SCharles.Forsyth }
11774a4d8c2SCharles.Forsyth 
11874a4d8c2SCharles.Forsyth void
xdefine(char * p,int t,long v)11974a4d8c2SCharles.Forsyth xdefine(char *p, int t, long v)
12074a4d8c2SCharles.Forsyth {
12174a4d8c2SCharles.Forsyth 	Sym *s;
12274a4d8c2SCharles.Forsyth 
12374a4d8c2SCharles.Forsyth 	s = lookup(p, 0);
12474a4d8c2SCharles.Forsyth 	if(s->type == 0 || s->type == SXREF) {
12574a4d8c2SCharles.Forsyth 		s->type = t;
12674a4d8c2SCharles.Forsyth 		s->value = v;
12774a4d8c2SCharles.Forsyth 	}
12874a4d8c2SCharles.Forsyth }
12974a4d8c2SCharles.Forsyth 
13074a4d8c2SCharles.Forsyth long
regoff(Adr * a)13174a4d8c2SCharles.Forsyth regoff(Adr *a)
13274a4d8c2SCharles.Forsyth {
13374a4d8c2SCharles.Forsyth 
13474a4d8c2SCharles.Forsyth 	instoffset = 0;
13574a4d8c2SCharles.Forsyth 	aclass(a);
13674a4d8c2SCharles.Forsyth 	return instoffset;
13774a4d8c2SCharles.Forsyth }
13874a4d8c2SCharles.Forsyth 
13974a4d8c2SCharles.Forsyth int
aclass(Adr * a)14074a4d8c2SCharles.Forsyth aclass(Adr *a)
14174a4d8c2SCharles.Forsyth {
14274a4d8c2SCharles.Forsyth 	Sym *s;
14374a4d8c2SCharles.Forsyth 	int t;
14474a4d8c2SCharles.Forsyth 
14574a4d8c2SCharles.Forsyth 	switch(a->type) {
14674a4d8c2SCharles.Forsyth 	case D_NONE:
14774a4d8c2SCharles.Forsyth 		return C_NONE;
14874a4d8c2SCharles.Forsyth 
14974a4d8c2SCharles.Forsyth 	case D_REG:
15074a4d8c2SCharles.Forsyth 		return C_REG;
15174a4d8c2SCharles.Forsyth 
15274a4d8c2SCharles.Forsyth 	case D_FREG:
15374a4d8c2SCharles.Forsyth 		return C_FREG;
15474a4d8c2SCharles.Forsyth 
15574a4d8c2SCharles.Forsyth 	case D_CREG:
15674a4d8c2SCharles.Forsyth 		return C_CREG;
15774a4d8c2SCharles.Forsyth 
15874a4d8c2SCharles.Forsyth 	case D_SPR:
15974a4d8c2SCharles.Forsyth 		if(a->offset == D_LR)
16074a4d8c2SCharles.Forsyth 			return C_LR;
16174a4d8c2SCharles.Forsyth 		if(a->offset == D_XER)
16274a4d8c2SCharles.Forsyth 			return C_XER;
16374a4d8c2SCharles.Forsyth 		if(a->offset == D_CTR)
16474a4d8c2SCharles.Forsyth 			return C_CTR;
16574a4d8c2SCharles.Forsyth 		return C_SPR;
16674a4d8c2SCharles.Forsyth 
16774a4d8c2SCharles.Forsyth 	case D_DCR:
16874a4d8c2SCharles.Forsyth 		return C_SPR;
16974a4d8c2SCharles.Forsyth 
17074a4d8c2SCharles.Forsyth 	case D_SREG:
17174a4d8c2SCharles.Forsyth 		return C_SREG;
17274a4d8c2SCharles.Forsyth 
17374a4d8c2SCharles.Forsyth 	case D_FPSCR:
17474a4d8c2SCharles.Forsyth 		return C_FPSCR;
17574a4d8c2SCharles.Forsyth 
17674a4d8c2SCharles.Forsyth 	case D_MSR:
17774a4d8c2SCharles.Forsyth 		return C_MSR;
17874a4d8c2SCharles.Forsyth 
17974a4d8c2SCharles.Forsyth 	case D_OREG:
18074a4d8c2SCharles.Forsyth 		switch(a->name) {
18174a4d8c2SCharles.Forsyth 		case D_EXTERN:
18274a4d8c2SCharles.Forsyth 		case D_STATIC:
18374a4d8c2SCharles.Forsyth 			if(a->sym == S)
18474a4d8c2SCharles.Forsyth 				break;
18574a4d8c2SCharles.Forsyth 			t = a->sym->type;
18674a4d8c2SCharles.Forsyth 			if(t == 0 || t == SXREF) {
18774a4d8c2SCharles.Forsyth 				diag("undefined external: %s in %s",
18874a4d8c2SCharles.Forsyth 					a->sym->name, TNAME);
18974a4d8c2SCharles.Forsyth 				a->sym->type = SDATA;
19074a4d8c2SCharles.Forsyth 			}
19174a4d8c2SCharles.Forsyth 			if(dlm){
19274a4d8c2SCharles.Forsyth 				instoffset = a->sym->value + a->offset;
19374a4d8c2SCharles.Forsyth 				switch(a->sym->type){
19474a4d8c2SCharles.Forsyth 				case STEXT:
19574a4d8c2SCharles.Forsyth 				case SLEAF:
19674a4d8c2SCharles.Forsyth 				case SCONST:
19774a4d8c2SCharles.Forsyth 				case SUNDEF:
19874a4d8c2SCharles.Forsyth 					break;
19974a4d8c2SCharles.Forsyth 				default:
20074a4d8c2SCharles.Forsyth 					instoffset += INITDAT;
20174a4d8c2SCharles.Forsyth 				}
20274a4d8c2SCharles.Forsyth 				return C_ADDR;
20374a4d8c2SCharles.Forsyth 			}
20474a4d8c2SCharles.Forsyth 			instoffset = a->sym->value + a->offset - BIG;
20574a4d8c2SCharles.Forsyth 			if(instoffset >= -BIG && instoffset < BIG)
20674a4d8c2SCharles.Forsyth 				return C_SEXT;
20774a4d8c2SCharles.Forsyth 			return C_LEXT;
20874a4d8c2SCharles.Forsyth 		case D_AUTO:
20974a4d8c2SCharles.Forsyth 			instoffset = autosize + a->offset;
21074a4d8c2SCharles.Forsyth 			if(instoffset >= -BIG && instoffset < BIG)
21174a4d8c2SCharles.Forsyth 				return C_SAUTO;
21274a4d8c2SCharles.Forsyth 			return C_LAUTO;
21374a4d8c2SCharles.Forsyth 
21474a4d8c2SCharles.Forsyth 		case D_PARAM:
21574a4d8c2SCharles.Forsyth 			instoffset = autosize + a->offset + 4L;
21674a4d8c2SCharles.Forsyth 			if(instoffset >= -BIG && instoffset < BIG)
21774a4d8c2SCharles.Forsyth 				return C_SAUTO;
21874a4d8c2SCharles.Forsyth 			return C_LAUTO;
21974a4d8c2SCharles.Forsyth 		case D_NONE:
22074a4d8c2SCharles.Forsyth 			instoffset = a->offset;
22174a4d8c2SCharles.Forsyth 			if(instoffset == 0)
22274a4d8c2SCharles.Forsyth 				return C_ZOREG;
22374a4d8c2SCharles.Forsyth 			if(instoffset >= -BIG && instoffset < BIG)
22474a4d8c2SCharles.Forsyth 				return C_SOREG;
22574a4d8c2SCharles.Forsyth 			return C_LOREG;
22674a4d8c2SCharles.Forsyth 		}
22774a4d8c2SCharles.Forsyth 		return C_GOK;
22874a4d8c2SCharles.Forsyth 
22974a4d8c2SCharles.Forsyth 	case D_OPT:
23074a4d8c2SCharles.Forsyth 		instoffset = a->offset & 31L;
23174a4d8c2SCharles.Forsyth 		if(a->name == D_NONE)
23274a4d8c2SCharles.Forsyth 			return C_SCON;
23374a4d8c2SCharles.Forsyth 		return C_GOK;
23474a4d8c2SCharles.Forsyth 
23574a4d8c2SCharles.Forsyth 	case D_CONST:
23674a4d8c2SCharles.Forsyth 		switch(a->name) {
23774a4d8c2SCharles.Forsyth 
23874a4d8c2SCharles.Forsyth 		case D_NONE:
23974a4d8c2SCharles.Forsyth 			instoffset = a->offset;
24074a4d8c2SCharles.Forsyth 		consize:
24174a4d8c2SCharles.Forsyth 			if(instoffset >= 0) {
24274a4d8c2SCharles.Forsyth 				if(r0iszero && instoffset == 0)
24374a4d8c2SCharles.Forsyth 					return C_ZCON;
24474a4d8c2SCharles.Forsyth 				if(instoffset <= 0x7fff)
24574a4d8c2SCharles.Forsyth 					return C_SCON;
24674a4d8c2SCharles.Forsyth 				if(instoffset <= 0xffff)
24774a4d8c2SCharles.Forsyth 					return C_ANDCON;
24874a4d8c2SCharles.Forsyth 				if((instoffset & 0xffff) == 0)
24974a4d8c2SCharles.Forsyth 					return C_UCON;
25074a4d8c2SCharles.Forsyth 				return C_LCON;
25174a4d8c2SCharles.Forsyth 			}
25274a4d8c2SCharles.Forsyth 			if(instoffset >= -0x8000)
25374a4d8c2SCharles.Forsyth 				return C_ADDCON;
25474a4d8c2SCharles.Forsyth 			if((instoffset & 0xffff) == 0)
25574a4d8c2SCharles.Forsyth 				return C_UCON;
25674a4d8c2SCharles.Forsyth 			return C_LCON;
25774a4d8c2SCharles.Forsyth 
25874a4d8c2SCharles.Forsyth 		case D_EXTERN:
25974a4d8c2SCharles.Forsyth 		case D_STATIC:
26074a4d8c2SCharles.Forsyth 			s = a->sym;
26174a4d8c2SCharles.Forsyth 			if(s == S)
26274a4d8c2SCharles.Forsyth 				break;
26374a4d8c2SCharles.Forsyth 			t = s->type;
26474a4d8c2SCharles.Forsyth 			if(t == 0 || t == SXREF) {
26574a4d8c2SCharles.Forsyth 				diag("undefined external: %s in %s",
26674a4d8c2SCharles.Forsyth 					s->name, TNAME);
26774a4d8c2SCharles.Forsyth 				s->type = SDATA;
26874a4d8c2SCharles.Forsyth 			}
26974a4d8c2SCharles.Forsyth 			if(s->type == STEXT || s->type == SLEAF || s->type == SUNDEF) {
27074a4d8c2SCharles.Forsyth 				instoffset = s->value + a->offset;
27174a4d8c2SCharles.Forsyth 				return C_LCON;
27274a4d8c2SCharles.Forsyth 			}
27374a4d8c2SCharles.Forsyth 			if(s->type == SCONST) {
27474a4d8c2SCharles.Forsyth 				instoffset = s->value + a->offset;
27574a4d8c2SCharles.Forsyth 				if(dlm)
27674a4d8c2SCharles.Forsyth 					return C_LCON;
27774a4d8c2SCharles.Forsyth 				goto consize;
27874a4d8c2SCharles.Forsyth 			}
27974a4d8c2SCharles.Forsyth 			if(!dlm){
28074a4d8c2SCharles.Forsyth 				instoffset = s->value + a->offset - BIG;
28174a4d8c2SCharles.Forsyth 				if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)
28274a4d8c2SCharles.Forsyth 					return C_SECON;
28374a4d8c2SCharles.Forsyth 			}
28474a4d8c2SCharles.Forsyth 			instoffset = s->value + a->offset + INITDAT;
28574a4d8c2SCharles.Forsyth 			if(dlm)
28674a4d8c2SCharles.Forsyth 				return C_LCON;
28774a4d8c2SCharles.Forsyth 			/* not sure why this barfs */
28874a4d8c2SCharles.Forsyth 			return C_LCON;
289d67b7dadSforsyth 		/*
29074a4d8c2SCharles.Forsyth 			if(instoffset == 0)
29174a4d8c2SCharles.Forsyth 				return C_ZCON;
29274a4d8c2SCharles.Forsyth 			if(instoffset >= -0x8000 && instoffset <= 0xffff)
29374a4d8c2SCharles.Forsyth 				return C_SCON;
29474a4d8c2SCharles.Forsyth 			if((instoffset & 0xffff) == 0)
29574a4d8c2SCharles.Forsyth 				return C_UCON;
29674a4d8c2SCharles.Forsyth 			return C_LCON;
297d67b7dadSforsyth 		*/
29874a4d8c2SCharles.Forsyth 
29974a4d8c2SCharles.Forsyth 		case D_AUTO:
30074a4d8c2SCharles.Forsyth 			instoffset = autosize + a->offset;
30174a4d8c2SCharles.Forsyth 			if(instoffset >= -BIG && instoffset < BIG)
30274a4d8c2SCharles.Forsyth 				return C_SACON;
30374a4d8c2SCharles.Forsyth 			return C_LACON;
30474a4d8c2SCharles.Forsyth 
30574a4d8c2SCharles.Forsyth 		case D_PARAM:
30674a4d8c2SCharles.Forsyth 			instoffset = autosize + a->offset + 4L;
30774a4d8c2SCharles.Forsyth 			if(instoffset >= -BIG && instoffset < BIG)
30874a4d8c2SCharles.Forsyth 				return C_SACON;
30974a4d8c2SCharles.Forsyth 			return C_LACON;
31074a4d8c2SCharles.Forsyth 		}
31174a4d8c2SCharles.Forsyth 		return C_GOK;
31274a4d8c2SCharles.Forsyth 
31374a4d8c2SCharles.Forsyth 	case D_BRANCH:
31474a4d8c2SCharles.Forsyth 		return C_SBRA;
31574a4d8c2SCharles.Forsyth 	}
31674a4d8c2SCharles.Forsyth 	return C_GOK;
31774a4d8c2SCharles.Forsyth }
31874a4d8c2SCharles.Forsyth 
31974a4d8c2SCharles.Forsyth Optab*
oplook(Prog * p)32074a4d8c2SCharles.Forsyth oplook(Prog *p)
32174a4d8c2SCharles.Forsyth {
32274a4d8c2SCharles.Forsyth 	int a1, a2, a3, a4, r;
32374a4d8c2SCharles.Forsyth 	char *c1, *c3, *c4;
32474a4d8c2SCharles.Forsyth 	Optab *o, *e;
32574a4d8c2SCharles.Forsyth 
32674a4d8c2SCharles.Forsyth 	a1 = p->optab;
32774a4d8c2SCharles.Forsyth 	if(a1)
32874a4d8c2SCharles.Forsyth 		return optab+(a1-1);
32974a4d8c2SCharles.Forsyth 	a1 = p->from.class;
33074a4d8c2SCharles.Forsyth 	if(a1 == 0) {
33174a4d8c2SCharles.Forsyth 		a1 = aclass(&p->from) + 1;
33274a4d8c2SCharles.Forsyth 		p->from.class = a1;
33374a4d8c2SCharles.Forsyth 	}
33474a4d8c2SCharles.Forsyth 	a1--;
33574a4d8c2SCharles.Forsyth 	a3 = p->from3.class;
33674a4d8c2SCharles.Forsyth 	if(a3 == 0) {
33774a4d8c2SCharles.Forsyth 		a3 = aclass(&p->from3) + 1;
33874a4d8c2SCharles.Forsyth 		p->from3.class = a3;
33974a4d8c2SCharles.Forsyth 	}
34074a4d8c2SCharles.Forsyth 	a3--;
34174a4d8c2SCharles.Forsyth 	a4 = p->to.class;
34274a4d8c2SCharles.Forsyth 	if(a4 == 0) {
34374a4d8c2SCharles.Forsyth 		a4 = aclass(&p->to) + 1;
34474a4d8c2SCharles.Forsyth 		p->to.class = a4;
34574a4d8c2SCharles.Forsyth 	}
34674a4d8c2SCharles.Forsyth 	a4--;
34774a4d8c2SCharles.Forsyth 	a2 = C_NONE;
34874a4d8c2SCharles.Forsyth 	if(p->reg != NREG)
34974a4d8c2SCharles.Forsyth 		a2 = C_REG;
35074a4d8c2SCharles.Forsyth 	r = p->as;
35174a4d8c2SCharles.Forsyth 	o = oprange[r].start;
35274a4d8c2SCharles.Forsyth 	if(o == 0)
35374a4d8c2SCharles.Forsyth 		o = oprange[r].stop; /* just generate an error */
35474a4d8c2SCharles.Forsyth 	e = oprange[r].stop;
35574a4d8c2SCharles.Forsyth 	c1 = xcmp[a1];
35674a4d8c2SCharles.Forsyth 	c3 = xcmp[a3];
35774a4d8c2SCharles.Forsyth 	c4 = xcmp[a4];
35874a4d8c2SCharles.Forsyth 	for(; o<e; o++)
35974a4d8c2SCharles.Forsyth 		if(o->a2 == a2)
36074a4d8c2SCharles.Forsyth 		if(c1[o->a1])
36174a4d8c2SCharles.Forsyth 		if(c3[o->a3])
36274a4d8c2SCharles.Forsyth 		if(c4[o->a4]) {
36374a4d8c2SCharles.Forsyth 			p->optab = (o-optab)+1;
36474a4d8c2SCharles.Forsyth 			return o;
36574a4d8c2SCharles.Forsyth 		}
36674a4d8c2SCharles.Forsyth 	diag("illegal combination %A %R %R %R %R",
36774a4d8c2SCharles.Forsyth 		p->as, a1, a2, a3, a4);
36874a4d8c2SCharles.Forsyth 	if(1||!debug['a'])
36974a4d8c2SCharles.Forsyth 		prasm(p);
37074a4d8c2SCharles.Forsyth 	if(o == 0)
37174a4d8c2SCharles.Forsyth 		errorexit();
37274a4d8c2SCharles.Forsyth 	return o;
37374a4d8c2SCharles.Forsyth }
37474a4d8c2SCharles.Forsyth 
37574a4d8c2SCharles.Forsyth int
cmp(int a,int b)37674a4d8c2SCharles.Forsyth cmp(int a, int b)
37774a4d8c2SCharles.Forsyth {
37874a4d8c2SCharles.Forsyth 
37974a4d8c2SCharles.Forsyth 	if(a == b)
38074a4d8c2SCharles.Forsyth 		return 1;
38174a4d8c2SCharles.Forsyth 	switch(a) {
38274a4d8c2SCharles.Forsyth 	case C_LCON:
38374a4d8c2SCharles.Forsyth 		if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
38474a4d8c2SCharles.Forsyth 			return 1;
38574a4d8c2SCharles.Forsyth 		break;
38674a4d8c2SCharles.Forsyth 	case C_ADDCON:
38774a4d8c2SCharles.Forsyth 		if(b == C_ZCON || b == C_SCON)
38874a4d8c2SCharles.Forsyth 			return 1;
38974a4d8c2SCharles.Forsyth 		break;
39074a4d8c2SCharles.Forsyth 	case C_ANDCON:
39174a4d8c2SCharles.Forsyth 		if(b == C_ZCON || b == C_SCON)
39274a4d8c2SCharles.Forsyth 			return 1;
39374a4d8c2SCharles.Forsyth 		break;
39474a4d8c2SCharles.Forsyth 	case C_SPR:
39574a4d8c2SCharles.Forsyth 		if(b == C_LR || b == C_XER || b == C_CTR)
39674a4d8c2SCharles.Forsyth 			return 1;
39774a4d8c2SCharles.Forsyth 		break;
39874a4d8c2SCharles.Forsyth 	case C_UCON:
39974a4d8c2SCharles.Forsyth 		if(b == C_ZCON)
40074a4d8c2SCharles.Forsyth 			return 1;
40174a4d8c2SCharles.Forsyth 		break;
40274a4d8c2SCharles.Forsyth 	case C_SCON:
40374a4d8c2SCharles.Forsyth 		if(b == C_ZCON)
40474a4d8c2SCharles.Forsyth 			return 1;
40574a4d8c2SCharles.Forsyth 		break;
40674a4d8c2SCharles.Forsyth 	case C_LACON:
40774a4d8c2SCharles.Forsyth 		if(b == C_SACON)
40874a4d8c2SCharles.Forsyth 			return 1;
40974a4d8c2SCharles.Forsyth 		break;
41074a4d8c2SCharles.Forsyth 	case C_LBRA:
41174a4d8c2SCharles.Forsyth 		if(b == C_SBRA)
41274a4d8c2SCharles.Forsyth 			return 1;
41374a4d8c2SCharles.Forsyth 		break;
41474a4d8c2SCharles.Forsyth 	case C_LEXT:
41574a4d8c2SCharles.Forsyth 		if(b == C_SEXT)
41674a4d8c2SCharles.Forsyth 			return 1;
41774a4d8c2SCharles.Forsyth 		break;
41874a4d8c2SCharles.Forsyth 	case C_LAUTO:
41974a4d8c2SCharles.Forsyth 		if(b == C_SAUTO)
42074a4d8c2SCharles.Forsyth 			return 1;
42174a4d8c2SCharles.Forsyth 		break;
42274a4d8c2SCharles.Forsyth 	case C_REG:
42374a4d8c2SCharles.Forsyth 		if(r0iszero && b == C_ZCON)
42474a4d8c2SCharles.Forsyth 			return 1;
42574a4d8c2SCharles.Forsyth 		break;
42674a4d8c2SCharles.Forsyth 	case C_LOREG:
42774a4d8c2SCharles.Forsyth 		if(b == C_ZOREG || b == C_SOREG)
42874a4d8c2SCharles.Forsyth 			return 1;
42974a4d8c2SCharles.Forsyth 		break;
43074a4d8c2SCharles.Forsyth 	case C_SOREG:
43174a4d8c2SCharles.Forsyth 		if(b == C_ZOREG)
43274a4d8c2SCharles.Forsyth 			return 1;
43374a4d8c2SCharles.Forsyth 		break;
43474a4d8c2SCharles.Forsyth 
43574a4d8c2SCharles.Forsyth 	case C_ANY:
43674a4d8c2SCharles.Forsyth 		return 1;
43774a4d8c2SCharles.Forsyth 	}
43874a4d8c2SCharles.Forsyth 	return 0;
43974a4d8c2SCharles.Forsyth }
44074a4d8c2SCharles.Forsyth 
44174a4d8c2SCharles.Forsyth int
ocmp(void * a1,void * a2)44274a4d8c2SCharles.Forsyth ocmp(void *a1, void *a2)
44374a4d8c2SCharles.Forsyth {
44474a4d8c2SCharles.Forsyth 	Optab *p1, *p2;
44574a4d8c2SCharles.Forsyth 	int n;
44674a4d8c2SCharles.Forsyth 
44774a4d8c2SCharles.Forsyth 	p1 = a1;
44874a4d8c2SCharles.Forsyth 	p2 = a2;
44974a4d8c2SCharles.Forsyth 	n = p1->as - p2->as;
45074a4d8c2SCharles.Forsyth 	if(n)
45174a4d8c2SCharles.Forsyth 		return n;
45274a4d8c2SCharles.Forsyth 	n = p1->a1 - p2->a1;
45374a4d8c2SCharles.Forsyth 	if(n)
45474a4d8c2SCharles.Forsyth 		return n;
45574a4d8c2SCharles.Forsyth 	n = p1->a2 - p2->a2;
45674a4d8c2SCharles.Forsyth 	if(n)
45774a4d8c2SCharles.Forsyth 		return n;
45874a4d8c2SCharles.Forsyth 	n = p1->a3 - p2->a3;
45974a4d8c2SCharles.Forsyth 	if(n)
46074a4d8c2SCharles.Forsyth 		return n;
46174a4d8c2SCharles.Forsyth 	n = p1->a4 - p2->a4;
46274a4d8c2SCharles.Forsyth 	if(n)
46374a4d8c2SCharles.Forsyth 		return n;
46474a4d8c2SCharles.Forsyth 	return 0;
46574a4d8c2SCharles.Forsyth }
46674a4d8c2SCharles.Forsyth 
46774a4d8c2SCharles.Forsyth void
buildop(void)46874a4d8c2SCharles.Forsyth buildop(void)
46974a4d8c2SCharles.Forsyth {
47074a4d8c2SCharles.Forsyth 	int i, n, r;
47174a4d8c2SCharles.Forsyth 
47274a4d8c2SCharles.Forsyth 	for(i=0; i<C_NCLASS; i++)
47374a4d8c2SCharles.Forsyth 		for(n=0; n<C_NCLASS; n++)
47474a4d8c2SCharles.Forsyth 			xcmp[i][n] = cmp(n, i);
47574a4d8c2SCharles.Forsyth 	for(n=0; optab[n].as != AXXX; n++)
47674a4d8c2SCharles.Forsyth 		;
47774a4d8c2SCharles.Forsyth 	qsort(optab, n, sizeof(optab[0]), ocmp);
47874a4d8c2SCharles.Forsyth 	for(i=0; i<n; i++) {
47974a4d8c2SCharles.Forsyth 		r = optab[i].as;
48074a4d8c2SCharles.Forsyth 		oprange[r].start = optab+i;
48174a4d8c2SCharles.Forsyth 		while(optab[i].as == r)
48274a4d8c2SCharles.Forsyth 			i++;
48374a4d8c2SCharles.Forsyth 		oprange[r].stop = optab+i;
48474a4d8c2SCharles.Forsyth 		i--;
48574a4d8c2SCharles.Forsyth 
48674a4d8c2SCharles.Forsyth 		switch(r)
48774a4d8c2SCharles.Forsyth 		{
48874a4d8c2SCharles.Forsyth 		default:
48974a4d8c2SCharles.Forsyth 			diag("unknown op in build: %A", r);
49074a4d8c2SCharles.Forsyth 			errorexit();
49174a4d8c2SCharles.Forsyth 		case ADCBF:	/* unary indexed: op (b+a); op (b) */
49274a4d8c2SCharles.Forsyth 			oprange[ADCBI] = oprange[r];
49374a4d8c2SCharles.Forsyth 			oprange[ADCBST] = oprange[r];
49474a4d8c2SCharles.Forsyth 			oprange[ADCBT] = oprange[r];
49574a4d8c2SCharles.Forsyth 			oprange[ADCBTST] = oprange[r];
49674a4d8c2SCharles.Forsyth 			oprange[ADCBZ] = oprange[r];
49774a4d8c2SCharles.Forsyth 			oprange[AICBI] = oprange[r];
49874a4d8c2SCharles.Forsyth 			break;
49974a4d8c2SCharles.Forsyth 		case AECOWX:	/* indexed store: op s,(b+a); op s,(b) */
50074a4d8c2SCharles.Forsyth 			oprange[ASTWCCC] = oprange[r];
50174a4d8c2SCharles.Forsyth 			break;
50274a4d8c2SCharles.Forsyth 		case AREM:	/* macro */
50374a4d8c2SCharles.Forsyth 			oprange[AREMCC] = oprange[r];
50474a4d8c2SCharles.Forsyth 			oprange[AREMV] = oprange[r];
50574a4d8c2SCharles.Forsyth 			oprange[AREMVCC] = oprange[r];
50674a4d8c2SCharles.Forsyth 			oprange[AREMU] = oprange[r];
50774a4d8c2SCharles.Forsyth 			oprange[AREMUCC] = oprange[r];
50874a4d8c2SCharles.Forsyth 			oprange[AREMUV] = oprange[r];
50974a4d8c2SCharles.Forsyth 			oprange[AREMUVCC] = oprange[r];
51074a4d8c2SCharles.Forsyth 			break;
51174a4d8c2SCharles.Forsyth 		case ADIVW:	/* op Rb[,Ra],Rd */
51274a4d8c2SCharles.Forsyth 			oprange[AMULHW] = oprange[r];
51374a4d8c2SCharles.Forsyth 			oprange[AMULHWCC] = oprange[r];
51474a4d8c2SCharles.Forsyth 			oprange[AMULHWU] = oprange[r];
51574a4d8c2SCharles.Forsyth 			oprange[AMULHWUCC] = oprange[r];
51674a4d8c2SCharles.Forsyth 			oprange[AMULLWCC] = oprange[r];
51774a4d8c2SCharles.Forsyth 			oprange[AMULLWVCC] = oprange[r];
51874a4d8c2SCharles.Forsyth 			oprange[AMULLWV] = oprange[r];
51974a4d8c2SCharles.Forsyth 			oprange[ADIVWCC] = oprange[r];
52074a4d8c2SCharles.Forsyth 			oprange[ADIVWV] = oprange[r];
52174a4d8c2SCharles.Forsyth 			oprange[ADIVWVCC] = oprange[r];
52274a4d8c2SCharles.Forsyth 			oprange[ADIVWU] = oprange[r];
52374a4d8c2SCharles.Forsyth 			oprange[ADIVWUCC] = oprange[r];
52474a4d8c2SCharles.Forsyth 			oprange[ADIVWUV] = oprange[r];
52574a4d8c2SCharles.Forsyth 			oprange[ADIVWUVCC] = oprange[r];
52674a4d8c2SCharles.Forsyth 			oprange[AADDCC] = oprange[r];
52774a4d8c2SCharles.Forsyth 			oprange[AADDCV] = oprange[r];
52874a4d8c2SCharles.Forsyth 			oprange[AADDCVCC] = oprange[r];
52974a4d8c2SCharles.Forsyth 			oprange[AADDV] = oprange[r];
53074a4d8c2SCharles.Forsyth 			oprange[AADDVCC] = oprange[r];
53174a4d8c2SCharles.Forsyth 			oprange[AADDE] = oprange[r];
53274a4d8c2SCharles.Forsyth 			oprange[AADDECC] = oprange[r];
53374a4d8c2SCharles.Forsyth 			oprange[AADDEV] = oprange[r];
53474a4d8c2SCharles.Forsyth 			oprange[AADDEVCC] = oprange[r];
53574a4d8c2SCharles.Forsyth 			oprange[ACRAND] = oprange[r];
53674a4d8c2SCharles.Forsyth 			oprange[ACRANDN] = oprange[r];
53774a4d8c2SCharles.Forsyth 			oprange[ACREQV] = oprange[r];
53874a4d8c2SCharles.Forsyth 			oprange[ACRNAND] = oprange[r];
53974a4d8c2SCharles.Forsyth 			oprange[ACRNOR] = oprange[r];
54074a4d8c2SCharles.Forsyth 			oprange[ACROR] = oprange[r];
54174a4d8c2SCharles.Forsyth 			oprange[ACRORN] = oprange[r];
54274a4d8c2SCharles.Forsyth 			oprange[ACRXOR] = oprange[r];
54374a4d8c2SCharles.Forsyth 			oprange[AMULCHW] = oprange[r];
54474a4d8c2SCharles.Forsyth 			oprange[AMULCHWCC] = oprange[r];
54574a4d8c2SCharles.Forsyth 			oprange[AMULCHWU] = oprange[r];
54674a4d8c2SCharles.Forsyth 			oprange[AMULCHWUCC] = oprange[r];
54774a4d8c2SCharles.Forsyth 			oprange[AMULHHW] = oprange[r];
54874a4d8c2SCharles.Forsyth 			oprange[AMULHHWCC] = oprange[r];
54974a4d8c2SCharles.Forsyth 			oprange[AMULHHWU] = oprange[r];
55074a4d8c2SCharles.Forsyth 			oprange[AMULHHWUCC] = oprange[r];
55174a4d8c2SCharles.Forsyth 			oprange[AMULLHW] = oprange[r];
55274a4d8c2SCharles.Forsyth 			oprange[AMULLHWCC] = oprange[r];
55374a4d8c2SCharles.Forsyth 			oprange[AMULLHWU] = oprange[r];
55474a4d8c2SCharles.Forsyth 			oprange[AMULLHWUCC] = oprange[r];
55574a4d8c2SCharles.Forsyth 			break;
55674a4d8c2SCharles.Forsyth 		case AMACCHW:	/* strictly 3 registers */
55774a4d8c2SCharles.Forsyth 			oprange[AMACCHWCC] = oprange[r];
55874a4d8c2SCharles.Forsyth 			oprange[AMACCHWS] = oprange[r];
55974a4d8c2SCharles.Forsyth 			oprange[AMACCHWSCC] = oprange[r];
56074a4d8c2SCharles.Forsyth 			oprange[AMACCHWSU] = oprange[r];
56174a4d8c2SCharles.Forsyth 			oprange[AMACCHWSUCC] = oprange[r];
56274a4d8c2SCharles.Forsyth 			oprange[AMACCHWSUV] = oprange[r];
56374a4d8c2SCharles.Forsyth 			oprange[AMACCHWSUVCC] = oprange[r];
56474a4d8c2SCharles.Forsyth 			oprange[AMACCHWSV] = oprange[r];
56574a4d8c2SCharles.Forsyth 			oprange[AMACCHWSVCC] = oprange[r];
56674a4d8c2SCharles.Forsyth 			oprange[AMACCHWU] = oprange[r];
56774a4d8c2SCharles.Forsyth 			oprange[AMACCHWUCC] = oprange[r];
56874a4d8c2SCharles.Forsyth 			oprange[AMACCHWUV] = oprange[r];
56974a4d8c2SCharles.Forsyth 			oprange[AMACCHWUVCC] = oprange[r];
57074a4d8c2SCharles.Forsyth 			oprange[AMACCHWV] = oprange[r];
57174a4d8c2SCharles.Forsyth 			oprange[AMACCHWVCC] = oprange[r];
57274a4d8c2SCharles.Forsyth 			oprange[AMACHHW] = oprange[r];
57374a4d8c2SCharles.Forsyth 			oprange[AMACHHWCC] = oprange[r];
57474a4d8c2SCharles.Forsyth 			oprange[AMACHHWS] = oprange[r];
57574a4d8c2SCharles.Forsyth 			oprange[AMACHHWSCC] = oprange[r];
57674a4d8c2SCharles.Forsyth 			oprange[AMACHHWSU] = oprange[r];
57774a4d8c2SCharles.Forsyth 			oprange[AMACHHWSUCC] = oprange[r];
57874a4d8c2SCharles.Forsyth 			oprange[AMACHHWSUV] = oprange[r];
57974a4d8c2SCharles.Forsyth 			oprange[AMACHHWSUVCC] = oprange[r];
58074a4d8c2SCharles.Forsyth 			oprange[AMACHHWSV] = oprange[r];
58174a4d8c2SCharles.Forsyth 			oprange[AMACHHWSVCC] = oprange[r];
58274a4d8c2SCharles.Forsyth 			oprange[AMACHHWU] = oprange[r];
58374a4d8c2SCharles.Forsyth 			oprange[AMACHHWUCC] = oprange[r];
58474a4d8c2SCharles.Forsyth 			oprange[AMACHHWUV] = oprange[r];
58574a4d8c2SCharles.Forsyth 			oprange[AMACHHWUVCC] = oprange[r];
58674a4d8c2SCharles.Forsyth 			oprange[AMACHHWV] = oprange[r];
58774a4d8c2SCharles.Forsyth 			oprange[AMACHHWVCC] = oprange[r];
58874a4d8c2SCharles.Forsyth 			oprange[AMACLHW] = oprange[r];
58974a4d8c2SCharles.Forsyth 			oprange[AMACLHWCC] = oprange[r];
59074a4d8c2SCharles.Forsyth 			oprange[AMACLHWS] = oprange[r];
59174a4d8c2SCharles.Forsyth 			oprange[AMACLHWSCC] = oprange[r];
59274a4d8c2SCharles.Forsyth 			oprange[AMACLHWSU] = oprange[r];
59374a4d8c2SCharles.Forsyth 			oprange[AMACLHWSUCC] = oprange[r];
59474a4d8c2SCharles.Forsyth 			oprange[AMACLHWSUV] = oprange[r];
59574a4d8c2SCharles.Forsyth 			oprange[AMACLHWSUVCC] = oprange[r];
59674a4d8c2SCharles.Forsyth 			oprange[AMACLHWSV] = oprange[r];
59774a4d8c2SCharles.Forsyth 			oprange[AMACLHWSVCC] = oprange[r];
59874a4d8c2SCharles.Forsyth 			oprange[AMACLHWU] = oprange[r];
59974a4d8c2SCharles.Forsyth 			oprange[AMACLHWUCC] = oprange[r];
60074a4d8c2SCharles.Forsyth 			oprange[AMACLHWUV] = oprange[r];
60174a4d8c2SCharles.Forsyth 			oprange[AMACLHWUVCC] = oprange[r];
60274a4d8c2SCharles.Forsyth 			oprange[AMACLHWV] = oprange[r];
60374a4d8c2SCharles.Forsyth 			oprange[AMACLHWVCC] = oprange[r];
60474a4d8c2SCharles.Forsyth 			oprange[ANMACCHW] = oprange[r];
60574a4d8c2SCharles.Forsyth 			oprange[ANMACCHWCC] = oprange[r];
60674a4d8c2SCharles.Forsyth 			oprange[ANMACCHWS] = oprange[r];
60774a4d8c2SCharles.Forsyth 			oprange[ANMACCHWSCC] = oprange[r];
60874a4d8c2SCharles.Forsyth 			oprange[ANMACCHWSV] = oprange[r];
60974a4d8c2SCharles.Forsyth 			oprange[ANMACCHWSVCC] = oprange[r];
61074a4d8c2SCharles.Forsyth 			oprange[ANMACCHWV] = oprange[r];
61174a4d8c2SCharles.Forsyth 			oprange[ANMACCHWVCC] = oprange[r];
61274a4d8c2SCharles.Forsyth 			oprange[ANMACHHW] = oprange[r];
61374a4d8c2SCharles.Forsyth 			oprange[ANMACHHWCC] = oprange[r];
61474a4d8c2SCharles.Forsyth 			oprange[ANMACHHWS] = oprange[r];
61574a4d8c2SCharles.Forsyth 			oprange[ANMACHHWSCC] = oprange[r];
61674a4d8c2SCharles.Forsyth 			oprange[ANMACHHWSV] = oprange[r];
61774a4d8c2SCharles.Forsyth 			oprange[ANMACHHWSVCC] = oprange[r];
61874a4d8c2SCharles.Forsyth 			oprange[ANMACHHWV] = oprange[r];
61974a4d8c2SCharles.Forsyth 			oprange[ANMACHHWVCC] = oprange[r];
62074a4d8c2SCharles.Forsyth 			oprange[ANMACLHW] = oprange[r];
62174a4d8c2SCharles.Forsyth 			oprange[ANMACLHWCC] = oprange[r];
62274a4d8c2SCharles.Forsyth 			oprange[ANMACLHWS] = oprange[r];
62374a4d8c2SCharles.Forsyth 			oprange[ANMACLHWSCC] = oprange[r];
62474a4d8c2SCharles.Forsyth 			oprange[ANMACLHWSV] = oprange[r];
62574a4d8c2SCharles.Forsyth 			oprange[ANMACLHWSVCC] = oprange[r];
62674a4d8c2SCharles.Forsyth 			oprange[ANMACLHWV] = oprange[r];
62774a4d8c2SCharles.Forsyth 			oprange[ANMACLHWVCC] = oprange[r];
62874a4d8c2SCharles.Forsyth 			break;
62974a4d8c2SCharles.Forsyth 		case AMOVBZ:	/* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
63074a4d8c2SCharles.Forsyth 			oprange[AMOVH] = oprange[r];
63174a4d8c2SCharles.Forsyth 			oprange[AMOVHZ] = oprange[r];
63274a4d8c2SCharles.Forsyth 			break;
63374a4d8c2SCharles.Forsyth 		case AMOVBZU:	/* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x */
63474a4d8c2SCharles.Forsyth 			oprange[AMOVHU] = oprange[r];
63574a4d8c2SCharles.Forsyth 			oprange[AMOVHZU] = oprange[r];
63674a4d8c2SCharles.Forsyth 			oprange[AMOVWU] = oprange[r];
63774a4d8c2SCharles.Forsyth 			oprange[AMOVMW] = oprange[r];
63874a4d8c2SCharles.Forsyth 			break;
63974a4d8c2SCharles.Forsyth 		case AAND:	/* logical op Rb,Rs,Ra; no literal */
64074a4d8c2SCharles.Forsyth 			oprange[AANDN] = oprange[r];
64174a4d8c2SCharles.Forsyth 			oprange[AANDNCC] = oprange[r];
64274a4d8c2SCharles.Forsyth 			oprange[AEQV] = oprange[r];
64374a4d8c2SCharles.Forsyth 			oprange[AEQVCC] = oprange[r];
64474a4d8c2SCharles.Forsyth 			oprange[ANAND] = oprange[r];
64574a4d8c2SCharles.Forsyth 			oprange[ANANDCC] = oprange[r];
64674a4d8c2SCharles.Forsyth 			oprange[ANOR] = oprange[r];
64774a4d8c2SCharles.Forsyth 			oprange[ANORCC] = oprange[r];
64874a4d8c2SCharles.Forsyth 			oprange[AORCC] = oprange[r];
64974a4d8c2SCharles.Forsyth 			oprange[AORN] = oprange[r];
65074a4d8c2SCharles.Forsyth 			oprange[AORNCC] = oprange[r];
65174a4d8c2SCharles.Forsyth 			oprange[AXORCC] = oprange[r];
65274a4d8c2SCharles.Forsyth 			break;
65374a4d8c2SCharles.Forsyth 		case AADDME:	/* op Ra, Rd */
65474a4d8c2SCharles.Forsyth 			oprange[AADDMECC] = oprange[r];
65574a4d8c2SCharles.Forsyth 			oprange[AADDMEV] = oprange[r];
65674a4d8c2SCharles.Forsyth 			oprange[AADDMEVCC] = oprange[r];
65774a4d8c2SCharles.Forsyth 			oprange[AADDZE] = oprange[r];
65874a4d8c2SCharles.Forsyth 			oprange[AADDZECC] = oprange[r];
65974a4d8c2SCharles.Forsyth 			oprange[AADDZEV] = oprange[r];
66074a4d8c2SCharles.Forsyth 			oprange[AADDZEVCC] = oprange[r];
66174a4d8c2SCharles.Forsyth 			oprange[ASUBME] = oprange[r];
66274a4d8c2SCharles.Forsyth 			oprange[ASUBMECC] = oprange[r];
66374a4d8c2SCharles.Forsyth 			oprange[ASUBMEV] = oprange[r];
66474a4d8c2SCharles.Forsyth 			oprange[ASUBMEVCC] = oprange[r];
66574a4d8c2SCharles.Forsyth 			oprange[ASUBZE] = oprange[r];
66674a4d8c2SCharles.Forsyth 			oprange[ASUBZECC] = oprange[r];
66774a4d8c2SCharles.Forsyth 			oprange[ASUBZEV] = oprange[r];
66874a4d8c2SCharles.Forsyth 			oprange[ASUBZEVCC] = oprange[r];
66974a4d8c2SCharles.Forsyth 			break;
67074a4d8c2SCharles.Forsyth 		case AADDC:
67174a4d8c2SCharles.Forsyth 			oprange[AADDCCC] = oprange[r];
67274a4d8c2SCharles.Forsyth 			break;
67374a4d8c2SCharles.Forsyth 		case ABEQ:
67474a4d8c2SCharles.Forsyth 			oprange[ABGE] = oprange[r];
67574a4d8c2SCharles.Forsyth 			oprange[ABGT] = oprange[r];
67674a4d8c2SCharles.Forsyth 			oprange[ABLE] = oprange[r];
67774a4d8c2SCharles.Forsyth 			oprange[ABLT] = oprange[r];
67874a4d8c2SCharles.Forsyth 			oprange[ABNE] = oprange[r];
67974a4d8c2SCharles.Forsyth 			oprange[ABVC] = oprange[r];
68074a4d8c2SCharles.Forsyth 			oprange[ABVS] = oprange[r];
68174a4d8c2SCharles.Forsyth 			break;
68274a4d8c2SCharles.Forsyth 		case ABR:
68374a4d8c2SCharles.Forsyth 			oprange[ABL] = oprange[r];
68474a4d8c2SCharles.Forsyth 			break;
68574a4d8c2SCharles.Forsyth 		case ABC:
68674a4d8c2SCharles.Forsyth 			oprange[ABCL] = oprange[r];
68774a4d8c2SCharles.Forsyth 			break;
68874a4d8c2SCharles.Forsyth 		case AEXTSB:	/* op Rs, Ra */
68974a4d8c2SCharles.Forsyth 			oprange[AEXTSBCC] = oprange[r];
69074a4d8c2SCharles.Forsyth 			oprange[AEXTSH] = oprange[r];
69174a4d8c2SCharles.Forsyth 			oprange[AEXTSHCC] = oprange[r];
69274a4d8c2SCharles.Forsyth 			oprange[ACNTLZW] = oprange[r];
69374a4d8c2SCharles.Forsyth 			oprange[ACNTLZWCC] = oprange[r];
69474a4d8c2SCharles.Forsyth 			break;
69574a4d8c2SCharles.Forsyth 		case AFABS:	/* fop [s,]d */
69674a4d8c2SCharles.Forsyth 			oprange[AFABSCC] = oprange[r];
69774a4d8c2SCharles.Forsyth 			oprange[AFNABS] = oprange[r];
69874a4d8c2SCharles.Forsyth 			oprange[AFNABSCC] = oprange[r];
69974a4d8c2SCharles.Forsyth 			oprange[AFNEG] = oprange[r];
70074a4d8c2SCharles.Forsyth 			oprange[AFNEGCC] = oprange[r];
70174a4d8c2SCharles.Forsyth 			oprange[AFRSP] = oprange[r];
70274a4d8c2SCharles.Forsyth 			oprange[AFRSPCC] = oprange[r];
70374a4d8c2SCharles.Forsyth 			oprange[AFCTIW] = oprange[r];
70474a4d8c2SCharles.Forsyth 			oprange[AFCTIWCC] = oprange[r];
70574a4d8c2SCharles.Forsyth 			oprange[AFCTIWZ] = oprange[r];
70674a4d8c2SCharles.Forsyth 			oprange[AFCTIWZCC] = oprange[r];
707d67b7dadSforsyth 			oprange[AFRES] = oprange[r];
708d67b7dadSforsyth 			oprange[AFRESCC] = oprange[r];
709d67b7dadSforsyth 			oprange[AFRSQRTE] = oprange[r];
710d67b7dadSforsyth 			oprange[AFRSQRTECC] = oprange[r];
711d67b7dadSforsyth 			oprange[AFSQRT] = oprange[r];
712d67b7dadSforsyth 			oprange[AFSQRTCC] = oprange[r];
713d67b7dadSforsyth 			oprange[AFSQRTS] = oprange[r];
714d67b7dadSforsyth 			oprange[AFSQRTSCC] = oprange[r];
715d67b7dadSforsyth 			oprange[AFPRE] = oprange[r];
716d67b7dadSforsyth 			oprange[AFPRSQRTE] = oprange[r];
717d67b7dadSforsyth 			oprange[AFPABS] = oprange[r];
718d67b7dadSforsyth 			oprange[AFPNEG] = oprange[r];
719d67b7dadSforsyth 			oprange[AFPRSP] = oprange[r];
720d67b7dadSforsyth 			oprange[AFPNABS] = oprange[r];
721d67b7dadSforsyth 			oprange[AFSABS] = oprange[r];
722d67b7dadSforsyth 			oprange[AFSNEG] = oprange[r];
723d67b7dadSforsyth 			oprange[AFSNABS] = oprange[r];
724d67b7dadSforsyth 			oprange[AFPCTIW] = oprange[r];
725d67b7dadSforsyth 			oprange[AFPCTIWZ] = oprange[r];
72674a4d8c2SCharles.Forsyth 			break;
72774a4d8c2SCharles.Forsyth 		case AFADD:
72874a4d8c2SCharles.Forsyth 			oprange[AFADDS] = oprange[r];
72974a4d8c2SCharles.Forsyth 			oprange[AFADDCC] = oprange[r];
73074a4d8c2SCharles.Forsyth 			oprange[AFADDSCC] = oprange[r];
73174a4d8c2SCharles.Forsyth 			oprange[AFDIV] = oprange[r];
73274a4d8c2SCharles.Forsyth 			oprange[AFDIVS] = oprange[r];
73374a4d8c2SCharles.Forsyth 			oprange[AFDIVCC] = oprange[r];
73474a4d8c2SCharles.Forsyth 			oprange[AFDIVSCC] = oprange[r];
73574a4d8c2SCharles.Forsyth 			oprange[AFSUB] = oprange[r];
73674a4d8c2SCharles.Forsyth 			oprange[AFSUBS] = oprange[r];
73774a4d8c2SCharles.Forsyth 			oprange[AFSUBCC] = oprange[r];
73874a4d8c2SCharles.Forsyth 			oprange[AFSUBSCC] = oprange[r];
739d67b7dadSforsyth 			oprange[AFPADD] = oprange[r];
740d67b7dadSforsyth 			oprange[AFPSUB] = oprange[r];
74174a4d8c2SCharles.Forsyth 			break;
74274a4d8c2SCharles.Forsyth 		case AFMADD:
74374a4d8c2SCharles.Forsyth 			oprange[AFMADDCC] = oprange[r];
74474a4d8c2SCharles.Forsyth 			oprange[AFMADDS] = oprange[r];
74574a4d8c2SCharles.Forsyth 			oprange[AFMADDSCC] = oprange[r];
74674a4d8c2SCharles.Forsyth 			oprange[AFMSUB] = oprange[r];
74774a4d8c2SCharles.Forsyth 			oprange[AFMSUBCC] = oprange[r];
74874a4d8c2SCharles.Forsyth 			oprange[AFMSUBS] = oprange[r];
74974a4d8c2SCharles.Forsyth 			oprange[AFMSUBSCC] = oprange[r];
75074a4d8c2SCharles.Forsyth 			oprange[AFNMADD] = oprange[r];
75174a4d8c2SCharles.Forsyth 			oprange[AFNMADDCC] = oprange[r];
75274a4d8c2SCharles.Forsyth 			oprange[AFNMADDS] = oprange[r];
75374a4d8c2SCharles.Forsyth 			oprange[AFNMADDSCC] = oprange[r];
75474a4d8c2SCharles.Forsyth 			oprange[AFNMSUB] = oprange[r];
75574a4d8c2SCharles.Forsyth 			oprange[AFNMSUBCC] = oprange[r];
75674a4d8c2SCharles.Forsyth 			oprange[AFNMSUBS] = oprange[r];
75774a4d8c2SCharles.Forsyth 			oprange[AFNMSUBSCC] = oprange[r];
758d67b7dadSforsyth 			oprange[AFSEL] = oprange[r];
759d67b7dadSforsyth 			oprange[AFSELCC] = oprange[r];
760d67b7dadSforsyth 			oprange[AFPSEL] = oprange[r];
761d67b7dadSforsyth 			oprange[AFPMADD] = oprange[r];
762d67b7dadSforsyth 			oprange[AFXMADD] = oprange[r];
763d67b7dadSforsyth 			oprange[AFXCPMADD] = oprange[r];
764d67b7dadSforsyth 			oprange[AFXCSMADD] = oprange[r];
765d67b7dadSforsyth 			oprange[AFPNMADD] = oprange[r];
766d67b7dadSforsyth 			oprange[AFXNMADD] = oprange[r];
767d67b7dadSforsyth 			oprange[AFXCPNMADD] = oprange[r];
768d67b7dadSforsyth 			oprange[AFXCSNMADD] = oprange[r];
769d67b7dadSforsyth 			oprange[AFPMSUB] = oprange[r];
770d67b7dadSforsyth 			oprange[AFXMSUB] = oprange[r];
771d67b7dadSforsyth 			oprange[AFXCPMSUB] = oprange[r];
772d67b7dadSforsyth 			oprange[AFXCSMSUB] = oprange[r];
773d67b7dadSforsyth 			oprange[AFPNMSUB] = oprange[r];
774d67b7dadSforsyth 			oprange[AFXNMSUB] = oprange[r];
775d67b7dadSforsyth 			oprange[AFXCPNMSUB] = oprange[r];
776d67b7dadSforsyth 			oprange[AFXCSNMSUB] = oprange[r];
777d67b7dadSforsyth 			oprange[AFXCPNPMA] = oprange[r];
778d67b7dadSforsyth 			oprange[AFXCSNPMA] = oprange[r];
779d67b7dadSforsyth 			oprange[AFXCPNSMA] = oprange[r];
780d67b7dadSforsyth 			oprange[AFXCSNSMA] = oprange[r];
781d67b7dadSforsyth 			oprange[AFXCXNPMA] = oprange[r];
782d67b7dadSforsyth 			oprange[AFXCXNSMA] = oprange[r];
783d67b7dadSforsyth 			oprange[AFXCXMA] = oprange[r];
784d67b7dadSforsyth 			oprange[AFXCXNMS] = oprange[r];
78574a4d8c2SCharles.Forsyth 			break;
78674a4d8c2SCharles.Forsyth 		case AFMUL:
78774a4d8c2SCharles.Forsyth 			oprange[AFMULS] = oprange[r];
78874a4d8c2SCharles.Forsyth 			oprange[AFMULCC] = oprange[r];
78974a4d8c2SCharles.Forsyth 			oprange[AFMULSCC] = oprange[r];
790d67b7dadSforsyth 			oprange[AFPMUL] = oprange[r];
791d67b7dadSforsyth 			oprange[AFXMUL] = oprange[r];
792d67b7dadSforsyth 			oprange[AFXPMUL] = oprange[r];
793d67b7dadSforsyth 			oprange[AFXSMUL] = oprange[r];
79474a4d8c2SCharles.Forsyth 			break;
79574a4d8c2SCharles.Forsyth 		case AFCMPO:
79674a4d8c2SCharles.Forsyth 			oprange[AFCMPU] = oprange[r];
79774a4d8c2SCharles.Forsyth 			break;
79874a4d8c2SCharles.Forsyth 		case AMTFSB0:
79974a4d8c2SCharles.Forsyth 			oprange[AMTFSB0CC] = oprange[r];
80074a4d8c2SCharles.Forsyth 			oprange[AMTFSB1] = oprange[r];
80174a4d8c2SCharles.Forsyth 			oprange[AMTFSB1CC] = oprange[r];
80274a4d8c2SCharles.Forsyth 			break;
80374a4d8c2SCharles.Forsyth 		case ANEG:	/* op [Ra,] Rd */
80474a4d8c2SCharles.Forsyth 			oprange[ANEGCC] = oprange[r];
80574a4d8c2SCharles.Forsyth 			oprange[ANEGV] = oprange[r];
80674a4d8c2SCharles.Forsyth 			oprange[ANEGVCC] = oprange[r];
80774a4d8c2SCharles.Forsyth 			break;
80874a4d8c2SCharles.Forsyth 		case AOR:	/* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
80974a4d8c2SCharles.Forsyth 			oprange[AXOR] = oprange[r];
81074a4d8c2SCharles.Forsyth 			break;
81174a4d8c2SCharles.Forsyth 		case ASLW:
81274a4d8c2SCharles.Forsyth 			oprange[ASLWCC] = oprange[r];
81374a4d8c2SCharles.Forsyth 			oprange[ASRW] = oprange[r];
81474a4d8c2SCharles.Forsyth 			oprange[ASRWCC] = oprange[r];
81574a4d8c2SCharles.Forsyth 			break;
81674a4d8c2SCharles.Forsyth 		case ASRAW:	/* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
81774a4d8c2SCharles.Forsyth 			oprange[ASRAWCC] = oprange[r];
81874a4d8c2SCharles.Forsyth 			break;
81974a4d8c2SCharles.Forsyth 		case ASUB:	/* SUB Ra,Rb,Rd => subf Rd,ra,rb */
82074a4d8c2SCharles.Forsyth 			oprange[ASUB] = oprange[r];
82174a4d8c2SCharles.Forsyth 			oprange[ASUBCC] = oprange[r];
82274a4d8c2SCharles.Forsyth 			oprange[ASUBV] = oprange[r];
82374a4d8c2SCharles.Forsyth 			oprange[ASUBVCC] = oprange[r];
82474a4d8c2SCharles.Forsyth 			oprange[ASUBCCC] = oprange[r];
82574a4d8c2SCharles.Forsyth 			oprange[ASUBCV] = oprange[r];
82674a4d8c2SCharles.Forsyth 			oprange[ASUBCVCC] = oprange[r];
82774a4d8c2SCharles.Forsyth 			oprange[ASUBE] = oprange[r];
82874a4d8c2SCharles.Forsyth 			oprange[ASUBECC] = oprange[r];
82974a4d8c2SCharles.Forsyth 			oprange[ASUBEV] = oprange[r];
83074a4d8c2SCharles.Forsyth 			oprange[ASUBEVCC] = oprange[r];
83174a4d8c2SCharles.Forsyth 			break;
83274a4d8c2SCharles.Forsyth 		case ASYNC:
83374a4d8c2SCharles.Forsyth 			oprange[AISYNC] = oprange[r];
83474a4d8c2SCharles.Forsyth 			break;
83574a4d8c2SCharles.Forsyth 		case ARLWMI:
83674a4d8c2SCharles.Forsyth 			oprange[ARLWMICC] = oprange[r];
83774a4d8c2SCharles.Forsyth 			oprange[ARLWNM] = oprange[r];
83874a4d8c2SCharles.Forsyth 			oprange[ARLWNMCC] = oprange[r];
83974a4d8c2SCharles.Forsyth 			break;
84074a4d8c2SCharles.Forsyth 		case AFMOVD:
84174a4d8c2SCharles.Forsyth 			oprange[AFMOVDCC] = oprange[r];
84274a4d8c2SCharles.Forsyth 			oprange[AFMOVDU] = oprange[r];
84374a4d8c2SCharles.Forsyth 			oprange[AFMOVS] = oprange[r];
84474a4d8c2SCharles.Forsyth 			oprange[AFMOVSU] = oprange[r];
84574a4d8c2SCharles.Forsyth 			break;
84674a4d8c2SCharles.Forsyth 		case AECIWX:
84774a4d8c2SCharles.Forsyth 			oprange[ALWAR] = oprange[r];
84874a4d8c2SCharles.Forsyth 			break;
84974a4d8c2SCharles.Forsyth 		case ASYSCALL:	/* just the op; flow of control */
85074a4d8c2SCharles.Forsyth 			oprange[ARFI] = oprange[r];
85174a4d8c2SCharles.Forsyth 			oprange[ARFCI] = oprange[r];
85274a4d8c2SCharles.Forsyth 			break;
85374a4d8c2SCharles.Forsyth 		case AMOVHBR:
85474a4d8c2SCharles.Forsyth 			oprange[AMOVWBR] = oprange[r];
85574a4d8c2SCharles.Forsyth 			break;
856*647adfbcSforsyth 		case AFSMOVS:	/* indexed floating loads and stores (fp2) */
857*647adfbcSforsyth 			oprange[AFSMOVSU] = oprange[r];
858*647adfbcSforsyth 			oprange[AFSMOVDU] = oprange[r];
859*647adfbcSforsyth 			oprange[AFXMOVS] = oprange[r];
860*647adfbcSforsyth 			oprange[AFXMOVSU] = oprange[r];
861*647adfbcSforsyth 			oprange[AFXMOVDU] = oprange[r];
862*647adfbcSforsyth 			oprange[AFPMOVS] = oprange[r];
863*647adfbcSforsyth 			oprange[AFPMOVSU] = oprange[r];
864*647adfbcSforsyth 			oprange[AFPMOVDU] = oprange[r];
865*647adfbcSforsyth 			oprange[AFPMOVIW] = oprange[r];
866*647adfbcSforsyth 			break;
867*647adfbcSforsyth 		case AFPMOVD:	/* indexed load/store and moves (fp2) */
868*647adfbcSforsyth 			oprange[AFSMOVD] = oprange[r];
869*647adfbcSforsyth 			oprange[AFXMOVD] = oprange[r];
870*647adfbcSforsyth 			break;
871*647adfbcSforsyth 		case AFMOVSPD:	/* move between fp reg sets (fp2) */
872*647adfbcSforsyth 			oprange[AFMOVPSD] = oprange[r];
873d67b7dadSforsyth 			break;
87474a4d8c2SCharles.Forsyth 		case AADD:
87574a4d8c2SCharles.Forsyth 		case AANDCC:	/* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
87674a4d8c2SCharles.Forsyth 		case ACMP:
87774a4d8c2SCharles.Forsyth 		case ACMPU:
87874a4d8c2SCharles.Forsyth 		case AEIEIO:
87974a4d8c2SCharles.Forsyth 		case ALSW:
88074a4d8c2SCharles.Forsyth 		case AMOVB:	/* macro: move byte with sign extension */
88174a4d8c2SCharles.Forsyth 		case AMOVBU:	/* macro: move byte with sign extension & update */
88274a4d8c2SCharles.Forsyth 		case AMOVW:
88374a4d8c2SCharles.Forsyth 		case AMOVFL:
88474a4d8c2SCharles.Forsyth 		case AMULLW:	/* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
88574a4d8c2SCharles.Forsyth 		case ASUBC:	/* op r1,$s,r3; op r1[,r2],r3 */
88674a4d8c2SCharles.Forsyth 		case ASTSW:
88774a4d8c2SCharles.Forsyth 		case ATLBIE:
88874a4d8c2SCharles.Forsyth 		case ATW:
88974a4d8c2SCharles.Forsyth 		case AWORD:
89074a4d8c2SCharles.Forsyth 		case ANOP:
89174a4d8c2SCharles.Forsyth 		case ATEXT:
89274a4d8c2SCharles.Forsyth 			break;
89374a4d8c2SCharles.Forsyth 		}
89474a4d8c2SCharles.Forsyth 	}
89574a4d8c2SCharles.Forsyth }
89674a4d8c2SCharles.Forsyth 
89774a4d8c2SCharles.Forsyth enum{
89874a4d8c2SCharles.Forsyth 	ABSD = 0,
89974a4d8c2SCharles.Forsyth 	ABSU = 1,
90074a4d8c2SCharles.Forsyth 	RELD = 2,
90174a4d8c2SCharles.Forsyth 	RELU = 3,
90274a4d8c2SCharles.Forsyth };
90374a4d8c2SCharles.Forsyth 
90474a4d8c2SCharles.Forsyth int modemap[8] = { 0, 1, -1, 2, 3, 4, 5, 6};
90574a4d8c2SCharles.Forsyth 
90674a4d8c2SCharles.Forsyth typedef struct Reloc Reloc;
90774a4d8c2SCharles.Forsyth 
90874a4d8c2SCharles.Forsyth struct Reloc
90974a4d8c2SCharles.Forsyth {
91074a4d8c2SCharles.Forsyth 	int n;
91174a4d8c2SCharles.Forsyth 	int t;
91274a4d8c2SCharles.Forsyth 	uchar *m;
91374a4d8c2SCharles.Forsyth 	ulong *a;
91474a4d8c2SCharles.Forsyth };
91574a4d8c2SCharles.Forsyth 
91674a4d8c2SCharles.Forsyth Reloc rels;
91774a4d8c2SCharles.Forsyth 
91874a4d8c2SCharles.Forsyth static void
grow(Reloc * r)91974a4d8c2SCharles.Forsyth grow(Reloc *r)
92074a4d8c2SCharles.Forsyth {
92174a4d8c2SCharles.Forsyth 	int t;
92274a4d8c2SCharles.Forsyth 	uchar *m, *nm;
92374a4d8c2SCharles.Forsyth 	ulong *a, *na;
92474a4d8c2SCharles.Forsyth 
92574a4d8c2SCharles.Forsyth 	t = r->t;
92674a4d8c2SCharles.Forsyth 	r->t += 64;
92774a4d8c2SCharles.Forsyth 	m = r->m;
92874a4d8c2SCharles.Forsyth 	a = r->a;
92974a4d8c2SCharles.Forsyth 	r->m = nm = malloc(r->t*sizeof(uchar));
93074a4d8c2SCharles.Forsyth 	r->a = na = malloc(r->t*sizeof(ulong));
93174a4d8c2SCharles.Forsyth 	memmove(nm, m, t*sizeof(uchar));
93274a4d8c2SCharles.Forsyth 	memmove(na, a, t*sizeof(ulong));
93374a4d8c2SCharles.Forsyth 	free(m);
93474a4d8c2SCharles.Forsyth 	free(a);
93574a4d8c2SCharles.Forsyth }
93674a4d8c2SCharles.Forsyth 
93774a4d8c2SCharles.Forsyth void
dynreloc(Sym * s,long v,int abs,int split,int sext)93874a4d8c2SCharles.Forsyth dynreloc(Sym *s, long v, int abs, int split, int sext)
93974a4d8c2SCharles.Forsyth {
94074a4d8c2SCharles.Forsyth 	int i, k, n;
94174a4d8c2SCharles.Forsyth 	uchar *m;
94274a4d8c2SCharles.Forsyth 	ulong *a;
94374a4d8c2SCharles.Forsyth 	Reloc *r;
94474a4d8c2SCharles.Forsyth 
94574a4d8c2SCharles.Forsyth 	if(v&3)
94674a4d8c2SCharles.Forsyth 		diag("bad relocation address");
94774a4d8c2SCharles.Forsyth 	v >>= 2;
94874a4d8c2SCharles.Forsyth 	if(s->type == SUNDEF)
94974a4d8c2SCharles.Forsyth 		k = abs ? ABSU : RELU;
95074a4d8c2SCharles.Forsyth 	else
95174a4d8c2SCharles.Forsyth 		k = abs ? ABSD : RELD;
95274a4d8c2SCharles.Forsyth 	if(split)
95374a4d8c2SCharles.Forsyth 		k += 4;
95474a4d8c2SCharles.Forsyth 	if(sext)
95574a4d8c2SCharles.Forsyth 		k += 2;
95674a4d8c2SCharles.Forsyth 	/* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, a, a, k); */
95774a4d8c2SCharles.Forsyth 	k = modemap[k];
95874a4d8c2SCharles.Forsyth 	r = &rels;
95974a4d8c2SCharles.Forsyth 	n = r->n;
96074a4d8c2SCharles.Forsyth 	if(n >= r->t)
96174a4d8c2SCharles.Forsyth 		grow(r);
96274a4d8c2SCharles.Forsyth 	m = r->m;
96374a4d8c2SCharles.Forsyth 	a = r->a;
96474a4d8c2SCharles.Forsyth 	for(i = n; i > 0; i--){
96574a4d8c2SCharles.Forsyth 		if(v < a[i-1]){	/* happens occasionally for data */
96674a4d8c2SCharles.Forsyth 			m[i] = m[i-1];
96774a4d8c2SCharles.Forsyth 			a[i] = a[i-1];
96874a4d8c2SCharles.Forsyth 		}
96974a4d8c2SCharles.Forsyth 		else
97074a4d8c2SCharles.Forsyth 			break;
97174a4d8c2SCharles.Forsyth 	}
97274a4d8c2SCharles.Forsyth 	m[i] = k;
97374a4d8c2SCharles.Forsyth 	a[i] = v;
97474a4d8c2SCharles.Forsyth 	r->n++;
97574a4d8c2SCharles.Forsyth }
97674a4d8c2SCharles.Forsyth 
97774a4d8c2SCharles.Forsyth static int
sput(char * s)97874a4d8c2SCharles.Forsyth sput(char *s)
97974a4d8c2SCharles.Forsyth {
98074a4d8c2SCharles.Forsyth 	char *p;
98174a4d8c2SCharles.Forsyth 
98274a4d8c2SCharles.Forsyth 	p = s;
98374a4d8c2SCharles.Forsyth 	while(*s)
98474a4d8c2SCharles.Forsyth 		cput(*s++);
98574a4d8c2SCharles.Forsyth 	cput(0);
98674a4d8c2SCharles.Forsyth 	return s-p+1;
98774a4d8c2SCharles.Forsyth }
98874a4d8c2SCharles.Forsyth 
98974a4d8c2SCharles.Forsyth void
asmdyn()99074a4d8c2SCharles.Forsyth asmdyn()
99174a4d8c2SCharles.Forsyth {
99274a4d8c2SCharles.Forsyth 	int i, n, t, c;
99374a4d8c2SCharles.Forsyth 	Sym *s;
99474a4d8c2SCharles.Forsyth 	ulong la, ra, *a;
99574a4d8c2SCharles.Forsyth 	vlong off;
99674a4d8c2SCharles.Forsyth 	uchar *m;
99774a4d8c2SCharles.Forsyth 	Reloc *r;
99874a4d8c2SCharles.Forsyth 
99974a4d8c2SCharles.Forsyth 	cflush();
100074a4d8c2SCharles.Forsyth 	off = seek(cout, 0, 1);
100174a4d8c2SCharles.Forsyth 	lput(0);
100274a4d8c2SCharles.Forsyth 	t = 0;
100374a4d8c2SCharles.Forsyth 	lput(imports);
100474a4d8c2SCharles.Forsyth 	t += 4;
100574a4d8c2SCharles.Forsyth 	for(i = 0; i < NHASH; i++)
100674a4d8c2SCharles.Forsyth 		for(s = hash[i]; s != S; s = s->link)
100774a4d8c2SCharles.Forsyth 			if(s->type == SUNDEF){
100874a4d8c2SCharles.Forsyth 				lput(s->sig);
100974a4d8c2SCharles.Forsyth 				t += 4;
101074a4d8c2SCharles.Forsyth 				t += sput(s->name);
101174a4d8c2SCharles.Forsyth 			}
101274a4d8c2SCharles.Forsyth 
101374a4d8c2SCharles.Forsyth 	la = 0;
101474a4d8c2SCharles.Forsyth 	r = &rels;
101574a4d8c2SCharles.Forsyth 	n = r->n;
101674a4d8c2SCharles.Forsyth 	m = r->m;
101774a4d8c2SCharles.Forsyth 	a = r->a;
101874a4d8c2SCharles.Forsyth 	lput(n);
101974a4d8c2SCharles.Forsyth 	t += 4;
102074a4d8c2SCharles.Forsyth 	for(i = 0; i < n; i++){
102174a4d8c2SCharles.Forsyth 		ra = *a-la;
102274a4d8c2SCharles.Forsyth 		if(*a < la)
102374a4d8c2SCharles.Forsyth 			diag("bad relocation order");
102474a4d8c2SCharles.Forsyth 		if(ra < 256)
102574a4d8c2SCharles.Forsyth 			c = 0;
102674a4d8c2SCharles.Forsyth 		else if(ra < 65536)
102774a4d8c2SCharles.Forsyth 			c = 1;
102874a4d8c2SCharles.Forsyth 		else
102974a4d8c2SCharles.Forsyth 			c = 2;
103074a4d8c2SCharles.Forsyth 		cput((c<<6)|*m++);
103174a4d8c2SCharles.Forsyth 		t++;
103274a4d8c2SCharles.Forsyth 		if(c == 0){
103374a4d8c2SCharles.Forsyth 			cput(ra);
103474a4d8c2SCharles.Forsyth 			t++;
103574a4d8c2SCharles.Forsyth 		}
103674a4d8c2SCharles.Forsyth 		else if(c == 1){
103774a4d8c2SCharles.Forsyth 			wput(ra);
103874a4d8c2SCharles.Forsyth 			t += 2;
103974a4d8c2SCharles.Forsyth 		}
104074a4d8c2SCharles.Forsyth 		else{
104174a4d8c2SCharles.Forsyth 			lput(ra);
104274a4d8c2SCharles.Forsyth 			t += 4;
104374a4d8c2SCharles.Forsyth 		}
104474a4d8c2SCharles.Forsyth 		la = *a++;
104574a4d8c2SCharles.Forsyth 	}
104674a4d8c2SCharles.Forsyth 
104774a4d8c2SCharles.Forsyth 	cflush();
104874a4d8c2SCharles.Forsyth 	seek(cout, off, 0);
104974a4d8c2SCharles.Forsyth 	lput(t);
105074a4d8c2SCharles.Forsyth 
105174a4d8c2SCharles.Forsyth 	if(debug['v']){
105274a4d8c2SCharles.Forsyth 		Bprint(&bso, "import table entries = %d\n", imports);
105374a4d8c2SCharles.Forsyth 		Bprint(&bso, "export table entries = %d\n", exports);
105474a4d8c2SCharles.Forsyth 	}
105574a4d8c2SCharles.Forsyth }
1056