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