13e12c5d1SDavid du Colombier #include "gc.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier int 43e12c5d1SDavid du Colombier swcmp(void *a1, void *a2) 53e12c5d1SDavid du Colombier { 63e12c5d1SDavid du Colombier C1 *p1, *p2; 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier p1 = a1; 93e12c5d1SDavid du Colombier p2 = a2; 103e12c5d1SDavid du Colombier if(p1->val < p2->val) 113e12c5d1SDavid du Colombier return -1; 123e12c5d1SDavid du Colombier return p1->val > p2->val; 133e12c5d1SDavid du Colombier } 143e12c5d1SDavid du Colombier 153e12c5d1SDavid du Colombier void 163e12c5d1SDavid du Colombier doswit(Node *n) 173e12c5d1SDavid du Colombier { 183e12c5d1SDavid du Colombier Case *c; 193e12c5d1SDavid du Colombier C1 *q, *iq; 203e12c5d1SDavid du Colombier long def, nc, i; 213e12c5d1SDavid du Colombier Node tn; 223e12c5d1SDavid du Colombier 233e12c5d1SDavid du Colombier def = 0; 243e12c5d1SDavid du Colombier nc = 0; 253e12c5d1SDavid du Colombier for(c = cases; c->link != C; c = c->link) { 263e12c5d1SDavid du Colombier if(c->def) { 273e12c5d1SDavid du Colombier if(def) 283e12c5d1SDavid du Colombier diag(n, "more than one default in switch"); 293e12c5d1SDavid du Colombier def = c->label; 303e12c5d1SDavid du Colombier continue; 313e12c5d1SDavid du Colombier } 323e12c5d1SDavid du Colombier nc++; 333e12c5d1SDavid du Colombier } 343e12c5d1SDavid du Colombier 353e12c5d1SDavid du Colombier i = nc*sizeof(C1); 363e12c5d1SDavid du Colombier while(nhunk < i) 373e12c5d1SDavid du Colombier gethunk(); 383e12c5d1SDavid du Colombier iq = (C1*)hunk; 393e12c5d1SDavid du Colombier nhunk -= i; 403e12c5d1SDavid du Colombier hunk += i; 413e12c5d1SDavid du Colombier 423e12c5d1SDavid du Colombier q = iq; 433e12c5d1SDavid du Colombier for(c = cases; c->link != C; c = c->link) { 443e12c5d1SDavid du Colombier if(c->def) 453e12c5d1SDavid du Colombier continue; 463e12c5d1SDavid du Colombier q->label = c->label; 473e12c5d1SDavid du Colombier q->val = c->val; 483e12c5d1SDavid du Colombier q++; 493e12c5d1SDavid du Colombier } 503e12c5d1SDavid du Colombier qsort(iq, nc, sizeof(C1), swcmp); 513e12c5d1SDavid du Colombier if(def == 0) 523e12c5d1SDavid du Colombier def = breakpc; 533e12c5d1SDavid du Colombier for(i=0; i<nc-1; i++) 543e12c5d1SDavid du Colombier if(iq[i].val == iq[i+1].val) 553e12c5d1SDavid du Colombier diag(n, "duplicate cases in switch %ld", iq[i].val); 563e12c5d1SDavid du Colombier regalloc(&tn, ®node, Z); 573e12c5d1SDavid du Colombier swit1(iq, nc, def, n, &tn); 583e12c5d1SDavid du Colombier regfree(&tn); 593e12c5d1SDavid du Colombier } 603e12c5d1SDavid du Colombier 613e12c5d1SDavid du Colombier void 623e12c5d1SDavid du Colombier swit1(C1 *q, int nc, long def, Node *n, Node *tn) 633e12c5d1SDavid du Colombier { 643e12c5d1SDavid du Colombier C1 *r; 653e12c5d1SDavid du Colombier int i; 663e12c5d1SDavid du Colombier Prog *sp; 673e12c5d1SDavid du Colombier 683e12c5d1SDavid du Colombier if(nc < 5) { 693e12c5d1SDavid du Colombier for(i=0; i<nc; i++) { 703e12c5d1SDavid du Colombier if(sval(q->val)) { 713e12c5d1SDavid du Colombier gopcode(OEQ, n, Z, nodconst(q->val)); 723e12c5d1SDavid du Colombier } else { 733e12c5d1SDavid du Colombier gopcode(OSUB, nodconst(q->val), n, tn); 743e12c5d1SDavid du Colombier gopcode(OEQ, tn, Z, nodconst(0)); 753e12c5d1SDavid du Colombier } 763e12c5d1SDavid du Colombier patch(p, q->label); 773e12c5d1SDavid du Colombier q++; 783e12c5d1SDavid du Colombier } 793e12c5d1SDavid du Colombier gbranch(OGOTO); 803e12c5d1SDavid du Colombier patch(p, def); 813e12c5d1SDavid du Colombier return; 823e12c5d1SDavid du Colombier } 833e12c5d1SDavid du Colombier i = nc / 2; 843e12c5d1SDavid du Colombier r = q+i; 853e12c5d1SDavid du Colombier if(sval(r->val)) { 863e12c5d1SDavid du Colombier gopcode(OGT, n, Z, nodconst(r->val)); 873e12c5d1SDavid du Colombier sp = p; 883e12c5d1SDavid du Colombier } else { 893e12c5d1SDavid du Colombier gopcode(OSUB, nodconst(r->val), n, tn); 903e12c5d1SDavid du Colombier gopcode(OGT, tn, Z, nodconst(0)); 913e12c5d1SDavid du Colombier sp = p; 923e12c5d1SDavid du Colombier } 933e12c5d1SDavid du Colombier gbranch(OGOTO); 943e12c5d1SDavid du Colombier p->as = ABE; 953e12c5d1SDavid du Colombier patch(p, r->label); 963e12c5d1SDavid du Colombier swit1(q, i, def, n, tn); 973e12c5d1SDavid du Colombier 983e12c5d1SDavid du Colombier patch(sp, pc); 993e12c5d1SDavid du Colombier swit1(r+1, nc-i-1, def, n, tn); 1003e12c5d1SDavid du Colombier } 1013e12c5d1SDavid du Colombier 1023e12c5d1SDavid du Colombier void 1033e12c5d1SDavid du Colombier cas(void) 1043e12c5d1SDavid du Colombier { 1053e12c5d1SDavid du Colombier Case *c; 1063e12c5d1SDavid du Colombier 1073e12c5d1SDavid du Colombier ALLOC(c, Case); 1083e12c5d1SDavid du Colombier c->link = cases; 1093e12c5d1SDavid du Colombier cases = c; 1103e12c5d1SDavid du Colombier } 1113e12c5d1SDavid du Colombier 1123e12c5d1SDavid du Colombier void 1133e12c5d1SDavid du Colombier bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) 1143e12c5d1SDavid du Colombier { 1153e12c5d1SDavid du Colombier int sh; 1163e12c5d1SDavid du Colombier long v; 1173e12c5d1SDavid du Colombier Node *l; 1183e12c5d1SDavid du Colombier 1193e12c5d1SDavid du Colombier /* 1203e12c5d1SDavid du Colombier * n1 gets adjusted/masked value 1213e12c5d1SDavid du Colombier * n2 gets address of cell 1223e12c5d1SDavid du Colombier * n3 gets contents of cell 1233e12c5d1SDavid du Colombier */ 1243e12c5d1SDavid du Colombier l = b->left; 1253e12c5d1SDavid du Colombier if(n2 != Z) { 1263e12c5d1SDavid du Colombier regalloc(n1, l, nn); 1273e12c5d1SDavid du Colombier reglcgen(n2, l, Z); 1283e12c5d1SDavid du Colombier regalloc(n3, l, Z); 1293e12c5d1SDavid du Colombier gopcode(OAS, n2, Z, n3); 1303e12c5d1SDavid du Colombier gopcode(OAS, n3, Z, n1); 1313e12c5d1SDavid du Colombier } else { 1323e12c5d1SDavid du Colombier regalloc(n1, l, nn); 1333e12c5d1SDavid du Colombier cgen(l, n1); 1343e12c5d1SDavid du Colombier } 1353e12c5d1SDavid du Colombier if(b->type->shift == 0 && typeu[b->type->etype]) { 1363e12c5d1SDavid du Colombier v = ~0 + (1L << b->type->nbits); 1373e12c5d1SDavid du Colombier gopcode(OAND, nodconst(v), Z, n1); 1383e12c5d1SDavid du Colombier } else { 1393e12c5d1SDavid du Colombier sh = 32 - b->type->shift - b->type->nbits; 1403e12c5d1SDavid du Colombier if(sh > 0) 1413e12c5d1SDavid du Colombier gopcode(OASHL, nodconst(sh), Z, n1); 1423e12c5d1SDavid du Colombier sh += b->type->shift; 1433e12c5d1SDavid du Colombier if(sh > 0) 1443e12c5d1SDavid du Colombier if(typeu[b->type->etype]) 1453e12c5d1SDavid du Colombier gopcode(OLSHR, nodconst(sh), Z, n1); 1463e12c5d1SDavid du Colombier else 1473e12c5d1SDavid du Colombier gopcode(OASHR, nodconst(sh), Z, n1); 1483e12c5d1SDavid du Colombier } 1493e12c5d1SDavid du Colombier } 1503e12c5d1SDavid du Colombier 1513e12c5d1SDavid du Colombier void 1523e12c5d1SDavid du Colombier bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) 1533e12c5d1SDavid du Colombier { 1543e12c5d1SDavid du Colombier long v; 1553e12c5d1SDavid du Colombier Node nod, *l; 1563e12c5d1SDavid du Colombier int sh; 1573e12c5d1SDavid du Colombier 1583e12c5d1SDavid du Colombier /* 1593e12c5d1SDavid du Colombier * n1 has adjusted/masked value 1603e12c5d1SDavid du Colombier * n2 has address of cell 1613e12c5d1SDavid du Colombier * n3 has contents of cell 1623e12c5d1SDavid du Colombier */ 1633e12c5d1SDavid du Colombier l = b->left; 1643e12c5d1SDavid du Colombier regalloc(&nod, l, Z); 1653e12c5d1SDavid du Colombier v = ~0 + (1L << b->type->nbits); 1663e12c5d1SDavid du Colombier gopcode(OAND, nodconst(v), Z, n1); 1673e12c5d1SDavid du Colombier gopcode(OAS, n1, Z, &nod); 1683e12c5d1SDavid du Colombier if(nn != Z) 1693e12c5d1SDavid du Colombier gopcode(OAS, n1, Z, nn); 1703e12c5d1SDavid du Colombier sh = b->type->shift; 1713e12c5d1SDavid du Colombier if(sh > 0) 1723e12c5d1SDavid du Colombier gopcode(OASHL, nodconst(sh), Z, &nod); 1733e12c5d1SDavid du Colombier v <<= sh; 1743e12c5d1SDavid du Colombier gopcode(OAND, nodconst(~v), Z, n3); 1753e12c5d1SDavid du Colombier gopcode(OOR, n3, Z, &nod); 1763e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, n2); 1773e12c5d1SDavid du Colombier 1783e12c5d1SDavid du Colombier regfree(&nod); 1793e12c5d1SDavid du Colombier regfree(n1); 1803e12c5d1SDavid du Colombier regfree(n2); 1813e12c5d1SDavid du Colombier regfree(n3); 1823e12c5d1SDavid du Colombier } 1833e12c5d1SDavid du Colombier 1843e12c5d1SDavid du Colombier long 1853e12c5d1SDavid du Colombier outstring(char *s, long n) 1863e12c5d1SDavid du Colombier { 1873e12c5d1SDavid du Colombier long r; 1883e12c5d1SDavid du Colombier 1893e12c5d1SDavid du Colombier r = nstring; 1903e12c5d1SDavid du Colombier while(n) { 1913e12c5d1SDavid du Colombier string[mnstring] = *s++; 1923e12c5d1SDavid du Colombier mnstring++; 1933e12c5d1SDavid du Colombier nstring++; 1943e12c5d1SDavid du Colombier if(mnstring >= NSNAME) { 1953e12c5d1SDavid du Colombier gpseudo(ADATA, symstring, nodconst(0L)); 1963e12c5d1SDavid du Colombier p->from.offset += nstring - NSNAME; 1973e12c5d1SDavid du Colombier p->reg = NSNAME; 1983e12c5d1SDavid du Colombier p->to.type = D_SCONST; 1993e12c5d1SDavid du Colombier memmove(p->to.sval, string, NSNAME); 2003e12c5d1SDavid du Colombier mnstring = 0; 2013e12c5d1SDavid du Colombier } 2023e12c5d1SDavid du Colombier n--; 2033e12c5d1SDavid du Colombier } 2043e12c5d1SDavid du Colombier return r; 2053e12c5d1SDavid du Colombier } 2063e12c5d1SDavid du Colombier 2073e12c5d1SDavid du Colombier long 2083e12c5d1SDavid du Colombier outlstring(ushort *s, long n) 2093e12c5d1SDavid du Colombier { 2103e12c5d1SDavid du Colombier char buf[2]; 2113e12c5d1SDavid du Colombier int c; 2123e12c5d1SDavid du Colombier long r; 2133e12c5d1SDavid du Colombier 2143e12c5d1SDavid du Colombier while(nstring & 1) 2153e12c5d1SDavid du Colombier outstring("", 1); 2163e12c5d1SDavid du Colombier r = nstring; 2173e12c5d1SDavid du Colombier while(n > 0) { 2183e12c5d1SDavid du Colombier c = *s++; 2193e12c5d1SDavid du Colombier if(endian(0)) { 2203e12c5d1SDavid du Colombier buf[0] = c>>8; 2213e12c5d1SDavid du Colombier buf[1] = c; 2223e12c5d1SDavid du Colombier } else { 2233e12c5d1SDavid du Colombier buf[0] = c; 2243e12c5d1SDavid du Colombier buf[1] = c>>8; 2253e12c5d1SDavid du Colombier } 2263e12c5d1SDavid du Colombier outstring(buf, 2); 2273e12c5d1SDavid du Colombier n -= sizeof(ushort); 2283e12c5d1SDavid du Colombier } 2293e12c5d1SDavid du Colombier return r; 2303e12c5d1SDavid du Colombier } 2313e12c5d1SDavid du Colombier 2323e12c5d1SDavid du Colombier int 2333e12c5d1SDavid du Colombier vlog(Node *n) 2343e12c5d1SDavid du Colombier { 235*219b2ee8SDavid du Colombier 236*219b2ee8SDavid du Colombier int s, i; 237*219b2ee8SDavid du Colombier ulong m, v; 2383e12c5d1SDavid du Colombier 2393e12c5d1SDavid du Colombier if(n->op != OCONST) 2403e12c5d1SDavid du Colombier goto bad; 241*219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 2423e12c5d1SDavid du Colombier goto bad; 243*219b2ee8SDavid du Colombier 244*219b2ee8SDavid du Colombier v = n->vconst; 245*219b2ee8SDavid du Colombier 246*219b2ee8SDavid du Colombier s = 0; 247*219b2ee8SDavid du Colombier m = MASK(64); 248*219b2ee8SDavid du Colombier for(i=32; i; i>>=1) { 249*219b2ee8SDavid du Colombier m >>= i; 250*219b2ee8SDavid du Colombier if(!(v & m)) { 251*219b2ee8SDavid du Colombier v >>= i; 252*219b2ee8SDavid du Colombier s += i; 2533e12c5d1SDavid du Colombier } 2543e12c5d1SDavid du Colombier } 255*219b2ee8SDavid du Colombier if(v == 1) 256*219b2ee8SDavid du Colombier return s; 2573e12c5d1SDavid du Colombier 2583e12c5d1SDavid du Colombier bad: 2593e12c5d1SDavid du Colombier return -1; 2603e12c5d1SDavid du Colombier } 2613e12c5d1SDavid du Colombier 2623e12c5d1SDavid du Colombier int 2633e12c5d1SDavid du Colombier mulcon(Node *n, Node *nn) 2643e12c5d1SDavid du Colombier { 2653e12c5d1SDavid du Colombier Node *l, *r, nod1, nod2; 2663e12c5d1SDavid du Colombier Multab *m; 2673e12c5d1SDavid du Colombier long v; 2683e12c5d1SDavid du Colombier int o; 2693e12c5d1SDavid du Colombier char code[sizeof(m->code)+2], *p; 2703e12c5d1SDavid du Colombier 271*219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 2723e12c5d1SDavid du Colombier return 0; 2733e12c5d1SDavid du Colombier l = n->left; 2743e12c5d1SDavid du Colombier r = n->right; 2753e12c5d1SDavid du Colombier if(l->op == OCONST) { 2763e12c5d1SDavid du Colombier l = r; 2773e12c5d1SDavid du Colombier r = n->left; 2783e12c5d1SDavid du Colombier } 2793e12c5d1SDavid du Colombier if(r->op != OCONST) 2803e12c5d1SDavid du Colombier return 0; 281*219b2ee8SDavid du Colombier v = convvtox(r->vconst, n->type->etype); 282*219b2ee8SDavid du Colombier if(v != r->vconst) { 283*219b2ee8SDavid du Colombier if(debug['M']) 284*219b2ee8SDavid du Colombier print("%L multiply conv: %lld\n", n->lineno, r->vconst); 2853e12c5d1SDavid du Colombier return 0; 286*219b2ee8SDavid du Colombier } 287*219b2ee8SDavid du Colombier m = mulcon0(n, v); 288*219b2ee8SDavid du Colombier if(!m) { 289*219b2ee8SDavid du Colombier if(debug['M']) 290*219b2ee8SDavid du Colombier print("%L multiply table: %lld\n", n->lineno, r->vconst); 291*219b2ee8SDavid du Colombier return 0; 292*219b2ee8SDavid du Colombier } 2933e12c5d1SDavid du Colombier 2943e12c5d1SDavid du Colombier memmove(code, m->code, sizeof(m->code)); 2953e12c5d1SDavid du Colombier code[sizeof(m->code)] = 0; 2963e12c5d1SDavid du Colombier 2973e12c5d1SDavid du Colombier p = code; 2983e12c5d1SDavid du Colombier if(p[1] == 'i') 2993e12c5d1SDavid du Colombier p += 2; 3003e12c5d1SDavid du Colombier regalloc(&nod1, n, nn); 3013e12c5d1SDavid du Colombier cgen(l, &nod1); 3023e12c5d1SDavid du Colombier if(v < 0) 3033e12c5d1SDavid du Colombier gopcode(OSUB, &nod1, nodconst(0), &nod1); 3043e12c5d1SDavid du Colombier regalloc(&nod2, n, Z); 3053e12c5d1SDavid du Colombier 3063e12c5d1SDavid du Colombier loop: 3073e12c5d1SDavid du Colombier switch(*p) { 3083e12c5d1SDavid du Colombier case 0: 3093e12c5d1SDavid du Colombier regfree(&nod2); 3103e12c5d1SDavid du Colombier gopcode(OAS, &nod1, Z, nn); 3113e12c5d1SDavid du Colombier regfree(&nod1); 3123e12c5d1SDavid du Colombier return 1; 3133e12c5d1SDavid du Colombier case '+': 3143e12c5d1SDavid du Colombier o = OADD; 3153e12c5d1SDavid du Colombier goto addsub; 3163e12c5d1SDavid du Colombier case '-': 3173e12c5d1SDavid du Colombier o = OSUB; 3183e12c5d1SDavid du Colombier addsub: /* number is r,n,l */ 3193e12c5d1SDavid du Colombier v = p[1] - '0'; 3203e12c5d1SDavid du Colombier r = &nod1; 3213e12c5d1SDavid du Colombier if(v&4) 3223e12c5d1SDavid du Colombier r = &nod2; 3233e12c5d1SDavid du Colombier n = &nod1; 3243e12c5d1SDavid du Colombier if(v&2) 3253e12c5d1SDavid du Colombier n = &nod2; 3263e12c5d1SDavid du Colombier l = &nod1; 3273e12c5d1SDavid du Colombier if(v&1) 3283e12c5d1SDavid du Colombier l = &nod2; 3293e12c5d1SDavid du Colombier gopcode(o, l, n, r); 3303e12c5d1SDavid du Colombier break; 3313e12c5d1SDavid du Colombier default: /* op is shiftcount, number is r,l */ 3323e12c5d1SDavid du Colombier v = p[1] - '0'; 3333e12c5d1SDavid du Colombier r = &nod1; 3343e12c5d1SDavid du Colombier if(v&2) 3353e12c5d1SDavid du Colombier r = &nod2; 3363e12c5d1SDavid du Colombier l = &nod1; 3373e12c5d1SDavid du Colombier if(v&1) 3383e12c5d1SDavid du Colombier l = &nod2; 3393e12c5d1SDavid du Colombier v = *p - 'a'; 3403e12c5d1SDavid du Colombier if(v < 0 || v >= 32) { 3413e12c5d1SDavid du Colombier diag(n, "mulcon unknown op: %c%c", p[0], p[1]); 3423e12c5d1SDavid du Colombier break; 3433e12c5d1SDavid du Colombier } 3443e12c5d1SDavid du Colombier gopcode(OASHL, nodconst(v), l, r); 3453e12c5d1SDavid du Colombier break; 3463e12c5d1SDavid du Colombier } 3473e12c5d1SDavid du Colombier p += 2; 3483e12c5d1SDavid du Colombier goto loop; 3493e12c5d1SDavid du Colombier } 3503e12c5d1SDavid du Colombier 3513e12c5d1SDavid du Colombier void 3523e12c5d1SDavid du Colombier nullwarn(Node *l, Node *r) 3533e12c5d1SDavid du Colombier { 3543e12c5d1SDavid du Colombier warn(Z, "result of operation not used"); 3553e12c5d1SDavid du Colombier if(l != Z) 3563e12c5d1SDavid du Colombier cgen(l, Z); 3573e12c5d1SDavid du Colombier if(r != Z) 3583e12c5d1SDavid du Colombier cgen(r, Z); 3593e12c5d1SDavid du Colombier } 3603e12c5d1SDavid du Colombier 3613e12c5d1SDavid du Colombier void 3623e12c5d1SDavid du Colombier sextern(Sym *s, Node *a, long o, long w) 3633e12c5d1SDavid du Colombier { 3643e12c5d1SDavid du Colombier long e, lw; 3653e12c5d1SDavid du Colombier 3663e12c5d1SDavid du Colombier for(e=0; e<w; e+=NSNAME) { 3673e12c5d1SDavid du Colombier lw = NSNAME; 3683e12c5d1SDavid du Colombier if(w-e < lw) 3693e12c5d1SDavid du Colombier lw = w-e; 370*219b2ee8SDavid du Colombier gpseudo(ADATA, s, nodconst(0)); 3713e12c5d1SDavid du Colombier p->from.offset += o+e; 3723e12c5d1SDavid du Colombier p->reg = lw; 3733e12c5d1SDavid du Colombier p->to.type = D_SCONST; 374*219b2ee8SDavid du Colombier memmove(p->to.sval, a->cstring+e, lw); 3753e12c5d1SDavid du Colombier } 3763e12c5d1SDavid du Colombier } 3773e12c5d1SDavid du Colombier 3783e12c5d1SDavid du Colombier void 3793e12c5d1SDavid du Colombier gextern(Sym *s, Node *a, long o, long w) 3803e12c5d1SDavid du Colombier { 381*219b2ee8SDavid du Colombier if(a->op == OCONST && typev[a->type->etype]) { 382*219b2ee8SDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst>>32)); 383*219b2ee8SDavid du Colombier p->from.offset += o; 384*219b2ee8SDavid du Colombier p->reg = 4; 385*219b2ee8SDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst)); 386*219b2ee8SDavid du Colombier p->from.offset += o + 4; 387*219b2ee8SDavid du Colombier p->reg = 4; 388*219b2ee8SDavid du Colombier return; 389*219b2ee8SDavid du Colombier } 3903e12c5d1SDavid du Colombier gpseudo(ADATA, s, a); 3913e12c5d1SDavid du Colombier p->from.offset += o; 3923e12c5d1SDavid du Colombier p->reg = w; 3933e12c5d1SDavid du Colombier if(p->to.type == D_OREG) 3943e12c5d1SDavid du Colombier p->to.type = D_CONST; 3953e12c5d1SDavid du Colombier } 3963e12c5d1SDavid du Colombier 3973e12c5d1SDavid du Colombier void zname(Biobuf*, char*, int, int); 3983e12c5d1SDavid du Colombier void zaddr(Biobuf*, Adr*, int); 3993e12c5d1SDavid du Colombier void zwrite(Biobuf*, Prog*, int, int); 4003e12c5d1SDavid du Colombier void outhist(Biobuf*); 4013e12c5d1SDavid du Colombier 4023e12c5d1SDavid du Colombier void 4033e12c5d1SDavid du Colombier outcode(void) 4043e12c5d1SDavid du Colombier { 4053e12c5d1SDavid du Colombier struct { Sym *sym; short type; } h[NSYM]; 4063e12c5d1SDavid du Colombier Prog *p; 4073e12c5d1SDavid du Colombier Sym *s; 408*219b2ee8SDavid du Colombier int sf, st, t, sym; 4093e12c5d1SDavid du Colombier 4103e12c5d1SDavid du Colombier if(debug['S']) { 4113e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) 4123e12c5d1SDavid du Colombier if(p->as != ADATA && p->as != AGLOBL) 4133e12c5d1SDavid du Colombier pc--; 4143e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 4153e12c5d1SDavid du Colombier print("%P\n", p); 4163e12c5d1SDavid du Colombier if(p->as != ADATA && p->as != AGLOBL) 4173e12c5d1SDavid du Colombier pc++; 4183e12c5d1SDavid du Colombier } 4193e12c5d1SDavid du Colombier } 420*219b2ee8SDavid du Colombier outhist(&outbuf); 4213e12c5d1SDavid du Colombier for(sym=0; sym<NSYM; sym++) { 4223e12c5d1SDavid du Colombier h[sym].sym = S; 4233e12c5d1SDavid du Colombier h[sym].type = 0; 4243e12c5d1SDavid du Colombier } 4253e12c5d1SDavid du Colombier sym = 1; 4263e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 4273e12c5d1SDavid du Colombier jackpot: 4283e12c5d1SDavid du Colombier sf = 0; 4293e12c5d1SDavid du Colombier s = p->from.sym; 4303e12c5d1SDavid du Colombier while(s != S) { 4313e12c5d1SDavid du Colombier sf = s->sym; 4323e12c5d1SDavid du Colombier if(sf < 0 || sf >= NSYM) 4333e12c5d1SDavid du Colombier sf = 0; 4343e12c5d1SDavid du Colombier t = p->from.name; 4353e12c5d1SDavid du Colombier if(h[sf].type == t) 4363e12c5d1SDavid du Colombier if(h[sf].sym == s) 4373e12c5d1SDavid du Colombier break; 438*219b2ee8SDavid du Colombier zname(&outbuf, s->name, t, sym); 4393e12c5d1SDavid du Colombier s->sym = sym; 4403e12c5d1SDavid du Colombier h[sym].sym = s; 4413e12c5d1SDavid du Colombier h[sym].type = t; 4423e12c5d1SDavid du Colombier sf = sym; 4433e12c5d1SDavid du Colombier sym++; 4443e12c5d1SDavid du Colombier if(sym >= NSYM) 4453e12c5d1SDavid du Colombier sym = 1; 4463e12c5d1SDavid du Colombier break; 4473e12c5d1SDavid du Colombier } 4483e12c5d1SDavid du Colombier st = 0; 4493e12c5d1SDavid du Colombier s = p->to.sym; 4503e12c5d1SDavid du Colombier while(s != S) { 4513e12c5d1SDavid du Colombier st = s->sym; 4523e12c5d1SDavid du Colombier if(st < 0 || st >= NSYM) 4533e12c5d1SDavid du Colombier st = 0; 4543e12c5d1SDavid du Colombier t = p->to.name; 4553e12c5d1SDavid du Colombier if(h[st].type == t) 4563e12c5d1SDavid du Colombier if(h[st].sym == s) 4573e12c5d1SDavid du Colombier break; 458*219b2ee8SDavid du Colombier zname(&outbuf, s->name, t, sym); 4593e12c5d1SDavid du Colombier s->sym = sym; 4603e12c5d1SDavid du Colombier h[sym].sym = s; 4613e12c5d1SDavid du Colombier h[sym].type = t; 4623e12c5d1SDavid du Colombier st = sym; 4633e12c5d1SDavid du Colombier sym++; 4643e12c5d1SDavid du Colombier if(sym >= NSYM) 4653e12c5d1SDavid du Colombier sym = 1; 4663e12c5d1SDavid du Colombier if(st == sf) 4673e12c5d1SDavid du Colombier goto jackpot; 4683e12c5d1SDavid du Colombier break; 4693e12c5d1SDavid du Colombier } 470*219b2ee8SDavid du Colombier zwrite(&outbuf, p, sf, st); 4713e12c5d1SDavid du Colombier } 4723e12c5d1SDavid du Colombier firstp = P; 4733e12c5d1SDavid du Colombier lastp = P; 4743e12c5d1SDavid du Colombier } 4753e12c5d1SDavid du Colombier 4763e12c5d1SDavid du Colombier void 4773e12c5d1SDavid du Colombier zwrite(Biobuf *b, Prog *p, int sf, int st) 4783e12c5d1SDavid du Colombier { 4793e12c5d1SDavid du Colombier long l; 4803e12c5d1SDavid du Colombier 4813e12c5d1SDavid du Colombier Bputc(b, p->as); 4823e12c5d1SDavid du Colombier Bputc(b, p->reg); 4833e12c5d1SDavid du Colombier l = p->lineno; 4843e12c5d1SDavid du Colombier Bputc(b, l); 4853e12c5d1SDavid du Colombier Bputc(b, l>>8); 4863e12c5d1SDavid du Colombier Bputc(b, l>>16); 4873e12c5d1SDavid du Colombier Bputc(b, l>>24); 4883e12c5d1SDavid du Colombier zaddr(b, &p->from, sf); 4893e12c5d1SDavid du Colombier zaddr(b, &p->to, st); 4903e12c5d1SDavid du Colombier } 4913e12c5d1SDavid du Colombier 4923e12c5d1SDavid du Colombier void 4933e12c5d1SDavid du Colombier outhist(Biobuf *b) 4943e12c5d1SDavid du Colombier { 4953e12c5d1SDavid du Colombier Hist *h; 496*219b2ee8SDavid du Colombier char *p, *q, *op; 4973e12c5d1SDavid du Colombier Prog pg; 4983e12c5d1SDavid du Colombier int n; 4993e12c5d1SDavid du Colombier 5003e12c5d1SDavid du Colombier pg = zprog; 5013e12c5d1SDavid du Colombier pg.as = AHISTORY; 5023e12c5d1SDavid du Colombier for(h = hist; h != H; h = h->link) { 5033e12c5d1SDavid du Colombier p = h->name; 504*219b2ee8SDavid du Colombier op = 0; 505*219b2ee8SDavid du Colombier if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { 506*219b2ee8SDavid du Colombier op = p; 507*219b2ee8SDavid du Colombier p = pathname; 508*219b2ee8SDavid du Colombier } 5093e12c5d1SDavid du Colombier while(p) { 5103e12c5d1SDavid du Colombier q = utfrune(p, '/'); 5113e12c5d1SDavid du Colombier if(q) { 5123e12c5d1SDavid du Colombier n = q-p; 5133e12c5d1SDavid du Colombier if(n == 0) 5143e12c5d1SDavid du Colombier n = 1; /* leading "/" */ 5153e12c5d1SDavid du Colombier q++; 5163e12c5d1SDavid du Colombier } else { 5173e12c5d1SDavid du Colombier n = strlen(p); 5183e12c5d1SDavid du Colombier q = 0; 5193e12c5d1SDavid du Colombier } 5203e12c5d1SDavid du Colombier if(n) { 521*219b2ee8SDavid du Colombier Bputc(b, ANAME); 522*219b2ee8SDavid du Colombier Bputc(b, D_FILE); 523*219b2ee8SDavid du Colombier Bputc(b, 1); 524*219b2ee8SDavid du Colombier Bputc(b, '<'); 525*219b2ee8SDavid du Colombier Bwrite(b, p, n); 526*219b2ee8SDavid du Colombier Bputc(b, 0); 5273e12c5d1SDavid du Colombier } 5283e12c5d1SDavid du Colombier p = q; 529*219b2ee8SDavid du Colombier if(p == 0 && op) { 530*219b2ee8SDavid du Colombier p = op; 531*219b2ee8SDavid du Colombier op = 0; 532*219b2ee8SDavid du Colombier } 5333e12c5d1SDavid du Colombier } 5343e12c5d1SDavid du Colombier pg.lineno = h->line; 5353e12c5d1SDavid du Colombier pg.to.type = zprog.to.type; 5363e12c5d1SDavid du Colombier pg.to.offset = h->offset; 5373e12c5d1SDavid du Colombier if(h->offset) 5383e12c5d1SDavid du Colombier pg.to.type = D_CONST; 5393e12c5d1SDavid du Colombier 5403e12c5d1SDavid du Colombier zwrite(b, &pg, 0, 0); 5413e12c5d1SDavid du Colombier } 5423e12c5d1SDavid du Colombier } 5433e12c5d1SDavid du Colombier 5443e12c5d1SDavid du Colombier void 5453e12c5d1SDavid du Colombier zname(Biobuf *b, char *n, int t, int s) 5463e12c5d1SDavid du Colombier { 5473e12c5d1SDavid du Colombier 5483e12c5d1SDavid du Colombier Bputc(b, ANAME); 5493e12c5d1SDavid du Colombier Bputc(b, t); /* type */ 5503e12c5d1SDavid du Colombier Bputc(b, s); /* sym */ 5513e12c5d1SDavid du Colombier while(*n) { 5523e12c5d1SDavid du Colombier Bputc(b, *n); 5533e12c5d1SDavid du Colombier n++; 5543e12c5d1SDavid du Colombier } 5553e12c5d1SDavid du Colombier Bputc(b, 0); 5563e12c5d1SDavid du Colombier } 5573e12c5d1SDavid du Colombier 5583e12c5d1SDavid du Colombier void 5593e12c5d1SDavid du Colombier zaddr(Biobuf *b, Adr *a, int s) 5603e12c5d1SDavid du Colombier { 5613e12c5d1SDavid du Colombier long l; 5623e12c5d1SDavid du Colombier int i; 5633e12c5d1SDavid du Colombier char *n; 5643e12c5d1SDavid du Colombier Ieee e; 5653e12c5d1SDavid du Colombier 5663e12c5d1SDavid du Colombier Bputc(b, a->type); 5673e12c5d1SDavid du Colombier Bputc(b, a->reg); 5683e12c5d1SDavid du Colombier Bputc(b, s); 5693e12c5d1SDavid du Colombier Bputc(b, a->name); 5703e12c5d1SDavid du Colombier switch(a->type) { 5713e12c5d1SDavid du Colombier default: 5723e12c5d1SDavid du Colombier diag(Z, "unknown type %d in zaddr", a->type); 5733e12c5d1SDavid du Colombier 5743e12c5d1SDavid du Colombier case D_NONE: 5753e12c5d1SDavid du Colombier case D_REG: 5763e12c5d1SDavid du Colombier case D_FREG: 5773e12c5d1SDavid du Colombier case D_CREG: 5783e12c5d1SDavid du Colombier break; 5793e12c5d1SDavid du Colombier 5803e12c5d1SDavid du Colombier case D_OREG: 5813e12c5d1SDavid du Colombier case D_CONST: 5823e12c5d1SDavid du Colombier case D_BRANCH: 5833e12c5d1SDavid du Colombier l = a->offset; 5843e12c5d1SDavid du Colombier Bputc(b, l); 5853e12c5d1SDavid du Colombier Bputc(b, l>>8); 5863e12c5d1SDavid du Colombier Bputc(b, l>>16); 5873e12c5d1SDavid du Colombier Bputc(b, l>>24); 5883e12c5d1SDavid du Colombier break; 5893e12c5d1SDavid du Colombier 5903e12c5d1SDavid du Colombier case D_SCONST: 5913e12c5d1SDavid du Colombier n = a->sval; 5923e12c5d1SDavid du Colombier for(i=0; i<NSNAME; i++) { 5933e12c5d1SDavid du Colombier Bputc(b, *n); 5943e12c5d1SDavid du Colombier n++; 5953e12c5d1SDavid du Colombier } 5963e12c5d1SDavid du Colombier break; 5973e12c5d1SDavid du Colombier 5983e12c5d1SDavid du Colombier case D_FCONST: 5993e12c5d1SDavid du Colombier ieeedtod(&e, a->dval); 6003e12c5d1SDavid du Colombier l = e.l; 6013e12c5d1SDavid du Colombier Bputc(b, l); 6023e12c5d1SDavid du Colombier Bputc(b, l>>8); 6033e12c5d1SDavid du Colombier Bputc(b, l>>16); 6043e12c5d1SDavid du Colombier Bputc(b, l>>24); 6053e12c5d1SDavid du Colombier l = e.h; 6063e12c5d1SDavid du Colombier Bputc(b, l); 6073e12c5d1SDavid du Colombier Bputc(b, l>>8); 6083e12c5d1SDavid du Colombier Bputc(b, l>>16); 6093e12c5d1SDavid du Colombier Bputc(b, l>>24); 6103e12c5d1SDavid du Colombier break; 6113e12c5d1SDavid du Colombier } 6123e12c5d1SDavid du Colombier } 6133e12c5d1SDavid du Colombier 6143e12c5d1SDavid du Colombier void 6153e12c5d1SDavid du Colombier ieeedtod(Ieee *ieee, double native) 6163e12c5d1SDavid du Colombier { 6173e12c5d1SDavid du Colombier double fr, ho, f; 6183e12c5d1SDavid du Colombier int exp; 6193e12c5d1SDavid du Colombier 6203e12c5d1SDavid du Colombier if(native < 0) { 6213e12c5d1SDavid du Colombier ieeedtod(ieee, -native); 6223e12c5d1SDavid du Colombier ieee->h |= 0x80000000L; 6233e12c5d1SDavid du Colombier return; 6243e12c5d1SDavid du Colombier } 6253e12c5d1SDavid du Colombier if(native == 0) { 6263e12c5d1SDavid du Colombier ieee->l = 0; 6273e12c5d1SDavid du Colombier ieee->h = 0; 6283e12c5d1SDavid du Colombier return; 6293e12c5d1SDavid du Colombier } 6303e12c5d1SDavid du Colombier fr = frexp(native, &exp); 6313e12c5d1SDavid du Colombier f = 2097152L; /* shouldnt use fp constants here */ 6323e12c5d1SDavid du Colombier fr = modf(fr*f, &ho); 6333e12c5d1SDavid du Colombier ieee->h = ho; 6343e12c5d1SDavid du Colombier ieee->h &= 0xfffffL; 6353e12c5d1SDavid du Colombier ieee->h |= (exp+1022L) << 20; 6363e12c5d1SDavid du Colombier f = 65536L; 6373e12c5d1SDavid du Colombier fr = modf(fr*f, &ho); 6383e12c5d1SDavid du Colombier ieee->l = ho; 6393e12c5d1SDavid du Colombier ieee->l <<= 16; 6403e12c5d1SDavid du Colombier ieee->l |= (long)(fr*f); 6413e12c5d1SDavid du Colombier } 6423e12c5d1SDavid du Colombier 6433e12c5d1SDavid du Colombier int 6443e12c5d1SDavid du Colombier endian(int w) 6453e12c5d1SDavid du Colombier { 6463e12c5d1SDavid du Colombier 6473e12c5d1SDavid du Colombier return tint->width - w; 6483e12c5d1SDavid du Colombier } 649*219b2ee8SDavid du Colombier 650*219b2ee8SDavid du Colombier int 651*219b2ee8SDavid du Colombier passbypointer(int et) 652*219b2ee8SDavid du Colombier { 653*219b2ee8SDavid du Colombier 654*219b2ee8SDavid du Colombier return typesuv[et]; 655*219b2ee8SDavid du Colombier } 656*219b2ee8SDavid du Colombier 657*219b2ee8SDavid du Colombier int 658*219b2ee8SDavid du Colombier argalign(long typewidth, long offset, int offsp) 659*219b2ee8SDavid du Colombier { 660*219b2ee8SDavid du Colombier USED(typewidth,offset,offsp); 661*219b2ee8SDavid du Colombier return 0; 662*219b2ee8SDavid du Colombier } 663