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