17edc7532SDavid du Colombier #include "gc.h"
27edc7532SDavid du Colombier
37edc7532SDavid du Colombier void
swit1(C1 * q,int nc,long def,Node * n)4*f8bc6aafSDavid du Colombier swit1(C1 *q, int nc, long def, Node *n)
57edc7532SDavid du Colombier {
67edc7532SDavid du Colombier Node tn;
77edc7532SDavid du Colombier
87edc7532SDavid du Colombier regalloc(&tn, ®node, Z);
9*f8bc6aafSDavid du Colombier swit2(q, nc, def, n, &tn);
107edc7532SDavid du Colombier regfree(&tn);
117edc7532SDavid du Colombier }
127edc7532SDavid du Colombier
137edc7532SDavid du Colombier void
swit2(C1 * q,int nc,long def,Node * n,Node * tn)14*f8bc6aafSDavid du Colombier swit2(C1 *q, int nc, long def, Node *n, Node *tn)
157edc7532SDavid du Colombier {
167edc7532SDavid du Colombier C1 *r;
177edc7532SDavid du Colombier int i;
187edc7532SDavid du Colombier Prog *sp;
197edc7532SDavid du Colombier
207edc7532SDavid du Colombier if(nc < 5) {
217edc7532SDavid du Colombier for(i=0; i<nc; i++) {
22*f8bc6aafSDavid du Colombier if(debug['K'])
23*f8bc6aafSDavid du Colombier print("case = %.8llux\n", q->val);
247edc7532SDavid du Colombier gmove(nodconst(q->val), tn);
257edc7532SDavid du Colombier gopcode(OEQ, n, tn, Z);
267edc7532SDavid du Colombier patch(p, q->label);
277edc7532SDavid du Colombier q++;
287edc7532SDavid du Colombier }
297edc7532SDavid du Colombier gbranch(OGOTO);
307edc7532SDavid du Colombier patch(p, def);
317edc7532SDavid du Colombier return;
327edc7532SDavid du Colombier }
337edc7532SDavid du Colombier i = nc / 2;
347edc7532SDavid du Colombier r = q+i;
35*f8bc6aafSDavid du Colombier if(debug['K'])
36*f8bc6aafSDavid du Colombier print("case > %.8llux\n", r->val);
377edc7532SDavid du Colombier gmove(nodconst(r->val), tn);
387edc7532SDavid du Colombier gopcode(OLT, tn, n, Z);
397edc7532SDavid du Colombier sp = p;
407edc7532SDavid du Colombier gopcode(OEQ, n, tn, Z);
417edc7532SDavid du Colombier patch(p, r->label);
42*f8bc6aafSDavid du Colombier swit2(q, i, def, n, tn);
437edc7532SDavid du Colombier
44*f8bc6aafSDavid du Colombier if(debug['K'])
45*f8bc6aafSDavid du Colombier print("case < %.8llux\n", r->val);
467edc7532SDavid du Colombier patch(sp, pc);
47*f8bc6aafSDavid du Colombier swit2(r+1, nc-i-1, def, n, tn);
487edc7532SDavid du Colombier }
497edc7532SDavid du Colombier
507edc7532SDavid du Colombier void
bitload(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)517edc7532SDavid du Colombier bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
527edc7532SDavid du Colombier {
537edc7532SDavid du Colombier int sh;
547edc7532SDavid du Colombier long v;
557edc7532SDavid du Colombier Node *l;
567edc7532SDavid du Colombier
577edc7532SDavid du Colombier /*
587edc7532SDavid du Colombier * n1 gets adjusted/masked value
597edc7532SDavid du Colombier * n2 gets address of cell
607edc7532SDavid du Colombier * n3 gets contents of cell
617edc7532SDavid du Colombier */
627edc7532SDavid du Colombier l = b->left;
637edc7532SDavid du Colombier if(n2 != Z) {
647edc7532SDavid du Colombier regalloc(n1, l, nn);
657edc7532SDavid du Colombier reglcgen(n2, l, Z);
667edc7532SDavid du Colombier regalloc(n3, l, Z);
677edc7532SDavid du Colombier gopcode(OAS, n2, Z, n3);
687edc7532SDavid du Colombier gopcode(OAS, n3, Z, n1);
697edc7532SDavid du Colombier } else {
707edc7532SDavid du Colombier regalloc(n1, l, nn);
717edc7532SDavid du Colombier cgen(l, n1);
727edc7532SDavid du Colombier }
737edc7532SDavid du Colombier if(b->type->shift == 0 && typeu[b->type->etype]) {
747edc7532SDavid du Colombier v = ~0 + (1L << b->type->nbits);
757edc7532SDavid du Colombier gopcode(OAND, nodconst(v), Z, n1);
767edc7532SDavid du Colombier } else {
777edc7532SDavid du Colombier sh = 32 - b->type->shift - b->type->nbits;
787edc7532SDavid du Colombier if(sh > 0)
797edc7532SDavid du Colombier gopcode(OASHL, nodconst(sh), Z, n1);
807edc7532SDavid du Colombier sh += b->type->shift;
817edc7532SDavid du Colombier if(sh > 0)
827edc7532SDavid du Colombier if(typeu[b->type->etype])
837edc7532SDavid du Colombier gopcode(OLSHR, nodconst(sh), Z, n1);
847edc7532SDavid du Colombier else
857edc7532SDavid du Colombier gopcode(OASHR, nodconst(sh), Z, n1);
867edc7532SDavid du Colombier }
877edc7532SDavid du Colombier }
887edc7532SDavid du Colombier
897edc7532SDavid du Colombier void
bitstore(Node * b,Node * n1,Node * n2,Node * n3,Node * nn)907edc7532SDavid du Colombier bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
917edc7532SDavid du Colombier {
927edc7532SDavid du Colombier long v;
937edc7532SDavid du Colombier Node nod, *l;
947edc7532SDavid du Colombier int sh;
957edc7532SDavid du Colombier
967edc7532SDavid du Colombier /*
977edc7532SDavid du Colombier * n1 has adjusted/masked value
987edc7532SDavid du Colombier * n2 has address of cell
997edc7532SDavid du Colombier * n3 has contents of cell
1007edc7532SDavid du Colombier */
1017edc7532SDavid du Colombier l = b->left;
1027edc7532SDavid du Colombier regalloc(&nod, l, Z);
1037edc7532SDavid du Colombier v = ~0 + (1L << b->type->nbits);
1047edc7532SDavid du Colombier gopcode(OAND, nodconst(v), Z, n1);
1057edc7532SDavid du Colombier gopcode(OAS, n1, Z, &nod);
1067edc7532SDavid du Colombier if(nn != Z)
1077edc7532SDavid du Colombier gopcode(OAS, n1, Z, nn);
1087edc7532SDavid du Colombier sh = b->type->shift;
1097edc7532SDavid du Colombier if(sh > 0)
1107edc7532SDavid du Colombier gopcode(OASHL, nodconst(sh), Z, &nod);
1117edc7532SDavid du Colombier v <<= sh;
1127edc7532SDavid du Colombier gopcode(OAND, nodconst(~v), Z, n3);
1137edc7532SDavid du Colombier gopcode(OOR, n3, Z, &nod);
1147edc7532SDavid du Colombier gopcode(OAS, &nod, Z, n2);
1157edc7532SDavid du Colombier
1167edc7532SDavid du Colombier regfree(&nod);
1177edc7532SDavid du Colombier regfree(n1);
1187edc7532SDavid du Colombier regfree(n2);
1197edc7532SDavid du Colombier regfree(n3);
1207edc7532SDavid du Colombier }
1217edc7532SDavid du Colombier
1227edc7532SDavid du Colombier long
outstring(char * s,long n)1237edc7532SDavid du Colombier outstring(char *s, long n)
1247edc7532SDavid du Colombier {
1257edc7532SDavid du Colombier long r;
1267edc7532SDavid du Colombier
127*f8bc6aafSDavid du Colombier if(suppress)
128*f8bc6aafSDavid du Colombier return nstring;
1297edc7532SDavid du Colombier r = nstring;
1307edc7532SDavid du Colombier while(n) {
1317edc7532SDavid du Colombier string[mnstring] = *s++;
1327edc7532SDavid du Colombier mnstring++;
1337edc7532SDavid du Colombier nstring++;
1347edc7532SDavid du Colombier if(mnstring >= NSNAME) {
1357edc7532SDavid du Colombier gpseudo(ADATA, symstring, nodconst(0L));
1367edc7532SDavid du Colombier p->from.offset += nstring - NSNAME;
1377edc7532SDavid du Colombier p->reg = NSNAME;
1387edc7532SDavid du Colombier p->to.type = D_SCONST;
1397edc7532SDavid du Colombier memmove(p->to.sval, string, NSNAME);
1407edc7532SDavid du Colombier mnstring = 0;
1417edc7532SDavid du Colombier }
1427edc7532SDavid du Colombier n--;
1437edc7532SDavid du Colombier }
1447edc7532SDavid du Colombier return r;
1457edc7532SDavid du Colombier }
1467edc7532SDavid du Colombier
1477edc7532SDavid du Colombier int
mulcon(Node * n,Node * nn)1487edc7532SDavid du Colombier mulcon(Node *n, Node *nn)
1497edc7532SDavid du Colombier {
1507edc7532SDavid du Colombier Node *l, *r, nod1, nod2;
1517edc7532SDavid du Colombier Multab *m;
1527edc7532SDavid du Colombier long v;
1537edc7532SDavid du Colombier int o;
1547edc7532SDavid du Colombier char code[sizeof(m->code)+2], *p;
1557edc7532SDavid du Colombier
1567edc7532SDavid du Colombier if(typefd[n->type->etype])
1577edc7532SDavid du Colombier return 0;
1587edc7532SDavid du Colombier l = n->left;
1597edc7532SDavid du Colombier r = n->right;
1607edc7532SDavid du Colombier if(l->op == OCONST) {
1617edc7532SDavid du Colombier l = r;
1627edc7532SDavid du Colombier r = n->left;
1637edc7532SDavid du Colombier }
1647edc7532SDavid du Colombier if(r->op != OCONST)
1657edc7532SDavid du Colombier return 0;
1667edc7532SDavid du Colombier v = convvtox(r->vconst, n->type->etype);
1677edc7532SDavid du Colombier if(v != r->vconst) {
1687edc7532SDavid du Colombier if(debug['M'])
1697edc7532SDavid du Colombier print("%L multiply conv: %lld\n", n->lineno, r->vconst);
1707edc7532SDavid du Colombier return 0;
1717edc7532SDavid du Colombier }
1727edc7532SDavid du Colombier m = mulcon0(v);
1737edc7532SDavid du Colombier if(!m) {
1747edc7532SDavid du Colombier if(debug['M'])
1757edc7532SDavid du Colombier print("%L multiply table: %lld\n", n->lineno, r->vconst);
1767edc7532SDavid du Colombier return 0;
1777edc7532SDavid du Colombier }
1787edc7532SDavid du Colombier if(debug['M'] && debug['v'])
1797edc7532SDavid du Colombier print("%L multiply: %ld\n", n->lineno, v);
1807edc7532SDavid du Colombier
1817edc7532SDavid du Colombier memmove(code, m->code, sizeof(m->code));
1827edc7532SDavid du Colombier code[sizeof(m->code)] = 0;
1837edc7532SDavid du Colombier
1847edc7532SDavid du Colombier p = code;
1857edc7532SDavid du Colombier if(p[1] == 'i')
1867edc7532SDavid du Colombier p += 2;
1877edc7532SDavid du Colombier regalloc(&nod1, n, nn);
1887edc7532SDavid du Colombier cgen(l, &nod1);
1897edc7532SDavid du Colombier if(v < 0)
1907edc7532SDavid du Colombier gopcode(OSUB, &nod1, nodconst(0), &nod1);
1917edc7532SDavid du Colombier regalloc(&nod2, n, Z);
1927edc7532SDavid du Colombier
1937edc7532SDavid du Colombier loop:
1947edc7532SDavid du Colombier switch(*p) {
1957edc7532SDavid du Colombier case 0:
1967edc7532SDavid du Colombier regfree(&nod2);
1977edc7532SDavid du Colombier gopcode(OAS, &nod1, Z, nn);
1987edc7532SDavid du Colombier regfree(&nod1);
1997edc7532SDavid du Colombier return 1;
2007edc7532SDavid du Colombier case '+':
2017edc7532SDavid du Colombier o = OADD;
2027edc7532SDavid du Colombier goto addsub;
2037edc7532SDavid du Colombier case '-':
2047edc7532SDavid du Colombier o = OSUB;
2057edc7532SDavid du Colombier addsub: /* number is r,n,l */
2067edc7532SDavid du Colombier v = p[1] - '0';
2077edc7532SDavid du Colombier r = &nod1;
2087edc7532SDavid du Colombier if(v&4)
2097edc7532SDavid du Colombier r = &nod2;
2107edc7532SDavid du Colombier n = &nod1;
2117edc7532SDavid du Colombier if(v&2)
2127edc7532SDavid du Colombier n = &nod2;
2137edc7532SDavid du Colombier l = &nod1;
2147edc7532SDavid du Colombier if(v&1)
2157edc7532SDavid du Colombier l = &nod2;
2167edc7532SDavid du Colombier gopcode(o, l, n, r);
2177edc7532SDavid du Colombier break;
2187edc7532SDavid du Colombier default: /* op is shiftcount, number is r,l */
2197edc7532SDavid du Colombier v = p[1] - '0';
2207edc7532SDavid du Colombier r = &nod1;
2217edc7532SDavid du Colombier if(v&2)
2227edc7532SDavid du Colombier r = &nod2;
2237edc7532SDavid du Colombier l = &nod1;
2247edc7532SDavid du Colombier if(v&1)
2257edc7532SDavid du Colombier l = &nod2;
2267edc7532SDavid du Colombier v = *p - 'a';
2277edc7532SDavid du Colombier if(v < 0 || v >= 32) {
2287edc7532SDavid du Colombier diag(n, "mulcon unknown op: %c%c", p[0], p[1]);
2297edc7532SDavid du Colombier break;
2307edc7532SDavid du Colombier }
2317edc7532SDavid du Colombier gopcode(OASHL, nodconst(v), l, r);
2327edc7532SDavid du Colombier break;
2337edc7532SDavid du Colombier }
2347edc7532SDavid du Colombier p += 2;
2357edc7532SDavid du Colombier goto loop;
2367edc7532SDavid du Colombier }
2377edc7532SDavid du Colombier
2387edc7532SDavid du Colombier void
gextern(Sym * s,Node * a,long o,long w)2397edc7532SDavid du Colombier gextern(Sym *s, Node *a, long o, long w)
2407edc7532SDavid du Colombier {
2417edc7532SDavid du Colombier
2427edc7532SDavid du Colombier if(a->op == OCONST && typev[a->type->etype]) {
243*f8bc6aafSDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
244*f8bc6aafSDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst>>32));
245*f8bc6aafSDavid du Colombier else
246*f8bc6aafSDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst));
2477edc7532SDavid du Colombier p->from.offset += o;
2487edc7532SDavid du Colombier p->reg = 4;
249*f8bc6aafSDavid du Colombier if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
250*f8bc6aafSDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst));
251*f8bc6aafSDavid du Colombier else
252*f8bc6aafSDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst>>32));
2537edc7532SDavid du Colombier p->from.offset += o + 4;
2547edc7532SDavid du Colombier p->reg = 4;
2557edc7532SDavid du Colombier return;
2567edc7532SDavid du Colombier }
2577edc7532SDavid du Colombier gpseudo(ADATA, s, a);
2587edc7532SDavid du Colombier p->from.offset += o;
2597edc7532SDavid du Colombier p->reg = w;
2607edc7532SDavid du Colombier if(p->to.type == D_OREG)
2617edc7532SDavid du Colombier p->to.type = D_CONST;
2627edc7532SDavid du Colombier }
2637edc7532SDavid du Colombier
264*f8bc6aafSDavid du Colombier void zname(Biobuf*, Sym*, int);
2657edc7532SDavid du Colombier char* zaddr(char*, Adr*, int);
2667edc7532SDavid du Colombier void zwrite(Biobuf*, Prog*, int, int);
2677edc7532SDavid du Colombier void outhist(Biobuf*);
2687edc7532SDavid du Colombier
2697edc7532SDavid du Colombier void
zwrite(Biobuf * b,Prog * p,int sf,int st)2707edc7532SDavid du Colombier zwrite(Biobuf *b, Prog *p, int sf, int st)
2717edc7532SDavid du Colombier {
2727edc7532SDavid du Colombier char bf[100], *bp;
2737edc7532SDavid du Colombier
2747edc7532SDavid du Colombier bf[0] = p->as;
2757edc7532SDavid du Colombier bf[1] = p->reg;
2767edc7532SDavid du Colombier bf[2] = p->lineno;
2777edc7532SDavid du Colombier bf[3] = p->lineno>>8;
2787edc7532SDavid du Colombier bf[4] = p->lineno>>16;
2797edc7532SDavid du Colombier bf[5] = p->lineno>>24;
2807edc7532SDavid du Colombier bp = zaddr(bf+6, &p->from, sf);
2817edc7532SDavid du Colombier bp = zaddr(bp, &p->to, st);
2827edc7532SDavid du Colombier Bwrite(b, bf, bp-bf);
2837edc7532SDavid du Colombier }
2847edc7532SDavid du Colombier
2857edc7532SDavid du Colombier void
outcode(void)2867edc7532SDavid du Colombier outcode(void)
2877edc7532SDavid du Colombier {
2887edc7532SDavid du Colombier struct { Sym *sym; short type; } h[NSYM];
2897edc7532SDavid du Colombier Prog *p;
2907edc7532SDavid du Colombier Sym *s;
2917edc7532SDavid du Colombier int sf, st, t, sym;
2927edc7532SDavid du Colombier
2937edc7532SDavid du Colombier if(debug['S']) {
2947edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link)
2957edc7532SDavid du Colombier if(p->as != ADATA && p->as != AGLOBL)
2967edc7532SDavid du Colombier pc--;
2977edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link) {
2987edc7532SDavid du Colombier print("%P\n", p);
2997edc7532SDavid du Colombier if(p->as != ADATA && p->as != AGLOBL)
3007edc7532SDavid du Colombier pc++;
3017edc7532SDavid du Colombier }
3027edc7532SDavid du Colombier }
3037edc7532SDavid du Colombier outhist(&outbuf);
3047edc7532SDavid du Colombier for(sym=0; sym<NSYM; sym++) {
3057edc7532SDavid du Colombier h[sym].sym = S;
3067edc7532SDavid du Colombier h[sym].type = 0;
3077edc7532SDavid du Colombier }
3087edc7532SDavid du Colombier sym = 1;
3097edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link) {
3107edc7532SDavid du Colombier jackpot:
3117edc7532SDavid du Colombier sf = 0;
3127edc7532SDavid du Colombier s = p->from.sym;
3137edc7532SDavid du Colombier while(s != S) {
3147edc7532SDavid du Colombier sf = s->sym;
3157edc7532SDavid du Colombier if(sf < 0 || sf >= NSYM)
3167edc7532SDavid du Colombier sf = 0;
3177edc7532SDavid du Colombier t = p->from.name;
3187edc7532SDavid du Colombier if(h[sf].type == t)
3197edc7532SDavid du Colombier if(h[sf].sym == s)
3207edc7532SDavid du Colombier break;
3217edc7532SDavid du Colombier s->sym = sym;
322*f8bc6aafSDavid du Colombier zname(&outbuf, s, t);
3237edc7532SDavid du Colombier h[sym].sym = s;
3247edc7532SDavid du Colombier h[sym].type = t;
3257edc7532SDavid du Colombier sf = sym;
3267edc7532SDavid du Colombier sym++;
3277edc7532SDavid du Colombier if(sym >= NSYM)
3287edc7532SDavid du Colombier sym = 1;
3297edc7532SDavid du Colombier break;
3307edc7532SDavid du Colombier }
3317edc7532SDavid du Colombier st = 0;
3327edc7532SDavid du Colombier s = p->to.sym;
3337edc7532SDavid du Colombier while(s != S) {
3347edc7532SDavid du Colombier st = s->sym;
3357edc7532SDavid du Colombier if(st < 0 || st >= NSYM)
3367edc7532SDavid du Colombier st = 0;
3377edc7532SDavid du Colombier t = p->to.name;
3387edc7532SDavid du Colombier if(h[st].type == t)
3397edc7532SDavid du Colombier if(h[st].sym == s)
3407edc7532SDavid du Colombier break;
3417edc7532SDavid du Colombier s->sym = sym;
342*f8bc6aafSDavid du Colombier zname(&outbuf, s, t);
3437edc7532SDavid du Colombier h[sym].sym = s;
3447edc7532SDavid du Colombier h[sym].type = t;
3457edc7532SDavid du Colombier st = sym;
3467edc7532SDavid du Colombier sym++;
3477edc7532SDavid du Colombier if(sym >= NSYM)
3487edc7532SDavid du Colombier sym = 1;
3497edc7532SDavid du Colombier if(st == sf)
3507edc7532SDavid du Colombier goto jackpot;
3517edc7532SDavid du Colombier break;
3527edc7532SDavid du Colombier }
3537edc7532SDavid du Colombier zwrite(&outbuf, p, sf, st);
3547edc7532SDavid du Colombier }
3557edc7532SDavid du Colombier firstp = P;
3567edc7532SDavid du Colombier lastp = P;
3577edc7532SDavid du Colombier }
3587edc7532SDavid du Colombier
3597edc7532SDavid du Colombier void
outhist(Biobuf * b)3607edc7532SDavid du Colombier outhist(Biobuf *b)
3617edc7532SDavid du Colombier {
3627edc7532SDavid du Colombier Hist *h;
3637edc7532SDavid du Colombier char *p, *q, *op, c;
3647edc7532SDavid du Colombier Prog pg;
3657edc7532SDavid du Colombier int n;
3667edc7532SDavid du Colombier
3677edc7532SDavid du Colombier pg = zprog;
3687edc7532SDavid du Colombier pg.as = AHISTORY;
3697edc7532SDavid du Colombier c = pathchar();
3707edc7532SDavid du Colombier for(h = hist; h != H; h = h->link) {
3717edc7532SDavid du Colombier p = h->name;
3727edc7532SDavid du Colombier op = 0;
373*f8bc6aafSDavid du Colombier /* on windows skip drive specifier in pathname */
374*f8bc6aafSDavid du Colombier if(systemtype(Windows) && p && p[1] == ':'){
375*f8bc6aafSDavid du Colombier p += 2;
376*f8bc6aafSDavid du Colombier c = *p;
377*f8bc6aafSDavid du Colombier }
3787edc7532SDavid du Colombier if(p && p[0] != c && h->offset == 0 && pathname){
3797edc7532SDavid du Colombier /* on windows skip drive specifier in pathname */
380*f8bc6aafSDavid du Colombier if(systemtype(Windows) && pathname[1] == ':') {
3817edc7532SDavid du Colombier op = p;
3827edc7532SDavid du Colombier p = pathname+2;
383*f8bc6aafSDavid du Colombier c = *p;
3847edc7532SDavid du Colombier } else if(pathname[0] == c){
3857edc7532SDavid du Colombier op = p;
3867edc7532SDavid du Colombier p = pathname;
3877edc7532SDavid du Colombier }
3887edc7532SDavid du Colombier }
3897edc7532SDavid du Colombier while(p) {
3907edc7532SDavid du Colombier q = utfrune(p, c);
3917edc7532SDavid du Colombier if(q) {
3927edc7532SDavid du Colombier n = q-p;
393*f8bc6aafSDavid du Colombier if(n == 0){
3947edc7532SDavid du Colombier n = 1; /* leading "/" */
395*f8bc6aafSDavid du Colombier *p = '/'; /* don't emit "\" on windows */
396*f8bc6aafSDavid du Colombier }
3977edc7532SDavid du Colombier q++;
3987edc7532SDavid du Colombier } else {
3997edc7532SDavid du Colombier n = strlen(p);
4007edc7532SDavid du Colombier q = 0;
4017edc7532SDavid du Colombier }
4027edc7532SDavid du Colombier if(n) {
4037edc7532SDavid du Colombier Bputc(b, ANAME);
4047edc7532SDavid du Colombier Bputc(b, D_FILE);
4057edc7532SDavid du Colombier Bputc(b, 1);
4067edc7532SDavid du Colombier Bputc(b, '<');
4077edc7532SDavid du Colombier Bwrite(b, p, n);
4087edc7532SDavid du Colombier Bputc(b, 0);
4097edc7532SDavid du Colombier }
4107edc7532SDavid du Colombier p = q;
4117edc7532SDavid du Colombier if(p == 0 && op) {
4127edc7532SDavid du Colombier p = op;
4137edc7532SDavid du Colombier op = 0;
4147edc7532SDavid du Colombier }
4157edc7532SDavid du Colombier }
4167edc7532SDavid du Colombier pg.lineno = h->line;
4177edc7532SDavid du Colombier pg.to.type = zprog.to.type;
4187edc7532SDavid du Colombier pg.to.offset = h->offset;
4197edc7532SDavid du Colombier if(h->offset)
4207edc7532SDavid du Colombier pg.to.type = D_CONST;
4217edc7532SDavid du Colombier
4227edc7532SDavid du Colombier zwrite(b, &pg, 0, 0);
4237edc7532SDavid du Colombier }
4247edc7532SDavid du Colombier }
4257edc7532SDavid du Colombier
4267edc7532SDavid du Colombier void
zname(Biobuf * b,Sym * s,int t)427*f8bc6aafSDavid du Colombier zname(Biobuf *b, Sym *s, int t)
4287edc7532SDavid du Colombier {
429*f8bc6aafSDavid du Colombier char *n, bf[7];
430*f8bc6aafSDavid du Colombier ulong sig;
4317edc7532SDavid du Colombier
432*f8bc6aafSDavid du Colombier n = s->name;
433*f8bc6aafSDavid du Colombier if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
434*f8bc6aafSDavid du Colombier sig = sign(s);
435*f8bc6aafSDavid du Colombier bf[0] = ASIGNAME;
436*f8bc6aafSDavid du Colombier bf[1] = sig;
437*f8bc6aafSDavid du Colombier bf[2] = sig>>8;
438*f8bc6aafSDavid du Colombier bf[3] = sig>>16;
439*f8bc6aafSDavid du Colombier bf[4] = sig>>24;
440*f8bc6aafSDavid du Colombier bf[5] = t;
441*f8bc6aafSDavid du Colombier bf[6] = s->sym;
442*f8bc6aafSDavid du Colombier Bwrite(b, bf, 7);
443*f8bc6aafSDavid du Colombier s->sig = SIGDONE;
444*f8bc6aafSDavid du Colombier }
445*f8bc6aafSDavid du Colombier else{
4467edc7532SDavid du Colombier bf[0] = ANAME;
4477edc7532SDavid du Colombier bf[1] = t; /* type */
448*f8bc6aafSDavid du Colombier bf[2] = s->sym; /* sym */
4497edc7532SDavid du Colombier Bwrite(b, bf, 3);
450*f8bc6aafSDavid du Colombier }
4517edc7532SDavid du Colombier Bwrite(b, n, strlen(n)+1);
4527edc7532SDavid du Colombier }
4537edc7532SDavid du Colombier
4547edc7532SDavid du Colombier char*
zaddr(char * bp,Adr * a,int s)4557edc7532SDavid du Colombier zaddr(char *bp, Adr *a, int s)
4567edc7532SDavid du Colombier {
4577edc7532SDavid du Colombier long l;
4587edc7532SDavid du Colombier Ieee e;
4597edc7532SDavid du Colombier
460*f8bc6aafSDavid du Colombier if(a->type == D_CONST) {
461*f8bc6aafSDavid du Colombier l = a->offset;
462*f8bc6aafSDavid du Colombier if((vlong)l != a->offset)
463*f8bc6aafSDavid du Colombier a->type = D_VCONST;
464*f8bc6aafSDavid du Colombier }
4657edc7532SDavid du Colombier bp[0] = a->type;
4667edc7532SDavid du Colombier bp[1] = a->reg;
4677edc7532SDavid du Colombier bp[2] = s;
4687edc7532SDavid du Colombier bp[3] = a->name;
4697edc7532SDavid du Colombier bp += 4;
4707edc7532SDavid du Colombier switch(a->type) {
4717edc7532SDavid du Colombier default:
4727edc7532SDavid du Colombier diag(Z, "unknown type %d in zaddr", a->type);
4737edc7532SDavid du Colombier
4747edc7532SDavid du Colombier case D_NONE:
4757edc7532SDavid du Colombier case D_REG:
4767edc7532SDavid du Colombier case D_FREG:
4777edc7532SDavid du Colombier case D_MREG:
4787edc7532SDavid du Colombier case D_FCREG:
4797edc7532SDavid du Colombier case D_LO:
4807edc7532SDavid du Colombier case D_HI:
4817edc7532SDavid du Colombier break;
4827edc7532SDavid du Colombier
4837edc7532SDavid du Colombier case D_OREG:
484*f8bc6aafSDavid du Colombier case D_CONST:
4857edc7532SDavid du Colombier case D_BRANCH:
4867edc7532SDavid du Colombier l = a->offset;
4877edc7532SDavid du Colombier bp[0] = l;
4887edc7532SDavid du Colombier bp[1] = l>>8;
4897edc7532SDavid du Colombier bp[2] = l>>16;
4907edc7532SDavid du Colombier bp[3] = l>>24;
4917edc7532SDavid du Colombier bp += 4;
4927edc7532SDavid du Colombier break;
4937edc7532SDavid du Colombier
4947edc7532SDavid du Colombier case D_SCONST:
4957edc7532SDavid du Colombier memmove(bp, a->sval, NSNAME);
4967edc7532SDavid du Colombier bp += NSNAME;
4977edc7532SDavid du Colombier break;
4987edc7532SDavid du Colombier
4997edc7532SDavid du Colombier case D_FCONST:
5007edc7532SDavid du Colombier ieeedtod(&e, a->dval);
5017edc7532SDavid du Colombier l = e.l;
5027edc7532SDavid du Colombier bp[0] = l;
5037edc7532SDavid du Colombier bp[1] = l>>8;
5047edc7532SDavid du Colombier bp[2] = l>>16;
5057edc7532SDavid du Colombier bp[3] = l>>24;
5067edc7532SDavid du Colombier bp += 4;
5077edc7532SDavid du Colombier l = e.h;
5087edc7532SDavid du Colombier bp[0] = l;
5097edc7532SDavid du Colombier bp[1] = l>>8;
5107edc7532SDavid du Colombier bp[2] = l>>16;
5117edc7532SDavid du Colombier bp[3] = l>>24;
5127edc7532SDavid du Colombier bp += 4;
5137edc7532SDavid du Colombier break;
5147edc7532SDavid du Colombier
5157edc7532SDavid du Colombier case D_VCONST:
516*f8bc6aafSDavid du Colombier l = a->offset;
517*f8bc6aafSDavid du Colombier bp[0] = l;
518*f8bc6aafSDavid du Colombier bp[1] = l>>8;
519*f8bc6aafSDavid du Colombier bp[2] = l>>16;
520*f8bc6aafSDavid du Colombier bp[3] = l>>24;
521*f8bc6aafSDavid du Colombier bp += 4;
522*f8bc6aafSDavid du Colombier l = a->offset>>32;
523*f8bc6aafSDavid du Colombier bp[0] = l;
524*f8bc6aafSDavid du Colombier bp[1] = l>>8;
525*f8bc6aafSDavid du Colombier bp[2] = l>>16;
526*f8bc6aafSDavid du Colombier bp[3] = l>>24;
527*f8bc6aafSDavid du Colombier bp += 4;
5287edc7532SDavid du Colombier break;
5297edc7532SDavid du Colombier }
5307edc7532SDavid du Colombier return bp;
5317edc7532SDavid du Colombier }
5327edc7532SDavid du Colombier
5337edc7532SDavid du Colombier long
align(long i,Type * t,int op)5347edc7532SDavid du Colombier align(long i, Type *t, int op)
5357edc7532SDavid du Colombier {
5367edc7532SDavid du Colombier long o;
5377edc7532SDavid du Colombier Type *v;
5387edc7532SDavid du Colombier int w;
5397edc7532SDavid du Colombier
5407edc7532SDavid du Colombier o = i;
5417edc7532SDavid du Colombier w = 1;
5427edc7532SDavid du Colombier switch(op) {
5437edc7532SDavid du Colombier default:
5447edc7532SDavid du Colombier diag(Z, "unknown align opcode %d", op);
5457edc7532SDavid du Colombier break;
5467edc7532SDavid du Colombier
5477edc7532SDavid du Colombier case Asu2: /* padding at end of a struct */
5487edc7532SDavid du Colombier w = SZ_VLONG;
549*f8bc6aafSDavid du Colombier if(packflg)
550*f8bc6aafSDavid du Colombier w = packflg;
5517edc7532SDavid du Colombier break;
5527edc7532SDavid du Colombier
5537edc7532SDavid du Colombier case Ael1: /* initial allign of struct element */
5547edc7532SDavid du Colombier for(v=t; v->etype==TARRAY; v=v->link)
5557edc7532SDavid du Colombier ;
5567edc7532SDavid du Colombier w = ewidth[v->etype];
5577edc7532SDavid du Colombier if(w <= 0 || w >= SZ_VLONG)
5587edc7532SDavid du Colombier w = SZ_VLONG;
559*f8bc6aafSDavid du Colombier if(packflg)
560*f8bc6aafSDavid du Colombier w = packflg;
5617edc7532SDavid du Colombier break;
5627edc7532SDavid du Colombier
5637edc7532SDavid du Colombier case Ael2: /* width of a struct element */
5647edc7532SDavid du Colombier o += t->width;
5657edc7532SDavid du Colombier break;
5667edc7532SDavid du Colombier
5677edc7532SDavid du Colombier case Aarg0: /* initial passbyptr argument in arg list */
5687edc7532SDavid du Colombier if(typesu[t->etype]) {
5697edc7532SDavid du Colombier o = align(o, types[TIND], Aarg1);
5707edc7532SDavid du Colombier o = align(o, types[TIND], Aarg2);
5717edc7532SDavid du Colombier }
5727edc7532SDavid du Colombier break;
5737edc7532SDavid du Colombier
5747edc7532SDavid du Colombier case Aarg1: /* initial allign of parameter */
5757edc7532SDavid du Colombier w = ewidth[t->etype];
5767edc7532SDavid du Colombier if(w <= 0 || w >= SZ_VLONG) {
5777edc7532SDavid du Colombier w = SZ_VLONG;
5787edc7532SDavid du Colombier break;
5797edc7532SDavid du Colombier }
580*f8bc6aafSDavid du Colombier if(thechar == '4')
581*f8bc6aafSDavid du Colombier o += SZ_VLONG - w; /* big endian adjustment */
5827edc7532SDavid du Colombier w = 1;
5837edc7532SDavid du Colombier break;
5847edc7532SDavid du Colombier
5857edc7532SDavid du Colombier case Aarg2: /* width of a parameter */
5867edc7532SDavid du Colombier o += t->width;
587*f8bc6aafSDavid du Colombier w = SZ_VLONG;
5887edc7532SDavid du Colombier break;
5897edc7532SDavid du Colombier
5907edc7532SDavid du Colombier case Aaut3: /* total allign of automatic */
5917edc7532SDavid du Colombier o = align(o, t, Ael1);
5927edc7532SDavid du Colombier o = align(o, t, Ael2);
5937edc7532SDavid du Colombier break;
5947edc7532SDavid du Colombier }
5957edc7532SDavid du Colombier o = round(o, w);
5967edc7532SDavid du Colombier if(debug['A'])
5977edc7532SDavid du Colombier print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
5987edc7532SDavid du Colombier return o;
5997edc7532SDavid du Colombier }
6007edc7532SDavid du Colombier
6017edc7532SDavid du Colombier long
maxround(long max,long v)6027edc7532SDavid du Colombier maxround(long max, long v)
6037edc7532SDavid du Colombier {
604*f8bc6aafSDavid du Colombier v = round(v, SZ_VLONG);
6057edc7532SDavid du Colombier if(v > max)
606*f8bc6aafSDavid du Colombier return v;
6077edc7532SDavid du Colombier return max;
6087edc7532SDavid du Colombier }
609