13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier void
swit1(C1 * q,int nc,long def,Node * n)43e12c5d1SDavid du Colombier swit1(C1 *q, int nc, long def, Node *n)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier C1 *r;
73e12c5d1SDavid du Colombier int i;
83e12c5d1SDavid du Colombier Prog *sp;
93e12c5d1SDavid du Colombier
103e12c5d1SDavid du Colombier if(nc < 5) {
113e12c5d1SDavid du Colombier for(i=0; i<nc; i++) {
12*178702b1SDavid du Colombier if(debug['K'])
133a276d32SDavid du Colombier print("case = %.8llux\n", q->val);
143e12c5d1SDavid du Colombier gopcode(OEQ, n->type, n, nodconst(q->val));
153e12c5d1SDavid du Colombier patch(p, q->label);
163e12c5d1SDavid du Colombier q++;
173e12c5d1SDavid du Colombier }
183e12c5d1SDavid du Colombier gbranch(OGOTO);
193e12c5d1SDavid du Colombier patch(p, def);
203e12c5d1SDavid du Colombier return;
213e12c5d1SDavid du Colombier }
223e12c5d1SDavid du Colombier i = nc / 2;
233e12c5d1SDavid du Colombier r = q+i;
24*178702b1SDavid du Colombier if(debug['K'])
253a276d32SDavid du Colombier print("case > %.8llux\n", r->val);
263e12c5d1SDavid du Colombier gopcode(OGT, n->type, n, nodconst(r->val));
273e12c5d1SDavid du Colombier sp = p;
283e12c5d1SDavid du Colombier gbranch(OGOTO);
293e12c5d1SDavid du Colombier p->as = AJEQ;
303e12c5d1SDavid du Colombier patch(p, r->label);
313e12c5d1SDavid du Colombier swit1(q, i, def, n);
323e12c5d1SDavid du Colombier
33*178702b1SDavid du Colombier if(debug['K'])
343a276d32SDavid du Colombier print("case < %.8llux\n", r->val);
353e12c5d1SDavid du Colombier patch(sp, pc);
363e12c5d1SDavid du Colombier swit1(r+1, nc-i-1, def, n);
373e12c5d1SDavid du Colombier }
383e12c5d1SDavid du Colombier
393e12c5d1SDavid du Colombier void
bitload(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)403e12c5d1SDavid du Colombier bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
413e12c5d1SDavid du Colombier {
423e12c5d1SDavid du Colombier int sh;
433e12c5d1SDavid du Colombier long v;
443e12c5d1SDavid du Colombier Node *l;
453e12c5d1SDavid du Colombier
463e12c5d1SDavid du Colombier /*
473e12c5d1SDavid du Colombier * n1 gets adjusted/masked value
483e12c5d1SDavid du Colombier * n2 gets address of cell
493e12c5d1SDavid du Colombier * n3 gets contents of cell
503e12c5d1SDavid du Colombier */
513e12c5d1SDavid du Colombier l = b->left;
523e12c5d1SDavid du Colombier if(n2 != Z) {
533e12c5d1SDavid du Colombier regalloc(n1, l, nn);
543e12c5d1SDavid du Colombier reglcgen(n2, l, Z);
553e12c5d1SDavid du Colombier regalloc(n3, l, Z);
563e12c5d1SDavid du Colombier gmove(n2, n3);
573e12c5d1SDavid du Colombier gmove(n3, n1);
583e12c5d1SDavid du Colombier } else {
593e12c5d1SDavid du Colombier regalloc(n1, l, nn);
603e12c5d1SDavid du Colombier cgen(l, n1);
613e12c5d1SDavid du Colombier }
623e12c5d1SDavid du Colombier if(b->type->shift == 0 && typeu[b->type->etype]) {
633e12c5d1SDavid du Colombier v = ~0 + (1L << b->type->nbits);
643e12c5d1SDavid du Colombier gopcode(OAND, types[TLONG], nodconst(v), n1);
653e12c5d1SDavid du Colombier } else {
663e12c5d1SDavid du Colombier sh = 32 - b->type->shift - b->type->nbits;
673e12c5d1SDavid du Colombier if(sh > 0)
683e12c5d1SDavid du Colombier gopcode(OASHL, types[TLONG], nodconst(sh), n1);
693e12c5d1SDavid du Colombier sh += b->type->shift;
703e12c5d1SDavid du Colombier if(sh > 0)
713e12c5d1SDavid du Colombier if(typeu[b->type->etype])
723e12c5d1SDavid du Colombier gopcode(OLSHR, types[TLONG], nodconst(sh), n1);
733e12c5d1SDavid du Colombier else
743e12c5d1SDavid du Colombier gopcode(OASHR, types[TLONG], nodconst(sh), n1);
753e12c5d1SDavid du Colombier }
763e12c5d1SDavid du Colombier }
773e12c5d1SDavid du Colombier
783e12c5d1SDavid du Colombier void
bitstore(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)793e12c5d1SDavid du Colombier bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
803e12c5d1SDavid du Colombier {
813e12c5d1SDavid du Colombier long v;
823e12c5d1SDavid du Colombier Node nod;
833e12c5d1SDavid du Colombier int sh;
843e12c5d1SDavid du Colombier
853e12c5d1SDavid du Colombier regalloc(&nod, b->left, Z);
863e12c5d1SDavid du Colombier v = ~0 + (1L << b->type->nbits);
873e12c5d1SDavid du Colombier gopcode(OAND, types[TLONG], nodconst(v), n1);
883e12c5d1SDavid du Colombier gmove(n1, &nod);
893e12c5d1SDavid du Colombier if(nn != Z)
903e12c5d1SDavid du Colombier gmove(n1, nn);
913e12c5d1SDavid du Colombier sh = b->type->shift;
923e12c5d1SDavid du Colombier if(sh > 0)
933e12c5d1SDavid du Colombier gopcode(OASHL, types[TLONG], nodconst(sh), &nod);
943e12c5d1SDavid du Colombier v <<= sh;
953e12c5d1SDavid du Colombier gopcode(OAND, types[TLONG], nodconst(~v), n3);
963e12c5d1SDavid du Colombier gopcode(OOR, types[TLONG], n3, &nod);
973e12c5d1SDavid du Colombier gmove(&nod, n2);
983e12c5d1SDavid du Colombier
993e12c5d1SDavid du Colombier regfree(&nod);
1003e12c5d1SDavid du Colombier regfree(n1);
1013e12c5d1SDavid du Colombier regfree(n2);
1023e12c5d1SDavid du Colombier regfree(n3);
1033e12c5d1SDavid du Colombier }
1043e12c5d1SDavid du Colombier
1053e12c5d1SDavid du Colombier long
outstring(char * s,long n)1063e12c5d1SDavid du Colombier outstring(char *s, long n)
1073e12c5d1SDavid du Colombier {
1083e12c5d1SDavid du Colombier long r;
1093e12c5d1SDavid du Colombier
1109a747e4fSDavid du Colombier if(suppress)
1119a747e4fSDavid du Colombier return nstring;
1123e12c5d1SDavid du Colombier r = nstring;
1133e12c5d1SDavid du Colombier while(n) {
1143e12c5d1SDavid du Colombier string[mnstring] = *s++;
1153e12c5d1SDavid du Colombier mnstring++;
1163e12c5d1SDavid du Colombier nstring++;
1173e12c5d1SDavid du Colombier if(mnstring >= NSNAME) {
1183e12c5d1SDavid du Colombier gpseudo(ADATA, symstring, nodconst(0L));
1193e12c5d1SDavid du Colombier p->from.offset += nstring - NSNAME;
1203e12c5d1SDavid du Colombier p->from.scale = NSNAME;
1213e12c5d1SDavid du Colombier p->to.type = D_SCONST;
1223e12c5d1SDavid du Colombier memmove(p->to.sval, string, NSNAME);
1233e12c5d1SDavid du Colombier mnstring = 0;
1243e12c5d1SDavid du Colombier }
1253e12c5d1SDavid du Colombier n--;
1263e12c5d1SDavid du Colombier }
1273e12c5d1SDavid du Colombier return r;
1283e12c5d1SDavid du Colombier }
1293e12c5d1SDavid du Colombier
1303e12c5d1SDavid du Colombier void
gextern(Sym * s,Node * a,long o,long w)1313e12c5d1SDavid du Colombier gextern(Sym *s, Node *a, long o, long w)
1323e12c5d1SDavid du Colombier {
133219b2ee8SDavid du Colombier if(a->op == OCONST && typev[a->type->etype]) {
134375daca8SDavid du Colombier gpseudo(ADATA, s, lo64(a));
135219b2ee8SDavid du Colombier p->from.offset += o;
136219b2ee8SDavid du Colombier p->from.scale = 4;
137375daca8SDavid du Colombier gpseudo(ADATA, s, hi64(a));
138219b2ee8SDavid du Colombier p->from.offset += o + 4;
139219b2ee8SDavid du Colombier p->from.scale = 4;
140219b2ee8SDavid du Colombier return;
141219b2ee8SDavid du Colombier }
1423e12c5d1SDavid du Colombier gpseudo(ADATA, s, a);
1433e12c5d1SDavid du Colombier p->from.offset += o;
1443e12c5d1SDavid du Colombier p->from.scale = w;
1453e12c5d1SDavid du Colombier switch(p->to.type) {
1463e12c5d1SDavid du Colombier default:
1473e12c5d1SDavid du Colombier p->to.index = p->to.type;
1483e12c5d1SDavid du Colombier p->to.type = D_ADDR;
1493e12c5d1SDavid du Colombier case D_CONST:
1503e12c5d1SDavid du Colombier case D_FCONST:
1513e12c5d1SDavid du Colombier case D_ADDR:
1523e12c5d1SDavid du Colombier break;
1533e12c5d1SDavid du Colombier }
1543e12c5d1SDavid du Colombier }
1553e12c5d1SDavid du Colombier
156375daca8SDavid du Colombier void zname(Biobuf*, Sym*, int);
1573e12c5d1SDavid du Colombier void zaddr(Biobuf*, Adr*, int);
1583e12c5d1SDavid du Colombier void outhist(Biobuf*);
1593e12c5d1SDavid du Colombier
1603e12c5d1SDavid du Colombier void
outcode(void)1613e12c5d1SDavid du Colombier outcode(void)
1623e12c5d1SDavid du Colombier {
1633e12c5d1SDavid du Colombier struct { Sym *sym; short type; } h[NSYM];
1643e12c5d1SDavid du Colombier Prog *p;
1653e12c5d1SDavid du Colombier Sym *s;
1663e12c5d1SDavid du Colombier int f, sf, st, t, sym;
1673e12c5d1SDavid du Colombier Biobuf b;
1683e12c5d1SDavid du Colombier
1693e12c5d1SDavid du Colombier if(debug['S']) {
1703e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link)
1713e12c5d1SDavid du Colombier if(p->as != ADATA && p->as != AGLOBL)
1723e12c5d1SDavid du Colombier pc--;
1733e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) {
1743e12c5d1SDavid du Colombier print("%P\n", p);
1753e12c5d1SDavid du Colombier if(p->as != ADATA && p->as != AGLOBL)
1763e12c5d1SDavid du Colombier pc++;
1773e12c5d1SDavid du Colombier }
1783e12c5d1SDavid du Colombier }
1793e12c5d1SDavid du Colombier f = open(outfile, OWRITE);
1803e12c5d1SDavid du Colombier if(f < 0) {
1813e12c5d1SDavid du Colombier diag(Z, "cannot open %s", outfile);
1823e12c5d1SDavid du Colombier return;
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier Binit(&b, f, OWRITE);
1853e12c5d1SDavid du Colombier Bseek(&b, 0L, 2);
1863e12c5d1SDavid du Colombier outhist(&b);
1873e12c5d1SDavid du Colombier for(sym=0; sym<NSYM; sym++) {
1883e12c5d1SDavid du Colombier h[sym].sym = S;
1893e12c5d1SDavid du Colombier h[sym].type = 0;
1903e12c5d1SDavid du Colombier }
1913e12c5d1SDavid du Colombier sym = 1;
1923e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) {
1933e12c5d1SDavid du Colombier jackpot:
1943e12c5d1SDavid du Colombier sf = 0;
1953e12c5d1SDavid du Colombier s = p->from.sym;
1963e12c5d1SDavid du Colombier while(s != S) {
1973e12c5d1SDavid du Colombier sf = s->sym;
1983e12c5d1SDavid du Colombier if(sf < 0 || sf >= NSYM)
1993e12c5d1SDavid du Colombier sf = 0;
2003e12c5d1SDavid du Colombier t = p->from.type;
2013e12c5d1SDavid du Colombier if(t == D_ADDR)
2023e12c5d1SDavid du Colombier t = p->from.index;
2033e12c5d1SDavid du Colombier if(h[sf].type == t)
2043e12c5d1SDavid du Colombier if(h[sf].sym == s)
2053e12c5d1SDavid du Colombier break;
2063e12c5d1SDavid du Colombier s->sym = sym;
207375daca8SDavid du Colombier zname(&b, s, t);
2083e12c5d1SDavid du Colombier h[sym].sym = s;
2093e12c5d1SDavid du Colombier h[sym].type = t;
2103e12c5d1SDavid du Colombier sf = sym;
2113e12c5d1SDavid du Colombier sym++;
2123e12c5d1SDavid du Colombier if(sym >= NSYM)
2133e12c5d1SDavid du Colombier sym = 1;
2143e12c5d1SDavid du Colombier break;
2153e12c5d1SDavid du Colombier }
2163e12c5d1SDavid du Colombier st = 0;
2173e12c5d1SDavid du Colombier s = p->to.sym;
2183e12c5d1SDavid du Colombier while(s != S) {
2193e12c5d1SDavid du Colombier st = s->sym;
2203e12c5d1SDavid du Colombier if(st < 0 || st >= NSYM)
2213e12c5d1SDavid du Colombier st = 0;
2223e12c5d1SDavid du Colombier t = p->to.type;
2233e12c5d1SDavid du Colombier if(t == D_ADDR)
2243e12c5d1SDavid du Colombier t = p->to.index;
2253e12c5d1SDavid du Colombier if(h[st].type == t)
2263e12c5d1SDavid du Colombier if(h[st].sym == s)
2273e12c5d1SDavid du Colombier break;
2283e12c5d1SDavid du Colombier s->sym = sym;
229375daca8SDavid du Colombier zname(&b, s, t);
2303e12c5d1SDavid du Colombier h[sym].sym = s;
2313e12c5d1SDavid du Colombier h[sym].type = t;
2323e12c5d1SDavid du Colombier st = sym;
2333e12c5d1SDavid du Colombier sym++;
2343e12c5d1SDavid du Colombier if(sym >= NSYM)
2353e12c5d1SDavid du Colombier sym = 1;
2363e12c5d1SDavid du Colombier if(st == sf)
2373e12c5d1SDavid du Colombier goto jackpot;
2383e12c5d1SDavid du Colombier break;
2393e12c5d1SDavid du Colombier }
2403e12c5d1SDavid du Colombier Bputc(&b, p->as);
2413e12c5d1SDavid du Colombier Bputc(&b, p->as>>8);
2423e12c5d1SDavid du Colombier Bputc(&b, p->lineno);
2433e12c5d1SDavid du Colombier Bputc(&b, p->lineno>>8);
2443e12c5d1SDavid du Colombier Bputc(&b, p->lineno>>16);
2453e12c5d1SDavid du Colombier Bputc(&b, p->lineno>>24);
2463e12c5d1SDavid du Colombier zaddr(&b, &p->from, sf);
2473e12c5d1SDavid du Colombier zaddr(&b, &p->to, st);
2483e12c5d1SDavid du Colombier }
2493e12c5d1SDavid du Colombier Bflush(&b);
2503e12c5d1SDavid du Colombier close(f);
2513e12c5d1SDavid du Colombier firstp = P;
2523e12c5d1SDavid du Colombier lastp = P;
2533e12c5d1SDavid du Colombier }
2543e12c5d1SDavid du Colombier
2553e12c5d1SDavid du Colombier void
outhist(Biobuf * b)2563e12c5d1SDavid du Colombier outhist(Biobuf *b)
2573e12c5d1SDavid du Colombier {
2583e12c5d1SDavid du Colombier Hist *h;
2597dd7cddfSDavid du Colombier char *p, *q, *op, c;
2603e12c5d1SDavid du Colombier Prog pg;
2613e12c5d1SDavid du Colombier int n;
2623e12c5d1SDavid du Colombier
2633e12c5d1SDavid du Colombier pg = zprog;
2643e12c5d1SDavid du Colombier pg.as = AHISTORY;
2657dd7cddfSDavid du Colombier c = pathchar();
2663e12c5d1SDavid du Colombier for(h = hist; h != H; h = h->link) {
2673e12c5d1SDavid du Colombier p = h->name;
268219b2ee8SDavid du Colombier op = 0;
269375daca8SDavid du Colombier /* on windows skip drive specifier in pathname */
270375daca8SDavid du Colombier if(systemtype(Windows) && p && p[1] == ':'){
271375daca8SDavid du Colombier p += 2;
272375daca8SDavid du Colombier c = *p;
273375daca8SDavid du Colombier }
2747dd7cddfSDavid du Colombier if(p && p[0] != c && h->offset == 0 && pathname){
2757dd7cddfSDavid du Colombier /* on windows skip drive specifier in pathname */
276375daca8SDavid du Colombier if(systemtype(Windows) && pathname[1] == ':') {
2777dd7cddfSDavid du Colombier op = p;
2787dd7cddfSDavid du Colombier p = pathname+2;
279375daca8SDavid du Colombier c = *p;
2807dd7cddfSDavid du Colombier } else if(pathname[0] == c){
281219b2ee8SDavid du Colombier op = p;
282219b2ee8SDavid du Colombier p = pathname;
283219b2ee8SDavid du Colombier }
2847dd7cddfSDavid du Colombier }
2853e12c5d1SDavid du Colombier while(p) {
2867dd7cddfSDavid du Colombier q = utfrune(p, c);
2873e12c5d1SDavid du Colombier if(q) {
2883e12c5d1SDavid du Colombier n = q-p;
289375daca8SDavid du Colombier if(n == 0){
2903e12c5d1SDavid du Colombier n = 1; /* leading "/" */
291375daca8SDavid du Colombier *p = '/'; /* don't emit "\" on windows */
292375daca8SDavid du Colombier }
2933e12c5d1SDavid du Colombier q++;
2943e12c5d1SDavid du Colombier } else {
2953e12c5d1SDavid du Colombier n = strlen(p);
2963e12c5d1SDavid du Colombier q = 0;
2973e12c5d1SDavid du Colombier }
2983e12c5d1SDavid du Colombier if(n) {
299219b2ee8SDavid du Colombier Bputc(b, ANAME);
300219b2ee8SDavid du Colombier Bputc(b, ANAME>>8);
301219b2ee8SDavid du Colombier Bputc(b, D_FILE);
302219b2ee8SDavid du Colombier Bputc(b, 1);
303219b2ee8SDavid du Colombier Bputc(b, '<');
304219b2ee8SDavid du Colombier Bwrite(b, p, n);
305219b2ee8SDavid du Colombier Bputc(b, 0);
3063e12c5d1SDavid du Colombier }
3073e12c5d1SDavid du Colombier p = q;
308219b2ee8SDavid du Colombier if(p == 0 && op) {
309219b2ee8SDavid du Colombier p = op;
310219b2ee8SDavid du Colombier op = 0;
311219b2ee8SDavid du Colombier }
3123e12c5d1SDavid du Colombier }
3133e12c5d1SDavid du Colombier pg.lineno = h->line;
3143e12c5d1SDavid du Colombier pg.to.type = zprog.to.type;
3153e12c5d1SDavid du Colombier pg.to.offset = h->offset;
3163e12c5d1SDavid du Colombier if(h->offset)
3173e12c5d1SDavid du Colombier pg.to.type = D_CONST;
3183e12c5d1SDavid du Colombier
3193e12c5d1SDavid du Colombier Bputc(b, pg.as);
3203e12c5d1SDavid du Colombier Bputc(b, pg.as>>8);
3213e12c5d1SDavid du Colombier Bputc(b, pg.lineno);
3223e12c5d1SDavid du Colombier Bputc(b, pg.lineno>>8);
3233e12c5d1SDavid du Colombier Bputc(b, pg.lineno>>16);
3243e12c5d1SDavid du Colombier Bputc(b, pg.lineno>>24);
3253e12c5d1SDavid du Colombier zaddr(b, &pg.from, 0);
3263e12c5d1SDavid du Colombier zaddr(b, &pg.to, 0);
3273e12c5d1SDavid du Colombier }
3283e12c5d1SDavid du Colombier }
3293e12c5d1SDavid du Colombier
3303e12c5d1SDavid du Colombier void
zname(Biobuf * b,Sym * s,int t)331375daca8SDavid du Colombier zname(Biobuf *b, Sym *s, int t)
3323e12c5d1SDavid du Colombier {
333375daca8SDavid du Colombier char *n;
334375daca8SDavid du Colombier ulong sig;
3353e12c5d1SDavid du Colombier
336375daca8SDavid du Colombier if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
337375daca8SDavid du Colombier sig = sign(s);
338375daca8SDavid du Colombier Bputc(b, ASIGNAME);
339375daca8SDavid du Colombier Bputc(b, ASIGNAME>>8);
340375daca8SDavid du Colombier Bputc(b, sig);
341375daca8SDavid du Colombier Bputc(b, sig>>8);
342375daca8SDavid du Colombier Bputc(b, sig>>16);
343375daca8SDavid du Colombier Bputc(b, sig>>24);
344375daca8SDavid du Colombier s->sig = SIGDONE;
345375daca8SDavid du Colombier }
346375daca8SDavid du Colombier else{
3473e12c5d1SDavid du Colombier Bputc(b, ANAME); /* as */
3483e12c5d1SDavid du Colombier Bputc(b, ANAME>>8); /* as */
349375daca8SDavid du Colombier }
3503e12c5d1SDavid du Colombier Bputc(b, t); /* type */
351375daca8SDavid du Colombier Bputc(b, s->sym); /* sym */
352375daca8SDavid du Colombier n = s->name;
3533e12c5d1SDavid du Colombier while(*n) {
3543e12c5d1SDavid du Colombier Bputc(b, *n);
3553e12c5d1SDavid du Colombier n++;
3563e12c5d1SDavid du Colombier }
3573e12c5d1SDavid du Colombier Bputc(b, 0);
3583e12c5d1SDavid du Colombier }
3593e12c5d1SDavid du Colombier
3603e12c5d1SDavid du Colombier void
zaddr(Biobuf * b,Adr * a,int s)3613e12c5d1SDavid du Colombier zaddr(Biobuf *b, Adr *a, int s)
3623e12c5d1SDavid du Colombier {
3633e12c5d1SDavid du Colombier long l;
3643e12c5d1SDavid du Colombier int i, t;
3653e12c5d1SDavid du Colombier char *n;
3663e12c5d1SDavid du Colombier Ieee e;
3673e12c5d1SDavid du Colombier
3683e12c5d1SDavid du Colombier t = 0;
3693e12c5d1SDavid du Colombier if(a->index != D_NONE || a->scale != 0)
3703e12c5d1SDavid du Colombier t |= T_INDEX;
3713e12c5d1SDavid du Colombier if(s != 0)
3723e12c5d1SDavid du Colombier t |= T_SYM;
3733e12c5d1SDavid du Colombier
3743e12c5d1SDavid du Colombier switch(a->type) {
3753e12c5d1SDavid du Colombier default:
3763e12c5d1SDavid du Colombier t |= T_TYPE;
3773e12c5d1SDavid du Colombier case D_NONE:
3783e12c5d1SDavid du Colombier if(a->offset != 0)
3793e12c5d1SDavid du Colombier t |= T_OFFSET;
3803e12c5d1SDavid du Colombier break;
3813e12c5d1SDavid du Colombier case D_FCONST:
3823e12c5d1SDavid du Colombier t |= T_FCONST;
3833e12c5d1SDavid du Colombier break;
3843e12c5d1SDavid du Colombier case D_SCONST:
3853e12c5d1SDavid du Colombier t |= T_SCONST;
3863e12c5d1SDavid du Colombier break;
3873e12c5d1SDavid du Colombier }
3883e12c5d1SDavid du Colombier Bputc(b, t);
3893e12c5d1SDavid du Colombier
3903e12c5d1SDavid du Colombier if(t & T_INDEX) { /* implies index, scale */
3913e12c5d1SDavid du Colombier Bputc(b, a->index);
3923e12c5d1SDavid du Colombier Bputc(b, a->scale);
3933e12c5d1SDavid du Colombier }
3943e12c5d1SDavid du Colombier if(t & T_OFFSET) { /* implies offset */
3953e12c5d1SDavid du Colombier l = a->offset;
3963e12c5d1SDavid du Colombier Bputc(b, l);
3973e12c5d1SDavid du Colombier Bputc(b, l>>8);
3983e12c5d1SDavid du Colombier Bputc(b, l>>16);
3993e12c5d1SDavid du Colombier Bputc(b, l>>24);
4003e12c5d1SDavid du Colombier }
4013e12c5d1SDavid du Colombier if(t & T_SYM) /* implies sym */
4023e12c5d1SDavid du Colombier Bputc(b, s);
4033e12c5d1SDavid du Colombier if(t & T_FCONST) {
4043e12c5d1SDavid du Colombier ieeedtod(&e, a->dval);
4053e12c5d1SDavid du Colombier l = e.l;
4063e12c5d1SDavid du Colombier Bputc(b, l);
4073e12c5d1SDavid du Colombier Bputc(b, l>>8);
4083e12c5d1SDavid du Colombier Bputc(b, l>>16);
4093e12c5d1SDavid du Colombier Bputc(b, l>>24);
4103e12c5d1SDavid du Colombier l = e.h;
4113e12c5d1SDavid du Colombier Bputc(b, l);
4123e12c5d1SDavid du Colombier Bputc(b, l>>8);
4133e12c5d1SDavid du Colombier Bputc(b, l>>16);
4143e12c5d1SDavid du Colombier Bputc(b, l>>24);
4153e12c5d1SDavid du Colombier return;
4163e12c5d1SDavid du Colombier }
4173e12c5d1SDavid du Colombier if(t & T_SCONST) {
4183e12c5d1SDavid du Colombier n = a->sval;
4193e12c5d1SDavid du Colombier for(i=0; i<NSNAME; i++) {
4203e12c5d1SDavid du Colombier Bputc(b, *n);
4213e12c5d1SDavid du Colombier n++;
4223e12c5d1SDavid du Colombier }
4233e12c5d1SDavid du Colombier return;
4243e12c5d1SDavid du Colombier }
4253e12c5d1SDavid du Colombier if(t & T_TYPE)
4263e12c5d1SDavid du Colombier Bputc(b, a->type);
4273e12c5d1SDavid du Colombier }
4283e12c5d1SDavid du Colombier
4297dd7cddfSDavid du Colombier long
align(long i,Type * t,int op)4307dd7cddfSDavid du Colombier align(long i, Type *t, int op)
4313e12c5d1SDavid du Colombier {
4327dd7cddfSDavid du Colombier long o;
4337dd7cddfSDavid du Colombier Type *v;
4347dd7cddfSDavid du Colombier int w;
4353e12c5d1SDavid du Colombier
4367dd7cddfSDavid du Colombier o = i;
4377dd7cddfSDavid du Colombier w = 1;
4387dd7cddfSDavid du Colombier switch(op) {
4397dd7cddfSDavid du Colombier default:
4407dd7cddfSDavid du Colombier diag(Z, "unknown align opcode %d", op);
4417dd7cddfSDavid du Colombier break;
4427dd7cddfSDavid du Colombier
4437dd7cddfSDavid du Colombier case Asu2: /* padding at end of a struct */
4447dd7cddfSDavid du Colombier w = SZ_LONG;
4459847521cSDavid du Colombier if(packflg)
4469847521cSDavid du Colombier w = packflg;
4477dd7cddfSDavid du Colombier break;
4487dd7cddfSDavid du Colombier
4497dd7cddfSDavid du Colombier case Ael1: /* initial allign of struct element */
4507dd7cddfSDavid du Colombier for(v=t; v->etype==TARRAY; v=v->link)
4517dd7cddfSDavid du Colombier ;
4527dd7cddfSDavid du Colombier w = ewidth[v->etype];
4537dd7cddfSDavid du Colombier if(w <= 0 || w >= SZ_LONG)
4547dd7cddfSDavid du Colombier w = SZ_LONG;
4559847521cSDavid du Colombier if(packflg)
4569847521cSDavid du Colombier w = packflg;
4577dd7cddfSDavid du Colombier break;
4587dd7cddfSDavid du Colombier
4597dd7cddfSDavid du Colombier case Ael2: /* width of a struct element */
4607dd7cddfSDavid du Colombier o += t->width;
4617dd7cddfSDavid du Colombier break;
4627dd7cddfSDavid du Colombier
4637dd7cddfSDavid du Colombier case Aarg0: /* initial passbyptr argument in arg list */
4647dd7cddfSDavid du Colombier if(typesuv[t->etype]) {
4657dd7cddfSDavid du Colombier o = align(o, types[TIND], Aarg1);
4667dd7cddfSDavid du Colombier o = align(o, types[TIND], Aarg2);
4677dd7cddfSDavid du Colombier }
4687dd7cddfSDavid du Colombier break;
4697dd7cddfSDavid du Colombier
4707dd7cddfSDavid du Colombier case Aarg1: /* initial allign of parameter */
4717dd7cddfSDavid du Colombier w = ewidth[t->etype];
4727dd7cddfSDavid du Colombier if(w <= 0 || w >= SZ_LONG) {
4737dd7cddfSDavid du Colombier w = SZ_LONG;
4747dd7cddfSDavid du Colombier break;
4757dd7cddfSDavid du Colombier }
4767dd7cddfSDavid du Colombier w = 1; /* little endian no adjustment */
4777dd7cddfSDavid du Colombier break;
4787dd7cddfSDavid du Colombier
4797dd7cddfSDavid du Colombier case Aarg2: /* width of a parameter */
4807dd7cddfSDavid du Colombier o += t->width;
4817dd7cddfSDavid du Colombier w = SZ_LONG;
4827dd7cddfSDavid du Colombier break;
4837dd7cddfSDavid du Colombier
4847dd7cddfSDavid du Colombier case Aaut3: /* total allign of automatic */
4857dd7cddfSDavid du Colombier o = align(o, t, Ael1);
4867dd7cddfSDavid du Colombier o = align(o, t, Ael2);
4877dd7cddfSDavid du Colombier break;
4887dd7cddfSDavid du Colombier }
4897dd7cddfSDavid du Colombier o = round(o, w);
4907dd7cddfSDavid du Colombier if(debug['A'])
4917dd7cddfSDavid du Colombier print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
4927dd7cddfSDavid du Colombier return o;
4933e12c5d1SDavid du Colombier }
4943e12c5d1SDavid du Colombier
4957dd7cddfSDavid du Colombier long
maxround(long max,long v)4967dd7cddfSDavid du Colombier maxround(long max, long v)
4973e12c5d1SDavid du Colombier {
49885e2e562SDavid du Colombier v = round(v, SZ_LONG);
4997dd7cddfSDavid du Colombier if(v > max)
50085e2e562SDavid du Colombier return v;
5017dd7cddfSDavid du Colombier return max;
502219b2ee8SDavid du Colombier }
503