xref: /plan9/sys/src/cmd/8l/span.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include	"l.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier void
43e12c5d1SDavid du Colombier span(void)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 	Prog *p, *q;
73e12c5d1SDavid du Colombier 	long v, c, idat;
83e12c5d1SDavid du Colombier 	int m, n, again;
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier 	xdefine("etext", STEXT, 0L);
113e12c5d1SDavid du Colombier 	idat = INITDAT;
123e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
133e12c5d1SDavid du Colombier 		if(p->as == ATEXT)
143e12c5d1SDavid du Colombier 			curtext = p;
153e12c5d1SDavid du Colombier 		n = 0;
163e12c5d1SDavid du Colombier 		if(p->to.type == D_BRANCH)
173e12c5d1SDavid du Colombier 			if(p->cond == P)
183e12c5d1SDavid du Colombier 				p->cond = p;
193e12c5d1SDavid du Colombier 		if((q = p->cond) != P)
203e12c5d1SDavid du Colombier 			if(q->back != 2)
213e12c5d1SDavid du Colombier 				n = 1;
223e12c5d1SDavid du Colombier 		p->back = n;
233e12c5d1SDavid du Colombier 		if(p->as == AADJSP) {
243e12c5d1SDavid du Colombier 			p->to.type = D_SP;
253e12c5d1SDavid du Colombier 			v = -p->from.offset;
263e12c5d1SDavid du Colombier 			p->from.offset = v;
273e12c5d1SDavid du Colombier 			p->as = AADDL;
283e12c5d1SDavid du Colombier 			if(v < 0) {
293e12c5d1SDavid du Colombier 				p->as = ASUBL;
303e12c5d1SDavid du Colombier 				v = -v;
313e12c5d1SDavid du Colombier 				p->from.offset = v;
323e12c5d1SDavid du Colombier 			}
333e12c5d1SDavid du Colombier 			if(v == 0)
343e12c5d1SDavid du Colombier 				p->as = ANOP;
353e12c5d1SDavid du Colombier 		}
363e12c5d1SDavid du Colombier 	}
373e12c5d1SDavid du Colombier 	n = 0;
383e12c5d1SDavid du Colombier 
393e12c5d1SDavid du Colombier start:
403e12c5d1SDavid du Colombier 	if(debug['v'])
413e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f span\n", cputime());
423e12c5d1SDavid du Colombier 	Bflush(&bso);
433e12c5d1SDavid du Colombier 	c = INITTEXT;
443e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
453e12c5d1SDavid du Colombier 		if(p->as == ATEXT)
463e12c5d1SDavid du Colombier 			curtext = p;
473e12c5d1SDavid du Colombier 		if(p->to.type == D_BRANCH)
483e12c5d1SDavid du Colombier 			if(p->back)
493e12c5d1SDavid du Colombier 				p->pc = c;
503e12c5d1SDavid du Colombier 		asmins(p);
513e12c5d1SDavid du Colombier 		p->pc = c;
523e12c5d1SDavid du Colombier 		m = andptr-and;
533e12c5d1SDavid du Colombier 		p->mark = m;
543e12c5d1SDavid du Colombier 		c += m;
553e12c5d1SDavid du Colombier 	}
563e12c5d1SDavid du Colombier 
573e12c5d1SDavid du Colombier loop:
583e12c5d1SDavid du Colombier 	n++;
593e12c5d1SDavid du Colombier 	if(debug['v'])
603e12c5d1SDavid du Colombier 		Bprint(&bso, "%5.2f span %d\n", cputime(), n);
613e12c5d1SDavid du Colombier 	Bflush(&bso);
623e12c5d1SDavid du Colombier 	if(n > 50) {
633e12c5d1SDavid du Colombier 		print("span must be looping\n");
643e12c5d1SDavid du Colombier 		errorexit();
653e12c5d1SDavid du Colombier 	}
663e12c5d1SDavid du Colombier 	again = 0;
673e12c5d1SDavid du Colombier 	c = INITTEXT;
683e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
693e12c5d1SDavid du Colombier 		if(p->as == ATEXT)
703e12c5d1SDavid du Colombier 			curtext = p;
713e12c5d1SDavid du Colombier 		if(p->to.type == D_BRANCH) {
723e12c5d1SDavid du Colombier 			if(p->back)
733e12c5d1SDavid du Colombier 				p->pc = c;
743e12c5d1SDavid du Colombier 			asmins(p);
753e12c5d1SDavid du Colombier 			m = andptr-and;
763e12c5d1SDavid du Colombier 			if(m != p->mark) {
773e12c5d1SDavid du Colombier 				p->mark = m;
783e12c5d1SDavid du Colombier 				again++;
793e12c5d1SDavid du Colombier 			}
803e12c5d1SDavid du Colombier 		}
813e12c5d1SDavid du Colombier 		p->pc = c;
823e12c5d1SDavid du Colombier 		c += p->mark;
833e12c5d1SDavid du Colombier 	}
843e12c5d1SDavid du Colombier 	if(again) {
853e12c5d1SDavid du Colombier 		textsize = c;
863e12c5d1SDavid du Colombier 		goto loop;
873e12c5d1SDavid du Colombier 	}
883e12c5d1SDavid du Colombier 	if(INITRND) {
893e12c5d1SDavid du Colombier 		INITDAT = rnd(c, INITRND);
903e12c5d1SDavid du Colombier 		if(INITDAT != idat) {
913e12c5d1SDavid du Colombier 			idat = INITDAT;
923e12c5d1SDavid du Colombier 			goto start;
933e12c5d1SDavid du Colombier 		}
943e12c5d1SDavid du Colombier 	}
953e12c5d1SDavid du Colombier 	xdefine("etext", STEXT, c);
963e12c5d1SDavid du Colombier 	if(debug['v'])
973e12c5d1SDavid du Colombier 		Bprint(&bso, "etext = %lux\n", c);
983e12c5d1SDavid du Colombier 	Bflush(&bso);
993e12c5d1SDavid du Colombier 	for(p = textp; p != P; p = p->cond)
1003e12c5d1SDavid du Colombier 		p->from.sym->value = p->pc;
1013e12c5d1SDavid du Colombier 	textsize = c - INITTEXT;
1023e12c5d1SDavid du Colombier }
1033e12c5d1SDavid du Colombier 
1043e12c5d1SDavid du Colombier void
1053e12c5d1SDavid du Colombier xdefine(char *p, int t, long v)
1063e12c5d1SDavid du Colombier {
1073e12c5d1SDavid du Colombier 	Sym *s;
1083e12c5d1SDavid du Colombier 
1093e12c5d1SDavid du Colombier 	s = lookup(p, 0);
1103e12c5d1SDavid du Colombier 	if(s->type == 0 || s->type == SXREF) {
1113e12c5d1SDavid du Colombier 		s->type = t;
1123e12c5d1SDavid du Colombier 		s->value = v;
1133e12c5d1SDavid du Colombier 	}
1143e12c5d1SDavid du Colombier 	if(s->type == STEXT && s->value == 0)
1153e12c5d1SDavid du Colombier 		s->value = v;
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier void
119*219b2ee8SDavid du Colombier putsymb(char *s, int t, long v, int ver)
1203e12c5d1SDavid du Colombier {
1213e12c5d1SDavid du Colombier 	int i, f;
1223e12c5d1SDavid du Colombier 
1233e12c5d1SDavid du Colombier 	if(t == 'f')
124*219b2ee8SDavid du Colombier 		s++;
1253e12c5d1SDavid du Colombier 	lput(v);
126*219b2ee8SDavid du Colombier 	if(ver)
1273e12c5d1SDavid du Colombier 		t += 'a' - 'A';
128*219b2ee8SDavid du Colombier 	CPUT(t+0x80);			/* 0x80 is variable length */
129*219b2ee8SDavid du Colombier 
130*219b2ee8SDavid du Colombier 	if(t == 'Z' || t == 'z') {
131*219b2ee8SDavid du Colombier 		CPUT(s[0]);
132*219b2ee8SDavid du Colombier 		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
133*219b2ee8SDavid du Colombier 			CPUT(s[i]);
134*219b2ee8SDavid du Colombier 			CPUT(s[i+1]);
135*219b2ee8SDavid du Colombier 		}
1363e12c5d1SDavid du Colombier 		CPUT(0);
1373e12c5d1SDavid du Colombier 		CPUT(0);
138*219b2ee8SDavid du Colombier 		i++;
139*219b2ee8SDavid du Colombier 	}
140*219b2ee8SDavid du Colombier 	else {
141*219b2ee8SDavid du Colombier 		for(i=0; s[i]; i++)
142*219b2ee8SDavid du Colombier 			CPUT(s[i]);
1433e12c5d1SDavid du Colombier 		CPUT(0);
144*219b2ee8SDavid du Colombier 	}
145*219b2ee8SDavid du Colombier 	symsize += 4 + 1 + i + 1;
146*219b2ee8SDavid du Colombier 
1473e12c5d1SDavid du Colombier 	if(debug['n']) {
1483e12c5d1SDavid du Colombier 		if(t == 'z' || t == 'Z') {
149*219b2ee8SDavid du Colombier 			Bprint(&bso, "%c %.8lux ", t, v);
150*219b2ee8SDavid du Colombier 			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
151*219b2ee8SDavid du Colombier 				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
152*219b2ee8SDavid du Colombier 				Bprint(&bso, "/%x", f);
1533e12c5d1SDavid du Colombier 			}
154*219b2ee8SDavid du Colombier 			Bprint(&bso, "\n");
1553e12c5d1SDavid du Colombier 			return;
1563e12c5d1SDavid du Colombier 		}
157*219b2ee8SDavid du Colombier 		if(ver)
158*219b2ee8SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
1593e12c5d1SDavid du Colombier 		else
160*219b2ee8SDavid du Colombier 			Bprint(&bso, "%c %.8lux %s\n", t, v, s);
1613e12c5d1SDavid du Colombier 	}
1623e12c5d1SDavid du Colombier }
1633e12c5d1SDavid du Colombier 
1643e12c5d1SDavid du Colombier void
1653e12c5d1SDavid du Colombier asmsym(void)
1663e12c5d1SDavid du Colombier {
1673e12c5d1SDavid du Colombier 	Prog *p;
1683e12c5d1SDavid du Colombier 	Auto *a;
1693e12c5d1SDavid du Colombier 	Sym *s;
1703e12c5d1SDavid du Colombier 	int h;
1713e12c5d1SDavid du Colombier 
1723e12c5d1SDavid du Colombier 	s = lookup("etext", 0);
1733e12c5d1SDavid du Colombier 	if(s->type == STEXT)
174*219b2ee8SDavid du Colombier 		putsymb(s->name, 'T', s->value, s->version);
1753e12c5d1SDavid du Colombier 
1763e12c5d1SDavid du Colombier 	for(h=0; h<NHASH; h++)
1773e12c5d1SDavid du Colombier 		for(s=hash[h]; s!=S; s=s->link)
1783e12c5d1SDavid du Colombier 			switch(s->type) {
179*219b2ee8SDavid du Colombier 			case SCONST:
180*219b2ee8SDavid du Colombier 				putsymb(s->name, 'D', s->value, s->version);
181*219b2ee8SDavid du Colombier 				continue;
182*219b2ee8SDavid du Colombier 
1833e12c5d1SDavid du Colombier 			case SDATA:
184*219b2ee8SDavid du Colombier 				putsymb(s->name, 'D', s->value+INITDAT, s->version);
1853e12c5d1SDavid du Colombier 				continue;
1863e12c5d1SDavid du Colombier 
1873e12c5d1SDavid du Colombier 			case SBSS:
188*219b2ee8SDavid du Colombier 				putsymb(s->name, 'B', s->value+INITDAT, s->version);
1893e12c5d1SDavid du Colombier 				continue;
1903e12c5d1SDavid du Colombier 
1913e12c5d1SDavid du Colombier 			case SFILE:
192*219b2ee8SDavid du Colombier 				putsymb(s->name, 'f', s->value, s->version);
1933e12c5d1SDavid du Colombier 				continue;
1943e12c5d1SDavid du Colombier 			}
1953e12c5d1SDavid du Colombier 
1963e12c5d1SDavid du Colombier 	for(p=textp; p!=P; p=p->cond) {
1973e12c5d1SDavid du Colombier 		s = p->from.sym;
1983e12c5d1SDavid du Colombier 		if(s->type != STEXT)
1993e12c5d1SDavid du Colombier 			continue;
2003e12c5d1SDavid du Colombier 
2013e12c5d1SDavid du Colombier 		/* filenames first */
2023e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
2033e12c5d1SDavid du Colombier 			if(a->type == D_FILE)
204*219b2ee8SDavid du Colombier 				putsymb(a->sym->name, 'z', a->offset, 0);
2053e12c5d1SDavid du Colombier 			else
2063e12c5d1SDavid du Colombier 			if(a->type == D_FILE1)
207*219b2ee8SDavid du Colombier 				putsymb(a->sym->name, 'Z', a->offset, 0);
2083e12c5d1SDavid du Colombier 
209*219b2ee8SDavid du Colombier 		putsymb(s->name, 'T', s->value, s->version);
2103e12c5d1SDavid du Colombier 
211*219b2ee8SDavid du Colombier 		/* frame, auto and param after */
212*219b2ee8SDavid du Colombier 		putsymb(".frame", 'm', p->to.offset+4, 0);
213*219b2ee8SDavid du Colombier 
2143e12c5d1SDavid du Colombier 		for(a=p->to.autom; a; a=a->link)
2153e12c5d1SDavid du Colombier 			if(a->type == D_AUTO)
216*219b2ee8SDavid du Colombier 				putsymb(a->sym->name, 'a', -a->offset, 0);
2173e12c5d1SDavid du Colombier 			else
2183e12c5d1SDavid du Colombier 			if(a->type == D_PARAM)
219*219b2ee8SDavid du Colombier 				putsymb(a->sym->name, 'p', a->offset, 0);
2203e12c5d1SDavid du Colombier 	}
2213e12c5d1SDavid du Colombier 	if(debug['v'] || debug['n'])
2223e12c5d1SDavid du Colombier 		Bprint(&bso, "symsize = %lud\n", symsize);
2233e12c5d1SDavid du Colombier 	Bflush(&bso);
2243e12c5d1SDavid du Colombier }
2253e12c5d1SDavid du Colombier 
2263e12c5d1SDavid du Colombier void
2273e12c5d1SDavid du Colombier asmlc(void)
2283e12c5d1SDavid du Colombier {
2293e12c5d1SDavid du Colombier 	long oldpc, oldlc;
2303e12c5d1SDavid du Colombier 	Prog *p;
2313e12c5d1SDavid du Colombier 	long v, s;
2323e12c5d1SDavid du Colombier 
2333e12c5d1SDavid du Colombier 	oldpc = INITTEXT;
2343e12c5d1SDavid du Colombier 	oldlc = 0;
2353e12c5d1SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
2363e12c5d1SDavid du Colombier 		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
2373e12c5d1SDavid du Colombier 			if(p->as == ATEXT)
2383e12c5d1SDavid du Colombier 				curtext = p;
2393e12c5d1SDavid du Colombier 			if(debug['L'])
2403e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
2413e12c5d1SDavid du Colombier 					p->pc, p);
2423e12c5d1SDavid du Colombier 			continue;
2433e12c5d1SDavid du Colombier 		}
2443e12c5d1SDavid du Colombier 		if(debug['L'])
2453e12c5d1SDavid du Colombier 			Bprint(&bso, "\t\t%6ld", lcsize);
2463e12c5d1SDavid du Colombier 		v = (p->pc - oldpc) / MINLC;
2473e12c5d1SDavid du Colombier 		while(v) {
2483e12c5d1SDavid du Colombier 			s = 127;
2493e12c5d1SDavid du Colombier 			if(v < 127)
2503e12c5d1SDavid du Colombier 				s = v;
2513e12c5d1SDavid du Colombier 			CPUT(s+128);	/* 129-255 +pc */
2523e12c5d1SDavid du Colombier 			if(debug['L'])
2533e12c5d1SDavid du Colombier 				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
2543e12c5d1SDavid du Colombier 			v -= s;
2553e12c5d1SDavid du Colombier 			lcsize++;
2563e12c5d1SDavid du Colombier 		}
2573e12c5d1SDavid du Colombier 		s = p->line - oldlc;
2583e12c5d1SDavid du Colombier 		oldlc = p->line;
2593e12c5d1SDavid du Colombier 		oldpc = p->pc + MINLC;
2603e12c5d1SDavid du Colombier 		if(s > 64 || s < -64) {
2613e12c5d1SDavid du Colombier 			CPUT(0);	/* 0 vv +lc */
2623e12c5d1SDavid du Colombier 			CPUT(s>>24);
2633e12c5d1SDavid du Colombier 			CPUT(s>>16);
2643e12c5d1SDavid du Colombier 			CPUT(s>>8);
2653e12c5d1SDavid du Colombier 			CPUT(s);
2663e12c5d1SDavid du Colombier 			if(debug['L']) {
2673e12c5d1SDavid du Colombier 				if(s > 0)
2683e12c5d1SDavid du Colombier 					Bprint(&bso, " lc+%ld(%d,%ld)\n",
2693e12c5d1SDavid du Colombier 						s, 0, s);
2703e12c5d1SDavid du Colombier 				else
2713e12c5d1SDavid du Colombier 					Bprint(&bso, " lc%ld(%d,%ld)\n",
2723e12c5d1SDavid du Colombier 						s, 0, s);
2733e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
2743e12c5d1SDavid du Colombier 					p->pc, p);
2753e12c5d1SDavid du Colombier 			}
2763e12c5d1SDavid du Colombier 			lcsize += 5;
2773e12c5d1SDavid du Colombier 			continue;
2783e12c5d1SDavid du Colombier 		}
2793e12c5d1SDavid du Colombier 		if(s > 0) {
2803e12c5d1SDavid du Colombier 			CPUT(0+s);	/* 1-64 +lc */
2813e12c5d1SDavid du Colombier 			if(debug['L']) {
2823e12c5d1SDavid du Colombier 				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
2833e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
2843e12c5d1SDavid du Colombier 					p->pc, p);
2853e12c5d1SDavid du Colombier 			}
2863e12c5d1SDavid du Colombier 		} else {
2873e12c5d1SDavid du Colombier 			CPUT(64-s);	/* 65-128 -lc */
2883e12c5d1SDavid du Colombier 			if(debug['L']) {
2893e12c5d1SDavid du Colombier 				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
2903e12c5d1SDavid du Colombier 				Bprint(&bso, "%6lux %P\n",
2913e12c5d1SDavid du Colombier 					p->pc, p);
2923e12c5d1SDavid du Colombier 			}
2933e12c5d1SDavid du Colombier 		}
2943e12c5d1SDavid du Colombier 		lcsize++;
2953e12c5d1SDavid du Colombier 	}
2963e12c5d1SDavid du Colombier 	while(lcsize & 1) {
2973e12c5d1SDavid du Colombier 		s = 129;
2983e12c5d1SDavid du Colombier 		CPUT(s);
2993e12c5d1SDavid du Colombier 		lcsize++;
3003e12c5d1SDavid du Colombier 	}
3013e12c5d1SDavid du Colombier 	if(debug['v'] || debug['L'])
3023e12c5d1SDavid du Colombier 		Bprint(&bso, "lcsize = %ld\n", lcsize);
3033e12c5d1SDavid du Colombier 	Bflush(&bso);
3043e12c5d1SDavid du Colombier }
3053e12c5d1SDavid du Colombier 
3063e12c5d1SDavid du Colombier int
3073e12c5d1SDavid du Colombier oclass(Adr *a)
3083e12c5d1SDavid du Colombier {
3093e12c5d1SDavid du Colombier 	long v;
3103e12c5d1SDavid du Colombier 
3113e12c5d1SDavid du Colombier 	if(a->type >= D_INDIR || a->index != D_NONE) {
3123e12c5d1SDavid du Colombier 		if(a->index != D_NONE && a->scale == 0) {
313*219b2ee8SDavid du Colombier 			if(a->type == D_ADDR) {
314*219b2ee8SDavid du Colombier 				switch(a->index) {
315*219b2ee8SDavid du Colombier 				case D_EXTERN:
316*219b2ee8SDavid du Colombier 				case D_STATIC:
3173e12c5d1SDavid du Colombier 					return Yi32;
318*219b2ee8SDavid du Colombier 				case D_AUTO:
319*219b2ee8SDavid du Colombier 				case D_PARAM:
320*219b2ee8SDavid du Colombier 					return Yiauto;
321*219b2ee8SDavid du Colombier 				}
322*219b2ee8SDavid du Colombier 				return Yxxx;
323*219b2ee8SDavid du Colombier 			}
3243e12c5d1SDavid du Colombier 			return Ycol;
3253e12c5d1SDavid du Colombier 		}
3263e12c5d1SDavid du Colombier 		return Ym;
3273e12c5d1SDavid du Colombier 	}
3283e12c5d1SDavid du Colombier 	switch(a->type)
3293e12c5d1SDavid du Colombier 	{
3303e12c5d1SDavid du Colombier 	case D_AL:
3313e12c5d1SDavid du Colombier 		return Yal;
3323e12c5d1SDavid du Colombier 
3333e12c5d1SDavid du Colombier 	case D_AX:
3343e12c5d1SDavid du Colombier 		return Yax;
3353e12c5d1SDavid du Colombier 
3363e12c5d1SDavid du Colombier 	case D_CL:
3373e12c5d1SDavid du Colombier 	case D_DL:
3383e12c5d1SDavid du Colombier 	case D_BL:
3393e12c5d1SDavid du Colombier 	case D_AH:
3403e12c5d1SDavid du Colombier 	case D_CH:
3413e12c5d1SDavid du Colombier 	case D_DH:
3423e12c5d1SDavid du Colombier 	case D_BH:
3433e12c5d1SDavid du Colombier 		return Yrb;
3443e12c5d1SDavid du Colombier 
3453e12c5d1SDavid du Colombier 	case D_CX:
3463e12c5d1SDavid du Colombier 		return Ycx;
3473e12c5d1SDavid du Colombier 
3483e12c5d1SDavid du Colombier 	case D_DX:
3493e12c5d1SDavid du Colombier 	case D_BX:
3503e12c5d1SDavid du Colombier 		return Yrx;
3513e12c5d1SDavid du Colombier 
3523e12c5d1SDavid du Colombier 	case D_SP:
3533e12c5d1SDavid du Colombier 	case D_BP:
3543e12c5d1SDavid du Colombier 	case D_SI:
3553e12c5d1SDavid du Colombier 	case D_DI:
3563e12c5d1SDavid du Colombier 		return Yrl;
3573e12c5d1SDavid du Colombier 
3583e12c5d1SDavid du Colombier 	case D_F0+0:
3593e12c5d1SDavid du Colombier 		return	Yf0;
3603e12c5d1SDavid du Colombier 
3613e12c5d1SDavid du Colombier 	case D_F0+1:
3623e12c5d1SDavid du Colombier 	case D_F0+2:
3633e12c5d1SDavid du Colombier 	case D_F0+3:
3643e12c5d1SDavid du Colombier 	case D_F0+4:
3653e12c5d1SDavid du Colombier 	case D_F0+5:
3663e12c5d1SDavid du Colombier 	case D_F0+6:
3673e12c5d1SDavid du Colombier 	case D_F0+7:
3683e12c5d1SDavid du Colombier 		return	Yrf;
3693e12c5d1SDavid du Colombier 
3703e12c5d1SDavid du Colombier 	case D_NONE:
3713e12c5d1SDavid du Colombier 		return Ynone;
3723e12c5d1SDavid du Colombier 
3733e12c5d1SDavid du Colombier 	case D_CS:	return	Ycs;
3743e12c5d1SDavid du Colombier 	case D_SS:	return	Yss;
3753e12c5d1SDavid du Colombier 	case D_DS:	return	Yds;
3763e12c5d1SDavid du Colombier 	case D_ES:	return	Yes;
3773e12c5d1SDavid du Colombier 	case D_FS:	return	Yfs;
3783e12c5d1SDavid du Colombier 	case D_GS:	return	Ygs;
3793e12c5d1SDavid du Colombier 
3803e12c5d1SDavid du Colombier 	case D_GDTR:	return	Ygdtr;
3813e12c5d1SDavid du Colombier 	case D_IDTR:	return	Yidtr;
3823e12c5d1SDavid du Colombier 	case D_LDTR:	return	Yldtr;
3833e12c5d1SDavid du Colombier 	case D_MSW:	return	Ymsw;
3843e12c5d1SDavid du Colombier 	case D_TASK:	return	Ytask;
3853e12c5d1SDavid du Colombier 
3863e12c5d1SDavid du Colombier 	case D_CR+0:	return	Ycr0;
3873e12c5d1SDavid du Colombier 	case D_CR+1:	return	Ycr1;
3883e12c5d1SDavid du Colombier 	case D_CR+2:	return	Ycr2;
3893e12c5d1SDavid du Colombier 	case D_CR+3:	return	Ycr3;
3903e12c5d1SDavid du Colombier 	case D_CR+4:	return	Ycr4;
3913e12c5d1SDavid du Colombier 	case D_CR+5:	return	Ycr5;
3923e12c5d1SDavid du Colombier 	case D_CR+6:	return	Ycr6;
3933e12c5d1SDavid du Colombier 	case D_CR+7:	return	Ycr7;
3943e12c5d1SDavid du Colombier 
3953e12c5d1SDavid du Colombier 	case D_DR+0:	return	Ydr0;
3963e12c5d1SDavid du Colombier 	case D_DR+1:	return	Ydr1;
3973e12c5d1SDavid du Colombier 	case D_DR+2:	return	Ydr2;
3983e12c5d1SDavid du Colombier 	case D_DR+3:	return	Ydr3;
3993e12c5d1SDavid du Colombier 	case D_DR+4:	return	Ydr4;
4003e12c5d1SDavid du Colombier 	case D_DR+5:	return	Ydr5;
4013e12c5d1SDavid du Colombier 	case D_DR+6:	return	Ydr6;
4023e12c5d1SDavid du Colombier 	case D_DR+7:	return	Ydr7;
4033e12c5d1SDavid du Colombier 
4043e12c5d1SDavid du Colombier 	case D_TR+0:	return	Ytr0;
4053e12c5d1SDavid du Colombier 	case D_TR+1:	return	Ytr1;
4063e12c5d1SDavid du Colombier 	case D_TR+2:	return	Ytr2;
4073e12c5d1SDavid du Colombier 	case D_TR+3:	return	Ytr3;
4083e12c5d1SDavid du Colombier 	case D_TR+4:	return	Ytr4;
4093e12c5d1SDavid du Colombier 	case D_TR+5:	return	Ytr5;
4103e12c5d1SDavid du Colombier 	case D_TR+6:	return	Ytr6;
4113e12c5d1SDavid du Colombier 	case D_TR+7:	return	Ytr7;
4123e12c5d1SDavid du Colombier 
4133e12c5d1SDavid du Colombier 	case D_EXTERN:
4143e12c5d1SDavid du Colombier 	case D_STATIC:
4153e12c5d1SDavid du Colombier 	case D_AUTO:
4163e12c5d1SDavid du Colombier 	case D_PARAM:
4173e12c5d1SDavid du Colombier 		return Ym;
4183e12c5d1SDavid du Colombier 
4193e12c5d1SDavid du Colombier 	case D_CONST:
4203e12c5d1SDavid du Colombier 	case D_ADDR:
4213e12c5d1SDavid du Colombier 		if(a->sym == S) {
4223e12c5d1SDavid du Colombier 			v = a->offset;
4233e12c5d1SDavid du Colombier 			if(v == 0)
4243e12c5d1SDavid du Colombier 				return Yi0;
4253e12c5d1SDavid du Colombier 			if(v == 1)
4263e12c5d1SDavid du Colombier 				return Yi1;
4273e12c5d1SDavid du Colombier 			if(v >= -128 && v <= 127)
4283e12c5d1SDavid du Colombier 				return Yi8;
4293e12c5d1SDavid du Colombier 		}
4303e12c5d1SDavid du Colombier 		return Yi32;
4313e12c5d1SDavid du Colombier 
4323e12c5d1SDavid du Colombier 	case D_BRANCH:
4333e12c5d1SDavid du Colombier 		return Ybr;
4343e12c5d1SDavid du Colombier 	}
4353e12c5d1SDavid du Colombier 	return Yxxx;
4363e12c5d1SDavid du Colombier }
4373e12c5d1SDavid du Colombier 
4383e12c5d1SDavid du Colombier void
4393e12c5d1SDavid du Colombier asmidx(Adr *a, int base)
4403e12c5d1SDavid du Colombier {
4413e12c5d1SDavid du Colombier 	int i;
4423e12c5d1SDavid du Colombier 
4433e12c5d1SDavid du Colombier 	switch(a->index) {
4443e12c5d1SDavid du Colombier 	default:
4453e12c5d1SDavid du Colombier 		goto bad;
4463e12c5d1SDavid du Colombier 
4473e12c5d1SDavid du Colombier 	case D_NONE:
4483e12c5d1SDavid du Colombier 		i = 4 << 3;
4493e12c5d1SDavid du Colombier 		goto bas;
4503e12c5d1SDavid du Colombier 
4513e12c5d1SDavid du Colombier 	case D_AX:
4523e12c5d1SDavid du Colombier 	case D_CX:
4533e12c5d1SDavid du Colombier 	case D_DX:
4543e12c5d1SDavid du Colombier 	case D_BX:
4553e12c5d1SDavid du Colombier 	case D_BP:
4563e12c5d1SDavid du Colombier 	case D_SI:
4573e12c5d1SDavid du Colombier 	case D_DI:
4583e12c5d1SDavid du Colombier 		i = reg[a->index] << 3;
4593e12c5d1SDavid du Colombier 		break;
4603e12c5d1SDavid du Colombier 	}
4613e12c5d1SDavid du Colombier 	switch(a->scale) {
4623e12c5d1SDavid du Colombier 	default:
4633e12c5d1SDavid du Colombier 		goto bad;
4643e12c5d1SDavid du Colombier 	case 1:
4653e12c5d1SDavid du Colombier 		break;
4663e12c5d1SDavid du Colombier 	case 2:
4673e12c5d1SDavid du Colombier 		i |= (1<<6);
4683e12c5d1SDavid du Colombier 		break;
4693e12c5d1SDavid du Colombier 	case 4:
4703e12c5d1SDavid du Colombier 		i |= (2<<6);
4713e12c5d1SDavid du Colombier 		break;
4723e12c5d1SDavid du Colombier 	case 8:
4733e12c5d1SDavid du Colombier 		i |= (3<<6);
4743e12c5d1SDavid du Colombier 		break;
4753e12c5d1SDavid du Colombier 	}
4763e12c5d1SDavid du Colombier bas:
4773e12c5d1SDavid du Colombier 	switch(base) {
4783e12c5d1SDavid du Colombier 	default:
4793e12c5d1SDavid du Colombier 		goto bad;
4803e12c5d1SDavid du Colombier 	case D_NONE:	/* must be mod=00 */
4813e12c5d1SDavid du Colombier 		i |= 5;
4823e12c5d1SDavid du Colombier 		break;
4833e12c5d1SDavid du Colombier 	case D_AX:
4843e12c5d1SDavid du Colombier 	case D_CX:
4853e12c5d1SDavid du Colombier 	case D_DX:
4863e12c5d1SDavid du Colombier 	case D_BX:
4873e12c5d1SDavid du Colombier 	case D_SP:
4883e12c5d1SDavid du Colombier 	case D_SI:
4893e12c5d1SDavid du Colombier 	case D_DI:
4903e12c5d1SDavid du Colombier 		i |= reg[base];
4913e12c5d1SDavid du Colombier 		break;
4923e12c5d1SDavid du Colombier 	}
4933e12c5d1SDavid du Colombier 	*andptr++ = i;
4943e12c5d1SDavid du Colombier 	return;
4953e12c5d1SDavid du Colombier bad:
4963e12c5d1SDavid du Colombier 	diag("asmidx: bad address %D\n", a);
4973e12c5d1SDavid du Colombier 	*andptr++ = 0;
4983e12c5d1SDavid du Colombier 	return;
4993e12c5d1SDavid du Colombier }
5003e12c5d1SDavid du Colombier 
5013e12c5d1SDavid du Colombier long
5023e12c5d1SDavid du Colombier vaddr(Adr *a)
5033e12c5d1SDavid du Colombier {
5043e12c5d1SDavid du Colombier 	int t;
5053e12c5d1SDavid du Colombier 	long v;
5063e12c5d1SDavid du Colombier 
5073e12c5d1SDavid du Colombier 	t = a->type;
5083e12c5d1SDavid du Colombier 	v = a->offset;
5093e12c5d1SDavid du Colombier 	if(t == D_ADDR)
5103e12c5d1SDavid du Colombier 		t = a->index;
5113e12c5d1SDavid du Colombier 	switch(t) {
5123e12c5d1SDavid du Colombier 	case D_STATIC:
5133e12c5d1SDavid du Colombier 	case D_EXTERN:
5143e12c5d1SDavid du Colombier 		if(a->sym) {
5153e12c5d1SDavid du Colombier 			v += a->sym->value;
516*219b2ee8SDavid du Colombier 			switch(a->sym->type) {
517*219b2ee8SDavid du Colombier 			case STEXT:
518*219b2ee8SDavid du Colombier 			case SCONST:
519*219b2ee8SDavid du Colombier 				break;
520*219b2ee8SDavid du Colombier 			default:
5213e12c5d1SDavid du Colombier 				v += INITDAT;
5223e12c5d1SDavid du Colombier 			}
5233e12c5d1SDavid du Colombier 		}
524*219b2ee8SDavid du Colombier 	}
5253e12c5d1SDavid du Colombier 	return v;
5263e12c5d1SDavid du Colombier }
5273e12c5d1SDavid du Colombier 
5283e12c5d1SDavid du Colombier void
5293e12c5d1SDavid du Colombier asmand(Adr *a, int r)
5303e12c5d1SDavid du Colombier {
5313e12c5d1SDavid du Colombier 	long v;
5323e12c5d1SDavid du Colombier 	int t;
5333e12c5d1SDavid du Colombier 	Adr aa;
5343e12c5d1SDavid du Colombier 
5353e12c5d1SDavid du Colombier 	v = a->offset;
5363e12c5d1SDavid du Colombier 	t = a->type;
5373e12c5d1SDavid du Colombier 	if(a->index != D_NONE) {
5383e12c5d1SDavid du Colombier 		if(t >= D_INDIR) {
5393e12c5d1SDavid du Colombier 			t -= D_INDIR;
5403e12c5d1SDavid du Colombier 			if(t == D_NONE) {
5413e12c5d1SDavid du Colombier 				*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
5423e12c5d1SDavid du Colombier 				asmidx(a, t);
5433e12c5d1SDavid du Colombier 				andptr[0] = v;
5443e12c5d1SDavid du Colombier 				andptr[1] = v>>8;
5453e12c5d1SDavid du Colombier 				andptr[2] = v>>16;
5463e12c5d1SDavid du Colombier 				andptr[3] = v>>24;
5473e12c5d1SDavid du Colombier 				andptr += 4;
5483e12c5d1SDavid du Colombier 				return;
5493e12c5d1SDavid du Colombier 			}
5503e12c5d1SDavid du Colombier 			if(v == 0) {
5513e12c5d1SDavid du Colombier 				*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
5523e12c5d1SDavid du Colombier 				asmidx(a, t);
5533e12c5d1SDavid du Colombier 				return;
5543e12c5d1SDavid du Colombier 			}
5553e12c5d1SDavid du Colombier 			if(v >= -128 && v < 128) {
5563e12c5d1SDavid du Colombier 				*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
5573e12c5d1SDavid du Colombier 				asmidx(a, t);
5583e12c5d1SDavid du Colombier 				*andptr++ = v;
5593e12c5d1SDavid du Colombier 				return;
5603e12c5d1SDavid du Colombier 			}
5613e12c5d1SDavid du Colombier 			*andptr++ = (2 << 6) | (4 << 0) | (r << 3);
5623e12c5d1SDavid du Colombier 			asmidx(a, t);
5633e12c5d1SDavid du Colombier 			andptr[0] = v;
5643e12c5d1SDavid du Colombier 			andptr[1] = v>>8;
5653e12c5d1SDavid du Colombier 			andptr[2] = v>>16;
5663e12c5d1SDavid du Colombier 			andptr[3] = v>>24;
5673e12c5d1SDavid du Colombier 			andptr += 4;
5683e12c5d1SDavid du Colombier 			return;
5693e12c5d1SDavid du Colombier 		}
5703e12c5d1SDavid du Colombier 		switch(t) {
5713e12c5d1SDavid du Colombier 		default:
5723e12c5d1SDavid du Colombier 			goto bad;
5733e12c5d1SDavid du Colombier 		case D_STATIC:
5743e12c5d1SDavid du Colombier 		case D_EXTERN:
5753e12c5d1SDavid du Colombier 			aa.type = D_NONE+D_INDIR;
5763e12c5d1SDavid du Colombier 			break;
5773e12c5d1SDavid du Colombier 		case D_AUTO:
5783e12c5d1SDavid du Colombier 		case D_PARAM:
5793e12c5d1SDavid du Colombier 			aa.type = D_SP+D_INDIR;
5803e12c5d1SDavid du Colombier 			break;
5813e12c5d1SDavid du Colombier 		}
5823e12c5d1SDavid du Colombier 		aa.offset = vaddr(a);
5833e12c5d1SDavid du Colombier 		aa.index = a->index;
5843e12c5d1SDavid du Colombier 		aa.scale = a->scale;
5853e12c5d1SDavid du Colombier 		asmand(&aa, r);
5863e12c5d1SDavid du Colombier 		return;
5873e12c5d1SDavid du Colombier 	}
5883e12c5d1SDavid du Colombier 	if(t >= D_AL && t <= D_F0+7) {
5893e12c5d1SDavid du Colombier 		if(v)
5903e12c5d1SDavid du Colombier 			goto bad;
5913e12c5d1SDavid du Colombier 		*andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
5923e12c5d1SDavid du Colombier 		return;
5933e12c5d1SDavid du Colombier 	}
5943e12c5d1SDavid du Colombier 	if(t >= D_INDIR) {
5953e12c5d1SDavid du Colombier 		t -= D_INDIR;
5963e12c5d1SDavid du Colombier 		if(t == D_NONE) {
5973e12c5d1SDavid du Colombier 			andptr[0] = (0 << 6) | (5 << 0) | (r << 3);
5983e12c5d1SDavid du Colombier 			andptr[1] = v;
5993e12c5d1SDavid du Colombier 			andptr[2] = v>>8;
6003e12c5d1SDavid du Colombier 			andptr[3] = v>>16;
6013e12c5d1SDavid du Colombier 			andptr[4] = v>>24;
6023e12c5d1SDavid du Colombier 			andptr += 5;
6033e12c5d1SDavid du Colombier 			return;
6043e12c5d1SDavid du Colombier 		}
6053e12c5d1SDavid du Colombier 		if(t == D_SP) {
6063e12c5d1SDavid du Colombier 			if(v == 0) {
6073e12c5d1SDavid du Colombier 				*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
6083e12c5d1SDavid du Colombier 				asmidx(a, D_SP);
6093e12c5d1SDavid du Colombier 				return;
6103e12c5d1SDavid du Colombier 			}
6113e12c5d1SDavid du Colombier 			if(v >= -128 && v < 128) {
6123e12c5d1SDavid du Colombier 				*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
6133e12c5d1SDavid du Colombier 				asmidx(a, D_SP);
6143e12c5d1SDavid du Colombier 				*andptr++ = v;
6153e12c5d1SDavid du Colombier 				return;
6163e12c5d1SDavid du Colombier 			}
6173e12c5d1SDavid du Colombier 			*andptr++ = (2 << 6) | (4 << 0) | (r << 3);
6183e12c5d1SDavid du Colombier 			asmidx(a, D_SP);
6193e12c5d1SDavid du Colombier 			andptr[0] = v;
6203e12c5d1SDavid du Colombier 			andptr[1] = v>>8;
6213e12c5d1SDavid du Colombier 			andptr[2] = v>>16;
6223e12c5d1SDavid du Colombier 			andptr[3] = v>>24;
6233e12c5d1SDavid du Colombier 			andptr += 4;
6243e12c5d1SDavid du Colombier 			return;
6253e12c5d1SDavid du Colombier 		}
6263e12c5d1SDavid du Colombier 		if(t >= D_AX && t <= D_DI) {
6273e12c5d1SDavid du Colombier 			if(v == 0 && t != D_BP) {
6283e12c5d1SDavid du Colombier 				*andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
6293e12c5d1SDavid du Colombier 				return;
6303e12c5d1SDavid du Colombier 			}
6313e12c5d1SDavid du Colombier 			if(v >= -128 && v < 128) {
6323e12c5d1SDavid du Colombier 				andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
6333e12c5d1SDavid du Colombier 				andptr[1] = v;
6343e12c5d1SDavid du Colombier 				andptr += 2;
6353e12c5d1SDavid du Colombier 				return;
6363e12c5d1SDavid du Colombier 			}
6373e12c5d1SDavid du Colombier 			andptr[0] = (2 << 6) | (reg[t] << 0) | (r << 3);
6383e12c5d1SDavid du Colombier 			andptr[1] = v;
6393e12c5d1SDavid du Colombier 			andptr[2] = v>>8;
6403e12c5d1SDavid du Colombier 			andptr[3] = v>>16;
6413e12c5d1SDavid du Colombier 			andptr[4] = v>>24;
6423e12c5d1SDavid du Colombier 			andptr += 5;
6433e12c5d1SDavid du Colombier 			return;
6443e12c5d1SDavid du Colombier 		}
6453e12c5d1SDavid du Colombier 		goto bad;
6463e12c5d1SDavid du Colombier 	}
6473e12c5d1SDavid du Colombier 	switch(a->type) {
6483e12c5d1SDavid du Colombier 	default:
6493e12c5d1SDavid du Colombier 		goto bad;
6503e12c5d1SDavid du Colombier 	case D_STATIC:
6513e12c5d1SDavid du Colombier 	case D_EXTERN:
6523e12c5d1SDavid du Colombier 		aa.type = D_NONE+D_INDIR;
6533e12c5d1SDavid du Colombier 		break;
6543e12c5d1SDavid du Colombier 	case D_AUTO:
6553e12c5d1SDavid du Colombier 	case D_PARAM:
6563e12c5d1SDavid du Colombier 		aa.type = D_SP+D_INDIR;
6573e12c5d1SDavid du Colombier 		break;
6583e12c5d1SDavid du Colombier 	}
6593e12c5d1SDavid du Colombier 	aa.index = D_NONE;
6603e12c5d1SDavid du Colombier 	aa.scale = 1;
6613e12c5d1SDavid du Colombier 	aa.offset = vaddr(a);
6623e12c5d1SDavid du Colombier 	asmand(&aa, r);
6633e12c5d1SDavid du Colombier 	return;
6643e12c5d1SDavid du Colombier bad:
6653e12c5d1SDavid du Colombier 	diag("asmand: bad address %D\n", a);
6663e12c5d1SDavid du Colombier 	return;
6673e12c5d1SDavid du Colombier }
6683e12c5d1SDavid du Colombier 
6693e12c5d1SDavid du Colombier #define	E	0xff
6703e12c5d1SDavid du Colombier uchar	ymovtab[] =
6713e12c5d1SDavid du Colombier {
6723e12c5d1SDavid du Colombier /* push */
6733e12c5d1SDavid du Colombier 	APUSHL,	Ycs,	Ynone,	0,	0x0e,E,0,0,
6743e12c5d1SDavid du Colombier 	APUSHL,	Yss,	Ynone,	0,	0x16,E,0,0,
6753e12c5d1SDavid du Colombier 	APUSHL,	Yds,	Ynone,	0,	0x1e,E,0,0,
6763e12c5d1SDavid du Colombier 	APUSHL,	Yes,	Ynone,	0,	0x06,E,0,0,
6773e12c5d1SDavid du Colombier 	APUSHL,	Yfs,	Ynone,	0,	0x0f,0xa0,E,0,
6783e12c5d1SDavid du Colombier 	APUSHL,	Ygs,	Ynone,	0,	0x0f,0xa8,E,0,
6793e12c5d1SDavid du Colombier 
6803e12c5d1SDavid du Colombier 	APUSHW,	Ycs,	Ynone,	0,	Pe,0x0e,E,0,
6813e12c5d1SDavid du Colombier 	APUSHW,	Yss,	Ynone,	0,	Pe,0x16,E,0,
6823e12c5d1SDavid du Colombier 	APUSHW,	Yds,	Ynone,	0,	Pe,0x1e,E,0,
6833e12c5d1SDavid du Colombier 	APUSHW,	Yes,	Ynone,	0,	Pe,0x06,E,0,
6843e12c5d1SDavid du Colombier 	APUSHW,	Yfs,	Ynone,	0,	Pe,0x0f,0xa0,E,
6853e12c5d1SDavid du Colombier 	APUSHW,	Ygs,	Ynone,	0,	Pe,0x0f,0xa8,E,
6863e12c5d1SDavid du Colombier 
6873e12c5d1SDavid du Colombier /* pop */
6883e12c5d1SDavid du Colombier 	APOPL,	Ynone,	Yds,	0,	0x1f,E,0,0,
6893e12c5d1SDavid du Colombier 	APOPL,	Ynone,	Yes,	0,	0x07,E,0,0,
6903e12c5d1SDavid du Colombier 	APOPL,	Ynone,	Yss,	0,	0x17,E,0,0,
6913e12c5d1SDavid du Colombier 	APOPL,	Ynone,	Yfs,	0,	0x0f,0xa1,E,0,
6923e12c5d1SDavid du Colombier 	APOPL,	Ynone,	Ygs,	0,	0x0f,0xa9,E,0,
6933e12c5d1SDavid du Colombier 
6943e12c5d1SDavid du Colombier 	APOPW,	Ynone,	Yds,	0,	Pe,0x1f,E,0,
6953e12c5d1SDavid du Colombier 	APOPW,	Ynone,	Yes,	0,	Pe,0x07,E,0,
6963e12c5d1SDavid du Colombier 	APOPW,	Ynone,	Yss,	0,	Pe,0x17,E,0,
6973e12c5d1SDavid du Colombier 	APOPW,	Ynone,	Yfs,	0,	Pe,0x0f,0xa1,E,
6983e12c5d1SDavid du Colombier 	APOPW,	Ynone,	Ygs,	0,	Pe,0x0f,0xa9,E,
6993e12c5d1SDavid du Colombier 
7003e12c5d1SDavid du Colombier /* mov seg */
7013e12c5d1SDavid du Colombier 	AMOVW,	Yes,	Yml,	1,	0x8c,0,0,0,
7023e12c5d1SDavid du Colombier 	AMOVW,	Ycs,	Yml,	1,	0x8c,1,0,0,
7033e12c5d1SDavid du Colombier 	AMOVW,	Yss,	Yml,	1,	0x8c,2,0,0,
7043e12c5d1SDavid du Colombier 	AMOVW,	Yds,	Yml,	1,	0x8c,3,0,0,
7053e12c5d1SDavid du Colombier 	AMOVW,	Yfs,	Yml,	1,	0x8c,4,0,0,
7063e12c5d1SDavid du Colombier 	AMOVW,	Ygs,	Yml,	1,	0x8c,5,0,0,
7073e12c5d1SDavid du Colombier 
7083e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Yes,	2,	0x8e,0,0,0,
7093e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Ycs,	2,	0x8e,1,0,0,
7103e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Yss,	2,	0x8e,2,0,0,
7113e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Yds,	2,	0x8e,3,0,0,
7123e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Yfs,	2,	0x8e,4,0,0,
7133e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Ygs,	2,	0x8e,5,0,0,
7143e12c5d1SDavid du Colombier 
7153e12c5d1SDavid du Colombier /* mov cr */
7163e12c5d1SDavid du Colombier 	AMOVL,	Ycr0,	Yml,	3,	0x0f,0x20,0,0,
7173e12c5d1SDavid du Colombier 	AMOVL,	Ycr2,	Yml,	3,	0x0f,0x20,2,0,
7183e12c5d1SDavid du Colombier 	AMOVL,	Ycr3,	Yml,	3,	0x0f,0x20,3,0,
7193e12c5d1SDavid du Colombier 
7203e12c5d1SDavid du Colombier 	AMOVL,	Yml,	Ycr0,	4,	0x0f,0x22,0,0,
7213e12c5d1SDavid du Colombier 	AMOVL,	Yml,	Ycr2,	4,	0x0f,0x22,2,0,
7223e12c5d1SDavid du Colombier 	AMOVL,	Yml,	Ycr3,	4,	0x0f,0x22,3,0,
7233e12c5d1SDavid du Colombier 
7243e12c5d1SDavid du Colombier /* mov dr */
7253e12c5d1SDavid du Colombier 	AMOVL,	Ydr0,	Yml,	3,	0x0f,0x21,0,0,
7263e12c5d1SDavid du Colombier 	AMOVL,	Ydr6,	Yml,	3,	0x0f,0x21,6,0,
7273e12c5d1SDavid du Colombier 	AMOVL,	Ydr7,	Yml,	3,	0x0f,0x21,7,0,
7283e12c5d1SDavid du Colombier 
7293e12c5d1SDavid du Colombier 	AMOVL,	Yml,	Ydr0,	4,	0x0f,0x23,0,0,
7303e12c5d1SDavid du Colombier 	AMOVL,	Yml,	Ydr6,	4,	0x0f,0x23,6,0,
7313e12c5d1SDavid du Colombier 	AMOVL,	Yml,	Ydr7,	4,	0x0f,0x23,7,0,
7323e12c5d1SDavid du Colombier 
7333e12c5d1SDavid du Colombier /* mov tr */
7343e12c5d1SDavid du Colombier 	AMOVL,	Ytr6,	Yml,	3,	0x0f,0x24,6,0,
7353e12c5d1SDavid du Colombier 	AMOVL,	Ytr7,	Yml,	3,	0x0f,0x24,7,0,
7363e12c5d1SDavid du Colombier 
7373e12c5d1SDavid du Colombier 	AMOVL,	Yml,	Ytr6,	4,	0x0f,0x26,6,E,
7383e12c5d1SDavid du Colombier 	AMOVL,	Yml,	Ytr7,	4,	0x0f,0x26,7,E,
7393e12c5d1SDavid du Colombier 
7403e12c5d1SDavid du Colombier /* lgdt, sgdt, lidt, sidt */
7413e12c5d1SDavid du Colombier 	AMOVL,	Ym,	Ygdtr,	4,	0x0f,0x01,2,0,
7423e12c5d1SDavid du Colombier 	AMOVL,	Ygdtr,	Ym,	3,	0x0f,0x01,0,0,
7433e12c5d1SDavid du Colombier 	AMOVL,	Ym,	Yidtr,	4,	0x0f,0x01,3,0,
7443e12c5d1SDavid du Colombier 	AMOVL,	Yidtr,	Ym,	3,	0x0f,0x01,1,0,
7453e12c5d1SDavid du Colombier 
7463e12c5d1SDavid du Colombier /* lldt, sldt */
7473e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Yldtr,	4,	0x0f,0x00,2,0,
7483e12c5d1SDavid du Colombier 	AMOVW,	Yldtr,	Yml,	3,	0x0f,0x00,0,0,
7493e12c5d1SDavid du Colombier 
7503e12c5d1SDavid du Colombier /* lmsw, smsw */
7513e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Ymsw,	4,	0x0f,0x01,6,0,
7523e12c5d1SDavid du Colombier 	AMOVW,	Ymsw,	Yml,	3,	0x0f,0x01,4,0,
7533e12c5d1SDavid du Colombier 
7543e12c5d1SDavid du Colombier /* ltr, str */
7553e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Ytask,	4,	0x0f,0x00,3,0,
7563e12c5d1SDavid du Colombier 	AMOVW,	Ytask,	Yml,	3,	0x0f,0x00,1,0,
7573e12c5d1SDavid du Colombier 
7583e12c5d1SDavid du Colombier /* load full pointer */
7593e12c5d1SDavid du Colombier 	AMOVL,	Yml,	Ycol,	5,	0,0,0,0,
7603e12c5d1SDavid du Colombier 	AMOVW,	Yml,	Ycol,	5,	Pe,0,0,0,
7613e12c5d1SDavid du Colombier 
7623e12c5d1SDavid du Colombier /* double shift */
7633e12c5d1SDavid du Colombier 	ASHLL,	Ycol,	Yml,	6,	0xa4,0xa5,0,0,
7643e12c5d1SDavid du Colombier 	ASHRL,	Ycol,	Yml,	6,	0xac,0xad,0,0,
7653e12c5d1SDavid du Colombier 
7663e12c5d1SDavid du Colombier 	0
7673e12c5d1SDavid du Colombier };
7683e12c5d1SDavid du Colombier 
7693e12c5d1SDavid du Colombier int
7703e12c5d1SDavid du Colombier isax(Adr *a)
7713e12c5d1SDavid du Colombier {
7723e12c5d1SDavid du Colombier 
7733e12c5d1SDavid du Colombier 	switch(a->type) {
7743e12c5d1SDavid du Colombier 	case D_AX:
7753e12c5d1SDavid du Colombier 	case D_AL:
7763e12c5d1SDavid du Colombier 	case D_AH:
7773e12c5d1SDavid du Colombier 	case D_INDIR+D_AX:
7783e12c5d1SDavid du Colombier 		return 1;
7793e12c5d1SDavid du Colombier 	}
7803e12c5d1SDavid du Colombier 	if(a->index == D_AX)
7813e12c5d1SDavid du Colombier 		return 1;
7823e12c5d1SDavid du Colombier 	return 0;
7833e12c5d1SDavid du Colombier }
7843e12c5d1SDavid du Colombier 
7853e12c5d1SDavid du Colombier void
7863e12c5d1SDavid du Colombier subreg(Prog *p, int from, int to)
7873e12c5d1SDavid du Colombier {
7883e12c5d1SDavid du Colombier 
7893e12c5d1SDavid du Colombier 	if(debug['Q'])
7903e12c5d1SDavid du Colombier 		print("\n%P	s/%R/%R/\n", p, from, to);
7913e12c5d1SDavid du Colombier 
7923e12c5d1SDavid du Colombier 	if(p->from.type == from)
7933e12c5d1SDavid du Colombier 		p->from.type = to;
7943e12c5d1SDavid du Colombier 	if(p->to.type == from)
7953e12c5d1SDavid du Colombier 		p->to.type = to;
7963e12c5d1SDavid du Colombier 
7973e12c5d1SDavid du Colombier 	if(p->from.index == from)
7983e12c5d1SDavid du Colombier 		p->from.index = to;
7993e12c5d1SDavid du Colombier 	if(p->to.index == from)
8003e12c5d1SDavid du Colombier 		p->to.index = to;
8013e12c5d1SDavid du Colombier 
8023e12c5d1SDavid du Colombier 	from += D_INDIR;
8033e12c5d1SDavid du Colombier 	if(p->from.type == from)
8043e12c5d1SDavid du Colombier 		p->from.type = to+D_INDIR;
8053e12c5d1SDavid du Colombier 	if(p->to.type == from)
8063e12c5d1SDavid du Colombier 		p->to.type = to+D_INDIR;
8073e12c5d1SDavid du Colombier 
8083e12c5d1SDavid du Colombier 	if(debug['Q'])
8093e12c5d1SDavid du Colombier 		print("%P\n", p);
8103e12c5d1SDavid du Colombier }
8113e12c5d1SDavid du Colombier 
8123e12c5d1SDavid du Colombier void
8133e12c5d1SDavid du Colombier doasm(Prog *p)
8143e12c5d1SDavid du Colombier {
8153e12c5d1SDavid du Colombier 	Optab *o;
8163e12c5d1SDavid du Colombier 	Prog *q, pp;
8173e12c5d1SDavid du Colombier 	uchar *t;
8183e12c5d1SDavid du Colombier 	int z, op, ft, tt;
8193e12c5d1SDavid du Colombier 	long v;
8203e12c5d1SDavid du Colombier 
8213e12c5d1SDavid du Colombier 	o = &optab[p->as];
8223e12c5d1SDavid du Colombier 	ft = oclass(&p->from) * Ymax;
8233e12c5d1SDavid du Colombier 	tt = oclass(&p->to) * Ymax;
8243e12c5d1SDavid du Colombier 	t = o->ytab;
8253e12c5d1SDavid du Colombier 	if(t == 0) {
8263e12c5d1SDavid du Colombier 		diag("asmins: noproto %P\n", p);
8273e12c5d1SDavid du Colombier 		return;
8283e12c5d1SDavid du Colombier 	}
8293e12c5d1SDavid du Colombier 	for(z=0; *t; z+=t[3],t+=4)
8303e12c5d1SDavid du Colombier 		if(ycover[ft+t[0]])
8313e12c5d1SDavid du Colombier 		if(ycover[tt+t[1]])
8323e12c5d1SDavid du Colombier 			goto found;
8333e12c5d1SDavid du Colombier 	goto domov;
8343e12c5d1SDavid du Colombier 
8353e12c5d1SDavid du Colombier found:
8363e12c5d1SDavid du Colombier 	switch(o->prefix) {
8373e12c5d1SDavid du Colombier 	case Pq:	/* 16 bit escape and opcode escape */
8383e12c5d1SDavid du Colombier 		*andptr++ = Pe;
8393e12c5d1SDavid du Colombier 		*andptr++ = Pm;
8403e12c5d1SDavid du Colombier 		break;
8413e12c5d1SDavid du Colombier 
8423e12c5d1SDavid du Colombier 	case Pm:	/* opcode escape */
8433e12c5d1SDavid du Colombier 		*andptr++ = Pm;
8443e12c5d1SDavid du Colombier 		break;
8453e12c5d1SDavid du Colombier 
8463e12c5d1SDavid du Colombier 	case Pe:	/* 16 bit escape */
8473e12c5d1SDavid du Colombier 		*andptr++ = Pe;
8483e12c5d1SDavid du Colombier 		break;
8493e12c5d1SDavid du Colombier 
8503e12c5d1SDavid du Colombier 	case Pb:	/* botch */
8513e12c5d1SDavid du Colombier 		break;
8523e12c5d1SDavid du Colombier 	}
8533e12c5d1SDavid du Colombier 	v = vaddr(&p->from);
8543e12c5d1SDavid du Colombier 	op = o->op[z];
8553e12c5d1SDavid du Colombier 	switch(t[2]) {
8563e12c5d1SDavid du Colombier 	default:
8573e12c5d1SDavid du Colombier 		diag("asmins: unknown z %d %P\n", t[2], p);
8583e12c5d1SDavid du Colombier 		return;
8593e12c5d1SDavid du Colombier 
8603e12c5d1SDavid du Colombier 	case Zpseudo:
8613e12c5d1SDavid du Colombier 		break;
8623e12c5d1SDavid du Colombier 
8633e12c5d1SDavid du Colombier 	case Zlit:
8643e12c5d1SDavid du Colombier 		for(; op = o->op[z]; z++)
8653e12c5d1SDavid du Colombier 			*andptr++ = op;
8663e12c5d1SDavid du Colombier 		break;
8673e12c5d1SDavid du Colombier 
8683e12c5d1SDavid du Colombier 	case Zm_r:
8693e12c5d1SDavid du Colombier 		*andptr++ = op;
8703e12c5d1SDavid du Colombier 		asmand(&p->from, reg[p->to.type]);
8713e12c5d1SDavid du Colombier 		break;
8723e12c5d1SDavid du Colombier 
873*219b2ee8SDavid du Colombier 	case Zaut_r:
874*219b2ee8SDavid du Colombier 		*andptr++ = 0x8d;	/* leal */
875*219b2ee8SDavid du Colombier 		if(p->from.type != D_ADDR)
876*219b2ee8SDavid du Colombier 			diag("asmins: Zaut sb type ADDR");
877*219b2ee8SDavid du Colombier 		p->from.type = p->from.index;
878*219b2ee8SDavid du Colombier 		p->from.index = D_NONE;
879*219b2ee8SDavid du Colombier 		asmand(&p->from, reg[p->to.type]);
880*219b2ee8SDavid du Colombier 		p->from.index = p->from.type;
881*219b2ee8SDavid du Colombier 		p->from.type = D_ADDR;
882*219b2ee8SDavid du Colombier 		break;
883*219b2ee8SDavid du Colombier 
8843e12c5d1SDavid du Colombier 	case Zm_o:
8853e12c5d1SDavid du Colombier 		*andptr++ = op;
8863e12c5d1SDavid du Colombier 		asmand(&p->from, o->op[z+1]);
8873e12c5d1SDavid du Colombier 		break;
8883e12c5d1SDavid du Colombier 
8893e12c5d1SDavid du Colombier 	case Zr_m:
8903e12c5d1SDavid du Colombier 		*andptr++ = op;
8913e12c5d1SDavid du Colombier 		asmand(&p->to, reg[p->from.type]);
8923e12c5d1SDavid du Colombier 		break;
8933e12c5d1SDavid du Colombier 
8943e12c5d1SDavid du Colombier 	case Zo_m:
8953e12c5d1SDavid du Colombier 		*andptr++ = op;
8963e12c5d1SDavid du Colombier 		asmand(&p->to, o->op[z+1]);
8973e12c5d1SDavid du Colombier 		break;
8983e12c5d1SDavid du Colombier 
8993e12c5d1SDavid du Colombier 	case Zm_ibo:
9003e12c5d1SDavid du Colombier 		v = vaddr(&p->to);
9013e12c5d1SDavid du Colombier 		*andptr++ = op;
9023e12c5d1SDavid du Colombier 		asmand(&p->from, o->op[z+1]);
9033e12c5d1SDavid du Colombier 		*andptr++ = v;
9043e12c5d1SDavid du Colombier 		break;
9053e12c5d1SDavid du Colombier 
9063e12c5d1SDavid du Colombier 	case Zibo_m:
9073e12c5d1SDavid du Colombier 		*andptr++ = op;
9083e12c5d1SDavid du Colombier 		asmand(&p->to, o->op[z+1]);
9093e12c5d1SDavid du Colombier 		*andptr++ = v;
9103e12c5d1SDavid du Colombier 		break;
9113e12c5d1SDavid du Colombier 
9123e12c5d1SDavid du Colombier 	case Z_ib:
9133e12c5d1SDavid du Colombier 		v = vaddr(&p->to);
9143e12c5d1SDavid du Colombier 	case Zib_:
9153e12c5d1SDavid du Colombier 		*andptr++ = op;
9163e12c5d1SDavid du Colombier 		*andptr++ = v;
9173e12c5d1SDavid du Colombier 		break;
9183e12c5d1SDavid du Colombier 
9193e12c5d1SDavid du Colombier 	case Zib_rp:
9203e12c5d1SDavid du Colombier 		*andptr++ = op + reg[p->to.type];
9213e12c5d1SDavid du Colombier 		*andptr++ = v;
9223e12c5d1SDavid du Colombier 		break;
9233e12c5d1SDavid du Colombier 
9243e12c5d1SDavid du Colombier 	case Zil_rp:
9253e12c5d1SDavid du Colombier 		*andptr++ = op + reg[p->to.type];
9263e12c5d1SDavid du Colombier 		*andptr++ = v;
9273e12c5d1SDavid du Colombier 		*andptr++ = v>>8;
9283e12c5d1SDavid du Colombier 		if(o->prefix != Pe) {
9293e12c5d1SDavid du Colombier 			*andptr++ = v>>16;
9303e12c5d1SDavid du Colombier 			*andptr++ = v>>24;
9313e12c5d1SDavid du Colombier 		}
9323e12c5d1SDavid du Colombier 		break;
9333e12c5d1SDavid du Colombier 
9343e12c5d1SDavid du Colombier 	case Z_il:
9353e12c5d1SDavid du Colombier 		v = vaddr(&p->to);
9363e12c5d1SDavid du Colombier 	case Zil_:
9373e12c5d1SDavid du Colombier 		*andptr++ = op;
9383e12c5d1SDavid du Colombier 		*andptr++ = v;
9393e12c5d1SDavid du Colombier 		*andptr++ = v>>8;
9403e12c5d1SDavid du Colombier 		if(o->prefix != Pe) {
9413e12c5d1SDavid du Colombier 			*andptr++ = v>>16;
9423e12c5d1SDavid du Colombier 			*andptr++ = v>>24;
9433e12c5d1SDavid du Colombier 		}
9443e12c5d1SDavid du Colombier 		break;
9453e12c5d1SDavid du Colombier 
9463e12c5d1SDavid du Colombier 	case Zm_ilo:
9473e12c5d1SDavid du Colombier 		v = vaddr(&p->to);
9483e12c5d1SDavid du Colombier 		*andptr++ = op;
9493e12c5d1SDavid du Colombier 		asmand(&p->from, o->op[z+1]);
9503e12c5d1SDavid du Colombier 		*andptr++ = v;
9513e12c5d1SDavid du Colombier 		*andptr++ = v>>8;
9523e12c5d1SDavid du Colombier 		if(o->prefix != Pe) {
9533e12c5d1SDavid du Colombier 			*andptr++ = v>>16;
9543e12c5d1SDavid du Colombier 			*andptr++ = v>>24;
9553e12c5d1SDavid du Colombier 		}
9563e12c5d1SDavid du Colombier 		break;
9573e12c5d1SDavid du Colombier 
9583e12c5d1SDavid du Colombier 	case Zilo_m:
9593e12c5d1SDavid du Colombier 		*andptr++ = op;
9603e12c5d1SDavid du Colombier 		asmand(&p->to, o->op[z+1]);
9613e12c5d1SDavid du Colombier 		*andptr++ = v;
9623e12c5d1SDavid du Colombier 		*andptr++ = v>>8;
9633e12c5d1SDavid du Colombier 		if(o->prefix != Pe) {
9643e12c5d1SDavid du Colombier 			*andptr++ = v>>16;
9653e12c5d1SDavid du Colombier 			*andptr++ = v>>24;
9663e12c5d1SDavid du Colombier 		}
9673e12c5d1SDavid du Colombier 		break;
9683e12c5d1SDavid du Colombier 
9693e12c5d1SDavid du Colombier 	case Z_rp:
9703e12c5d1SDavid du Colombier 		*andptr++ = op + reg[p->to.type];
9713e12c5d1SDavid du Colombier 		break;
9723e12c5d1SDavid du Colombier 
9733e12c5d1SDavid du Colombier 	case Zrp_:
9743e12c5d1SDavid du Colombier 		*andptr++ = op + reg[p->from.type];
9753e12c5d1SDavid du Colombier 		break;
9763e12c5d1SDavid du Colombier 
9773e12c5d1SDavid du Colombier 	case Zclr:
9783e12c5d1SDavid du Colombier 		*andptr++ = op;
9793e12c5d1SDavid du Colombier 		asmand(&p->to, reg[p->to.type]);
9803e12c5d1SDavid du Colombier 		break;
9813e12c5d1SDavid du Colombier 
9823e12c5d1SDavid du Colombier 	case Zbr:
9833e12c5d1SDavid du Colombier 		q = p->cond;
9843e12c5d1SDavid du Colombier 		if(q) {
9853e12c5d1SDavid du Colombier 			v = q->pc - p->pc - 2;
9863e12c5d1SDavid du Colombier 			if(v >= -128 && v <= 127) {
9873e12c5d1SDavid du Colombier 				*andptr++ = op;
9883e12c5d1SDavid du Colombier 				*andptr++ = v;
9893e12c5d1SDavid du Colombier 			} else {
9903e12c5d1SDavid du Colombier 				v -= 6-2;
9913e12c5d1SDavid du Colombier 				*andptr++ = 0x0f;
9923e12c5d1SDavid du Colombier 				*andptr++ = o->op[z+1];
9933e12c5d1SDavid du Colombier 				*andptr++ = v;
9943e12c5d1SDavid du Colombier 				*andptr++ = v>>8;
9953e12c5d1SDavid du Colombier 				*andptr++ = v>>16;
9963e12c5d1SDavid du Colombier 				*andptr++ = v>>24;
9973e12c5d1SDavid du Colombier 			}
9983e12c5d1SDavid du Colombier 		}
9993e12c5d1SDavid du Colombier 		break;
10003e12c5d1SDavid du Colombier 
10013e12c5d1SDavid du Colombier 	case Zcall:
10023e12c5d1SDavid du Colombier 		q = p->cond;
10033e12c5d1SDavid du Colombier 		if(q) {
10043e12c5d1SDavid du Colombier 			v = q->pc - p->pc - 5;
10053e12c5d1SDavid du Colombier 			*andptr++ = op;
10063e12c5d1SDavid du Colombier 			*andptr++ = v;
10073e12c5d1SDavid du Colombier 			*andptr++ = v>>8;
10083e12c5d1SDavid du Colombier 			*andptr++ = v>>16;
10093e12c5d1SDavid du Colombier 			*andptr++ = v>>24;
10103e12c5d1SDavid du Colombier 		}
10113e12c5d1SDavid du Colombier 		break;
10123e12c5d1SDavid du Colombier 
10133e12c5d1SDavid du Colombier 	case Zjmp:
10143e12c5d1SDavid du Colombier 		q = p->cond;
10153e12c5d1SDavid du Colombier 		if(q) {
10163e12c5d1SDavid du Colombier 			v = q->pc - p->pc - 2;
10173e12c5d1SDavid du Colombier 			if(v >= -128 && v <= 127) {
10183e12c5d1SDavid du Colombier 				*andptr++ = op;
10193e12c5d1SDavid du Colombier 				*andptr++ = v;
10203e12c5d1SDavid du Colombier 			} else {
10213e12c5d1SDavid du Colombier 				v -= 5-2;
10223e12c5d1SDavid du Colombier 				*andptr++ = o->op[z+1];
10233e12c5d1SDavid du Colombier 				*andptr++ = v;
10243e12c5d1SDavid du Colombier 				*andptr++ = v>>8;
10253e12c5d1SDavid du Colombier 				*andptr++ = v>>16;
10263e12c5d1SDavid du Colombier 				*andptr++ = v>>24;
10273e12c5d1SDavid du Colombier 			}
10283e12c5d1SDavid du Colombier 		}
10293e12c5d1SDavid du Colombier 		break;
10303e12c5d1SDavid du Colombier 
10313e12c5d1SDavid du Colombier 	case Zloop:
10323e12c5d1SDavid du Colombier 		q = p->cond;
10333e12c5d1SDavid du Colombier 		if(q) {
10343e12c5d1SDavid du Colombier 			v = q->pc - p->pc - 2;
10353e12c5d1SDavid du Colombier 			if(v < -128 && v > 127)
10363e12c5d1SDavid du Colombier 				diag("loop too far: %P\n", p);
10373e12c5d1SDavid du Colombier 			*andptr++ = op;
10383e12c5d1SDavid du Colombier 			*andptr++ = v;
10393e12c5d1SDavid du Colombier 		}
10403e12c5d1SDavid du Colombier 		break;
10413e12c5d1SDavid du Colombier 
10423e12c5d1SDavid du Colombier 	case Zbyte:
10433e12c5d1SDavid du Colombier 		*andptr++ = v;
10443e12c5d1SDavid du Colombier 		if(op > 1) {
10453e12c5d1SDavid du Colombier 			*andptr++ = v>>8;
10463e12c5d1SDavid du Colombier 			if(op > 2) {
10473e12c5d1SDavid du Colombier 				*andptr++ = v>>16;
10483e12c5d1SDavid du Colombier 				*andptr++ = v>>24;
10493e12c5d1SDavid du Colombier 			}
10503e12c5d1SDavid du Colombier 		}
10513e12c5d1SDavid du Colombier 		break;
10523e12c5d1SDavid du Colombier 
10533e12c5d1SDavid du Colombier 	case Zmov:
10543e12c5d1SDavid du Colombier 		goto domov;
10553e12c5d1SDavid du Colombier 	}
10563e12c5d1SDavid du Colombier 	return;
10573e12c5d1SDavid du Colombier 
10583e12c5d1SDavid du Colombier domov:
10593e12c5d1SDavid du Colombier 	for(t=ymovtab; *t; t+=8)
10603e12c5d1SDavid du Colombier 		if(p->as == t[0])
10613e12c5d1SDavid du Colombier 		if(ycover[ft+t[1]])
10623e12c5d1SDavid du Colombier 		if(ycover[tt+t[2]])
10633e12c5d1SDavid du Colombier 			goto mfound;
10643e12c5d1SDavid du Colombier bad:
10653e12c5d1SDavid du Colombier 	/*
10663e12c5d1SDavid du Colombier 	 * here, the assembly has failed.
10673e12c5d1SDavid du Colombier 	 * if its a byte instruction that has
10683e12c5d1SDavid du Colombier 	 * unaddressable registers, try to
10693e12c5d1SDavid du Colombier 	 * exchange registers and reissue the
10703e12c5d1SDavid du Colombier 	 * instruction with the operands renamed.
10713e12c5d1SDavid du Colombier 	 */
10723e12c5d1SDavid du Colombier 	pp = *p;
10733e12c5d1SDavid du Colombier 	z = p->from.type;
10743e12c5d1SDavid du Colombier 	if(z >= D_BP && z <= D_DI) {
10753e12c5d1SDavid du Colombier 		if(isax(&p->to)) {
10763e12c5d1SDavid du Colombier 			*andptr++ = 0x87;			/* xchg lhs,bx */
10773e12c5d1SDavid du Colombier 			asmand(&p->from, reg[D_BX]);
10783e12c5d1SDavid du Colombier 			subreg(&pp, z, D_BX);
10793e12c5d1SDavid du Colombier 			doasm(&pp);
10803e12c5d1SDavid du Colombier 			*andptr++ = 0x87;			/* xchg lhs,bx */
10813e12c5d1SDavid du Colombier 			asmand(&p->from, reg[D_BX]);
10823e12c5d1SDavid du Colombier 		} else {
10833e12c5d1SDavid du Colombier 			*andptr++ = 0x90 + reg[z];		/* xchg lsh,ax */
10843e12c5d1SDavid du Colombier 			subreg(&pp, z, D_AX);
10853e12c5d1SDavid du Colombier 			doasm(&pp);
10863e12c5d1SDavid du Colombier 			*andptr++ = 0x90 + reg[z];		/* xchg lsh,ax */
10873e12c5d1SDavid du Colombier 		}
10883e12c5d1SDavid du Colombier 		return;
10893e12c5d1SDavid du Colombier 	}
10903e12c5d1SDavid du Colombier 	z = p->to.type;
10913e12c5d1SDavid du Colombier 	if(z >= D_BP && z <= D_DI) {
10923e12c5d1SDavid du Colombier 		if(isax(&p->from)) {
10933e12c5d1SDavid du Colombier 			*andptr++ = 0x87;			/* xchg rhs,bx */
10943e12c5d1SDavid du Colombier 			asmand(&p->to, reg[D_BX]);
10953e12c5d1SDavid du Colombier 			subreg(&pp, z, D_BX);
10963e12c5d1SDavid du Colombier 			doasm(&pp);
10973e12c5d1SDavid du Colombier 			*andptr++ = 0x87;			/* xchg rhs,bx */
10983e12c5d1SDavid du Colombier 			asmand(&p->to, reg[D_BX]);
10993e12c5d1SDavid du Colombier 		} else {
11003e12c5d1SDavid du Colombier 			*andptr++ = 0x90 + reg[z];		/* xchg rsh,ax */
11013e12c5d1SDavid du Colombier 			subreg(&pp, z, D_AX);
11023e12c5d1SDavid du Colombier 			doasm(&pp);
11033e12c5d1SDavid du Colombier 			*andptr++ = 0x90 + reg[z];		/* xchg rsh,ax */
11043e12c5d1SDavid du Colombier 		}
11053e12c5d1SDavid du Colombier 		return;
11063e12c5d1SDavid du Colombier 	}
11073e12c5d1SDavid du Colombier 	diag("doasm: notfound %P\n", p);
11083e12c5d1SDavid du Colombier 	return;
11093e12c5d1SDavid du Colombier 
11103e12c5d1SDavid du Colombier mfound:
11113e12c5d1SDavid du Colombier 	switch(t[3]) {
11123e12c5d1SDavid du Colombier 	default:
11133e12c5d1SDavid du Colombier 		diag("asmins: unknown mov %d %P\n", t[3], p);
11143e12c5d1SDavid du Colombier 		break;
11153e12c5d1SDavid du Colombier 
11163e12c5d1SDavid du Colombier 	case 0:	/* lit */
11173e12c5d1SDavid du Colombier 		for(z=4; t[z]!=E; z++)
11183e12c5d1SDavid du Colombier 			*andptr++ = t[z];
11193e12c5d1SDavid du Colombier 		break;
11203e12c5d1SDavid du Colombier 
11213e12c5d1SDavid du Colombier 	case 1:	/* r,m */
11223e12c5d1SDavid du Colombier 		*andptr++ = t[4];
11233e12c5d1SDavid du Colombier 		asmand(&p->to, t[5]);
11243e12c5d1SDavid du Colombier 		break;
11253e12c5d1SDavid du Colombier 
11263e12c5d1SDavid du Colombier 	case 2:	/* m,r */
11273e12c5d1SDavid du Colombier 		*andptr++ = t[4];
11283e12c5d1SDavid du Colombier 		asmand(&p->from, t[5]);
11293e12c5d1SDavid du Colombier 		break;
11303e12c5d1SDavid du Colombier 
11313e12c5d1SDavid du Colombier 	case 3:	/* r,m - 2op */
11323e12c5d1SDavid du Colombier 		*andptr++ = t[4];
11333e12c5d1SDavid du Colombier 		*andptr++ = t[5];
11343e12c5d1SDavid du Colombier 		asmand(&p->to, t[6]);
11353e12c5d1SDavid du Colombier 		break;
11363e12c5d1SDavid du Colombier 
11373e12c5d1SDavid du Colombier 	case 4:	/* m,r - 2op */
11383e12c5d1SDavid du Colombier 		*andptr++ = t[4];
11393e12c5d1SDavid du Colombier 		*andptr++ = t[5];
11403e12c5d1SDavid du Colombier 		asmand(&p->from, t[6]);
11413e12c5d1SDavid du Colombier 		break;
11423e12c5d1SDavid du Colombier 
11433e12c5d1SDavid du Colombier 	case 5:	/* load full pointer, trash heap */
11443e12c5d1SDavid du Colombier 		if(t[4])
11453e12c5d1SDavid du Colombier 			*andptr++ = t[4];
11463e12c5d1SDavid du Colombier 		switch(p->to.index) {
11473e12c5d1SDavid du Colombier 		default:
11483e12c5d1SDavid du Colombier 			goto bad;
11493e12c5d1SDavid du Colombier 		case D_DS:
11503e12c5d1SDavid du Colombier 			*andptr++ = 0xc5;
11513e12c5d1SDavid du Colombier 			break;
11523e12c5d1SDavid du Colombier 		case D_SS:
11533e12c5d1SDavid du Colombier 			*andptr++ = 0x0f;
11543e12c5d1SDavid du Colombier 			*andptr++ = 0xb2;
11553e12c5d1SDavid du Colombier 			break;
11563e12c5d1SDavid du Colombier 		case D_ES:
11573e12c5d1SDavid du Colombier 			*andptr++ = 0xc4;
11583e12c5d1SDavid du Colombier 			break;
11593e12c5d1SDavid du Colombier 		case D_FS:
11603e12c5d1SDavid du Colombier 			*andptr++ = 0x0f;
11613e12c5d1SDavid du Colombier 			*andptr++ = 0xb4;
11623e12c5d1SDavid du Colombier 			break;
11633e12c5d1SDavid du Colombier 		case D_GS:
11643e12c5d1SDavid du Colombier 			*andptr++ = 0x0f;
11653e12c5d1SDavid du Colombier 			*andptr++ = 0xb5;
11663e12c5d1SDavid du Colombier 			break;
11673e12c5d1SDavid du Colombier 		}
11683e12c5d1SDavid du Colombier 		asmand(&p->from, reg[p->to.type]);
11693e12c5d1SDavid du Colombier 		break;
11703e12c5d1SDavid du Colombier 
1171*219b2ee8SDavid du Colombier 	case 6:	/* double shift */
11723e12c5d1SDavid du Colombier 		z = p->from.type;
11733e12c5d1SDavid du Colombier 		switch(z) {
11743e12c5d1SDavid du Colombier 		default:
11753e12c5d1SDavid du Colombier 			goto bad;
11763e12c5d1SDavid du Colombier 		case D_CONST:
11773e12c5d1SDavid du Colombier 			*andptr++ = 0x0f;
11783e12c5d1SDavid du Colombier 			*andptr++ = t[4];
1179*219b2ee8SDavid du Colombier 			asmand(&p->to, reg[p->from.index]);
11803e12c5d1SDavid du Colombier 			*andptr++ = p->from.offset;
11813e12c5d1SDavid du Colombier 			break;
11823e12c5d1SDavid du Colombier 		case D_CL:
11833e12c5d1SDavid du Colombier 		case D_CX:
11843e12c5d1SDavid du Colombier 			*andptr++ = 0x0f;
11853e12c5d1SDavid du Colombier 			*andptr++ = t[5];
1186*219b2ee8SDavid du Colombier 			asmand(&p->to, reg[p->from.index]);
11873e12c5d1SDavid du Colombier 			break;
11883e12c5d1SDavid du Colombier 		}
11893e12c5d1SDavid du Colombier 		break;
11903e12c5d1SDavid du Colombier 	}
11913e12c5d1SDavid du Colombier }
11923e12c5d1SDavid du Colombier 
11933e12c5d1SDavid du Colombier void
11943e12c5d1SDavid du Colombier asmins(Prog *p)
11953e12c5d1SDavid du Colombier {
11963e12c5d1SDavid du Colombier 
11973e12c5d1SDavid du Colombier 	andptr = and;
11983e12c5d1SDavid du Colombier 	doasm(p);
11993e12c5d1SDavid du Colombier }
1200