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