xref: /plan9/sys/src/cmd/6c/swt.c (revision 178702b161d3fe3e021aa6cb2f305be898e56ca0)
1e887ea33SDavid du Colombier #include "gc.h"
2e887ea33SDavid du Colombier 
3e887ea33SDavid du Colombier void
swit1(C1 * q,int nc,long def,Node * n)4e887ea33SDavid du Colombier swit1(C1 *q, int nc, long def, Node *n)
5e887ea33SDavid du Colombier {
6e887ea33SDavid du Colombier 	C1 *r;
7e887ea33SDavid du Colombier 	int i;
8e887ea33SDavid du Colombier 	Prog *sp;
9e887ea33SDavid du Colombier 
10e887ea33SDavid du Colombier 	if(nc < 5) {
11e887ea33SDavid du Colombier 		for(i=0; i<nc; i++) {
12*178702b1SDavid du Colombier 			if(debug['K'])
13e887ea33SDavid du Colombier 				print("case = %.8llux\n", q->val);
14e887ea33SDavid du Colombier 			gcmp(OEQ, n, q->val);
15e887ea33SDavid du Colombier 			patch(p, q->label);
16e887ea33SDavid du Colombier 			q++;
17e887ea33SDavid du Colombier 		}
18e887ea33SDavid du Colombier 		gbranch(OGOTO);
19e887ea33SDavid du Colombier 		patch(p, def);
20e887ea33SDavid du Colombier 		return;
21e887ea33SDavid du Colombier 	}
22e887ea33SDavid du Colombier 	i = nc / 2;
23e887ea33SDavid du Colombier 	r = q+i;
24*178702b1SDavid du Colombier 	if(debug['K'])
25e887ea33SDavid du Colombier 		print("case > %.8llux\n", r->val);
26e887ea33SDavid du Colombier 	gcmp(OGT, n, r->val);
27e887ea33SDavid du Colombier 	sp = p;
28e887ea33SDavid du Colombier 	gbranch(OGOTO);
29e887ea33SDavid du Colombier 	p->as = AJEQ;
30e887ea33SDavid du Colombier 	patch(p, r->label);
31e887ea33SDavid du Colombier 	swit1(q, i, def, n);
32e887ea33SDavid du Colombier 
33*178702b1SDavid du Colombier 	if(debug['K'])
34e887ea33SDavid du Colombier 		print("case < %.8llux\n", r->val);
35e887ea33SDavid du Colombier 	patch(sp, pc);
36e887ea33SDavid du Colombier 	swit1(r+1, nc-i-1, def, n);
37e887ea33SDavid du Colombier }
38e887ea33SDavid du Colombier 
39e887ea33SDavid du Colombier void
bitload(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)40e887ea33SDavid du Colombier bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
41e887ea33SDavid du Colombier {
42e887ea33SDavid du Colombier 	int sh;
43e887ea33SDavid du Colombier 	long v;
44e887ea33SDavid du Colombier 	Node *l;
45e887ea33SDavid du Colombier 
46e887ea33SDavid du Colombier 	/*
47e887ea33SDavid du Colombier 	 * n1 gets adjusted/masked value
48e887ea33SDavid du Colombier 	 * n2 gets address of cell
49e887ea33SDavid du Colombier 	 * n3 gets contents of cell
50e887ea33SDavid du Colombier 	 */
51e887ea33SDavid du Colombier 	l = b->left;
52e887ea33SDavid du Colombier 	if(n2 != Z) {
53e887ea33SDavid du Colombier 		regalloc(n1, l, nn);
54e887ea33SDavid du Colombier 		reglcgen(n2, l, Z);
55e887ea33SDavid du Colombier 		regalloc(n3, l, Z);
56e887ea33SDavid du Colombier 		gmove(n2, n3);
57e887ea33SDavid du Colombier 		gmove(n3, n1);
58e887ea33SDavid du Colombier 	} else {
59e887ea33SDavid du Colombier 		regalloc(n1, l, nn);
60e887ea33SDavid du Colombier 		cgen(l, n1);
61e887ea33SDavid du Colombier 	}
62e887ea33SDavid du Colombier 	if(b->type->shift == 0 && typeu[b->type->etype]) {
63e887ea33SDavid du Colombier 		v = ~0 + (1L << b->type->nbits);
64e887ea33SDavid du Colombier 		gopcode(OAND, tfield, nodconst(v), n1);
65e887ea33SDavid du Colombier 	} else {
66e887ea33SDavid du Colombier 		sh = 32 - b->type->shift - b->type->nbits;
67e887ea33SDavid du Colombier 		if(sh > 0)
68e887ea33SDavid du Colombier 			gopcode(OASHL, tfield, nodconst(sh), n1);
69e887ea33SDavid du Colombier 		sh += b->type->shift;
70e887ea33SDavid du Colombier 		if(sh > 0)
71e887ea33SDavid du Colombier 			if(typeu[b->type->etype])
72e887ea33SDavid du Colombier 				gopcode(OLSHR, tfield, nodconst(sh), n1);
73e887ea33SDavid du Colombier 			else
74e887ea33SDavid du Colombier 				gopcode(OASHR, tfield, nodconst(sh), n1);
75e887ea33SDavid du Colombier 	}
76e887ea33SDavid du Colombier }
77e887ea33SDavid du Colombier 
78e887ea33SDavid du Colombier void
bitstore(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)79e887ea33SDavid du Colombier bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
80e887ea33SDavid du Colombier {
81e887ea33SDavid du Colombier 	long v;
82e887ea33SDavid du Colombier 	Node nod;
83e887ea33SDavid du Colombier 	int sh;
84e887ea33SDavid du Colombier 
85e887ea33SDavid du Colombier 	regalloc(&nod, b->left, Z);
86e887ea33SDavid du Colombier 	v = ~0 + (1L << b->type->nbits);
87e887ea33SDavid du Colombier 	gopcode(OAND, types[TLONG], nodconst(v), n1);
88e887ea33SDavid du Colombier 	gmove(n1, &nod);
89e887ea33SDavid du Colombier 	if(nn != Z)
90e887ea33SDavid du Colombier 		gmove(n1, nn);
91e887ea33SDavid du Colombier 	sh = b->type->shift;
92e887ea33SDavid du Colombier 	if(sh > 0)
93e887ea33SDavid du Colombier 		gopcode(OASHL, types[TLONG], nodconst(sh), &nod);
94e887ea33SDavid du Colombier 	v <<= sh;
95e887ea33SDavid du Colombier 	gopcode(OAND, types[TLONG], nodconst(~v), n3);
96e887ea33SDavid du Colombier 	gopcode(OOR, types[TLONG], n3, &nod);
97e887ea33SDavid du Colombier 	gmove(&nod, n2);
98e887ea33SDavid du Colombier 
99e887ea33SDavid du Colombier 	regfree(&nod);
100e887ea33SDavid du Colombier 	regfree(n1);
101e887ea33SDavid du Colombier 	regfree(n2);
102e887ea33SDavid du Colombier 	regfree(n3);
103e887ea33SDavid du Colombier }
104e887ea33SDavid du Colombier 
105e887ea33SDavid du Colombier long
outstring(char * s,long n)106e887ea33SDavid du Colombier outstring(char *s, long n)
107e887ea33SDavid du Colombier {
108e887ea33SDavid du Colombier 	long r;
109e887ea33SDavid du Colombier 
110e887ea33SDavid du Colombier 	if(suppress)
111e887ea33SDavid du Colombier 		return nstring;
112e887ea33SDavid du Colombier 	r = nstring;
113e887ea33SDavid du Colombier 	while(n) {
114e887ea33SDavid du Colombier 		string[mnstring] = *s++;
115e887ea33SDavid du Colombier 		mnstring++;
116e887ea33SDavid du Colombier 		nstring++;
117e887ea33SDavid du Colombier 		if(mnstring >= NSNAME) {
118e887ea33SDavid du Colombier 			gpseudo(ADATA, symstring, nodconst(0L));
119e887ea33SDavid du Colombier 			p->from.offset += nstring - NSNAME;
120e887ea33SDavid du Colombier 			p->from.scale = NSNAME;
121e887ea33SDavid du Colombier 			p->to.type = D_SCONST;
122e887ea33SDavid du Colombier 			memmove(p->to.sval, string, NSNAME);
123e887ea33SDavid du Colombier 			mnstring = 0;
124e887ea33SDavid du Colombier 		}
125e887ea33SDavid du Colombier 		n--;
126e887ea33SDavid du Colombier 	}
127e887ea33SDavid du Colombier 	return r;
128e887ea33SDavid du Colombier }
129e887ea33SDavid du Colombier 
130e887ea33SDavid du Colombier void
gextern(Sym * s,Node * a,long o,long w)131e887ea33SDavid du Colombier gextern(Sym *s, Node *a, long o, long w)
132e887ea33SDavid du Colombier {
133e887ea33SDavid du Colombier 	if(0 && a->op == OCONST && typev[a->type->etype]) {
134e887ea33SDavid du Colombier 		gpseudo(ADATA, s, lo64(a));
135e887ea33SDavid du Colombier 		p->from.offset += o;
136e887ea33SDavid du Colombier 		p->from.scale = 4;
137e887ea33SDavid du Colombier 		gpseudo(ADATA, s, hi64(a));
138e887ea33SDavid du Colombier 		p->from.offset += o + 4;
139e887ea33SDavid du Colombier 		p->from.scale = 4;
140e887ea33SDavid du Colombier 		return;
141e887ea33SDavid du Colombier 	}
142e887ea33SDavid du Colombier 	gpseudo(ADATA, s, a);
143e887ea33SDavid du Colombier 	p->from.offset += o;
144e887ea33SDavid du Colombier 	p->from.scale = w;
145e887ea33SDavid du Colombier 	switch(p->to.type) {
146e887ea33SDavid du Colombier 	default:
147e887ea33SDavid du Colombier 		p->to.index = p->to.type;
148e887ea33SDavid du Colombier 		p->to.type = D_ADDR;
149e887ea33SDavid du Colombier 	case D_CONST:
150e887ea33SDavid du Colombier 	case D_FCONST:
151e887ea33SDavid du Colombier 	case D_ADDR:
152e887ea33SDavid du Colombier 		break;
153e887ea33SDavid du Colombier 	}
154e887ea33SDavid du Colombier }
155e887ea33SDavid du Colombier 
156e887ea33SDavid du Colombier void	zname(Biobuf*, Sym*, int);
157e887ea33SDavid du Colombier void	zaddr(Biobuf*, Adr*, int);
158e887ea33SDavid du Colombier void	outhist(Biobuf*);
159e887ea33SDavid du Colombier 
160e887ea33SDavid du Colombier void
outcode(void)161e887ea33SDavid du Colombier outcode(void)
162e887ea33SDavid du Colombier {
163e887ea33SDavid du Colombier 	struct { Sym *sym; short type; } h[NSYM];
164e887ea33SDavid du Colombier 	Prog *p;
165e887ea33SDavid du Colombier 	Sym *s;
166e887ea33SDavid du Colombier 	int f, sf, st, t, sym;
167e887ea33SDavid du Colombier 	Biobuf b;
168e887ea33SDavid du Colombier 
169e887ea33SDavid du Colombier 	if(debug['S']) {
170e887ea33SDavid du Colombier 		for(p = firstp; p != P; p = p->link)
171e887ea33SDavid du Colombier 			if(p->as != ADATA && p->as != AGLOBL)
172e887ea33SDavid du Colombier 				pc--;
173e887ea33SDavid du Colombier 		for(p = firstp; p != P; p = p->link) {
174e887ea33SDavid du Colombier 			print("%P\n", p);
175e887ea33SDavid du Colombier 			if(p->as != ADATA && p->as != AGLOBL)
176e887ea33SDavid du Colombier 				pc++;
177e887ea33SDavid du Colombier 		}
178e887ea33SDavid du Colombier 	}
179e887ea33SDavid du Colombier 	f = open(outfile, OWRITE);
180e887ea33SDavid du Colombier 	if(f < 0) {
181e887ea33SDavid du Colombier 		diag(Z, "cannot open %s", outfile);
182e887ea33SDavid du Colombier 		return;
183e887ea33SDavid du Colombier 	}
184e887ea33SDavid du Colombier 	Binit(&b, f, OWRITE);
185e887ea33SDavid du Colombier 	Bseek(&b, 0L, 2);
186e887ea33SDavid du Colombier 	outhist(&b);
187e887ea33SDavid du Colombier 	for(sym=0; sym<NSYM; sym++) {
188e887ea33SDavid du Colombier 		h[sym].sym = S;
189e887ea33SDavid du Colombier 		h[sym].type = 0;
190e887ea33SDavid du Colombier 	}
191e887ea33SDavid du Colombier 	sym = 1;
192e887ea33SDavid du Colombier 	for(p = firstp; p != P; p = p->link) {
193e887ea33SDavid du Colombier 	jackpot:
194e887ea33SDavid du Colombier 		sf = 0;
195e887ea33SDavid du Colombier 		s = p->from.sym;
196e887ea33SDavid du Colombier 		while(s != S) {
197e887ea33SDavid du Colombier 			sf = s->sym;
198e887ea33SDavid du Colombier 			if(sf < 0 || sf >= NSYM)
199e887ea33SDavid du Colombier 				sf = 0;
200e887ea33SDavid du Colombier 			t = p->from.type;
201e887ea33SDavid du Colombier 			if(t == D_ADDR)
202e887ea33SDavid du Colombier 				t = p->from.index;
203e887ea33SDavid du Colombier 			if(h[sf].type == t)
204e887ea33SDavid du Colombier 			if(h[sf].sym == s)
205e887ea33SDavid du Colombier 				break;
206e887ea33SDavid du Colombier 			s->sym = sym;
207e887ea33SDavid du Colombier 			zname(&b, s, t);
208e887ea33SDavid du Colombier 			h[sym].sym = s;
209e887ea33SDavid du Colombier 			h[sym].type = t;
210e887ea33SDavid du Colombier 			sf = sym;
211e887ea33SDavid du Colombier 			sym++;
212e887ea33SDavid du Colombier 			if(sym >= NSYM)
213e887ea33SDavid du Colombier 				sym = 1;
214e887ea33SDavid du Colombier 			break;
215e887ea33SDavid du Colombier 		}
216e887ea33SDavid du Colombier 		st = 0;
217e887ea33SDavid du Colombier 		s = p->to.sym;
218e887ea33SDavid du Colombier 		while(s != S) {
219e887ea33SDavid du Colombier 			st = s->sym;
220e887ea33SDavid du Colombier 			if(st < 0 || st >= NSYM)
221e887ea33SDavid du Colombier 				st = 0;
222e887ea33SDavid du Colombier 			t = p->to.type;
223e887ea33SDavid du Colombier 			if(t == D_ADDR)
224e887ea33SDavid du Colombier 				t = p->to.index;
225e887ea33SDavid du Colombier 			if(h[st].type == t)
226e887ea33SDavid du Colombier 			if(h[st].sym == s)
227e887ea33SDavid du Colombier 				break;
228e887ea33SDavid du Colombier 			s->sym = sym;
229e887ea33SDavid du Colombier 			zname(&b, s, t);
230e887ea33SDavid du Colombier 			h[sym].sym = s;
231e887ea33SDavid du Colombier 			h[sym].type = t;
232e887ea33SDavid du Colombier 			st = sym;
233e887ea33SDavid du Colombier 			sym++;
234e887ea33SDavid du Colombier 			if(sym >= NSYM)
235e887ea33SDavid du Colombier 				sym = 1;
236e887ea33SDavid du Colombier 			if(st == sf)
237e887ea33SDavid du Colombier 				goto jackpot;
238e887ea33SDavid du Colombier 			break;
239e887ea33SDavid du Colombier 		}
240e887ea33SDavid du Colombier 		Bputc(&b, p->as);
241e887ea33SDavid du Colombier 		Bputc(&b, p->as>>8);
242e887ea33SDavid du Colombier 		Bputc(&b, p->lineno);
243e887ea33SDavid du Colombier 		Bputc(&b, p->lineno>>8);
244e887ea33SDavid du Colombier 		Bputc(&b, p->lineno>>16);
245e887ea33SDavid du Colombier 		Bputc(&b, p->lineno>>24);
246e887ea33SDavid du Colombier 		zaddr(&b, &p->from, sf);
247e887ea33SDavid du Colombier 		zaddr(&b, &p->to, st);
248e887ea33SDavid du Colombier 	}
249e887ea33SDavid du Colombier 	Bflush(&b);
250e887ea33SDavid du Colombier 	close(f);
251e887ea33SDavid du Colombier 	firstp = P;
252e887ea33SDavid du Colombier 	lastp = P;
253e887ea33SDavid du Colombier }
254e887ea33SDavid du Colombier 
255e887ea33SDavid du Colombier void
outhist(Biobuf * b)256e887ea33SDavid du Colombier outhist(Biobuf *b)
257e887ea33SDavid du Colombier {
258e887ea33SDavid du Colombier 	Hist *h;
259e887ea33SDavid du Colombier 	char *p, *q, *op, c;
260e887ea33SDavid du Colombier 	Prog pg;
261e887ea33SDavid du Colombier 	int n;
262e887ea33SDavid du Colombier 
263e887ea33SDavid du Colombier 	pg = zprog;
264e887ea33SDavid du Colombier 	pg.as = AHISTORY;
265e887ea33SDavid du Colombier 	c = pathchar();
266e887ea33SDavid du Colombier 	for(h = hist; h != H; h = h->link) {
267e887ea33SDavid du Colombier 		p = h->name;
268e887ea33SDavid du Colombier 		op = 0;
269e887ea33SDavid du Colombier 		/* on windows skip drive specifier in pathname */
270e887ea33SDavid du Colombier 		if(systemtype(Windows) && p && p[1] == ':'){
271e887ea33SDavid du Colombier 			p += 2;
272e887ea33SDavid du Colombier 			c = *p;
273e887ea33SDavid du Colombier 		}
274e887ea33SDavid du Colombier 		if(p && p[0] != c && h->offset == 0 && pathname){
275e887ea33SDavid du Colombier 			/* on windows skip drive specifier in pathname */
276e887ea33SDavid du Colombier 			if(systemtype(Windows) && pathname[1] == ':') {
277e887ea33SDavid du Colombier 				op = p;
278e887ea33SDavid du Colombier 				p = pathname+2;
279e887ea33SDavid du Colombier 				c = *p;
280e887ea33SDavid du Colombier 			} else if(pathname[0] == c){
281e887ea33SDavid du Colombier 				op = p;
282e887ea33SDavid du Colombier 				p = pathname;
283e887ea33SDavid du Colombier 			}
284e887ea33SDavid du Colombier 		}
285e887ea33SDavid du Colombier 		while(p) {
286e887ea33SDavid du Colombier 			q = utfrune(p, c);
287e887ea33SDavid du Colombier 			if(q) {
288e887ea33SDavid du Colombier 				n = q-p;
289e887ea33SDavid du Colombier 				if(n == 0){
290e887ea33SDavid du Colombier 					n = 1;	/* leading "/" */
291e887ea33SDavid du Colombier 					*p = '/';	/* don't emit "\" on windows */
292e887ea33SDavid du Colombier 				}
293e887ea33SDavid du Colombier 				q++;
294e887ea33SDavid du Colombier 			} else {
295e887ea33SDavid du Colombier 				n = strlen(p);
296e887ea33SDavid du Colombier 				q = 0;
297e887ea33SDavid du Colombier 			}
298e887ea33SDavid du Colombier 			if(n) {
299e887ea33SDavid du Colombier 				Bputc(b, ANAME);
300e887ea33SDavid du Colombier 				Bputc(b, ANAME>>8);
301e887ea33SDavid du Colombier 				Bputc(b, D_FILE);
302e887ea33SDavid du Colombier 				Bputc(b, 1);
303e887ea33SDavid du Colombier 				Bputc(b, '<');
304e887ea33SDavid du Colombier 				Bwrite(b, p, n);
305e887ea33SDavid du Colombier 				Bputc(b, 0);
306e887ea33SDavid du Colombier 			}
307e887ea33SDavid du Colombier 			p = q;
308e887ea33SDavid du Colombier 			if(p == 0 && op) {
309e887ea33SDavid du Colombier 				p = op;
310e887ea33SDavid du Colombier 				op = 0;
311e887ea33SDavid du Colombier 			}
312e887ea33SDavid du Colombier 		}
313e887ea33SDavid du Colombier 		pg.lineno = h->line;
314e887ea33SDavid du Colombier 		pg.to.type = zprog.to.type;
315e887ea33SDavid du Colombier 		pg.to.offset = h->offset;
316e887ea33SDavid du Colombier 		if(h->offset)
317e887ea33SDavid du Colombier 			pg.to.type = D_CONST;
318e887ea33SDavid du Colombier 
319e887ea33SDavid du Colombier 		Bputc(b, pg.as);
320e887ea33SDavid du Colombier 		Bputc(b, pg.as>>8);
321e887ea33SDavid du Colombier 		Bputc(b, pg.lineno);
322e887ea33SDavid du Colombier 		Bputc(b, pg.lineno>>8);
323e887ea33SDavid du Colombier 		Bputc(b, pg.lineno>>16);
324e887ea33SDavid du Colombier 		Bputc(b, pg.lineno>>24);
325e887ea33SDavid du Colombier 		zaddr(b, &pg.from, 0);
326e887ea33SDavid du Colombier 		zaddr(b, &pg.to, 0);
327e887ea33SDavid du Colombier 	}
328e887ea33SDavid du Colombier }
329e887ea33SDavid du Colombier 
330e887ea33SDavid du Colombier void
zname(Biobuf * b,Sym * s,int t)331e887ea33SDavid du Colombier zname(Biobuf *b, Sym *s, int t)
332e887ea33SDavid du Colombier {
333e887ea33SDavid du Colombier 	char *n;
334e887ea33SDavid du Colombier 	ulong sig;
335e887ea33SDavid du Colombier 
336e887ea33SDavid du Colombier 	if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
337e887ea33SDavid du Colombier 		sig = sign(s);
338e887ea33SDavid du Colombier 		Bputc(b, ASIGNAME);
339e887ea33SDavid du Colombier 		Bputc(b, ASIGNAME>>8);
340e887ea33SDavid du Colombier 		Bputc(b, sig);
341e887ea33SDavid du Colombier 		Bputc(b, sig>>8);
342e887ea33SDavid du Colombier 		Bputc(b, sig>>16);
343e887ea33SDavid du Colombier 		Bputc(b, sig>>24);
344e887ea33SDavid du Colombier 		s->sig = SIGDONE;
345e887ea33SDavid du Colombier 	}
346e887ea33SDavid du Colombier 	else{
347e887ea33SDavid du Colombier 		Bputc(b, ANAME);	/* as */
348e887ea33SDavid du Colombier 		Bputc(b, ANAME>>8);	/* as */
349e887ea33SDavid du Colombier 	}
350e887ea33SDavid du Colombier 	Bputc(b, t);			/* type */
351e887ea33SDavid du Colombier 	Bputc(b, s->sym);		/* sym */
352e887ea33SDavid du Colombier 	n = s->name;
353e887ea33SDavid du Colombier 	while(*n) {
354e887ea33SDavid du Colombier 		Bputc(b, *n);
355e887ea33SDavid du Colombier 		n++;
356e887ea33SDavid du Colombier 	}
357e887ea33SDavid du Colombier 	Bputc(b, 0);
358e887ea33SDavid du Colombier }
359e887ea33SDavid du Colombier 
360e887ea33SDavid du Colombier void
zaddr(Biobuf * b,Adr * a,int s)361e887ea33SDavid du Colombier zaddr(Biobuf *b, Adr *a, int s)
362e887ea33SDavid du Colombier {
363e887ea33SDavid du Colombier 	long l;
364e887ea33SDavid du Colombier 	int i, t;
365e887ea33SDavid du Colombier 	char *n;
366e887ea33SDavid du Colombier 	Ieee e;
367e887ea33SDavid du Colombier 
368e887ea33SDavid du Colombier 	t = 0;
369e887ea33SDavid du Colombier 	if(a->index != D_NONE || a->scale != 0)
370e887ea33SDavid du Colombier 		t |= T_INDEX;
371e887ea33SDavid du Colombier 	if(s != 0)
372e887ea33SDavid du Colombier 		t |= T_SYM;
373e887ea33SDavid du Colombier 
374e887ea33SDavid du Colombier 	switch(a->type) {
375e887ea33SDavid du Colombier 	default:
376e887ea33SDavid du Colombier 		t |= T_TYPE;
377e887ea33SDavid du Colombier 	case D_NONE:
378e887ea33SDavid du Colombier 		if(a->offset != 0) {
379e887ea33SDavid du Colombier 			t |= T_OFFSET;
380e887ea33SDavid du Colombier 			l = a->offset;
381e887ea33SDavid du Colombier 			if((vlong)l != a->offset)
382e887ea33SDavid du Colombier 				t |= T_64;
383e887ea33SDavid du Colombier 		}
384e887ea33SDavid du Colombier 		break;
385e887ea33SDavid du Colombier 	case D_FCONST:
386e887ea33SDavid du Colombier 		t |= T_FCONST;
387e887ea33SDavid du Colombier 		break;
388e887ea33SDavid du Colombier 	case D_SCONST:
389e887ea33SDavid du Colombier 		t |= T_SCONST;
390e887ea33SDavid du Colombier 		break;
391e887ea33SDavid du Colombier 	}
392e887ea33SDavid du Colombier 	Bputc(b, t);
393e887ea33SDavid du Colombier 
394e887ea33SDavid du Colombier 	if(t & T_INDEX) {	/* implies index, scale */
395e887ea33SDavid du Colombier 		Bputc(b, a->index);
396e887ea33SDavid du Colombier 		Bputc(b, a->scale);
397e887ea33SDavid du Colombier 	}
398e887ea33SDavid du Colombier 	if(t & T_OFFSET) {	/* implies offset */
399e887ea33SDavid du Colombier 		l = a->offset;
400e887ea33SDavid du Colombier 		Bputc(b, l);
401e887ea33SDavid du Colombier 		Bputc(b, l>>8);
402e887ea33SDavid du Colombier 		Bputc(b, l>>16);
403e887ea33SDavid du Colombier 		Bputc(b, l>>24);
404e887ea33SDavid du Colombier 		if(t & T_64) {
405e887ea33SDavid du Colombier 			l = a->offset>>32;
406e887ea33SDavid du Colombier 			Bputc(b, l);
407e887ea33SDavid du Colombier 			Bputc(b, l>>8);
408e887ea33SDavid du Colombier 			Bputc(b, l>>16);
409e887ea33SDavid du Colombier 			Bputc(b, l>>24);
410e887ea33SDavid du Colombier 		}
411e887ea33SDavid du Colombier 	}
412e887ea33SDavid du Colombier 	if(t & T_SYM)		/* implies sym */
413e887ea33SDavid du Colombier 		Bputc(b, s);
414e887ea33SDavid du Colombier 	if(t & T_FCONST) {
415e887ea33SDavid du Colombier 		ieeedtod(&e, a->dval);
416e887ea33SDavid du Colombier 		l = e.l;
417e887ea33SDavid du Colombier 		Bputc(b, l);
418e887ea33SDavid du Colombier 		Bputc(b, l>>8);
419e887ea33SDavid du Colombier 		Bputc(b, l>>16);
420e887ea33SDavid du Colombier 		Bputc(b, l>>24);
421e887ea33SDavid du Colombier 		l = e.h;
422e887ea33SDavid du Colombier 		Bputc(b, l);
423e887ea33SDavid du Colombier 		Bputc(b, l>>8);
424e887ea33SDavid du Colombier 		Bputc(b, l>>16);
425e887ea33SDavid du Colombier 		Bputc(b, l>>24);
426e887ea33SDavid du Colombier 		return;
427e887ea33SDavid du Colombier 	}
428e887ea33SDavid du Colombier 	if(t & T_SCONST) {
429e887ea33SDavid du Colombier 		n = a->sval;
430e887ea33SDavid du Colombier 		for(i=0; i<NSNAME; i++) {
431e887ea33SDavid du Colombier 			Bputc(b, *n);
432e887ea33SDavid du Colombier 			n++;
433e887ea33SDavid du Colombier 		}
434e887ea33SDavid du Colombier 		return;
435e887ea33SDavid du Colombier 	}
436e887ea33SDavid du Colombier 	if(t & T_TYPE)
437e887ea33SDavid du Colombier 		Bputc(b, a->type);
438e887ea33SDavid du Colombier }
439e887ea33SDavid du Colombier 
440e887ea33SDavid du Colombier long
align(long i,Type * t,int op)441e887ea33SDavid du Colombier align(long i, Type *t, int op)
442e887ea33SDavid du Colombier {
443e887ea33SDavid du Colombier 	long o;
444e887ea33SDavid du Colombier 	Type *v;
445e887ea33SDavid du Colombier 	int w;
446e887ea33SDavid du Colombier 
447e887ea33SDavid du Colombier 	o = i;
448e887ea33SDavid du Colombier 	w = 1;
449e887ea33SDavid du Colombier 	switch(op) {
450e887ea33SDavid du Colombier 	default:
451e887ea33SDavid du Colombier 		diag(Z, "unknown align opcode %d", op);
452e887ea33SDavid du Colombier 		break;
453e887ea33SDavid du Colombier 
454e887ea33SDavid du Colombier 	case Asu2:	/* padding at end of a struct */
455e887ea33SDavid du Colombier 		w = SZ_VLONG;
456e887ea33SDavid du Colombier 		if(packflg)
457e887ea33SDavid du Colombier 			w = packflg;
458e887ea33SDavid du Colombier 		break;
459e887ea33SDavid du Colombier 
460e887ea33SDavid du Colombier 	case Ael1:	/* initial align of struct element */
461e887ea33SDavid du Colombier 		for(v=t; v->etype==TARRAY; v=v->link)
462e887ea33SDavid du Colombier 			;
463e887ea33SDavid du Colombier 		w = ewidth[v->etype];
464e887ea33SDavid du Colombier 		if(w <= 0 || w >= SZ_VLONG)
465e887ea33SDavid du Colombier 			w = SZ_VLONG;
466e887ea33SDavid du Colombier 		if(packflg)
467e887ea33SDavid du Colombier 			w = packflg;
468e887ea33SDavid du Colombier 		break;
469e887ea33SDavid du Colombier 
470e887ea33SDavid du Colombier 	case Ael2:	/* width of a struct element */
471e887ea33SDavid du Colombier 		o += t->width;
472e887ea33SDavid du Colombier 		break;
473e887ea33SDavid du Colombier 
474e887ea33SDavid du Colombier 	case Aarg0:	/* initial passbyptr argument in arg list */
475e887ea33SDavid du Colombier 		if(typesu[t->etype]) {
476e887ea33SDavid du Colombier 			o = align(o, types[TIND], Aarg1);
477e887ea33SDavid du Colombier 			o = align(o, types[TIND], Aarg2);
478e887ea33SDavid du Colombier 		}
479e887ea33SDavid du Colombier 		break;
480e887ea33SDavid du Colombier 
481e887ea33SDavid du Colombier 	case Aarg1:	/* initial align of parameter */
482e887ea33SDavid du Colombier 		w = ewidth[t->etype];
483e887ea33SDavid du Colombier 		if(w <= 0 || w >= SZ_VLONG) {
484e887ea33SDavid du Colombier 			w = SZ_VLONG;
485e887ea33SDavid du Colombier 			break;
486e887ea33SDavid du Colombier 		}
487e887ea33SDavid du Colombier 		w = 1;		/* little endian no adjustment */
488e887ea33SDavid du Colombier 		break;
489e887ea33SDavid du Colombier 
490e887ea33SDavid du Colombier 	case Aarg2:	/* width of a parameter */
491e887ea33SDavid du Colombier 		o += t->width;
492e887ea33SDavid du Colombier 		w = SZ_VLONG;
493e887ea33SDavid du Colombier 		break;
494e887ea33SDavid du Colombier 
495e887ea33SDavid du Colombier 	case Aaut3:	/* total allign of automatic */
496e887ea33SDavid du Colombier 		o = align(o, t, Ael1);
497e887ea33SDavid du Colombier 		o = align(o, t, Ael2);
498e887ea33SDavid du Colombier 		break;
499e887ea33SDavid du Colombier 	}
500e887ea33SDavid du Colombier 	o = round(o, w);
501e887ea33SDavid du Colombier 	if(debug['A'])
502e887ea33SDavid du Colombier 		print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
503e887ea33SDavid du Colombier 	return o;
504e887ea33SDavid du Colombier }
505e887ea33SDavid du Colombier 
506e887ea33SDavid du Colombier long
maxround(long max,long v)507e887ea33SDavid du Colombier maxround(long max, long v)
508e887ea33SDavid du Colombier {
50985e2e562SDavid du Colombier 	v = round(v, SZ_VLONG);
510e887ea33SDavid du Colombier 	if(v > max)
51185e2e562SDavid du Colombier 		return v;
512e887ea33SDavid du Colombier 	return max;
513e887ea33SDavid du Colombier }
514