parse.c (25708B)
1 #include "all.h" 2 #include <ctype.h> 3 #include <stdarg.h> 4 5 enum { 6 Ksb = 4, /* matches Oarg/Opar/Jret */ 7 Kub, 8 Ksh, 9 Kuh, 10 Kc, 11 K0, 12 13 Ke = -2, /* erroneous mode */ 14 Km = Kl, /* memory pointer */ 15 }; 16 17 Op optab[NOp] = { 18 #undef P 19 #define P(cf, hi, id) .canfold = cf, .hasid = hi, .idval = id 20 #define O(op, t, p) [O##op]={.name = #op, .argcls = t, p}, 21 #include "ops.h" 22 #undef P 23 }; 24 25 typedef enum { 26 PXXX, 27 PLbl, 28 PPhi, 29 PIns, 30 PEnd, 31 } PState; 32 33 enum Token { 34 Txxx = 0, 35 36 /* aliases */ 37 Tloadw = NPubOp, 38 Tloadl, 39 Tloads, 40 Tloadd, 41 Talloc1, 42 Talloc2, 43 44 Tblit, 45 Tcall, 46 Tenv, 47 Tphi, 48 Tjmp, 49 Tjnz, 50 Tret, 51 Thlt, 52 Texport, 53 Tthread, 54 Tcommon, 55 Tfunc, 56 Ttype, 57 Tdata, 58 Tsection, 59 Talign, 60 Tdbgfile, 61 Tl, 62 Tw, 63 Tsh, 64 Tuh, 65 Th, 66 Tsb, 67 Tub, 68 Tb, 69 Td, 70 Ts, 71 Tz, 72 73 Tint, 74 Tflts, 75 Tfltd, 76 Ttmp, 77 Tlbl, 78 Tglo, 79 Ttyp, 80 Tstr, 81 82 Tplus, 83 Teq, 84 Tcomma, 85 Tlparen, 86 Trparen, 87 Tlbrace, 88 Trbrace, 89 Tnl, 90 Tdots, 91 Teof, 92 93 Ntok 94 }; 95 96 static char *kwmap[Ntok] = { 97 [Tloadw] = "loadw", 98 [Tloadl] = "loadl", 99 [Tloads] = "loads", 100 [Tloadd] = "loadd", 101 [Talloc1] = "alloc1", 102 [Talloc2] = "alloc2", 103 [Tblit] = "blit", 104 [Tcall] = "call", 105 [Tenv] = "env", 106 [Tphi] = "phi", 107 [Tjmp] = "jmp", 108 [Tjnz] = "jnz", 109 [Tret] = "ret", 110 [Thlt] = "hlt", 111 [Texport] = "export", 112 [Tthread] = "thread", 113 [Tcommon] = "common", 114 [Tfunc] = "function", 115 [Ttype] = "type", 116 [Tdata] = "data", 117 [Tsection] = "section", 118 [Talign] = "align", 119 [Tdbgfile] = "dbgfile", 120 [Tsb] = "sb", 121 [Tub] = "ub", 122 [Tsh] = "sh", 123 [Tuh] = "uh", 124 [Tb] = "b", 125 [Th] = "h", 126 [Tw] = "w", 127 [Tl] = "l", 128 [Ts] = "s", 129 [Td] = "d", 130 [Tz] = "z", 131 [Tdots] = "...", 132 }; 133 134 enum { 135 NPred = 63, 136 137 TMask = 16383, /* for temps hash */ 138 BMask = 8191, /* for blocks hash */ 139 140 K = 11183273, /* found using tools/lexh.c */ 141 M = 23, 142 }; 143 144 static uchar lexh[1 << (32-M)]; 145 static FILE *inf; 146 static char *inpath; 147 static int thead; 148 static struct { 149 char chr; 150 double fltd; 151 float flts; 152 int64_t num; 153 char *str; 154 } tokval; 155 static int lnum; 156 157 static Fn *curf; 158 static int *tmph; 159 static int tmphcap; 160 static Phi **plink; 161 static Blk *curb; 162 static Blk **blink; 163 static Blk *blkh[BMask+1]; 164 static int nblk; 165 static int rcls; 166 static uint ntyp; 167 168 void 169 err(char *s, ...) 170 { 171 va_list ap; 172 173 va_start(ap, s); 174 fprintf(stderr, "qbe:%s:%d: ", inpath, lnum); 175 vfprintf(stderr, s, ap); 176 fprintf(stderr, "\n"); 177 va_end(ap); 178 exit(1); 179 } 180 181 static void 182 lexinit() 183 { 184 static int done; 185 int i; 186 long h; 187 188 if (done) 189 return; 190 for (i=0; i<NPubOp; ++i) 191 if (optab[i].name) 192 kwmap[i] = optab[i].name; 193 assert(Ntok <= UCHAR_MAX); 194 for (i=0; i<Ntok; ++i) 195 if (kwmap[i]) { 196 h = hash(kwmap[i])*K >> M; 197 assert(lexh[h] == Txxx); 198 lexh[h] = i; 199 } 200 done = 1; 201 } 202 203 static int64_t 204 getint() 205 { 206 uint64_t n; 207 int c, m; 208 209 n = 0; 210 c = fgetc(inf); 211 m = (c == '-'); 212 if (m) 213 c = fgetc(inf); 214 do { 215 n = 10*n + (c - '0'); 216 c = fgetc(inf); 217 } while ('0' <= c && c <= '9'); 218 ungetc(c, inf); 219 if (m) 220 n = 1 + ~n; 221 return *(int64_t *)&n; 222 } 223 224 static int 225 lex() 226 { 227 static char tok[NString]; 228 int c, i, esc; 229 int t; 230 231 do 232 c = fgetc(inf); 233 while (isblank(c)); 234 t = Txxx; 235 tokval.chr = c; 236 switch (c) { 237 case EOF: 238 return Teof; 239 case ',': 240 return Tcomma; 241 case '(': 242 return Tlparen; 243 case ')': 244 return Trparen; 245 case '{': 246 return Tlbrace; 247 case '}': 248 return Trbrace; 249 case '=': 250 return Teq; 251 case '+': 252 return Tplus; 253 case 's': 254 if (fscanf(inf, "_%f", &tokval.flts) != 1) 255 break; 256 return Tflts; 257 case 'd': 258 if (fscanf(inf, "_%lf", &tokval.fltd) != 1) 259 break; 260 return Tfltd; 261 case '%': 262 t = Ttmp; 263 c = fgetc(inf); 264 goto Alpha; 265 case '@': 266 t = Tlbl; 267 c = fgetc(inf); 268 goto Alpha; 269 case '$': 270 t = Tglo; 271 if ((c = fgetc(inf)) == '"') 272 goto Quoted; 273 goto Alpha; 274 case ':': 275 t = Ttyp; 276 c = fgetc(inf); 277 goto Alpha; 278 case '#': 279 while ((c=fgetc(inf)) != '\n' && c != EOF) 280 ; 281 /* fall through */ 282 case '\n': 283 lnum++; 284 return Tnl; 285 } 286 if (isdigit(c) || c == '-') { 287 ungetc(c, inf); 288 tokval.num = getint(); 289 return Tint; 290 } 291 if (c == '"') { 292 t = Tstr; 293 Quoted: 294 tokval.str = vnew(2, 1, PFn); 295 tokval.str[0] = c; 296 esc = 0; 297 for (i=1;; i++) { 298 c = fgetc(inf); 299 if (c == EOF) 300 err("unterminated string"); 301 vgrow(&tokval.str, i+2); 302 tokval.str[i] = c; 303 if (c == '"' && !esc) { 304 tokval.str[i+1] = 0; 305 return t; 306 } 307 esc = (c == '\\' && !esc); 308 } 309 } 310 Alpha: 311 if (!isalpha(c) && c != '.' && c != '_') 312 err("invalid character %c (%d)", c, c); 313 i = 0; 314 do { 315 if (i >= NString-1) 316 err("identifier too long"); 317 tok[i++] = c; 318 c = fgetc(inf); 319 } while (isalpha(c) || c == '$' || c == '.' || c == '_' || isdigit(c)); 320 tok[i] = 0; 321 ungetc(c, inf); 322 tokval.str = tok; 323 if (t != Txxx) { 324 return t; 325 } 326 t = lexh[hash(tok)*K >> M]; 327 if (t == Txxx || strcmp(kwmap[t], tok) != 0) { 328 err("unknown keyword %s", tok); 329 return Txxx; 330 } 331 return t; 332 } 333 334 static int 335 peek() 336 { 337 if (thead == Txxx) 338 thead = lex(); 339 return thead; 340 } 341 342 static int 343 next() 344 { 345 int t; 346 347 t = peek(); 348 thead = Txxx; 349 return t; 350 } 351 352 static int 353 nextnl() 354 { 355 int t; 356 357 while ((t = next()) == Tnl) 358 ; 359 return t; 360 } 361 362 static void 363 expect(int t) 364 { 365 static char *ttoa[] = { 366 [Tlbl] = "label", 367 [Tcomma] = ",", 368 [Teq] = "=", 369 [Tnl] = "newline", 370 [Tlparen] = "(", 371 [Trparen] = ")", 372 [Tlbrace] = "{", 373 [Trbrace] = "}", 374 [Teof] = 0, 375 }; 376 char buf[128], *s1, *s2; 377 int t1; 378 379 t1 = next(); 380 if (t == t1) 381 return; 382 s1 = ttoa[t] ? ttoa[t] : "??"; 383 s2 = ttoa[t1] ? ttoa[t1] : "??"; 384 sprintf(buf, "%s expected, got %s instead", s1, s2); 385 err(buf); 386 } 387 388 static Ref 389 tmpref(char *v) 390 { 391 int t, i; 392 393 if (tmphcap/2 <= curf->ntmp-Tmp0) { 394 free(tmph); 395 tmphcap = tmphcap ? tmphcap*2 : TMask+1; 396 tmph = emalloc(tmphcap * sizeof tmph[0]); 397 for (t=Tmp0; t<curf->ntmp; t++) { 398 i = hash(curf->tmp[t].name) & (tmphcap-1); 399 for (; tmph[i]; i=(i+1) & (tmphcap-1)) 400 ; 401 tmph[i] = t; 402 } 403 } 404 i = hash(v) & (tmphcap-1); 405 for (; tmph[i]; i=(i+1) & (tmphcap-1)) { 406 t = tmph[i]; 407 if (strcmp(curf->tmp[t].name, v) == 0) 408 return TMP(t); 409 } 410 t = curf->ntmp; 411 tmph[i] = t; 412 newtmp(0, Kx, curf); 413 strcpy(curf->tmp[t].name, v); 414 return TMP(t); 415 } 416 417 static Ref 418 parseref() 419 { 420 Con c; 421 422 memset(&c, 0, sizeof c); 423 switch (next()) { 424 default: 425 return R; 426 case Ttmp: 427 return tmpref(tokval.str); 428 case Tint: 429 c.type = CBits; 430 c.bits.i = tokval.num; 431 break; 432 case Tflts: 433 c.type = CBits; 434 c.bits.s = tokval.flts; 435 c.flt = 1; 436 break; 437 case Tfltd: 438 c.type = CBits; 439 c.bits.d = tokval.fltd; 440 c.flt = 2; 441 break; 442 case Tthread: 443 c.sym.type = SThr; 444 expect(Tglo); 445 /* fall through */ 446 case Tglo: 447 c.type = CAddr; 448 c.sym.id = intern(tokval.str); 449 break; 450 } 451 return newcon(&c, curf); 452 } 453 454 static int 455 findtyp(int i) 456 { 457 while (--i >= 0) 458 if (strcmp(tokval.str, typ[i].name) == 0) 459 return i; 460 err("undefined type :%s", tokval.str); 461 } 462 463 static int 464 parsecls(int *tyn) 465 { 466 switch (next()) { 467 default: 468 err("invalid class specifier"); 469 case Ttyp: 470 *tyn = findtyp(ntyp); 471 return Kc; 472 case Tsb: 473 return Ksb; 474 case Tub: 475 return Kub; 476 case Tsh: 477 return Ksh; 478 case Tuh: 479 return Kuh; 480 case Tw: 481 return Kw; 482 case Tl: 483 return Kl; 484 case Ts: 485 return Ks; 486 case Td: 487 return Kd; 488 } 489 } 490 491 static int 492 parserefl(int arg) 493 { 494 int k, ty, env, hasenv, vararg; 495 Ref r; 496 497 hasenv = 0; 498 vararg = 0; 499 expect(Tlparen); 500 while (peek() != Trparen) { 501 if (curi - insb >= NIns) 502 err("too many instructions"); 503 if (!arg && vararg) 504 err("no parameters allowed after '...'"); 505 switch (peek()) { 506 case Tdots: 507 if (vararg) 508 err("only one '...' allowed"); 509 vararg = 1; 510 if (arg) { 511 *curi = (Ins){.op = Oargv}; 512 curi++; 513 } 514 next(); 515 goto Next; 516 case Tenv: 517 if (hasenv) 518 err("only one environment allowed"); 519 hasenv = 1; 520 env = 1; 521 next(); 522 k = Kl; 523 break; 524 default: 525 env = 0; 526 k = parsecls(&ty); 527 break; 528 } 529 r = parseref(); 530 if (req(r, R)) 531 err("invalid argument"); 532 if (!arg && rtype(r) != RTmp) 533 err("invalid function parameter"); 534 if (env) 535 if (arg) 536 *curi = (Ins){Oarge, k, R, {r}}; 537 else 538 *curi = (Ins){Opare, k, r, {R}}; 539 else if (k == Kc) 540 if (arg) 541 *curi = (Ins){Oargc, Kl, R, {TYPE(ty), r}}; 542 else 543 *curi = (Ins){Oparc, Kl, r, {TYPE(ty)}}; 544 else if (k >= Ksb) 545 if (arg) 546 *curi = (Ins){Oargsb+(k-Ksb), Kw, R, {r}}; 547 else 548 *curi = (Ins){Oparsb+(k-Ksb), Kw, r, {R}}; 549 else 550 if (arg) 551 *curi = (Ins){Oarg, k, R, {r}}; 552 else 553 *curi = (Ins){Opar, k, r, {R}}; 554 curi++; 555 Next: 556 if (peek() == Trparen) 557 break; 558 expect(Tcomma); 559 } 560 expect(Trparen); 561 return vararg; 562 } 563 564 static Blk * 565 findblk(char *name) 566 { 567 Blk *b; 568 uint32_t h; 569 570 h = hash(name) & BMask; 571 for (b=blkh[h]; b; b=b->dlink) 572 if (strcmp(b->name, name) == 0) 573 return b; 574 b = newblk(); 575 b->id = nblk++; 576 strcpy(b->name, name); 577 b->dlink = blkh[h]; 578 blkh[h] = b; 579 return b; 580 } 581 582 static void 583 closeblk() 584 { 585 curb->nins = curi - insb; 586 idup(&curb->ins, insb, curb->nins); 587 blink = &curb->link; 588 curi = insb; 589 } 590 591 static PState 592 parseline(PState ps) 593 { 594 Ref arg[NPred] = {R}; 595 Blk *blk[NPred]; 596 Phi *phi; 597 Ref r; 598 Blk *b; 599 Con *c; 600 int t, op, i, k, ty; 601 602 t = nextnl(); 603 if (ps == PLbl && t != Tlbl && t != Trbrace) 604 err("label or } expected"); 605 switch (t) { 606 case Ttmp: 607 r = tmpref(tokval.str); 608 expect(Teq); 609 k = parsecls(&ty); 610 op = next(); 611 break; 612 default: 613 if (isstore(t)) { 614 case Tblit: 615 case Tcall: 616 case Ovastart: 617 /* operations without result */ 618 r = R; 619 k = Kw; 620 op = t; 621 break; 622 } 623 err("label, instruction or jump expected"); 624 case Trbrace: 625 return PEnd; 626 case Tlbl: 627 b = findblk(tokval.str); 628 if (curb && curb->jmp.type == Jxxx) { 629 closeblk(); 630 curb->jmp.type = Jjmp; 631 curb->s1 = b; 632 } 633 if (b->jmp.type != Jxxx) 634 err("multiple definitions of block @%s", b->name); 635 *blink = b; 636 curb = b; 637 plink = &curb->phi; 638 expect(Tnl); 639 return PPhi; 640 case Tret: 641 curb->jmp.type = Jretw + rcls; 642 if (peek() == Tnl) 643 curb->jmp.type = Jret0; 644 else if (rcls != K0) { 645 r = parseref(); 646 if (req(r, R)) 647 err("invalid return value"); 648 curb->jmp.arg = r; 649 } 650 goto Close; 651 case Tjmp: 652 curb->jmp.type = Jjmp; 653 goto Jump; 654 case Tjnz: 655 curb->jmp.type = Jjnz; 656 r = parseref(); 657 if (req(r, R)) 658 err("invalid argument for jnz jump"); 659 curb->jmp.arg = r; 660 expect(Tcomma); 661 Jump: 662 expect(Tlbl); 663 curb->s1 = findblk(tokval.str); 664 if (curb->jmp.type != Jjmp) { 665 expect(Tcomma); 666 expect(Tlbl); 667 curb->s2 = findblk(tokval.str); 668 } 669 if (curb->s1 == curf->start || curb->s2 == curf->start) 670 err("invalid jump to the start block"); 671 goto Close; 672 case Thlt: 673 curb->jmp.type = Jhlt; 674 Close: 675 expect(Tnl); 676 closeblk(); 677 return PLbl; 678 case Odbgloc: 679 op = t; 680 k = Kw; 681 r = R; 682 expect(Tint); 683 arg[0] = INT(tokval.num); 684 if (arg[0].val != tokval.num) 685 err("line number too big"); 686 if (peek() == Tcomma) { 687 next(); 688 expect(Tint); 689 arg[1] = INT(tokval.num); 690 if (arg[1].val != tokval.num) 691 err("column number too big"); 692 } else 693 arg[1] = INT(0); 694 goto Ins; 695 } 696 if (op == Tcall) { 697 arg[0] = parseref(); 698 parserefl(1); 699 op = Ocall; 700 expect(Tnl); 701 if (k == Kc) { 702 k = Kl; 703 arg[1] = TYPE(ty); 704 } 705 if (k >= Ksb) 706 k = Kw; 707 goto Ins; 708 } 709 if (op == Tloadw) 710 op = Oloadsw; 711 if (op >= Tloadl && op <= Tloadd) 712 op = Oload; 713 if (op == Talloc1 || op == Talloc2) 714 op = Oalloc; 715 if (op == Ovastart && !curf->vararg) 716 err("cannot use vastart in non-variadic function"); 717 if (k >= Ksb) 718 err("size class must be w, l, s, or d"); 719 i = 0; 720 if (peek() != Tnl) 721 for (;;) { 722 if (i == NPred) 723 err("too many arguments"); 724 if (op == Tphi) { 725 expect(Tlbl); 726 blk[i] = findblk(tokval.str); 727 } 728 arg[i] = parseref(); 729 if (req(arg[i], R)) 730 err("invalid instruction argument"); 731 i++; 732 t = peek(); 733 if (t == Tnl) 734 break; 735 if (t != Tcomma) 736 err(", or end of line expected"); 737 next(); 738 } 739 next(); 740 switch (op) { 741 case Tphi: 742 if (ps != PPhi || curb == curf->start) 743 err("unexpected phi instruction"); 744 phi = alloc(sizeof *phi); 745 phi->to = r; 746 phi->cls = k; 747 phi->arg = vnew(i, sizeof arg[0], PFn); 748 memcpy(phi->arg, arg, i * sizeof arg[0]); 749 phi->blk = vnew(i, sizeof blk[0], PFn); 750 memcpy(phi->blk, blk, i * sizeof blk[0]); 751 phi->narg = i; 752 *plink = phi; 753 plink = &phi->link; 754 return PPhi; 755 case Tblit: 756 if (curi - insb >= NIns-1) 757 err("too many instructions"); 758 memset(curi, 0, 2 * sizeof(Ins)); 759 curi->op = Oblit0; 760 curi->arg[0] = arg[0]; 761 curi->arg[1] = arg[1]; 762 curi++; 763 if (rtype(arg[2]) != RCon) 764 err("blit size must be constant"); 765 c = &curf->con[arg[2].val]; 766 r = INT(c->bits.i); 767 if (c->type != CBits 768 || rsval(r) < 0 769 || rsval(r) != c->bits.i) 770 err("invalid blit size"); 771 curi->op = Oblit1; 772 curi->arg[0] = r; 773 curi++; 774 return PIns; 775 default: 776 if (op >= NPubOp) 777 err("invalid instruction"); 778 Ins: 779 if (curi - insb >= NIns) 780 err("too many instructions"); 781 curi->op = op; 782 curi->cls = k; 783 curi->to = r; 784 curi->arg[0] = arg[0]; 785 curi->arg[1] = arg[1]; 786 curi++; 787 return PIns; 788 } 789 } 790 791 static int 792 usecheck(Ref r, int k, Fn *fn) 793 { 794 return rtype(r) != RTmp || fn->tmp[r.val].cls == k 795 || (fn->tmp[r.val].cls == Kl && k == Kw); 796 } 797 798 static void 799 typecheck(Fn *fn) 800 { 801 Blk *b; 802 Phi *p; 803 Ins *i; 804 uint n; 805 int k; 806 Tmp *t; 807 Ref r; 808 BSet pb[1], ppb[1]; 809 810 fillpreds(fn); 811 bsinit(pb, fn->nblk); 812 bsinit(ppb, fn->nblk); 813 for (b=fn->start; b; b=b->link) { 814 for (p=b->phi; p; p=p->link) 815 fn->tmp[p->to.val].cls = p->cls; 816 for (i=b->ins; i<&b->ins[b->nins]; i++) 817 if (rtype(i->to) == RTmp) { 818 t = &fn->tmp[i->to.val]; 819 if (clsmerge(&t->cls, i->cls)) 820 err("temporary %%%s is assigned with" 821 " multiple types", t->name); 822 } 823 } 824 for (b=fn->start; b; b=b->link) { 825 bszero(pb); 826 for (n=0; n<b->npred; n++) 827 bsset(pb, b->pred[n]->id); 828 for (p=b->phi; p; p=p->link) { 829 bszero(ppb); 830 t = &fn->tmp[p->to.val]; 831 for (n=0; n<p->narg; n++) { 832 k = t->cls; 833 if (bshas(ppb, p->blk[n]->id)) 834 err("multiple entries for @%s in phi %%%s", 835 p->blk[n]->name, t->name); 836 if (!usecheck(p->arg[n], k, fn)) 837 err("invalid type for operand %%%s in phi %%%s", 838 fn->tmp[p->arg[n].val].name, t->name); 839 bsset(ppb, p->blk[n]->id); 840 } 841 if (!bsequal(pb, ppb)) 842 err("predecessors not matched in phi %%%s", t->name); 843 } 844 for (i=b->ins; i<&b->ins[b->nins]; i++) 845 for (n=0; n<2; n++) { 846 k = optab[i->op].argcls[n][i->cls]; 847 r = i->arg[n]; 848 t = &fn->tmp[r.val]; 849 if (k == Ke) 850 err("invalid instruction type in %s", 851 optab[i->op].name); 852 if (rtype(r) == RType) 853 continue; 854 if (rtype(r) != -1 && k == Kx) 855 err("no %s operand expected in %s", 856 n == 1 ? "second" : "first", 857 optab[i->op].name); 858 if (rtype(r) == -1 && k != Kx) 859 err("missing %s operand in %s", 860 n == 1 ? "second" : "first", 861 optab[i->op].name); 862 if (!usecheck(r, k, fn)) 863 err("invalid type for %s operand %%%s in %s", 864 n == 1 ? "second" : "first", 865 t->name, optab[i->op].name); 866 } 867 r = b->jmp.arg; 868 if (isret(b->jmp.type)) { 869 if (b->jmp.type == Jretc) 870 k = Kl; 871 else if (b->jmp.type >= Jretsb) 872 k = Kw; 873 else 874 k = b->jmp.type - Jretw; 875 if (!usecheck(r, k, fn)) 876 goto JErr; 877 } 878 if (b->jmp.type == Jjnz && !usecheck(r, Kw, fn)) 879 JErr: 880 err("invalid type for jump argument %%%s in block @%s", 881 fn->tmp[r.val].name, b->name); 882 if (b->s1 && b->s1->jmp.type == Jxxx) 883 err("block @%s is used undefined", b->s1->name); 884 if (b->s2 && b->s2->jmp.type == Jxxx) 885 err("block @%s is used undefined", b->s2->name); 886 } 887 } 888 889 static Fn * 890 parsefn(Lnk *lnk) 891 { 892 Blk *b; 893 int i; 894 PState ps; 895 896 curb = 0; 897 nblk = 0; 898 curi = insb; 899 curf = alloc(sizeof *curf); 900 curf->ntmp = 0; 901 curf->ncon = 2; 902 curf->tmp = vnew(curf->ntmp, sizeof curf->tmp[0], PFn); 903 curf->con = vnew(curf->ncon, sizeof curf->con[0], PFn); 904 for (i=0; i<Tmp0; ++i) 905 if (T.fpr0 <= i && i < T.fpr0 + T.nfpr) 906 newtmp(0, Kd, curf); 907 else 908 newtmp(0, Kl, curf); 909 curf->con[0].type = CBits; 910 curf->con[0].bits.i = 0xdeaddead; /* UNDEF */ 911 curf->con[1].type = CBits; 912 curf->lnk = *lnk; 913 blink = &curf->start; 914 curf->retty = Kx; 915 if (peek() != Tglo) 916 rcls = parsecls(&curf->retty); 917 else 918 rcls = K0; 919 if (next() != Tglo) 920 err("function name expected"); 921 strncpy(curf->name, tokval.str, NString-1); 922 curf->vararg = parserefl(0); 923 if (nextnl() != Tlbrace) 924 err("function body must start with {"); 925 ps = PLbl; 926 do 927 ps = parseline(ps); 928 while (ps != PEnd); 929 if (!curb) 930 err("empty function"); 931 if (curb->jmp.type == Jxxx) 932 err("last block misses jump"); 933 curf->mem = vnew(0, sizeof curf->mem[0], PFn); 934 curf->nmem = 0; 935 curf->nblk = nblk; 936 curf->rpo = 0; 937 for (b=curf->start; b; b=b->link) 938 b->dlink = 0; /* was trashed by findblk() */ 939 for (i=0; i<BMask+1; ++i) 940 blkh[i] = 0; 941 memset(tmph, 0, tmphcap * sizeof tmph[0]); 942 typecheck(curf); 943 return curf; 944 } 945 946 static void 947 parsefields(Field *fld, Typ *ty, int t) 948 { 949 Typ *ty1; 950 int n, c, a, al, type; 951 uint64_t sz, s; 952 953 n = 0; 954 sz = 0; 955 al = ty->align; 956 while (t != Trbrace) { 957 ty1 = 0; 958 switch (t) { 959 default: err("invalid type member specifier"); 960 case Td: type = Fd; s = 8; a = 3; break; 961 case Tl: type = Fl; s = 8; a = 3; break; 962 case Ts: type = Fs; s = 4; a = 2; break; 963 case Tw: type = Fw; s = 4; a = 2; break; 964 case Th: type = Fh; s = 2; a = 1; break; 965 case Tb: type = Fb; s = 1; a = 0; break; 966 case Ttyp: 967 type = FTyp; 968 ty1 = &typ[findtyp(ntyp-1)]; 969 s = ty1->size; 970 a = ty1->align; 971 break; 972 } 973 if (a > al) 974 al = a; 975 a = (1 << a) - 1; 976 a = ((sz + a) & ~a) - sz; 977 if (a) { 978 if (n < NField) { 979 /* padding */ 980 fld[n].type = FPad; 981 fld[n].len = a; 982 n++; 983 } 984 } 985 t = nextnl(); 986 if (t == Tint) { 987 c = tokval.num; 988 t = nextnl(); 989 } else 990 c = 1; 991 sz += a + c*s; 992 if (type == FTyp) 993 s = ty1 - typ; 994 for (; c>0 && n<NField; c--, n++) { 995 fld[n].type = type; 996 fld[n].len = s; 997 } 998 if (t != Tcomma) 999 break; 1000 t = nextnl(); 1001 } 1002 if (t != Trbrace) 1003 err(", or } expected"); 1004 fld[n].type = FEnd; 1005 a = 1 << al; 1006 if (sz < ty->size) 1007 sz = ty->size; 1008 ty->size = (sz + a - 1) & -a; 1009 ty->align = al; 1010 } 1011 1012 static void 1013 parsetyp() 1014 { 1015 Typ *ty; 1016 int t, al; 1017 uint n; 1018 1019 /* be careful if extending the syntax 1020 * to handle nested types, any pointer 1021 * held to typ[] might be invalidated! 1022 */ 1023 vgrow(&typ, ntyp+1); 1024 ty = &typ[ntyp++]; 1025 ty->isdark = 0; 1026 ty->isunion = 0; 1027 ty->align = -1; 1028 ty->size = 0; 1029 if (nextnl() != Ttyp || nextnl() != Teq) 1030 err("type name and then = expected"); 1031 strcpy(ty->name, tokval.str); 1032 t = nextnl(); 1033 if (t == Talign) { 1034 if (nextnl() != Tint) 1035 err("alignment expected"); 1036 for (al=0; tokval.num /= 2; al++) 1037 ; 1038 ty->align = al; 1039 t = nextnl(); 1040 } 1041 if (t != Tlbrace) 1042 err("type body must start with {"); 1043 t = nextnl(); 1044 if (t == Tint) { 1045 ty->isdark = 1; 1046 ty->size = tokval.num; 1047 if (ty->align == -1) 1048 err("dark types need alignment"); 1049 if (nextnl() != Trbrace) 1050 err("} expected"); 1051 return; 1052 } 1053 n = 0; 1054 ty->fields = vnew(1, sizeof ty->fields[0], PHeap); 1055 if (t == Tlbrace) { 1056 ty->isunion = 1; 1057 do { 1058 if (t != Tlbrace) 1059 err("invalid union member"); 1060 vgrow(&ty->fields, n+1); 1061 parsefields(ty->fields[n++], ty, nextnl()); 1062 t = nextnl(); 1063 } while (t != Trbrace); 1064 } else 1065 parsefields(ty->fields[n++], ty, t); 1066 ty->nunion = n; 1067 } 1068 1069 static void 1070 parsedatref(Dat *d) 1071 { 1072 int t; 1073 1074 d->isref = 1; 1075 d->u.ref.name = tokval.str; 1076 d->u.ref.off = 0; 1077 t = peek(); 1078 if (t == Tplus) { 1079 next(); 1080 if (next() != Tint) 1081 err("invalid token after offset in ref"); 1082 d->u.ref.off = tokval.num; 1083 } 1084 } 1085 1086 static void 1087 parsedatstr(Dat *d) 1088 { 1089 d->isstr = 1; 1090 d->u.str = tokval.str; 1091 } 1092 1093 static void 1094 parsedat(void cb(Dat *), Lnk *lnk) 1095 { 1096 char name[NString] = {0}; 1097 int t; 1098 Dat d; 1099 1100 if (nextnl() != Tglo || nextnl() != Teq) 1101 err("data name, then = expected"); 1102 strncpy(name, tokval.str, NString-1); 1103 t = nextnl(); 1104 lnk->align = 8; 1105 if (t == Talign) { 1106 if (nextnl() != Tint) 1107 err("alignment expected"); 1108 if (tokval.num <= 0 || tokval.num > CHAR_MAX 1109 || (tokval.num & (tokval.num-1)) != 0) 1110 err("invalid alignment"); 1111 lnk->align = tokval.num; 1112 t = nextnl(); 1113 } 1114 d.type = DStart; 1115 d.name = name; 1116 d.lnk = lnk; 1117 cb(&d); 1118 1119 if (t != Tlbrace) 1120 err("expected data contents in { .. }"); 1121 for (;;) { 1122 switch (nextnl()) { 1123 default: err("invalid size specifier %c in data", tokval.chr); 1124 case Trbrace: goto Done; 1125 case Tl: d.type = DL; break; 1126 case Tw: d.type = DW; break; 1127 case Th: d.type = DH; break; 1128 case Tb: d.type = DB; break; 1129 case Ts: d.type = DW; break; 1130 case Td: d.type = DL; break; 1131 case Tz: d.type = DZ; break; 1132 } 1133 t = nextnl(); 1134 do { 1135 d.isstr = 0; 1136 d.isref = 0; 1137 memset(&d.u, 0, sizeof d.u); 1138 if (t == Tflts) 1139 d.u.flts = tokval.flts; 1140 else if (t == Tfltd) 1141 d.u.fltd = tokval.fltd; 1142 else if (t == Tint) 1143 d.u.num = tokval.num; 1144 else if (t == Tglo) 1145 parsedatref(&d); 1146 else if (t == Tstr) 1147 parsedatstr(&d); 1148 else 1149 err("constant literal expected"); 1150 cb(&d); 1151 t = nextnl(); 1152 } while (t == Tint || t == Tflts || t == Tfltd || t == Tstr || t == Tglo); 1153 if (t == Trbrace) 1154 break; 1155 if (t != Tcomma) 1156 err(", or } expected"); 1157 } 1158 Done: 1159 d.type = DEnd; 1160 cb(&d); 1161 } 1162 1163 static int 1164 parselnk(Lnk *lnk) 1165 { 1166 int t, haslnk; 1167 1168 for (haslnk=0;; haslnk=1) 1169 switch ((t=nextnl())) { 1170 case Texport: 1171 lnk->export = 1; 1172 break; 1173 case Tthread: 1174 lnk->thread = 1; 1175 break; 1176 case Tcommon: 1177 lnk->common = 1; 1178 break; 1179 case Tsection: 1180 if (lnk->sec) 1181 err("only one section allowed"); 1182 if (next() != Tstr) 1183 err("section \"name\" expected"); 1184 lnk->sec = tokval.str; 1185 if (peek() == Tstr) { 1186 next(); 1187 lnk->secf = tokval.str; 1188 } 1189 break; 1190 default: 1191 if (t == Tfunc && lnk->thread) 1192 err("only data may have thread linkage"); 1193 if (haslnk && t != Tdata && t != Tfunc) 1194 err("only data and function have linkage"); 1195 return t; 1196 } 1197 } 1198 1199 void 1200 parse(FILE *f, char *path, void dbgfile(char *), void data(Dat *), void func(Fn *)) 1201 { 1202 Lnk lnk; 1203 uint n; 1204 1205 lexinit(); 1206 inf = f; 1207 inpath = path; 1208 lnum = 1; 1209 thead = Txxx; 1210 ntyp = 0; 1211 typ = vnew(0, sizeof typ[0], PHeap); 1212 for (;;) { 1213 lnk = (Lnk){0}; 1214 switch (parselnk(&lnk)) { 1215 default: 1216 err("top-level definition expected"); 1217 case Tdbgfile: 1218 expect(Tstr); 1219 dbgfile(tokval.str); 1220 break; 1221 case Tfunc: 1222 func(parsefn(&lnk)); 1223 break; 1224 case Tdata: 1225 parsedat(data, &lnk); 1226 break; 1227 case Ttype: 1228 parsetyp(); 1229 break; 1230 case Teof: 1231 for (n=0; n<ntyp; n++) 1232 if (typ[n].nunion) 1233 vfree(typ[n].fields); 1234 vfree(typ); 1235 return; 1236 } 1237 } 1238 } 1239 1240 static void 1241 printcon(Con *c, FILE *f) 1242 { 1243 switch (c->type) { 1244 case CUndef: 1245 break; 1246 case CAddr: 1247 if (c->sym.type == SThr) 1248 fprintf(f, "thread "); 1249 fprintf(f, "$%s", str(c->sym.id)); 1250 if (c->bits.i) 1251 fprintf(f, "%+"PRIi64, c->bits.i); 1252 break; 1253 case CBits: 1254 if (c->flt == 1) 1255 fprintf(f, "s_%f", c->bits.s); 1256 else if (c->flt == 2) 1257 fprintf(f, "d_%lf", c->bits.d); 1258 else 1259 fprintf(f, "%"PRIi64, c->bits.i); 1260 break; 1261 } 1262 } 1263 1264 void 1265 printref(Ref r, Fn *fn, FILE *f) 1266 { 1267 int i; 1268 Mem *m; 1269 1270 switch (rtype(r)) { 1271 case RTmp: 1272 if (r.val < Tmp0) 1273 fprintf(f, "R%d", r.val); 1274 else 1275 fprintf(f, "%%%s", fn->tmp[r.val].name); 1276 break; 1277 case RCon: 1278 if (req(r, UNDEF)) 1279 fprintf(f, "UNDEF"); 1280 else 1281 printcon(&fn->con[r.val], f); 1282 break; 1283 case RSlot: 1284 fprintf(f, "S%d", rsval(r)); 1285 break; 1286 case RCall: 1287 fprintf(f, "%04x", r.val); 1288 break; 1289 case RType: 1290 fprintf(f, ":%s", typ[r.val].name); 1291 break; 1292 case RMem: 1293 i = 0; 1294 m = &fn->mem[r.val]; 1295 fputc('[', f); 1296 if (m->offset.type != CUndef) { 1297 printcon(&m->offset, f); 1298 i = 1; 1299 } 1300 if (!req(m->base, R)) { 1301 if (i) 1302 fprintf(f, " + "); 1303 printref(m->base, fn, f); 1304 i = 1; 1305 } 1306 if (!req(m->index, R)) { 1307 if (i) 1308 fprintf(f, " + "); 1309 fprintf(f, "%d * ", m->scale); 1310 printref(m->index, fn, f); 1311 } 1312 fputc(']', f); 1313 break; 1314 case RInt: 1315 fprintf(f, "%d", rsval(r)); 1316 break; 1317 case -1: 1318 fprintf(f, "R"); 1319 break; 1320 } 1321 } 1322 1323 void 1324 printfn(Fn *fn, FILE *f) 1325 { 1326 static char ktoc[] = "wlsd"; 1327 static char *jtoa[NJmp] = { 1328 #define X(j) [J##j] = #j, 1329 JMPS(X) 1330 #undef X 1331 }; 1332 Blk *b; 1333 Phi *p; 1334 Ins *i; 1335 uint n; 1336 1337 fprintf(f, "function $%s() {\n", fn->name); 1338 for (b=fn->start; b; b=b->link) { 1339 fprintf(f, "@%s\n", b->name); 1340 for (p=b->phi; p; p=p->link) { 1341 fprintf(f, "\t"); 1342 printref(p->to, fn, f); 1343 fprintf(f, " =%c phi ", ktoc[p->cls]); 1344 assert(p->narg); 1345 for (n=0;; n++) { 1346 fprintf(f, "@%s ", p->blk[n]->name); 1347 printref(p->arg[n], fn, f); 1348 if (n == p->narg-1) { 1349 fprintf(f, "\n"); 1350 break; 1351 } else 1352 fprintf(f, ", "); 1353 } 1354 } 1355 for (i=b->ins; i<&b->ins[b->nins]; i++) { 1356 fprintf(f, "\t"); 1357 if (!req(i->to, R)) { 1358 printref(i->to, fn, f); 1359 fprintf(f, " =%c ", ktoc[i->cls]); 1360 } 1361 assert(optab[i->op].name); 1362 fprintf(f, "%s", optab[i->op].name); 1363 if (req(i->to, R)) 1364 switch (i->op) { 1365 case Oarg: 1366 case Oswap: 1367 case Oxcmp: 1368 case Oacmp: 1369 case Oacmn: 1370 case Oafcmp: 1371 case Oxtest: 1372 case Oxdiv: 1373 case Oxidiv: 1374 fputc(ktoc[i->cls], f); 1375 } 1376 if (!req(i->arg[0], R)) { 1377 fprintf(f, " "); 1378 printref(i->arg[0], fn, f); 1379 } 1380 if (!req(i->arg[1], R)) { 1381 fprintf(f, ", "); 1382 printref(i->arg[1], fn, f); 1383 } 1384 fprintf(f, "\n"); 1385 } 1386 switch (b->jmp.type) { 1387 case Jret0: 1388 case Jretsb: 1389 case Jretub: 1390 case Jretsh: 1391 case Jretuh: 1392 case Jretw: 1393 case Jretl: 1394 case Jrets: 1395 case Jretd: 1396 case Jretc: 1397 fprintf(f, "\t%s", jtoa[b->jmp.type]); 1398 if (b->jmp.type != Jret0 || !req(b->jmp.arg, R)) { 1399 fprintf(f, " "); 1400 printref(b->jmp.arg, fn, f); 1401 } 1402 if (b->jmp.type == Jretc) 1403 fprintf(f, ", :%s", typ[fn->retty].name); 1404 fprintf(f, "\n"); 1405 break; 1406 case Jhlt: 1407 fprintf(f, "\thlt\n"); 1408 break; 1409 case Jjmp: 1410 if (b->s1 != b->link) 1411 fprintf(f, "\tjmp @%s\n", b->s1->name); 1412 break; 1413 default: 1414 fprintf(f, "\t%s ", jtoa[b->jmp.type]); 1415 if (b->jmp.type == Jjnz) { 1416 printref(b->jmp.arg, fn, f); 1417 fprintf(f, ", "); 1418 } 1419 assert(b->s1 && b->s2); 1420 fprintf(f, "@%s, @%s\n", b->s1->name, b->s2->name); 1421 break; 1422 } 1423 } 1424 fprintf(f, "}\n"); 1425 }