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(debug['W']) 523e12c5d1SDavid du Colombier for(i=0; i<nc; i++) 533e12c5d1SDavid du Colombier print("case %2d: = %.8lux\n", i, iq[i].val); 543e12c5d1SDavid du Colombier if(def == 0) 553e12c5d1SDavid du Colombier def = breakpc; 563e12c5d1SDavid du Colombier for(i=0; i<nc-1; i++) 573e12c5d1SDavid du Colombier if(iq[i].val == iq[i+1].val) 583e12c5d1SDavid du Colombier diag(n, "duplicate cases in switch %ld", iq[i].val); 593e12c5d1SDavid du Colombier regalloc(&tn, ®node, Z); 603e12c5d1SDavid du Colombier swit1(iq, nc, def, n, &tn); 613e12c5d1SDavid du Colombier regfree(&tn); 623e12c5d1SDavid du Colombier } 633e12c5d1SDavid du Colombier 643e12c5d1SDavid du Colombier void 653e12c5d1SDavid du Colombier swit1(C1 *q, int nc, long def, Node *n, Node *tn) 663e12c5d1SDavid du Colombier { 673e12c5d1SDavid du Colombier C1 *r; 683e12c5d1SDavid du Colombier int i; 693e12c5d1SDavid du Colombier Prog *sp; 703e12c5d1SDavid du Colombier 713e12c5d1SDavid du Colombier if(nc < 5) { 723e12c5d1SDavid du Colombier for(i=0; i<nc; i++) { 733e12c5d1SDavid du Colombier if(debug['W']) 743e12c5d1SDavid du Colombier print("case = %.8lux\n", q->val); 753e12c5d1SDavid du Colombier gmove(nodconst(q->val), tn); 763e12c5d1SDavid du Colombier gopcode(OEQ, n, tn, Z); 773e12c5d1SDavid du Colombier patch(p, q->label); 783e12c5d1SDavid du Colombier q++; 793e12c5d1SDavid du Colombier } 803e12c5d1SDavid du Colombier gbranch(OGOTO); 813e12c5d1SDavid du Colombier patch(p, def); 823e12c5d1SDavid du Colombier return; 833e12c5d1SDavid du Colombier } 843e12c5d1SDavid du Colombier i = nc / 2; 853e12c5d1SDavid du Colombier r = q+i; 863e12c5d1SDavid du Colombier if(debug['W']) 873e12c5d1SDavid du Colombier print("case > %.8lux\n", r->val); 883e12c5d1SDavid du Colombier gmove(nodconst(r->val), tn); 893e12c5d1SDavid du Colombier gopcode(OLT, tn, n, Z); 903e12c5d1SDavid du Colombier sp = p; 913e12c5d1SDavid du Colombier gopcode(OEQ, n, tn, Z); 923e12c5d1SDavid du Colombier patch(p, r->label); 933e12c5d1SDavid du Colombier swit1(q, i, def, n, tn); 943e12c5d1SDavid du Colombier 953e12c5d1SDavid du Colombier if(debug['W']) 963e12c5d1SDavid du Colombier print("case < %.8lux\n", r->val); 973e12c5d1SDavid du Colombier patch(sp, pc); 983e12c5d1SDavid du Colombier swit1(r+1, nc-i-1, def, n, tn); 993e12c5d1SDavid du Colombier } 1003e12c5d1SDavid du Colombier 1013e12c5d1SDavid du Colombier void 1023e12c5d1SDavid du Colombier cas(void) 1033e12c5d1SDavid du Colombier { 1043e12c5d1SDavid du Colombier Case *c; 1053e12c5d1SDavid du Colombier 1063e12c5d1SDavid du Colombier ALLOC(c, Case); 1073e12c5d1SDavid du Colombier c->link = cases; 1083e12c5d1SDavid du Colombier cases = c; 1093e12c5d1SDavid du Colombier } 1103e12c5d1SDavid du Colombier 1113e12c5d1SDavid du Colombier void 1123e12c5d1SDavid du Colombier bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) 1133e12c5d1SDavid du Colombier { 1143e12c5d1SDavid du Colombier int sh; 1153e12c5d1SDavid du Colombier long v; 1163e12c5d1SDavid du Colombier Node *l; 1173e12c5d1SDavid du Colombier 1183e12c5d1SDavid du Colombier /* 1193e12c5d1SDavid du Colombier * n1 gets adjusted/masked value 1203e12c5d1SDavid du Colombier * n2 gets address of cell 1213e12c5d1SDavid du Colombier * n3 gets contents of cell 1223e12c5d1SDavid du Colombier */ 1233e12c5d1SDavid du Colombier l = b->left; 1243e12c5d1SDavid du Colombier if(n2 != Z) { 1253e12c5d1SDavid du Colombier regalloc(n1, l, nn); 1263e12c5d1SDavid du Colombier reglcgen(n2, l, Z); 1273e12c5d1SDavid du Colombier regalloc(n3, l, Z); 1283e12c5d1SDavid du Colombier gopcode(OAS, n2, Z, n3); 1293e12c5d1SDavid du Colombier gopcode(OAS, n3, Z, n1); 1303e12c5d1SDavid du Colombier } else { 1313e12c5d1SDavid du Colombier regalloc(n1, l, nn); 1323e12c5d1SDavid du Colombier cgen(l, n1); 1333e12c5d1SDavid du Colombier } 1343e12c5d1SDavid du Colombier if(b->type->shift == 0 && typeu[b->type->etype]) { 1353e12c5d1SDavid du Colombier v = ~0 + (1L << b->type->nbits); 1363e12c5d1SDavid du Colombier gopcode(OAND, nodconst(v), Z, n1); 1373e12c5d1SDavid du Colombier } else { 1383e12c5d1SDavid du Colombier sh = 32 - b->type->shift - b->type->nbits; 1393e12c5d1SDavid du Colombier if(sh > 0) 1403e12c5d1SDavid du Colombier gopcode(OASHL, nodconst(sh), Z, n1); 1413e12c5d1SDavid du Colombier sh += b->type->shift; 1423e12c5d1SDavid du Colombier if(sh > 0) 1433e12c5d1SDavid du Colombier if(typeu[b->type->etype]) 1443e12c5d1SDavid du Colombier gopcode(OLSHR, nodconst(sh), Z, n1); 1453e12c5d1SDavid du Colombier else 1463e12c5d1SDavid du Colombier gopcode(OASHR, nodconst(sh), Z, n1); 1473e12c5d1SDavid du Colombier } 1483e12c5d1SDavid du Colombier } 1493e12c5d1SDavid du Colombier 1503e12c5d1SDavid du Colombier void 1513e12c5d1SDavid du Colombier bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) 1523e12c5d1SDavid du Colombier { 1533e12c5d1SDavid du Colombier long v; 1543e12c5d1SDavid du Colombier Node nod, *l; 1553e12c5d1SDavid du Colombier int sh; 1563e12c5d1SDavid du Colombier 1573e12c5d1SDavid du Colombier /* 1583e12c5d1SDavid du Colombier * n1 has adjusted/masked value 1593e12c5d1SDavid du Colombier * n2 has address of cell 1603e12c5d1SDavid du Colombier * n3 has contents of cell 1613e12c5d1SDavid du Colombier */ 1623e12c5d1SDavid du Colombier l = b->left; 1633e12c5d1SDavid du Colombier regalloc(&nod, l, Z); 1643e12c5d1SDavid du Colombier v = ~0 + (1L << b->type->nbits); 1653e12c5d1SDavid du Colombier gopcode(OAND, nodconst(v), Z, n1); 1663e12c5d1SDavid du Colombier gopcode(OAS, n1, Z, &nod); 1673e12c5d1SDavid du Colombier if(nn != Z) 1683e12c5d1SDavid du Colombier gopcode(OAS, n1, Z, nn); 1693e12c5d1SDavid du Colombier sh = b->type->shift; 1703e12c5d1SDavid du Colombier if(sh > 0) 1713e12c5d1SDavid du Colombier gopcode(OASHL, nodconst(sh), Z, &nod); 1723e12c5d1SDavid du Colombier v <<= sh; 1733e12c5d1SDavid du Colombier gopcode(OAND, nodconst(~v), Z, n3); 1743e12c5d1SDavid du Colombier gopcode(OOR, n3, Z, &nod); 1753e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, n2); 1763e12c5d1SDavid du Colombier 1773e12c5d1SDavid du Colombier regfree(&nod); 1783e12c5d1SDavid du Colombier regfree(n1); 1793e12c5d1SDavid du Colombier regfree(n2); 1803e12c5d1SDavid du Colombier regfree(n3); 1813e12c5d1SDavid du Colombier } 1823e12c5d1SDavid du Colombier 1833e12c5d1SDavid du Colombier long 1843e12c5d1SDavid du Colombier outstring(char *s, long n) 1853e12c5d1SDavid du Colombier { 1863e12c5d1SDavid du Colombier long r; 1873e12c5d1SDavid du Colombier 1883e12c5d1SDavid du Colombier r = nstring; 1893e12c5d1SDavid du Colombier while(n) { 1903e12c5d1SDavid du Colombier string[mnstring] = *s++; 1913e12c5d1SDavid du Colombier mnstring++; 1923e12c5d1SDavid du Colombier nstring++; 1933e12c5d1SDavid du Colombier if(mnstring >= NSNAME) { 1943e12c5d1SDavid du Colombier gpseudo(ADATA, symstring, nodconst(0L)); 1953e12c5d1SDavid du Colombier p->from.offset += nstring - NSNAME; 1963e12c5d1SDavid du Colombier p->reg = NSNAME; 1973e12c5d1SDavid du Colombier p->to.type = D_SCONST; 1983e12c5d1SDavid du Colombier memmove(p->to.sval, string, NSNAME); 1993e12c5d1SDavid du Colombier mnstring = 0; 2003e12c5d1SDavid du Colombier } 2013e12c5d1SDavid du Colombier n--; 2023e12c5d1SDavid du Colombier } 2033e12c5d1SDavid du Colombier return r; 2043e12c5d1SDavid du Colombier } 2053e12c5d1SDavid du Colombier 2063e12c5d1SDavid du Colombier long 2073e12c5d1SDavid du Colombier outlstring(ushort *s, long n) 2083e12c5d1SDavid du Colombier { 2093e12c5d1SDavid du Colombier char buf[2]; 2103e12c5d1SDavid du Colombier int c; 2113e12c5d1SDavid du Colombier long r; 2123e12c5d1SDavid du Colombier 2133e12c5d1SDavid du Colombier while(nstring & 1) 2143e12c5d1SDavid du Colombier outstring("", 1); 2153e12c5d1SDavid du Colombier r = nstring; 2163e12c5d1SDavid du Colombier while(n > 0) { 2173e12c5d1SDavid du Colombier c = *s++; 2183e12c5d1SDavid du Colombier if(endian(0)) { 2193e12c5d1SDavid du Colombier buf[0] = c>>8; 2203e12c5d1SDavid du Colombier buf[1] = c; 2213e12c5d1SDavid du Colombier } else { 2223e12c5d1SDavid du Colombier buf[0] = c; 2233e12c5d1SDavid du Colombier buf[1] = c>>8; 2243e12c5d1SDavid du Colombier } 2253e12c5d1SDavid du Colombier outstring(buf, 2); 2263e12c5d1SDavid du Colombier n -= sizeof(ushort); 2273e12c5d1SDavid du Colombier } 2283e12c5d1SDavid du Colombier return r; 2293e12c5d1SDavid du Colombier } 2303e12c5d1SDavid du Colombier 2313e12c5d1SDavid du Colombier int 2323e12c5d1SDavid du Colombier vlog(Node *n) 2333e12c5d1SDavid du Colombier { 234*219b2ee8SDavid du Colombier int s, i; 235*219b2ee8SDavid du Colombier ulong m, v; 2363e12c5d1SDavid du Colombier 2373e12c5d1SDavid du Colombier if(n->op != OCONST) 2383e12c5d1SDavid du Colombier goto bad; 239*219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 2403e12c5d1SDavid du Colombier goto bad; 241*219b2ee8SDavid du Colombier 242*219b2ee8SDavid du Colombier v = n->vconst; 243*219b2ee8SDavid du Colombier 244*219b2ee8SDavid du Colombier s = 0; 245*219b2ee8SDavid du Colombier m = MASK(64); 246*219b2ee8SDavid du Colombier for(i=32; i; i>>=1) { 247*219b2ee8SDavid du Colombier m >>= i; 248*219b2ee8SDavid du Colombier if(!(v & m)) { 249*219b2ee8SDavid du Colombier v >>= i; 250*219b2ee8SDavid du Colombier s += i; 2513e12c5d1SDavid du Colombier } 2523e12c5d1SDavid du Colombier } 253*219b2ee8SDavid du Colombier if(v == 1) 254*219b2ee8SDavid du Colombier return s; 2553e12c5d1SDavid du Colombier 2563e12c5d1SDavid du Colombier bad: 2573e12c5d1SDavid du Colombier return -1; 2583e12c5d1SDavid du Colombier } 2593e12c5d1SDavid du Colombier 260*219b2ee8SDavid du Colombier int 261*219b2ee8SDavid du Colombier mulcon(Node *n, Node *nn) 262*219b2ee8SDavid du Colombier { 263*219b2ee8SDavid du Colombier Node *l, *r, nod1, nod2; 264*219b2ee8SDavid du Colombier Multab *m; 265*219b2ee8SDavid du Colombier long v; 266*219b2ee8SDavid du Colombier int o; 267*219b2ee8SDavid du Colombier char code[sizeof(m->code)+2], *p; 268*219b2ee8SDavid du Colombier 269*219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 270*219b2ee8SDavid du Colombier return 0; 271*219b2ee8SDavid du Colombier l = n->left; 272*219b2ee8SDavid du Colombier r = n->right; 273*219b2ee8SDavid du Colombier if(l->op == OCONST) { 274*219b2ee8SDavid du Colombier l = r; 275*219b2ee8SDavid du Colombier r = n->left; 276*219b2ee8SDavid du Colombier } 277*219b2ee8SDavid du Colombier if(r->op != OCONST) 278*219b2ee8SDavid du Colombier return 0; 279*219b2ee8SDavid du Colombier v = convvtox(r->vconst, n->type->etype); 280*219b2ee8SDavid du Colombier if(v != r->vconst) { 281*219b2ee8SDavid du Colombier if(debug['M']) 282*219b2ee8SDavid du Colombier print("%L multiply conv: %lld\n", n->lineno, r->vconst); 283*219b2ee8SDavid du Colombier return 0; 284*219b2ee8SDavid du Colombier } 285*219b2ee8SDavid du Colombier m = mulcon0(v); 286*219b2ee8SDavid du Colombier if(!m) { 287*219b2ee8SDavid du Colombier if(debug['M']) 288*219b2ee8SDavid du Colombier print("%L multiply table: %lld\n", n->lineno, r->vconst); 289*219b2ee8SDavid du Colombier return 0; 290*219b2ee8SDavid du Colombier } 291*219b2ee8SDavid du Colombier if(debug['M'] && debug['v']) 292*219b2ee8SDavid du Colombier print("%L multiply: %ld\n", n->lineno, v); 293*219b2ee8SDavid du Colombier 294*219b2ee8SDavid du Colombier memmove(code, m->code, sizeof(m->code)); 295*219b2ee8SDavid du Colombier code[sizeof(m->code)] = 0; 296*219b2ee8SDavid du Colombier 297*219b2ee8SDavid du Colombier p = code; 298*219b2ee8SDavid du Colombier if(p[1] == 'i') 299*219b2ee8SDavid du Colombier p += 2; 300*219b2ee8SDavid du Colombier regalloc(&nod1, n, nn); 301*219b2ee8SDavid du Colombier cgen(l, &nod1); 302*219b2ee8SDavid du Colombier if(v < 0) 303*219b2ee8SDavid du Colombier gopcode(OSUB, &nod1, nodconst(0), &nod1); 304*219b2ee8SDavid du Colombier regalloc(&nod2, n, Z); 305*219b2ee8SDavid du Colombier 306*219b2ee8SDavid du Colombier loop: 307*219b2ee8SDavid du Colombier switch(*p) { 308*219b2ee8SDavid du Colombier case 0: 309*219b2ee8SDavid du Colombier regfree(&nod2); 310*219b2ee8SDavid du Colombier gopcode(OAS, &nod1, Z, nn); 311*219b2ee8SDavid du Colombier regfree(&nod1); 312*219b2ee8SDavid du Colombier return 1; 313*219b2ee8SDavid du Colombier case '+': 314*219b2ee8SDavid du Colombier o = OADD; 315*219b2ee8SDavid du Colombier goto addsub; 316*219b2ee8SDavid du Colombier case '-': 317*219b2ee8SDavid du Colombier o = OSUB; 318*219b2ee8SDavid du Colombier addsub: /* number is r,n,l */ 319*219b2ee8SDavid du Colombier v = p[1] - '0'; 320*219b2ee8SDavid du Colombier r = &nod1; 321*219b2ee8SDavid du Colombier if(v&4) 322*219b2ee8SDavid du Colombier r = &nod2; 323*219b2ee8SDavid du Colombier n = &nod1; 324*219b2ee8SDavid du Colombier if(v&2) 325*219b2ee8SDavid du Colombier n = &nod2; 326*219b2ee8SDavid du Colombier l = &nod1; 327*219b2ee8SDavid du Colombier if(v&1) 328*219b2ee8SDavid du Colombier l = &nod2; 329*219b2ee8SDavid du Colombier gopcode(o, l, n, r); 330*219b2ee8SDavid du Colombier break; 331*219b2ee8SDavid du Colombier default: /* op is shiftcount, number is r,l */ 332*219b2ee8SDavid du Colombier v = p[1] - '0'; 333*219b2ee8SDavid du Colombier r = &nod1; 334*219b2ee8SDavid du Colombier if(v&2) 335*219b2ee8SDavid du Colombier r = &nod2; 336*219b2ee8SDavid du Colombier l = &nod1; 337*219b2ee8SDavid du Colombier if(v&1) 338*219b2ee8SDavid du Colombier l = &nod2; 339*219b2ee8SDavid du Colombier v = *p - 'a'; 340*219b2ee8SDavid du Colombier if(v < 0 || v >= 32) { 341*219b2ee8SDavid du Colombier diag(n, "mulcon unknown op: %c%c", p[0], p[1]); 342*219b2ee8SDavid du Colombier break; 343*219b2ee8SDavid du Colombier } 344*219b2ee8SDavid du Colombier gopcode(OASHL, nodconst(v), l, r); 345*219b2ee8SDavid du Colombier break; 346*219b2ee8SDavid du Colombier } 347*219b2ee8SDavid du Colombier p += 2; 348*219b2ee8SDavid du Colombier goto loop; 349*219b2ee8SDavid du Colombier } 350*219b2ee8SDavid 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 382*219b2ee8SDavid du Colombier if(a->op == OCONST && typev[a->type->etype]) { 383*219b2ee8SDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst>>32)); 384*219b2ee8SDavid du Colombier p->from.offset += o; 385*219b2ee8SDavid du Colombier p->reg = 4; 386*219b2ee8SDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst)); 387*219b2ee8SDavid du Colombier p->from.offset += o + 4; 388*219b2ee8SDavid du Colombier p->reg = 4; 389*219b2ee8SDavid du Colombier return; 390*219b2ee8SDavid du Colombier } 3913e12c5d1SDavid du Colombier gpseudo(ADATA, s, a); 3923e12c5d1SDavid du Colombier p->from.offset += o; 3933e12c5d1SDavid du Colombier p->reg = w; 3943e12c5d1SDavid du Colombier if(p->to.type == D_OREG) 3953e12c5d1SDavid du Colombier p->to.type = D_CONST; 3963e12c5d1SDavid du Colombier } 3973e12c5d1SDavid du Colombier 3983e12c5d1SDavid du Colombier void zname(Biobuf*, char*, int, int); 3993e12c5d1SDavid du Colombier char* zaddr(char*, Adr*, int); 4003e12c5d1SDavid du Colombier void zwrite(Biobuf*, Prog*, int, int); 4013e12c5d1SDavid du Colombier void outhist(Biobuf*); 4023e12c5d1SDavid du Colombier 4033e12c5d1SDavid du Colombier void 4043e12c5d1SDavid du Colombier zwrite(Biobuf *b, Prog *p, int sf, int st) 4053e12c5d1SDavid du Colombier { 4063e12c5d1SDavid du Colombier char bf[100], *bp; 4073e12c5d1SDavid du Colombier 4083e12c5d1SDavid du Colombier bf[0] = p->as; 4093e12c5d1SDavid du Colombier bf[1] = p->reg; 4103e12c5d1SDavid du Colombier bf[2] = p->lineno; 4113e12c5d1SDavid du Colombier bf[3] = p->lineno>>8; 4123e12c5d1SDavid du Colombier bf[4] = p->lineno>>16; 4133e12c5d1SDavid du Colombier bf[5] = p->lineno>>24; 4143e12c5d1SDavid du Colombier bp = zaddr(bf+6, &p->from, sf); 4153e12c5d1SDavid du Colombier bp = zaddr(bp, &p->to, st); 4163e12c5d1SDavid du Colombier Bwrite(b, bf, bp-bf); 4173e12c5d1SDavid du Colombier } 4183e12c5d1SDavid du Colombier 4193e12c5d1SDavid du Colombier void 4203e12c5d1SDavid du Colombier outcode(void) 4213e12c5d1SDavid du Colombier { 4223e12c5d1SDavid du Colombier struct { Sym *sym; short type; } h[NSYM]; 4233e12c5d1SDavid du Colombier Prog *p; 4243e12c5d1SDavid du Colombier Sym *s; 425*219b2ee8SDavid du Colombier int sf, st, t, sym; 4263e12c5d1SDavid du Colombier 4273e12c5d1SDavid du Colombier if(debug['S']) { 4283e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) 4293e12c5d1SDavid du Colombier if(p->as != ADATA && p->as != AGLOBL) 4303e12c5d1SDavid du Colombier pc--; 4313e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 4323e12c5d1SDavid du Colombier print("%P\n", p); 4333e12c5d1SDavid du Colombier if(p->as != ADATA && p->as != AGLOBL) 4343e12c5d1SDavid du Colombier pc++; 4353e12c5d1SDavid du Colombier } 4363e12c5d1SDavid du Colombier } 437*219b2ee8SDavid du Colombier outhist(&outbuf); 4383e12c5d1SDavid du Colombier for(sym=0; sym<NSYM; sym++) { 4393e12c5d1SDavid du Colombier h[sym].sym = S; 4403e12c5d1SDavid du Colombier h[sym].type = 0; 4413e12c5d1SDavid du Colombier } 4423e12c5d1SDavid du Colombier sym = 1; 4433e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 4443e12c5d1SDavid du Colombier jackpot: 4453e12c5d1SDavid du Colombier sf = 0; 4463e12c5d1SDavid du Colombier s = p->from.sym; 4473e12c5d1SDavid du Colombier while(s != S) { 4483e12c5d1SDavid du Colombier sf = s->sym; 4493e12c5d1SDavid du Colombier if(sf < 0 || sf >= NSYM) 4503e12c5d1SDavid du Colombier sf = 0; 4513e12c5d1SDavid du Colombier t = p->from.name; 4523e12c5d1SDavid du Colombier if(h[sf].type == t) 4533e12c5d1SDavid du Colombier if(h[sf].sym == s) 4543e12c5d1SDavid du Colombier break; 455*219b2ee8SDavid du Colombier zname(&outbuf, s->name, t, sym); 4563e12c5d1SDavid du Colombier s->sym = sym; 4573e12c5d1SDavid du Colombier h[sym].sym = s; 4583e12c5d1SDavid du Colombier h[sym].type = t; 4593e12c5d1SDavid du Colombier sf = sym; 4603e12c5d1SDavid du Colombier sym++; 4613e12c5d1SDavid du Colombier if(sym >= NSYM) 4623e12c5d1SDavid du Colombier sym = 1; 4633e12c5d1SDavid du Colombier break; 4643e12c5d1SDavid du Colombier } 4653e12c5d1SDavid du Colombier st = 0; 4663e12c5d1SDavid du Colombier s = p->to.sym; 4673e12c5d1SDavid du Colombier while(s != S) { 4683e12c5d1SDavid du Colombier st = s->sym; 4693e12c5d1SDavid du Colombier if(st < 0 || st >= NSYM) 4703e12c5d1SDavid du Colombier st = 0; 4713e12c5d1SDavid du Colombier t = p->to.name; 4723e12c5d1SDavid du Colombier if(h[st].type == t) 4733e12c5d1SDavid du Colombier if(h[st].sym == s) 4743e12c5d1SDavid du Colombier break; 475*219b2ee8SDavid du Colombier zname(&outbuf, s->name, t, sym); 4763e12c5d1SDavid du Colombier s->sym = sym; 4773e12c5d1SDavid du Colombier h[sym].sym = s; 4783e12c5d1SDavid du Colombier h[sym].type = t; 4793e12c5d1SDavid du Colombier st = sym; 4803e12c5d1SDavid du Colombier sym++; 4813e12c5d1SDavid du Colombier if(sym >= NSYM) 4823e12c5d1SDavid du Colombier sym = 1; 4833e12c5d1SDavid du Colombier if(st == sf) 4843e12c5d1SDavid du Colombier goto jackpot; 4853e12c5d1SDavid du Colombier break; 4863e12c5d1SDavid du Colombier } 487*219b2ee8SDavid du Colombier zwrite(&outbuf, p, sf, st); 4883e12c5d1SDavid du Colombier } 4893e12c5d1SDavid du Colombier firstp = P; 4903e12c5d1SDavid du Colombier lastp = P; 4913e12c5d1SDavid du Colombier } 4923e12c5d1SDavid du Colombier 4933e12c5d1SDavid du Colombier void 4943e12c5d1SDavid du Colombier outhist(Biobuf *b) 4953e12c5d1SDavid du Colombier { 4963e12c5d1SDavid du Colombier Hist *h; 497*219b2ee8SDavid du Colombier char *p, *q, *op; 4983e12c5d1SDavid du Colombier Prog pg; 4993e12c5d1SDavid du Colombier int n; 5003e12c5d1SDavid du Colombier 5013e12c5d1SDavid du Colombier pg = zprog; 5023e12c5d1SDavid du Colombier pg.as = AHISTORY; 5033e12c5d1SDavid du Colombier for(h = hist; h != H; h = h->link) { 5043e12c5d1SDavid du Colombier p = h->name; 505*219b2ee8SDavid du Colombier op = 0; 506*219b2ee8SDavid du Colombier if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { 507*219b2ee8SDavid du Colombier op = p; 508*219b2ee8SDavid du Colombier p = pathname; 509*219b2ee8SDavid du Colombier } 5103e12c5d1SDavid du Colombier while(p) { 5113e12c5d1SDavid du Colombier q = utfrune(p, '/'); 5123e12c5d1SDavid du Colombier if(q) { 5133e12c5d1SDavid du Colombier n = q-p; 5143e12c5d1SDavid du Colombier if(n == 0) 5153e12c5d1SDavid du Colombier n = 1; /* leading "/" */ 5163e12c5d1SDavid du Colombier q++; 5173e12c5d1SDavid du Colombier } else { 5183e12c5d1SDavid du Colombier n = strlen(p); 5193e12c5d1SDavid du Colombier q = 0; 5203e12c5d1SDavid du Colombier } 5213e12c5d1SDavid du Colombier if(n) { 522*219b2ee8SDavid du Colombier Bputc(b, ANAME); 523*219b2ee8SDavid du Colombier Bputc(b, D_FILE); 524*219b2ee8SDavid du Colombier Bputc(b, 1); 525*219b2ee8SDavid du Colombier Bputc(b, '<'); 526*219b2ee8SDavid du Colombier Bwrite(b, p, n); 527*219b2ee8SDavid du Colombier Bputc(b, 0); 5283e12c5d1SDavid du Colombier } 5293e12c5d1SDavid du Colombier p = q; 530*219b2ee8SDavid du Colombier if(p == 0 && op) { 531*219b2ee8SDavid du Colombier p = op; 532*219b2ee8SDavid du Colombier op = 0; 533*219b2ee8SDavid du Colombier } 5343e12c5d1SDavid du Colombier } 5353e12c5d1SDavid du Colombier pg.lineno = h->line; 5363e12c5d1SDavid du Colombier pg.to.type = zprog.to.type; 5373e12c5d1SDavid du Colombier pg.to.offset = h->offset; 5383e12c5d1SDavid du Colombier if(h->offset) 5393e12c5d1SDavid du Colombier pg.to.type = D_CONST; 5403e12c5d1SDavid du Colombier 5413e12c5d1SDavid du Colombier zwrite(b, &pg, 0, 0); 5423e12c5d1SDavid du Colombier } 5433e12c5d1SDavid du Colombier } 5443e12c5d1SDavid du Colombier 5453e12c5d1SDavid du Colombier void 5463e12c5d1SDavid du Colombier zname(Biobuf *b, char *n, int t, int s) 5473e12c5d1SDavid du Colombier { 548*219b2ee8SDavid du Colombier char bf[3]; 5493e12c5d1SDavid du Colombier 550*219b2ee8SDavid du Colombier bf[0] = ANAME; 551*219b2ee8SDavid du Colombier bf[1] = t; /* type */ 552*219b2ee8SDavid du Colombier bf[2] = s; /* sym */ 553*219b2ee8SDavid du Colombier Bwrite(b, bf, 3); 554*219b2ee8SDavid du Colombier Bwrite(b, n, strlen(n)+1); 5553e12c5d1SDavid du Colombier } 5563e12c5d1SDavid du Colombier 5573e12c5d1SDavid du Colombier char* 5583e12c5d1SDavid du Colombier zaddr(char *bp, Adr *a, int s) 5593e12c5d1SDavid du Colombier { 5603e12c5d1SDavid du Colombier long l; 5613e12c5d1SDavid du Colombier Ieee e; 5623e12c5d1SDavid du Colombier 5633e12c5d1SDavid du Colombier bp[0] = a->type; 5643e12c5d1SDavid du Colombier bp[1] = a->reg; 5653e12c5d1SDavid du Colombier bp[2] = s; 5663e12c5d1SDavid du Colombier bp[3] = a->name; 5673e12c5d1SDavid du Colombier bp += 4; 5683e12c5d1SDavid du Colombier switch(a->type) { 5693e12c5d1SDavid du Colombier default: 5703e12c5d1SDavid du Colombier diag(Z, "unknown type %d in zaddr", a->type); 5713e12c5d1SDavid du Colombier 5723e12c5d1SDavid du Colombier case D_NONE: 5733e12c5d1SDavid du Colombier case D_REG: 5743e12c5d1SDavid du Colombier case D_FREG: 5753e12c5d1SDavid du Colombier case D_MREG: 5763e12c5d1SDavid du Colombier case D_FCREG: 5773e12c5d1SDavid du Colombier case D_LO: 5783e12c5d1SDavid du Colombier case D_HI: 5793e12c5d1SDavid du Colombier break; 5803e12c5d1SDavid du Colombier 5813e12c5d1SDavid du Colombier case D_OREG: 5823e12c5d1SDavid du Colombier case D_CONST: 5833e12c5d1SDavid du Colombier case D_BRANCH: 5843e12c5d1SDavid du Colombier l = a->offset; 5853e12c5d1SDavid du Colombier bp[0] = l; 5863e12c5d1SDavid du Colombier bp[1] = l>>8; 5873e12c5d1SDavid du Colombier bp[2] = l>>16; 5883e12c5d1SDavid du Colombier bp[3] = l>>24; 5893e12c5d1SDavid du Colombier bp += 4; 5903e12c5d1SDavid du Colombier break; 5913e12c5d1SDavid du Colombier 5923e12c5d1SDavid du Colombier case D_SCONST: 5933e12c5d1SDavid du Colombier memmove(bp, a->sval, NSNAME); 5943e12c5d1SDavid du Colombier bp += NSNAME; 5953e12c5d1SDavid du Colombier break; 5963e12c5d1SDavid du Colombier 5973e12c5d1SDavid du Colombier case D_FCONST: 5983e12c5d1SDavid du Colombier ieeedtod(&e, a->dval); 5993e12c5d1SDavid du Colombier l = e.l; 6003e12c5d1SDavid du Colombier bp[0] = l; 6013e12c5d1SDavid du Colombier bp[1] = l>>8; 6023e12c5d1SDavid du Colombier bp[2] = l>>16; 6033e12c5d1SDavid du Colombier bp[3] = l>>24; 6043e12c5d1SDavid du Colombier bp += 4; 6053e12c5d1SDavid du Colombier l = e.h; 6063e12c5d1SDavid du Colombier bp[0] = l; 6073e12c5d1SDavid du Colombier bp[1] = l>>8; 6083e12c5d1SDavid du Colombier bp[2] = l>>16; 6093e12c5d1SDavid du Colombier bp[3] = l>>24; 6103e12c5d1SDavid du Colombier bp += 4; 6113e12c5d1SDavid du Colombier break; 6123e12c5d1SDavid du Colombier } 6133e12c5d1SDavid du Colombier return bp; 6143e12c5d1SDavid du Colombier } 6153e12c5d1SDavid du Colombier 6163e12c5d1SDavid du Colombier void 6173e12c5d1SDavid du Colombier ieeedtod(Ieee *ieee, double native) 6183e12c5d1SDavid du Colombier { 6193e12c5d1SDavid du Colombier double fr, ho, f; 6203e12c5d1SDavid du Colombier int exp; 6213e12c5d1SDavid du Colombier 6223e12c5d1SDavid du Colombier if(native < 0) { 6233e12c5d1SDavid du Colombier ieeedtod(ieee, -native); 6243e12c5d1SDavid du Colombier ieee->h |= 0x80000000L; 6253e12c5d1SDavid du Colombier return; 6263e12c5d1SDavid du Colombier } 6273e12c5d1SDavid du Colombier if(native == 0) { 6283e12c5d1SDavid du Colombier ieee->l = 0; 6293e12c5d1SDavid du Colombier ieee->h = 0; 6303e12c5d1SDavid du Colombier return; 6313e12c5d1SDavid du Colombier } 6323e12c5d1SDavid du Colombier fr = frexp(native, &exp); 6333e12c5d1SDavid du Colombier f = 2097152L; /* shouldnt use fp constants here */ 6343e12c5d1SDavid du Colombier fr = modf(fr*f, &ho); 6353e12c5d1SDavid du Colombier ieee->h = ho; 6363e12c5d1SDavid du Colombier ieee->h &= 0xfffffL; 6373e12c5d1SDavid du Colombier ieee->h |= (exp+1022L) << 20; 6383e12c5d1SDavid du Colombier f = 65536L; 6393e12c5d1SDavid du Colombier fr = modf(fr*f, &ho); 6403e12c5d1SDavid du Colombier ieee->l = ho; 6413e12c5d1SDavid du Colombier ieee->l <<= 16; 6423e12c5d1SDavid du Colombier ieee->l |= (long)(fr*f); 6433e12c5d1SDavid du Colombier } 6443e12c5d1SDavid du Colombier 6453e12c5d1SDavid du Colombier int 6463e12c5d1SDavid du Colombier endian(int w) 6473e12c5d1SDavid du Colombier { 6483e12c5d1SDavid du Colombier 6493e12c5d1SDavid du Colombier return tint->width - w; 6503e12c5d1SDavid du Colombier } 651*219b2ee8SDavid du Colombier 652*219b2ee8SDavid du Colombier int 653*219b2ee8SDavid du Colombier passbypointer(int et) 654*219b2ee8SDavid du Colombier { 655*219b2ee8SDavid du Colombier 656*219b2ee8SDavid du Colombier return typesuv[et]; 657*219b2ee8SDavid du Colombier } 658*219b2ee8SDavid du Colombier 659*219b2ee8SDavid du Colombier int 660*219b2ee8SDavid du Colombier argalign(long typewidth, long offset, int offsp) 661*219b2ee8SDavid du Colombier { 662*219b2ee8SDavid du Colombier USED(typewidth,offset,offsp); 663*219b2ee8SDavid du Colombier return 0; 664*219b2ee8SDavid du Colombier } 665