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