1*7dd7cddfSDavid du Colombier #include "gc.h" 2*7dd7cddfSDavid du Colombier 3*7dd7cddfSDavid du Colombier int 4*7dd7cddfSDavid du Colombier swcmp(void *a1, void *a2) 5*7dd7cddfSDavid du Colombier { 6*7dd7cddfSDavid du Colombier C1 *p1, *p2; 7*7dd7cddfSDavid du Colombier 8*7dd7cddfSDavid du Colombier p1 = a1; 9*7dd7cddfSDavid du Colombier p2 = a2; 10*7dd7cddfSDavid du Colombier if(p1->val < p2->val) 11*7dd7cddfSDavid du Colombier return -1; 12*7dd7cddfSDavid du Colombier return p1->val > p2->val; 13*7dd7cddfSDavid du Colombier } 14*7dd7cddfSDavid du Colombier 15*7dd7cddfSDavid du Colombier void 16*7dd7cddfSDavid du Colombier doswit(Node *n) 17*7dd7cddfSDavid du Colombier { 18*7dd7cddfSDavid du Colombier Case *c; 19*7dd7cddfSDavid du Colombier C1 *q, *iq; 20*7dd7cddfSDavid du Colombier long def, nc, i; 21*7dd7cddfSDavid du Colombier Node tn; 22*7dd7cddfSDavid du Colombier 23*7dd7cddfSDavid du Colombier def = 0; 24*7dd7cddfSDavid du Colombier nc = 0; 25*7dd7cddfSDavid du Colombier for(c = cases; c->link != C; c = c->link) { 26*7dd7cddfSDavid du Colombier if(c->def) { 27*7dd7cddfSDavid du Colombier if(def) 28*7dd7cddfSDavid du Colombier diag(n, "more than one default in switch"); 29*7dd7cddfSDavid du Colombier def = c->label; 30*7dd7cddfSDavid du Colombier continue; 31*7dd7cddfSDavid du Colombier } 32*7dd7cddfSDavid du Colombier nc++; 33*7dd7cddfSDavid du Colombier } 34*7dd7cddfSDavid du Colombier 35*7dd7cddfSDavid du Colombier iq = alloc(nc*sizeof(C1)); 36*7dd7cddfSDavid du Colombier q = iq; 37*7dd7cddfSDavid du Colombier for(c = cases; c->link != C; c = c->link) { 38*7dd7cddfSDavid du Colombier if(c->def) 39*7dd7cddfSDavid du Colombier continue; 40*7dd7cddfSDavid du Colombier q->label = c->label; 41*7dd7cddfSDavid du Colombier q->val = c->val; 42*7dd7cddfSDavid du Colombier q++; 43*7dd7cddfSDavid du Colombier } 44*7dd7cddfSDavid du Colombier qsort(iq, nc, sizeof(C1), swcmp); 45*7dd7cddfSDavid du Colombier if(def == 0) 46*7dd7cddfSDavid du Colombier def = breakpc; 47*7dd7cddfSDavid du Colombier for(i=0; i<nc-1; i++) 48*7dd7cddfSDavid du Colombier if(iq[i].val == iq[i+1].val) 49*7dd7cddfSDavid du Colombier diag(n, "duplicate cases in switch %ld", iq[i].val); 50*7dd7cddfSDavid du Colombier regalloc(&tn, ®node, Z); 51*7dd7cddfSDavid du Colombier swit1(iq, nc, def, n, &tn); 52*7dd7cddfSDavid du Colombier regfree(&tn); 53*7dd7cddfSDavid du Colombier } 54*7dd7cddfSDavid du Colombier 55*7dd7cddfSDavid du Colombier void 56*7dd7cddfSDavid du Colombier swit1(C1 *q, int nc, long def, Node *n, Node *tn) 57*7dd7cddfSDavid du Colombier { 58*7dd7cddfSDavid du Colombier C1 *r; 59*7dd7cddfSDavid du Colombier int i; 60*7dd7cddfSDavid du Colombier Prog *sp; 61*7dd7cddfSDavid du Colombier 62*7dd7cddfSDavid du Colombier if(nc < 5) { 63*7dd7cddfSDavid du Colombier for(i=0; i<nc; i++) { 64*7dd7cddfSDavid du Colombier if(sval(q->val)) { 65*7dd7cddfSDavid du Colombier gopcode(OEQ, n, Z, nodconst(q->val)); 66*7dd7cddfSDavid du Colombier } else { 67*7dd7cddfSDavid du Colombier gopcode(OSUB, nodconst(q->val), n, tn); 68*7dd7cddfSDavid du Colombier gopcode(OEQ, tn, Z, nodconst(0)); 69*7dd7cddfSDavid du Colombier } 70*7dd7cddfSDavid du Colombier patch(p, q->label); 71*7dd7cddfSDavid du Colombier q++; 72*7dd7cddfSDavid du Colombier } 73*7dd7cddfSDavid du Colombier gbranch(OGOTO); 74*7dd7cddfSDavid du Colombier patch(p, def); 75*7dd7cddfSDavid du Colombier return; 76*7dd7cddfSDavid du Colombier } 77*7dd7cddfSDavid du Colombier i = nc / 2; 78*7dd7cddfSDavid du Colombier r = q+i; 79*7dd7cddfSDavid du Colombier if(sval(r->val)) { 80*7dd7cddfSDavid du Colombier gopcode(OGT, n, Z, nodconst(r->val)); 81*7dd7cddfSDavid du Colombier sp = p; 82*7dd7cddfSDavid du Colombier } else { 83*7dd7cddfSDavid du Colombier gopcode(OSUB, nodconst(r->val), n, tn); 84*7dd7cddfSDavid du Colombier gopcode(OGT, tn, Z, nodconst(0)); 85*7dd7cddfSDavid du Colombier sp = p; 86*7dd7cddfSDavid du Colombier } 87*7dd7cddfSDavid du Colombier gbranch(OGOTO); 88*7dd7cddfSDavid du Colombier p->as = ABEQ; 89*7dd7cddfSDavid du Colombier patch(p, r->label); 90*7dd7cddfSDavid du Colombier swit1(q, i, def, n, tn); 91*7dd7cddfSDavid du Colombier 92*7dd7cddfSDavid du Colombier patch(sp, pc); 93*7dd7cddfSDavid du Colombier swit1(r+1, nc-i-1, def, n, tn); 94*7dd7cddfSDavid du Colombier } 95*7dd7cddfSDavid du Colombier 96*7dd7cddfSDavid du Colombier void 97*7dd7cddfSDavid du Colombier cas(void) 98*7dd7cddfSDavid du Colombier { 99*7dd7cddfSDavid du Colombier Case *c; 100*7dd7cddfSDavid du Colombier 101*7dd7cddfSDavid du Colombier c = alloc(sizeof(*c)); 102*7dd7cddfSDavid du Colombier c->link = cases; 103*7dd7cddfSDavid du Colombier cases = c; 104*7dd7cddfSDavid du Colombier } 105*7dd7cddfSDavid du Colombier 106*7dd7cddfSDavid du Colombier void 107*7dd7cddfSDavid du Colombier bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) 108*7dd7cddfSDavid du Colombier { 109*7dd7cddfSDavid du Colombier int sh; 110*7dd7cddfSDavid du Colombier long v; 111*7dd7cddfSDavid du Colombier Node *l; 112*7dd7cddfSDavid du Colombier 113*7dd7cddfSDavid du Colombier /* 114*7dd7cddfSDavid du Colombier * n1 gets adjusted/masked value 115*7dd7cddfSDavid du Colombier * n2 gets address of cell 116*7dd7cddfSDavid du Colombier * n3 gets contents of cell 117*7dd7cddfSDavid du Colombier */ 118*7dd7cddfSDavid du Colombier l = b->left; 119*7dd7cddfSDavid du Colombier if(n2 != Z) { 120*7dd7cddfSDavid du Colombier regalloc(n1, l, nn); 121*7dd7cddfSDavid du Colombier reglcgen(n2, l, Z); 122*7dd7cddfSDavid du Colombier regalloc(n3, l, Z); 123*7dd7cddfSDavid du Colombier gopcode(OAS, n2, Z, n3); 124*7dd7cddfSDavid du Colombier gopcode(OAS, n3, Z, n1); 125*7dd7cddfSDavid du Colombier } else { 126*7dd7cddfSDavid du Colombier regalloc(n1, l, nn); 127*7dd7cddfSDavid du Colombier cgen(l, n1); 128*7dd7cddfSDavid du Colombier } 129*7dd7cddfSDavid du Colombier if(b->type->shift == 0 && typeu[b->type->etype]) { 130*7dd7cddfSDavid du Colombier v = ~0 + (1L << b->type->nbits); 131*7dd7cddfSDavid du Colombier gopcode(OAND, nodconst(v), Z, n1); 132*7dd7cddfSDavid du Colombier } else { 133*7dd7cddfSDavid du Colombier sh = 32 - b->type->shift - b->type->nbits; 134*7dd7cddfSDavid du Colombier if(sh > 0) 135*7dd7cddfSDavid du Colombier gopcode(OASHL, nodconst(sh), Z, n1); 136*7dd7cddfSDavid du Colombier sh += b->type->shift; 137*7dd7cddfSDavid du Colombier if(sh > 0) 138*7dd7cddfSDavid du Colombier if(typeu[b->type->etype]) 139*7dd7cddfSDavid du Colombier gopcode(OLSHR, nodconst(sh), Z, n1); 140*7dd7cddfSDavid du Colombier else 141*7dd7cddfSDavid du Colombier gopcode(OASHR, nodconst(sh), Z, n1); 142*7dd7cddfSDavid du Colombier } 143*7dd7cddfSDavid du Colombier } 144*7dd7cddfSDavid du Colombier 145*7dd7cddfSDavid du Colombier void 146*7dd7cddfSDavid du Colombier bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) 147*7dd7cddfSDavid du Colombier { 148*7dd7cddfSDavid du Colombier long v; 149*7dd7cddfSDavid du Colombier Node nod, *l; 150*7dd7cddfSDavid du Colombier int sh; 151*7dd7cddfSDavid du Colombier 152*7dd7cddfSDavid du Colombier /* 153*7dd7cddfSDavid du Colombier * n1 has adjusted/masked value 154*7dd7cddfSDavid du Colombier * n2 has address of cell 155*7dd7cddfSDavid du Colombier * n3 has contents of cell 156*7dd7cddfSDavid du Colombier */ 157*7dd7cddfSDavid du Colombier l = b->left; 158*7dd7cddfSDavid du Colombier regalloc(&nod, l, Z); 159*7dd7cddfSDavid du Colombier v = ~0 + (1L << b->type->nbits); 160*7dd7cddfSDavid du Colombier gopcode(OAND, nodconst(v), Z, n1); 161*7dd7cddfSDavid du Colombier gopcode(OAS, n1, Z, &nod); 162*7dd7cddfSDavid du Colombier if(nn != Z) 163*7dd7cddfSDavid du Colombier gopcode(OAS, n1, Z, nn); 164*7dd7cddfSDavid du Colombier sh = b->type->shift; 165*7dd7cddfSDavid du Colombier if(sh > 0) 166*7dd7cddfSDavid du Colombier gopcode(OASHL, nodconst(sh), Z, &nod); 167*7dd7cddfSDavid du Colombier v <<= sh; 168*7dd7cddfSDavid du Colombier gopcode(OAND, nodconst(~v), Z, n3); 169*7dd7cddfSDavid du Colombier gopcode(OOR, n3, Z, &nod); 170*7dd7cddfSDavid du Colombier gopcode(OAS, &nod, Z, n2); 171*7dd7cddfSDavid du Colombier 172*7dd7cddfSDavid du Colombier regfree(&nod); 173*7dd7cddfSDavid du Colombier regfree(n1); 174*7dd7cddfSDavid du Colombier regfree(n2); 175*7dd7cddfSDavid du Colombier regfree(n3); 176*7dd7cddfSDavid du Colombier } 177*7dd7cddfSDavid du Colombier 178*7dd7cddfSDavid du Colombier long 179*7dd7cddfSDavid du Colombier outstring(char *s, long n) 180*7dd7cddfSDavid du Colombier { 181*7dd7cddfSDavid du Colombier long r; 182*7dd7cddfSDavid du Colombier 183*7dd7cddfSDavid du Colombier r = nstring; 184*7dd7cddfSDavid du Colombier while(n) { 185*7dd7cddfSDavid du Colombier string[mnstring] = *s++; 186*7dd7cddfSDavid du Colombier mnstring++; 187*7dd7cddfSDavid du Colombier nstring++; 188*7dd7cddfSDavid du Colombier if(mnstring >= NSNAME) { 189*7dd7cddfSDavid du Colombier gpseudo(ADATA, symstring, nodconst(0L)); 190*7dd7cddfSDavid du Colombier p->from.offset += nstring - NSNAME; 191*7dd7cddfSDavid du Colombier p->reg = NSNAME; 192*7dd7cddfSDavid du Colombier p->to.type = D_SCONST; 193*7dd7cddfSDavid du Colombier memmove(p->to.sval, string, NSNAME); 194*7dd7cddfSDavid du Colombier mnstring = 0; 195*7dd7cddfSDavid du Colombier } 196*7dd7cddfSDavid du Colombier n--; 197*7dd7cddfSDavid du Colombier } 198*7dd7cddfSDavid du Colombier return r; 199*7dd7cddfSDavid du Colombier } 200*7dd7cddfSDavid du Colombier 201*7dd7cddfSDavid du Colombier long 202*7dd7cddfSDavid du Colombier outlstring(ushort *s, long n) 203*7dd7cddfSDavid du Colombier { 204*7dd7cddfSDavid du Colombier char buf[2]; 205*7dd7cddfSDavid du Colombier int c; 206*7dd7cddfSDavid du Colombier long r; 207*7dd7cddfSDavid du Colombier 208*7dd7cddfSDavid du Colombier while(nstring & 1) 209*7dd7cddfSDavid du Colombier outstring("", 1); 210*7dd7cddfSDavid du Colombier r = nstring; 211*7dd7cddfSDavid du Colombier while(n > 0) { 212*7dd7cddfSDavid du Colombier c = *s++; 213*7dd7cddfSDavid du Colombier if(align(0, types[TCHAR], Aarg1)) { 214*7dd7cddfSDavid du Colombier buf[0] = c>>8; 215*7dd7cddfSDavid du Colombier buf[1] = c; 216*7dd7cddfSDavid du Colombier } else { 217*7dd7cddfSDavid du Colombier buf[0] = c; 218*7dd7cddfSDavid du Colombier buf[1] = c>>8; 219*7dd7cddfSDavid du Colombier } 220*7dd7cddfSDavid du Colombier outstring(buf, 2); 221*7dd7cddfSDavid du Colombier n -= sizeof(ushort); 222*7dd7cddfSDavid du Colombier } 223*7dd7cddfSDavid du Colombier return r; 224*7dd7cddfSDavid du Colombier } 225*7dd7cddfSDavid du Colombier 226*7dd7cddfSDavid du Colombier int 227*7dd7cddfSDavid du Colombier mulcon(Node *n, Node *nn) 228*7dd7cddfSDavid du Colombier { 229*7dd7cddfSDavid du Colombier Node *l, *r, nod1, nod2; 230*7dd7cddfSDavid du Colombier Multab *m; 231*7dd7cddfSDavid du Colombier long v; 232*7dd7cddfSDavid du Colombier int o; 233*7dd7cddfSDavid du Colombier char code[sizeof(m->code)+2], *p; 234*7dd7cddfSDavid du Colombier 235*7dd7cddfSDavid du Colombier if(typefd[n->type->etype]) 236*7dd7cddfSDavid du Colombier return 0; 237*7dd7cddfSDavid du Colombier l = n->left; 238*7dd7cddfSDavid du Colombier r = n->right; 239*7dd7cddfSDavid du Colombier if(l->op == OCONST) { 240*7dd7cddfSDavid du Colombier l = r; 241*7dd7cddfSDavid du Colombier r = n->left; 242*7dd7cddfSDavid du Colombier } 243*7dd7cddfSDavid du Colombier if(r->op != OCONST) 244*7dd7cddfSDavid du Colombier return 0; 245*7dd7cddfSDavid du Colombier v = convvtox(r->vconst, n->type->etype); 246*7dd7cddfSDavid du Colombier if(v != r->vconst) { 247*7dd7cddfSDavid du Colombier if(debug['M']) 248*7dd7cddfSDavid du Colombier print("%L multiply conv: %lld\n", n->lineno, r->vconst); 249*7dd7cddfSDavid du Colombier return 0; 250*7dd7cddfSDavid du Colombier } 251*7dd7cddfSDavid du Colombier m = mulcon0(n, v); 252*7dd7cddfSDavid du Colombier if(!m) { 253*7dd7cddfSDavid du Colombier if(debug['M']) 254*7dd7cddfSDavid du Colombier print("%L multiply table: %lld\n", n->lineno, r->vconst); 255*7dd7cddfSDavid du Colombier return 0; 256*7dd7cddfSDavid du Colombier } 257*7dd7cddfSDavid du Colombier 258*7dd7cddfSDavid du Colombier memmove(code, m->code, sizeof(m->code)); 259*7dd7cddfSDavid du Colombier code[sizeof(m->code)] = 0; 260*7dd7cddfSDavid du Colombier 261*7dd7cddfSDavid du Colombier p = code; 262*7dd7cddfSDavid du Colombier if(p[1] == 'i') 263*7dd7cddfSDavid du Colombier p += 2; 264*7dd7cddfSDavid du Colombier regalloc(&nod1, n, nn); 265*7dd7cddfSDavid du Colombier cgen(l, &nod1); 266*7dd7cddfSDavid du Colombier if(v < 0) 267*7dd7cddfSDavid du Colombier gopcode(ONEG, &nod1, Z, &nod1); 268*7dd7cddfSDavid du Colombier regalloc(&nod2, n, Z); 269*7dd7cddfSDavid du Colombier 270*7dd7cddfSDavid du Colombier loop: 271*7dd7cddfSDavid du Colombier switch(*p) { 272*7dd7cddfSDavid du Colombier case 0: 273*7dd7cddfSDavid du Colombier regfree(&nod2); 274*7dd7cddfSDavid du Colombier gopcode(OAS, &nod1, Z, nn); 275*7dd7cddfSDavid du Colombier regfree(&nod1); 276*7dd7cddfSDavid du Colombier return 1; 277*7dd7cddfSDavid du Colombier case '+': 278*7dd7cddfSDavid du Colombier o = OADD; 279*7dd7cddfSDavid du Colombier goto addsub; 280*7dd7cddfSDavid du Colombier case '-': 281*7dd7cddfSDavid du Colombier o = OSUB; 282*7dd7cddfSDavid du Colombier addsub: /* number is r,n,l */ 283*7dd7cddfSDavid du Colombier v = p[1] - '0'; 284*7dd7cddfSDavid du Colombier r = &nod1; 285*7dd7cddfSDavid du Colombier if(v&4) 286*7dd7cddfSDavid du Colombier r = &nod2; 287*7dd7cddfSDavid du Colombier n = &nod1; 288*7dd7cddfSDavid du Colombier if(v&2) 289*7dd7cddfSDavid du Colombier n = &nod2; 290*7dd7cddfSDavid du Colombier l = &nod1; 291*7dd7cddfSDavid du Colombier if(v&1) 292*7dd7cddfSDavid du Colombier l = &nod2; 293*7dd7cddfSDavid du Colombier gopcode(o, l, n, r); 294*7dd7cddfSDavid du Colombier break; 295*7dd7cddfSDavid du Colombier default: /* op is shiftcount, number is r,l */ 296*7dd7cddfSDavid du Colombier v = p[1] - '0'; 297*7dd7cddfSDavid du Colombier r = &nod1; 298*7dd7cddfSDavid du Colombier if(v&2) 299*7dd7cddfSDavid du Colombier r = &nod2; 300*7dd7cddfSDavid du Colombier l = &nod1; 301*7dd7cddfSDavid du Colombier if(v&1) 302*7dd7cddfSDavid du Colombier l = &nod2; 303*7dd7cddfSDavid du Colombier v = *p - 'a'; 304*7dd7cddfSDavid du Colombier if(v < 0 || v >= 32) { 305*7dd7cddfSDavid du Colombier diag(n, "mulcon unknown op: %c%c", p[0], p[1]); 306*7dd7cddfSDavid du Colombier break; 307*7dd7cddfSDavid du Colombier } 308*7dd7cddfSDavid du Colombier gopcode(OASHL, nodconst(v), l, r); 309*7dd7cddfSDavid du Colombier break; 310*7dd7cddfSDavid du Colombier } 311*7dd7cddfSDavid du Colombier p += 2; 312*7dd7cddfSDavid du Colombier goto loop; 313*7dd7cddfSDavid du Colombier } 314*7dd7cddfSDavid du Colombier 315*7dd7cddfSDavid du Colombier void 316*7dd7cddfSDavid du Colombier nullwarn(Node *l, Node *r) 317*7dd7cddfSDavid du Colombier { 318*7dd7cddfSDavid du Colombier warn(Z, "result of operation not used"); 319*7dd7cddfSDavid du Colombier if(l != Z) 320*7dd7cddfSDavid du Colombier cgen(l, Z); 321*7dd7cddfSDavid du Colombier if(r != Z) 322*7dd7cddfSDavid du Colombier cgen(r, Z); 323*7dd7cddfSDavid du Colombier } 324*7dd7cddfSDavid du Colombier 325*7dd7cddfSDavid du Colombier void 326*7dd7cddfSDavid du Colombier sextern(Sym *s, Node *a, long o, long w) 327*7dd7cddfSDavid du Colombier { 328*7dd7cddfSDavid du Colombier long e, lw; 329*7dd7cddfSDavid du Colombier 330*7dd7cddfSDavid du Colombier for(e=0; e<w; e+=NSNAME) { 331*7dd7cddfSDavid du Colombier lw = NSNAME; 332*7dd7cddfSDavid du Colombier if(w-e < lw) 333*7dd7cddfSDavid du Colombier lw = w-e; 334*7dd7cddfSDavid du Colombier gpseudo(ADATA, s, nodconst(0)); 335*7dd7cddfSDavid du Colombier p->from.offset += o+e; 336*7dd7cddfSDavid du Colombier p->reg = lw; 337*7dd7cddfSDavid du Colombier p->to.type = D_SCONST; 338*7dd7cddfSDavid du Colombier memmove(p->to.sval, a->cstring+e, lw); 339*7dd7cddfSDavid du Colombier } 340*7dd7cddfSDavid du Colombier } 341*7dd7cddfSDavid du Colombier 342*7dd7cddfSDavid du Colombier void 343*7dd7cddfSDavid du Colombier gextern(Sym *s, Node *a, long o, long w) 344*7dd7cddfSDavid du Colombier { 345*7dd7cddfSDavid du Colombier if(a->op == OCONST && typev[a->type->etype]) { 346*7dd7cddfSDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst>>32)); 347*7dd7cddfSDavid du Colombier p->from.offset += o; 348*7dd7cddfSDavid du Colombier p->reg = 4; 349*7dd7cddfSDavid du Colombier gpseudo(ADATA, s, nod32const(a->vconst)); 350*7dd7cddfSDavid du Colombier p->from.offset += o + 4; 351*7dd7cddfSDavid du Colombier p->reg = 4; 352*7dd7cddfSDavid du Colombier return; 353*7dd7cddfSDavid du Colombier } 354*7dd7cddfSDavid du Colombier gpseudo(ADATA, s, a); 355*7dd7cddfSDavid du Colombier p->from.offset += o; 356*7dd7cddfSDavid du Colombier p->reg = w; 357*7dd7cddfSDavid du Colombier if(p->to.type == D_OREG) 358*7dd7cddfSDavid du Colombier p->to.type = D_CONST; 359*7dd7cddfSDavid du Colombier } 360*7dd7cddfSDavid du Colombier 361*7dd7cddfSDavid du Colombier void zname(Biobuf*, char*, int, int); 362*7dd7cddfSDavid du Colombier char* zaddr(char*, Adr*, int); 363*7dd7cddfSDavid du Colombier void zwrite(Biobuf*, Prog*, int, int); 364*7dd7cddfSDavid du Colombier void outhist(Biobuf*); 365*7dd7cddfSDavid du Colombier 366*7dd7cddfSDavid du Colombier void 367*7dd7cddfSDavid du Colombier outcode(void) 368*7dd7cddfSDavid du Colombier { 369*7dd7cddfSDavid du Colombier struct { Sym *sym; short type; } h[NSYM]; 370*7dd7cddfSDavid du Colombier Prog *p; 371*7dd7cddfSDavid du Colombier Sym *s; 372*7dd7cddfSDavid du Colombier int sf, st, t, sym; 373*7dd7cddfSDavid du Colombier 374*7dd7cddfSDavid du Colombier if(debug['S']) { 375*7dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) 376*7dd7cddfSDavid du Colombier if(p->as != ADATA && p->as != AGLOBL) 377*7dd7cddfSDavid du Colombier pc--; 378*7dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) { 379*7dd7cddfSDavid du Colombier print("%P\n", p); 380*7dd7cddfSDavid du Colombier if(p->as != ADATA && p->as != AGLOBL) 381*7dd7cddfSDavid du Colombier pc++; 382*7dd7cddfSDavid du Colombier } 383*7dd7cddfSDavid du Colombier } 384*7dd7cddfSDavid du Colombier outhist(&outbuf); 385*7dd7cddfSDavid du Colombier for(sym=0; sym<NSYM; sym++) { 386*7dd7cddfSDavid du Colombier h[sym].sym = S; 387*7dd7cddfSDavid du Colombier h[sym].type = 0; 388*7dd7cddfSDavid du Colombier } 389*7dd7cddfSDavid du Colombier sym = 1; 390*7dd7cddfSDavid du Colombier for(p = firstp; p != P; p = p->link) { 391*7dd7cddfSDavid du Colombier jackpot: 392*7dd7cddfSDavid du Colombier sf = 0; 393*7dd7cddfSDavid du Colombier s = p->from.sym; 394*7dd7cddfSDavid du Colombier while(s != S) { 395*7dd7cddfSDavid du Colombier sf = s->sym; 396*7dd7cddfSDavid du Colombier if(sf < 0 || sf >= NSYM) 397*7dd7cddfSDavid du Colombier sf = 0; 398*7dd7cddfSDavid du Colombier t = p->from.name; 399*7dd7cddfSDavid du Colombier if(h[sf].type == t) 400*7dd7cddfSDavid du Colombier if(h[sf].sym == s) 401*7dd7cddfSDavid du Colombier break; 402*7dd7cddfSDavid du Colombier zname(&outbuf, s->name, t, sym); 403*7dd7cddfSDavid du Colombier s->sym = sym; 404*7dd7cddfSDavid du Colombier h[sym].sym = s; 405*7dd7cddfSDavid du Colombier h[sym].type = t; 406*7dd7cddfSDavid du Colombier sf = sym; 407*7dd7cddfSDavid du Colombier sym++; 408*7dd7cddfSDavid du Colombier if(sym >= NSYM) 409*7dd7cddfSDavid du Colombier sym = 1; 410*7dd7cddfSDavid du Colombier break; 411*7dd7cddfSDavid du Colombier } 412*7dd7cddfSDavid du Colombier st = 0; 413*7dd7cddfSDavid du Colombier s = p->to.sym; 414*7dd7cddfSDavid du Colombier while(s != S) { 415*7dd7cddfSDavid du Colombier st = s->sym; 416*7dd7cddfSDavid du Colombier if(st < 0 || st >= NSYM) 417*7dd7cddfSDavid du Colombier st = 0; 418*7dd7cddfSDavid du Colombier t = p->to.name; 419*7dd7cddfSDavid du Colombier if(h[st].type == t) 420*7dd7cddfSDavid du Colombier if(h[st].sym == s) 421*7dd7cddfSDavid du Colombier break; 422*7dd7cddfSDavid du Colombier zname(&outbuf, s->name, t, sym); 423*7dd7cddfSDavid du Colombier s->sym = sym; 424*7dd7cddfSDavid du Colombier h[sym].sym = s; 425*7dd7cddfSDavid du Colombier h[sym].type = t; 426*7dd7cddfSDavid du Colombier st = sym; 427*7dd7cddfSDavid du Colombier sym++; 428*7dd7cddfSDavid du Colombier if(sym >= NSYM) 429*7dd7cddfSDavid du Colombier sym = 1; 430*7dd7cddfSDavid du Colombier if(st == sf) 431*7dd7cddfSDavid du Colombier goto jackpot; 432*7dd7cddfSDavid du Colombier break; 433*7dd7cddfSDavid du Colombier } 434*7dd7cddfSDavid du Colombier zwrite(&outbuf, p, sf, st); 435*7dd7cddfSDavid du Colombier } 436*7dd7cddfSDavid du Colombier firstp = P; 437*7dd7cddfSDavid du Colombier lastp = P; 438*7dd7cddfSDavid du Colombier } 439*7dd7cddfSDavid du Colombier 440*7dd7cddfSDavid du Colombier void 441*7dd7cddfSDavid du Colombier zwrite(Biobuf *b, Prog *p, int sf, int st) 442*7dd7cddfSDavid du Colombier { 443*7dd7cddfSDavid du Colombier char bf[100], *bp; 444*7dd7cddfSDavid du Colombier long l; 445*7dd7cddfSDavid du Colombier 446*7dd7cddfSDavid du Colombier bf[0] = p->as; 447*7dd7cddfSDavid du Colombier bf[1] = p->reg; 448*7dd7cddfSDavid du Colombier l = p->lineno; 449*7dd7cddfSDavid du Colombier bf[2] = l; 450*7dd7cddfSDavid du Colombier bf[3] = l>>8; 451*7dd7cddfSDavid du Colombier bf[4] = l>>16; 452*7dd7cddfSDavid du Colombier bf[5] = l>>24; 453*7dd7cddfSDavid du Colombier bp = zaddr(bf+6, &p->from, sf); 454*7dd7cddfSDavid du Colombier bp = zaddr(bp, &p->to, st); 455*7dd7cddfSDavid du Colombier Bwrite(b, bf, bp-bf); 456*7dd7cddfSDavid du Colombier } 457*7dd7cddfSDavid du Colombier 458*7dd7cddfSDavid du Colombier void 459*7dd7cddfSDavid du Colombier outhist(Biobuf *b) 460*7dd7cddfSDavid du Colombier { 461*7dd7cddfSDavid du Colombier Hist *h; 462*7dd7cddfSDavid du Colombier char *p, *q, *op; 463*7dd7cddfSDavid du Colombier Prog pg; 464*7dd7cddfSDavid du Colombier int n; 465*7dd7cddfSDavid du Colombier 466*7dd7cddfSDavid du Colombier pg = zprog; 467*7dd7cddfSDavid du Colombier pg.as = AHISTORY; 468*7dd7cddfSDavid du Colombier for(h = hist; h != H; h = h->link) { 469*7dd7cddfSDavid du Colombier p = h->name; 470*7dd7cddfSDavid du Colombier op = 0; 471*7dd7cddfSDavid du Colombier if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { 472*7dd7cddfSDavid du Colombier op = p; 473*7dd7cddfSDavid du Colombier p = pathname; 474*7dd7cddfSDavid du Colombier } 475*7dd7cddfSDavid du Colombier while(p) { 476*7dd7cddfSDavid du Colombier q = utfrune(p, '/'); 477*7dd7cddfSDavid du Colombier if(q) { 478*7dd7cddfSDavid du Colombier n = q-p; 479*7dd7cddfSDavid du Colombier if(n == 0) 480*7dd7cddfSDavid du Colombier n = 1; /* leading "/" */ 481*7dd7cddfSDavid du Colombier q++; 482*7dd7cddfSDavid du Colombier } else { 483*7dd7cddfSDavid du Colombier n = strlen(p); 484*7dd7cddfSDavid du Colombier q = 0; 485*7dd7cddfSDavid du Colombier } 486*7dd7cddfSDavid du Colombier if(n) { 487*7dd7cddfSDavid du Colombier Bputc(b, ANAME); 488*7dd7cddfSDavid du Colombier Bputc(b, D_FILE); 489*7dd7cddfSDavid du Colombier Bputc(b, 1); 490*7dd7cddfSDavid du Colombier Bputc(b, '<'); 491*7dd7cddfSDavid du Colombier Bwrite(b, p, n); 492*7dd7cddfSDavid du Colombier Bputc(b, 0); 493*7dd7cddfSDavid du Colombier } 494*7dd7cddfSDavid du Colombier p = q; 495*7dd7cddfSDavid du Colombier if(p == 0 && op) { 496*7dd7cddfSDavid du Colombier p = op; 497*7dd7cddfSDavid du Colombier op = 0; 498*7dd7cddfSDavid du Colombier } 499*7dd7cddfSDavid du Colombier } 500*7dd7cddfSDavid du Colombier pg.lineno = h->line; 501*7dd7cddfSDavid du Colombier pg.to.type = zprog.to.type; 502*7dd7cddfSDavid du Colombier pg.to.offset = h->offset; 503*7dd7cddfSDavid du Colombier if(h->offset) 504*7dd7cddfSDavid du Colombier pg.to.type = D_CONST; 505*7dd7cddfSDavid du Colombier 506*7dd7cddfSDavid du Colombier zwrite(b, &pg, 0, 0); 507*7dd7cddfSDavid du Colombier } 508*7dd7cddfSDavid du Colombier } 509*7dd7cddfSDavid du Colombier 510*7dd7cddfSDavid du Colombier void 511*7dd7cddfSDavid du Colombier zname(Biobuf *b, char *n, int t, int s) 512*7dd7cddfSDavid du Colombier { 513*7dd7cddfSDavid du Colombier char bf[3]; 514*7dd7cddfSDavid du Colombier 515*7dd7cddfSDavid du Colombier bf[0] = ANAME; 516*7dd7cddfSDavid du Colombier bf[1] = t; /* type */ 517*7dd7cddfSDavid du Colombier bf[2] = s; /* sym */ 518*7dd7cddfSDavid du Colombier Bwrite(b, bf, 3); 519*7dd7cddfSDavid du Colombier Bwrite(b, n, strlen(n)+1); 520*7dd7cddfSDavid du Colombier } 521*7dd7cddfSDavid du Colombier 522*7dd7cddfSDavid du Colombier char* 523*7dd7cddfSDavid du Colombier zaddr(char *bp, Adr *a, int s) 524*7dd7cddfSDavid du Colombier { 525*7dd7cddfSDavid du Colombier long l; 526*7dd7cddfSDavid du Colombier Ieee e; 527*7dd7cddfSDavid du Colombier 528*7dd7cddfSDavid du Colombier bp[0] = a->type; 529*7dd7cddfSDavid du Colombier bp[1] = a->reg; 530*7dd7cddfSDavid du Colombier bp[2] = s; 531*7dd7cddfSDavid du Colombier bp[3] = a->name; 532*7dd7cddfSDavid du Colombier bp += 4; 533*7dd7cddfSDavid du Colombier switch(a->type) { 534*7dd7cddfSDavid du Colombier default: 535*7dd7cddfSDavid du Colombier diag(Z, "unknown type %d in zaddr", a->type); 536*7dd7cddfSDavid du Colombier 537*7dd7cddfSDavid du Colombier case D_NONE: 538*7dd7cddfSDavid du Colombier case D_REG: 539*7dd7cddfSDavid du Colombier case D_FREG: 540*7dd7cddfSDavid du Colombier case D_CREG: 541*7dd7cddfSDavid du Colombier break; 542*7dd7cddfSDavid du Colombier 543*7dd7cddfSDavid du Colombier case D_OREG: 544*7dd7cddfSDavid du Colombier case D_CONST: 545*7dd7cddfSDavid du Colombier case D_BRANCH: 546*7dd7cddfSDavid du Colombier l = a->offset; 547*7dd7cddfSDavid du Colombier bp[0] = l; 548*7dd7cddfSDavid du Colombier bp[1] = l>>8; 549*7dd7cddfSDavid du Colombier bp[2] = l>>16; 550*7dd7cddfSDavid du Colombier bp[3] = l>>24; 551*7dd7cddfSDavid du Colombier bp += 4; 552*7dd7cddfSDavid du Colombier break; 553*7dd7cddfSDavid du Colombier 554*7dd7cddfSDavid du Colombier case D_SCONST: 555*7dd7cddfSDavid du Colombier memmove(bp, a->sval, NSNAME); 556*7dd7cddfSDavid du Colombier bp += NSNAME; 557*7dd7cddfSDavid du Colombier break; 558*7dd7cddfSDavid du Colombier 559*7dd7cddfSDavid du Colombier case D_FCONST: 560*7dd7cddfSDavid du Colombier ieeedtod(&e, a->dval); 561*7dd7cddfSDavid du Colombier l = e.l; 562*7dd7cddfSDavid du Colombier bp[0] = l; 563*7dd7cddfSDavid du Colombier bp[1] = l>>8; 564*7dd7cddfSDavid du Colombier bp[2] = l>>16; 565*7dd7cddfSDavid du Colombier bp[3] = l>>24; 566*7dd7cddfSDavid du Colombier bp += 4; 567*7dd7cddfSDavid du Colombier l = e.h; 568*7dd7cddfSDavid du Colombier bp[0] = l; 569*7dd7cddfSDavid du Colombier bp[1] = l>>8; 570*7dd7cddfSDavid du Colombier bp[2] = l>>16; 571*7dd7cddfSDavid du Colombier bp[3] = l>>24; 572*7dd7cddfSDavid du Colombier bp += 4; 573*7dd7cddfSDavid du Colombier break; 574*7dd7cddfSDavid du Colombier } 575*7dd7cddfSDavid du Colombier return bp; 576*7dd7cddfSDavid du Colombier } 577*7dd7cddfSDavid du Colombier 578*7dd7cddfSDavid du Colombier void 579*7dd7cddfSDavid du Colombier ieeedtod(Ieee *ieee, double native) 580*7dd7cddfSDavid du Colombier { 581*7dd7cddfSDavid du Colombier double fr, ho, f; 582*7dd7cddfSDavid du Colombier int exp; 583*7dd7cddfSDavid du Colombier 584*7dd7cddfSDavid du Colombier if(native < 0) { 585*7dd7cddfSDavid du Colombier ieeedtod(ieee, -native); 586*7dd7cddfSDavid du Colombier ieee->h |= 0x80000000L; 587*7dd7cddfSDavid du Colombier return; 588*7dd7cddfSDavid du Colombier } 589*7dd7cddfSDavid du Colombier if(native == 0) { 590*7dd7cddfSDavid du Colombier ieee->l = 0; 591*7dd7cddfSDavid du Colombier ieee->h = 0; 592*7dd7cddfSDavid du Colombier return; 593*7dd7cddfSDavid du Colombier } 594*7dd7cddfSDavid du Colombier fr = frexp(native, &exp); 595*7dd7cddfSDavid du Colombier f = 2097152L; /* shouldnt use fp constants here */ 596*7dd7cddfSDavid du Colombier fr = modf(fr*f, &ho); 597*7dd7cddfSDavid du Colombier ieee->h = ho; 598*7dd7cddfSDavid du Colombier ieee->h &= 0xfffffL; 599*7dd7cddfSDavid du Colombier ieee->h |= (exp+1022L) << 20; 600*7dd7cddfSDavid du Colombier f = 65536L; 601*7dd7cddfSDavid du Colombier fr = modf(fr*f, &ho); 602*7dd7cddfSDavid du Colombier ieee->l = ho; 603*7dd7cddfSDavid du Colombier ieee->l <<= 16; 604*7dd7cddfSDavid du Colombier ieee->l |= (long)(fr*f); 605*7dd7cddfSDavid du Colombier } 606*7dd7cddfSDavid du Colombier 607*7dd7cddfSDavid du Colombier long 608*7dd7cddfSDavid du Colombier align(long i, Type *t, int op) 609*7dd7cddfSDavid du Colombier { 610*7dd7cddfSDavid du Colombier long o; 611*7dd7cddfSDavid du Colombier Type *v; 612*7dd7cddfSDavid du Colombier int w; 613*7dd7cddfSDavid du Colombier 614*7dd7cddfSDavid du Colombier o = i; 615*7dd7cddfSDavid du Colombier w = 1; 616*7dd7cddfSDavid du Colombier switch(op) { 617*7dd7cddfSDavid du Colombier default: 618*7dd7cddfSDavid du Colombier diag(Z, "unknown align opcode %d", op); 619*7dd7cddfSDavid du Colombier break; 620*7dd7cddfSDavid du Colombier 621*7dd7cddfSDavid du Colombier case Asu2: /* padding at end of a struct */ 622*7dd7cddfSDavid du Colombier w = SZ_LONG; 623*7dd7cddfSDavid du Colombier break; 624*7dd7cddfSDavid du Colombier 625*7dd7cddfSDavid du Colombier case Ael1: /* initial allign of struct element */ 626*7dd7cddfSDavid du Colombier for(v=t; v->etype==TARRAY; v=v->link) 627*7dd7cddfSDavid du Colombier ; 628*7dd7cddfSDavid du Colombier w = ewidth[v->etype]; 629*7dd7cddfSDavid du Colombier if(w <= 0 || w >= SZ_LONG) 630*7dd7cddfSDavid du Colombier w = SZ_LONG; 631*7dd7cddfSDavid du Colombier break; 632*7dd7cddfSDavid du Colombier 633*7dd7cddfSDavid du Colombier case Ael2: /* width of a struct element */ 634*7dd7cddfSDavid du Colombier o += t->width; 635*7dd7cddfSDavid du Colombier break; 636*7dd7cddfSDavid du Colombier 637*7dd7cddfSDavid du Colombier case Aarg0: /* initial passbyptr argument in arg list */ 638*7dd7cddfSDavid du Colombier if(typesuv[t->etype]) { 639*7dd7cddfSDavid du Colombier o = align(o, types[TIND], Aarg1); 640*7dd7cddfSDavid du Colombier o = align(o, types[TIND], Aarg2); 641*7dd7cddfSDavid du Colombier } 642*7dd7cddfSDavid du Colombier break; 643*7dd7cddfSDavid du Colombier 644*7dd7cddfSDavid du Colombier case Aarg1: /* initial allign of parameter */ 645*7dd7cddfSDavid du Colombier w = ewidth[t->etype]; 646*7dd7cddfSDavid du Colombier if(w <= 0 || w >= SZ_LONG) { 647*7dd7cddfSDavid du Colombier w = SZ_LONG; 648*7dd7cddfSDavid du Colombier break; 649*7dd7cddfSDavid du Colombier } 650*7dd7cddfSDavid du Colombier o += SZ_LONG - w; /* big endian adjustment */ 651*7dd7cddfSDavid du Colombier w = 1; 652*7dd7cddfSDavid du Colombier break; 653*7dd7cddfSDavid du Colombier 654*7dd7cddfSDavid du Colombier case Aarg2: /* width of a parameter */ 655*7dd7cddfSDavid du Colombier o += t->width; 656*7dd7cddfSDavid du Colombier w = SZ_LONG; 657*7dd7cddfSDavid du Colombier break; 658*7dd7cddfSDavid du Colombier 659*7dd7cddfSDavid du Colombier case Aaut3: /* total allign of automatic */ 660*7dd7cddfSDavid du Colombier o = align(o, t, Ael1); 661*7dd7cddfSDavid du Colombier o = align(o, t, Ael2); 662*7dd7cddfSDavid du Colombier break; 663*7dd7cddfSDavid du Colombier } 664*7dd7cddfSDavid du Colombier o = round(o, w); 665*7dd7cddfSDavid du Colombier if(debug['A']) 666*7dd7cddfSDavid du Colombier print("align %s %ld %T = %ld\n", bnames[op], i, t, o); 667*7dd7cddfSDavid du Colombier return o; 668*7dd7cddfSDavid du Colombier } 669*7dd7cddfSDavid du Colombier 670*7dd7cddfSDavid du Colombier long 671*7dd7cddfSDavid du Colombier maxround(long max, long v) 672*7dd7cddfSDavid du Colombier { 673*7dd7cddfSDavid du Colombier v += SZ_LONG-1; 674*7dd7cddfSDavid du Colombier if(v > max) 675*7dd7cddfSDavid du Colombier max = round(v, SZ_LONG); 676*7dd7cddfSDavid du Colombier return max; 677*7dd7cddfSDavid du Colombier } 678