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