1 #include "limbo.h" 2 3 static Node* putinline(Node*); 4 static void fpcall(Src*, int, Node*, Node*); 5 6 void 7 optabinit(void) 8 { 9 int i; 10 11 for(i = 0; setisbyteinst[i] >= 0; i++) 12 isbyteinst[setisbyteinst[i]] = 1; 13 14 for(i = 0; setisused[i] >= 0; i++) 15 isused[setisused[i]] = 1; 16 17 for(i = 0; setsideeffect[i] >= 0; i++) 18 sideeffect[setsideeffect[i]] = 1; 19 20 opind[Tbyte] = 1; 21 opind[Tint] = 2; 22 opind[Tbig] = 3; 23 opind[Treal] = 4; 24 opind[Tstring] = 5; 25 opind[Tfix] = 6; 26 27 opcommute[Oeq] = Oeq; 28 opcommute[Oneq] = Oneq; 29 opcommute[Olt] = Ogt; 30 opcommute[Ogt] = Olt; 31 opcommute[Ogeq] = Oleq; 32 opcommute[Oleq] = Ogeq; 33 opcommute[Oadd] = Oadd; 34 opcommute[Omul] = Omul; 35 opcommute[Oxor] = Oxor; 36 opcommute[Oor] = Oor; 37 opcommute[Oand] = Oand; 38 39 oprelinvert[Oeq] = Oneq; 40 oprelinvert[Oneq] = Oeq; 41 oprelinvert[Olt] = Ogeq; 42 oprelinvert[Ogt] = Oleq; 43 oprelinvert[Ogeq] = Olt; 44 oprelinvert[Oleq] = Ogt; 45 46 isrelop[Oeq] = 1; 47 isrelop[Oneq] = 1; 48 isrelop[Olt] = 1; 49 isrelop[Oleq] = 1; 50 isrelop[Ogt] = 1; 51 isrelop[Ogeq] = 1; 52 isrelop[Oandand] = 1; 53 isrelop[Ooror] = 1; 54 isrelop[Onot] = 1; 55 56 precasttab[Tstring][Tbyte] = tint; 57 precasttab[Tbyte][Tstring] = tint; 58 precasttab[Treal][Tbyte] = tint; 59 precasttab[Tbyte][Treal] = tint; 60 precasttab[Tbig][Tbyte] = tint; 61 precasttab[Tbyte][Tbig] = tint; 62 precasttab[Tfix][Tbyte] = tint; 63 precasttab[Tbyte][Tfix] = tint; 64 precasttab[Tbig][Tfix] = treal; 65 precasttab[Tfix][Tbig] = treal; 66 precasttab[Tstring][Tfix] = treal; 67 precasttab[Tfix][Tstring] = treal; 68 69 casttab[Tint][Tint] = IMOVW; 70 casttab[Tbig][Tbig] = IMOVL; 71 casttab[Treal][Treal] = IMOVF; 72 casttab[Tbyte][Tbyte] = IMOVB; 73 casttab[Tstring][Tstring] = IMOVP; 74 casttab[Tfix][Tfix] = ICVTXX; /* never same type */ 75 76 casttab[Tint][Tbyte] = ICVTWB; 77 casttab[Tint][Treal] = ICVTWF; 78 casttab[Tint][Tstring] = ICVTWC; 79 casttab[Tint][Tfix] = ICVTXX; 80 casttab[Tbyte][Tint] = ICVTBW; 81 casttab[Treal][Tint] = ICVTFW; 82 casttab[Tstring][Tint] = ICVTCW; 83 casttab[Tfix][Tint] = ICVTXX; 84 85 casttab[Tint][Tbig] = ICVTWL; 86 casttab[Treal][Tbig] = ICVTFL; 87 casttab[Tstring][Tbig] = ICVTCL; 88 casttab[Tbig][Tint] = ICVTLW; 89 casttab[Tbig][Treal] = ICVTLF; 90 casttab[Tbig][Tstring] = ICVTLC; 91 92 casttab[Treal][Tstring] = ICVTFC; 93 casttab[Tstring][Treal] = ICVTCF; 94 95 casttab[Treal][Tfix] = ICVTFX; 96 casttab[Tfix][Treal] = ICVTXF; 97 98 casttab[Tstring][Tarray] = ICVTCA; 99 casttab[Tarray][Tstring] = ICVTAC; 100 101 /* 102 * placeholders; fixed in precasttab 103 */ 104 casttab[Tbyte][Tstring] = 0xff; 105 casttab[Tstring][Tbyte] = 0xff; 106 casttab[Tbyte][Treal] = 0xff; 107 casttab[Treal][Tbyte] = 0xff; 108 casttab[Tbyte][Tbig] = 0xff; 109 casttab[Tbig][Tbyte] = 0xff; 110 casttab[Tfix][Tbyte] = 0xff; 111 casttab[Tbyte][Tfix] = 0xff; 112 casttab[Tfix][Tbig] = 0xff; 113 casttab[Tbig][Tfix] = 0xff; 114 casttab[Tfix][Tstring] = 0xff; 115 casttab[Tstring][Tfix] = 0xff; 116 } 117 118 /* 119 * global variable and constant initialization checking 120 */ 121 int 122 vcom(Decl *ids) 123 { 124 Decl *v; 125 int ok; 126 127 ok = 1; 128 for(v = ids; v != nil; v = v->next) 129 ok &= varcom(v); 130 for(v = ids; v != nil; v = v->next) 131 v->init = simplify(v->init); 132 return ok; 133 } 134 135 Node* 136 simplify(Node *n) 137 { 138 if(n == nil) 139 return nil; 140 if(debug['F']) 141 print("simplify %n\n", n); 142 n = efold(rewrite(n)); 143 if(debug['F']) 144 print("simplified %n\n", n); 145 return n; 146 } 147 148 static int 149 isfix(Node *n) 150 { 151 if(n->ty->kind == Tint || n->ty->kind == Tfix){ 152 if(n->op == Ocast) 153 return n->left->ty->kind == Tint || n->left->ty->kind == Tfix; 154 return 1; 155 } 156 return 0; 157 } 158 159 /* 160 * rewrite an expression to make it easiser to compile, 161 * or give the correct results 162 */ 163 Node* 164 rewrite(Node *n) 165 { 166 Long v; 167 Type *t; 168 Decl *d; 169 Node *nn, *left, *right; 170 171 if(n == nil) 172 return nil; 173 174 left = n->left; 175 right = n->right; 176 177 /* 178 * rewrites 179 */ 180 switch(n->op){ 181 case Oname: 182 d = n->decl; 183 if(d->importid != nil){ 184 left = mkbin(Omdot, dupn(1, &n->src, d->eimport), mkdeclname(&n->src, d->importid)); 185 left->ty = n->ty; 186 return rewrite(left); 187 } 188 if((t = n->ty)->kind == Texception){ 189 if(t->cons) 190 fatal("cons in rewrite Oname"); 191 n = mkbin(Oadd, n, mkconst(&n->src, 2*IBY2WD)); 192 n = mkunary(Oind, n); 193 n->ty = t; 194 n->left->ty = n->left->left->ty = tint; 195 return rewrite(n); 196 } 197 break; 198 case Odas: 199 n->op = Oas; 200 return rewrite(n); 201 case Oneg: 202 n->left = rewrite(left); 203 if(n->ty == treal) 204 break; 205 left = n->left; 206 n->right = left; 207 n->left = mkconst(&n->src, 0); 208 n->left->ty = n->ty; 209 n->op = Osub; 210 break; 211 case Ocomp: 212 v = 0; 213 v = ~v; 214 n->right = mkconst(&n->src, v); 215 n->right->ty = n->ty; 216 n->left = rewrite(left); 217 n->op = Oxor; 218 break; 219 case Oinc: 220 case Odec: 221 case Opreinc: 222 case Opredec: 223 n->left = rewrite(left); 224 switch(n->ty->kind){ 225 case Treal: 226 n->right = mkrconst(&n->src, 1.0); 227 break; 228 case Tint: 229 case Tbig: 230 case Tbyte: 231 case Tfix: 232 n->right = mkconst(&n->src, 1); 233 n->right->ty = n->ty; 234 break; 235 default: 236 fatal("can't rewrite inc/dec %n", n); 237 break; 238 } 239 if(n->op == Opreinc) 240 n->op = Oaddas; 241 else if(n->op == Opredec) 242 n->op = Osubas; 243 break; 244 case Oslice: 245 if(right->left->op == Onothing) 246 right->left = mkconst(&right->left->src, 0); 247 n->left = rewrite(left); 248 n->right = rewrite(right); 249 break; 250 case Oindex: 251 n->op = Oindx; 252 n->left = rewrite(left); 253 n->right = rewrite(right); 254 n = mkunary(Oind, n); 255 n->ty = n->left->ty; 256 n->left->ty = tint; 257 break; 258 case Oload: 259 n->right = mkn(Oname, nil, nil); 260 n->right->src = n->left->src; 261 n->right->decl = n->ty->tof->decl; 262 n->right->ty = n->ty; 263 n->left = rewrite(left); 264 break; 265 case Ocast: 266 if(left->ty->kind == Texception){ 267 n = rewrite(left); 268 break; 269 } 270 n->op = Ocast; 271 t = precasttab[left->ty->kind][n->ty->kind]; 272 if(t != nil){ 273 n->left = mkunary(Ocast, left); 274 n->left->ty = t; 275 return rewrite(n); 276 } 277 n->left = rewrite(left); 278 break; 279 case Oraise: 280 if(left->ty == tstring) 281 {} 282 else if(!left->ty->cons) 283 break; 284 else if(left->op != Ocall || left->left->ty->kind == Tfn){ 285 left = mkunary(Ocall, left); 286 left->ty = left->left->ty; 287 } 288 n->left = rewrite(left); 289 break; 290 case Ocall: 291 t = left->ty; 292 if(t->kind == Tref) 293 t = t->tof; 294 if(t->kind == Tfn){ 295 if(debug['U']) print("call %n\n", left); 296 if(left->ty->kind == Tref){ /* call by function reference */ 297 n->left = mkunary(Oind, left); 298 n->left->ty = t; 299 return rewrite(n); 300 } 301 d = nil; 302 if(left->op == Oname) 303 d = left->decl; 304 else if(left->op == Omdot && left->right->op == Odot) 305 d = left->right->right->decl; 306 else if(left->op == Omdot || left->op == Odot) 307 d = left->right->decl; 308 else if(left->op != Oind) 309 fatal("cannot deal with call %n in rewrite", n); 310 if(ispoly(d)) 311 addfnptrs(d, 0); 312 n->left = rewrite(left); 313 if(right != nil) 314 n->right = rewrite(right); 315 if(d != nil && d->caninline == 1) 316 n = simplify(putinline(n)); 317 break; 318 } 319 switch(n->ty->kind){ 320 case Tref: 321 n = mkunary(Oref, n); 322 n->ty = n->left->ty; 323 n->left->ty = n->left->ty->tof; 324 n->left->left->ty = n->left->ty; 325 return rewrite(n); 326 case Tadt: 327 n->op = Otuple; 328 n->right = nil; 329 if(n->ty->tags != nil){ 330 n->left = nn = mkunary(Oseq, mkconst(&n->src, left->right->decl->tag)); 331 if(right != nil){ 332 nn->right = right; 333 nn->src.stop = right->src.stop; 334 } 335 n->ty = left->right->decl->ty->tof; 336 }else 337 n->left = right; 338 return rewrite(n); 339 case Tadtpick: 340 n->op = Otuple; 341 n->right = nil; 342 n->left = nn = mkunary(Oseq, mkconst(&n->src, left->right->decl->tag)); 343 if(right != nil){ 344 nn->right = right; 345 nn->src.stop = right->src.stop; 346 } 347 n->ty = left->right->decl->ty->tof; 348 return rewrite(n); 349 case Texception: 350 if(!n->ty->cons) 351 return n->left; 352 if(left->op == Omdot){ 353 left->right->ty = left->ty; 354 left = left->right; 355 } 356 n->op = Otuple; 357 n->right = nil; 358 n->left = nn = mkunary(Oseq, left->decl->init); 359 nn->right = mkunary(Oseq, mkconst(&n->src, 0)); 360 nn->right->right = right; 361 n->ty = mkexbasetype(n->ty); 362 n = mkunary(Oref, n); 363 n->ty = internaltype(mktype(&n->src.start, &n->src.stop, Tref, t, nil)); 364 return rewrite(n); 365 default: 366 fatal("can't deal with %n in rewrite/Ocall", n); 367 break; 368 } 369 break; 370 case Omdot: 371 /* 372 * what about side effects from left? 373 */ 374 d = right->decl; 375 switch(d->store){ 376 case Dfn: 377 n->left = rewrite(left); 378 if(right->op == Odot){ 379 n->right = dupn(1, &left->src, right->right); 380 n->right->ty = d->ty; 381 } 382 break; 383 case Dconst: 384 case Dtag: 385 case Dtype: 386 /* handled by fold */ 387 return n; 388 case Dglobal: 389 right->op = Oconst; 390 right->val = d->offset; 391 right->ty = tint; 392 393 n->left = left = mkunary(Oind, left); 394 left->ty = tint; 395 n->op = Oadd; 396 n = mkunary(Oind, n); 397 n->ty = n->left->ty; 398 n->left->ty = tint; 399 n->left = rewrite(n->left); 400 return n; 401 case Darg: 402 return n; 403 default: 404 fatal("can't deal with %n in rewrite/Omdot", n); 405 break; 406 } 407 break; 408 case Odot: 409 /* 410 * what about side effects from left? 411 */ 412 d = right->decl; 413 switch(d->store){ 414 case Dfn: 415 if(right->left != nil){ 416 n = mkbin(Omdot, dupn(1, &left->src, right->left), right); 417 right->left = nil; 418 n->ty = d->ty; 419 return rewrite(n); 420 } 421 if(left->ty->kind == Tpoly){ 422 n = mkbin(Omdot, mkdeclname(&left->src, d->link), mkdeclname(&left->src, d->link->next)); 423 n->ty = d->ty; 424 return rewrite(n); 425 } 426 n->op = Oname; 427 n->decl = d; 428 n->right = nil; 429 n->left = nil; 430 return n; 431 case Dconst: 432 case Dtag: 433 case Dtype: 434 /* handled by fold */ 435 return n; 436 } 437 if(istuple(left)) 438 return n; /* handled by fold */ 439 right->op = Oconst; 440 right->val = d->offset; 441 right->ty = tint; 442 443 if(left->ty->kind != Tref){ 444 n->left = mkunary(Oadr, left); 445 n->left->ty = tint; 446 } 447 n->op = Oadd; 448 n = mkunary(Oind, n); 449 n->ty = n->left->ty; 450 n->left->ty = tint; 451 n->left = rewrite(n->left); 452 return n; 453 case Oadr: 454 left = rewrite(left); 455 n->left = left; 456 if(left->op == Oind) 457 return left->left; 458 break; 459 case Otagof: 460 if(n->decl == nil){ 461 n->op = Oind; 462 return rewrite(n); 463 } 464 return n; 465 case Omul: 466 case Odiv: 467 left = n->left = rewrite(left); 468 right = n->right = rewrite(right); 469 if(n->ty->kind == Tfix && isfix(left) && isfix(right)){ 470 if(left->op == Ocast && tequal(left->ty, n->ty)) 471 n->left = left->left; 472 if(right->op == Ocast && tequal(right->ty, n->ty)) 473 n->right = right->left; 474 } 475 break; 476 case Oself: 477 if(newfnptr) 478 return n; 479 if(selfdecl == nil){ 480 d = selfdecl = mkids(&n->src, enter(strdup(".self"), 5), tany, nil); 481 installids(Dglobal, d); 482 d->refs++; 483 } 484 nn = mkn(Oload, nil, nil); 485 nn->src = n->src; 486 nn->left = mksconst(&n->src, enterstring(strdup("$self"), 5)); 487 nn->ty = impdecl->ty; 488 usetype(nn->ty); 489 usetype(nn->ty->tof); 490 nn = rewrite(nn); 491 nn->op = Oself; 492 return nn; 493 case Ofnptr: 494 if(n->flags == 0){ 495 /* module */ 496 if(left == nil) 497 left = mkn(Oself, nil, nil); 498 return rewrite(left); 499 } 500 right->flags = n->flags; 501 n = right; 502 d = n->decl; 503 if(n->flags == FNPTR2){ 504 if(left != nil && left->op != Oname) 505 fatal("not Oname for addiface"); 506 if(left == nil){ 507 addiface(nil, d); 508 if(newfnptr) 509 n->flags |= FNPTRN; 510 } 511 else 512 addiface(left->decl, d); /* is this necessary ? */ 513 n->ty = tint; 514 return n; 515 } 516 if(n->flags == FNPTRA){ 517 n = mkdeclname(&n->src, d->link); 518 n->ty = tany; 519 return n; 520 } 521 if(n->flags == (FNPTRA|FNPTR2)){ 522 n = mkdeclname(&n->src, d->link->next); 523 n->ty = tint; 524 return n; 525 } 526 break; 527 case Ochan: 528 if(left == nil) 529 left = n->left = mkconst(&n->src, 0); 530 n->left = rewrite(left); 531 break; 532 default: 533 n->left = rewrite(left); 534 n->right = rewrite(right); 535 break; 536 } 537 538 return n; 539 } 540 541 /* 542 * label a node with sethi-ullman numbers and addressablity 543 * genaddr interprets addable to generate operands, 544 * so a change here mandates a change there. 545 * 546 * addressable: 547 * const Rconst $value may also be Roff or Rdesc or Rnoff 548 * Asmall(local) Rreg value(FP) 549 * Asmall(global) Rmreg value(MP) 550 * ind(Rareg) Rreg value(FP) 551 * ind(Ramreg) Rmreg value(MP) 552 * ind(Rreg) Radr *value(FP) 553 * ind(Rmreg) Rmadr *value(MP) 554 * ind(Raadr) Radr value(value(FP)) 555 * ind(Ramadr) Rmadr value(value(MP)) 556 * 557 * almost addressable: 558 * adr(Rreg) Rareg 559 * adr(Rmreg) Ramreg 560 * add(const, Rareg) Rareg 561 * add(const, Ramreg) Ramreg 562 * add(const, Rreg) Raadr 563 * add(const, Rmreg) Ramadr 564 * add(const, Raadr) Raadr 565 * add(const, Ramadr) Ramadr 566 * adr(Radr) Raadr 567 * adr(Rmadr) Ramadr 568 * 569 * strangely addressable: 570 * fn Rpc 571 * mdot(module,exp) Rmpc 572 */ 573 Node* 574 sumark(Node *n) 575 { 576 Node *left, *right; 577 long v; 578 579 if(n == nil) 580 return nil; 581 582 n->temps = 0; 583 n->addable = Rcant; 584 585 left = n->left; 586 right = n->right; 587 if(left != nil){ 588 sumark(left); 589 n->temps = left->temps; 590 } 591 if(right != nil){ 592 sumark(right); 593 if(right->temps == n->temps) 594 n->temps++; 595 else if(right->temps > n->temps) 596 n->temps = right->temps; 597 } 598 599 switch(n->op){ 600 case Oadr: 601 switch(left->addable){ 602 case Rreg: 603 n->addable = Rareg; 604 break; 605 case Rmreg: 606 n->addable = Ramreg; 607 break; 608 case Radr: 609 n->addable = Raadr; 610 break; 611 case Rmadr: 612 n->addable = Ramadr; 613 break; 614 } 615 break; 616 case Oind: 617 switch(left->addable){ 618 case Rreg: 619 n->addable = Radr; 620 break; 621 case Rmreg: 622 n->addable = Rmadr; 623 break; 624 case Rareg: 625 n->addable = Rreg; 626 break; 627 case Ramreg: 628 n->addable = Rmreg; 629 break; 630 case Raadr: 631 n->addable = Radr; 632 break; 633 case Ramadr: 634 n->addable = Rmadr; 635 break; 636 } 637 break; 638 case Oname: 639 switch(n->decl->store){ 640 case Darg: 641 case Dlocal: 642 n->addable = Rreg; 643 break; 644 case Dglobal: 645 n->addable = Rmreg; 646 if(LDT && n->decl->ty->kind == Tiface) 647 n->addable = Rldt; 648 break; 649 case Dtype: 650 /* 651 * check for inferface to load 652 */ 653 if(n->decl->ty->kind == Tmodule) 654 n->addable = Rmreg; 655 break; 656 case Dfn: 657 if(n->flags & FNPTR){ 658 if(n->flags == FNPTR2) 659 n->addable = Roff; 660 else if(n->flags == (FNPTR2|FNPTRN)) 661 n->addable = Rnoff; 662 } 663 else 664 n->addable = Rpc; 665 break; 666 default: 667 fatal("cannot deal with %K in Oname in %n", n->decl, n); 668 break; 669 } 670 break; 671 case Omdot: 672 n->addable = Rmpc; 673 break; 674 case Oconst: 675 switch(n->ty->kind){ 676 case Tint: 677 case Tfix: 678 v = n->val; 679 if(v < 0 && ((v >> 29) & 0x7) != 7 680 || v > 0 && (v >> 29) != 0){ 681 n->decl = globalconst(n); 682 n->addable = Rmreg; 683 }else 684 n->addable = Rconst; 685 break; 686 case Tbig: 687 n->decl = globalBconst(n); 688 n->addable = Rmreg; 689 break; 690 case Tbyte: 691 n->decl = globalbconst(n); 692 n->addable = Rmreg; 693 break; 694 case Treal: 695 n->decl = globalfconst(n); 696 n->addable = Rmreg; 697 break; 698 case Tstring: 699 n->decl = globalsconst(n); 700 n->addable = Rmreg; 701 break; 702 default: 703 fatal("cannot %T const in sumark", n->ty); 704 break; 705 } 706 break; 707 case Oadd: 708 if(right->addable == Rconst){ 709 switch(left->addable){ 710 case Rareg: 711 n->addable = Rareg; 712 break; 713 case Ramreg: 714 n->addable = Ramreg; 715 break; 716 case Rreg: 717 case Raadr: 718 n->addable = Raadr; 719 break; 720 case Rmreg: 721 case Ramadr: 722 n->addable = Ramadr; 723 break; 724 } 725 } 726 break; 727 } 728 if(n->addable < Rcant) 729 n->temps = 0; 730 else if(n->temps == 0) 731 n->temps = 1; 732 return n; 733 } 734 735 Node* 736 mktn(Type *t) 737 { 738 Node *n; 739 740 n = mkn(Oname, nil, nil); 741 usedesc(mktdesc(t)); 742 n->ty = t; 743 n->decl = t->decl; 744 if(n->decl == nil) 745 fatal("mktn t %T nil decl", t); 746 n->addable = Rdesc; 747 return n; 748 } 749 750 /* does a tuple of the form (a, b, ...) form a contiguous block 751 * of memory on the stack when offsets are assigned later 752 * - only when (a, b, ...) := rhs and none of the names nil 753 * can we guarantee this 754 */ 755 static int 756 tupblk0(Node *n, Decl **dd) 757 { 758 Decl *d; 759 int nid; 760 761 switch(n->op){ 762 case Otuple: 763 for(n = n->left; n != nil; n = n->right) 764 if(!tupblk0(n->left, dd)) 765 return 0; 766 return 1; 767 case Oname: 768 if(n->decl == nildecl) 769 return 0; 770 d = *dd; 771 if(d != nil && d->next != n->decl) 772 return 0; 773 nid = n->decl->nid; 774 if(d == nil && nid == 1) 775 return 0; 776 if(d != nil && nid != 0) 777 return 0; 778 *dd = n->decl; 779 return 1; 780 } 781 return 0; 782 } 783 784 /* could force locals to be next to each other 785 * - need to shuffle locals list 786 * - later 787 */ 788 static Node* 789 tupblk(Node *n) 790 { 791 Decl *d; 792 793 if(n->op != Otuple) 794 return nil; 795 d = nil; 796 if(!tupblk0(n, &d)) 797 return nil; 798 while(n->op == Otuple) 799 n = n->left->left; 800 if(n->op != Oname || n->decl->nid == 1) 801 fatal("bad tupblk"); 802 return n; 803 } 804 805 /* for cprof */ 806 #define esrc(src, osrc, nto) (src != nil && nto != nil ? src : osrc) 807 808 /* 809 * compile an expression with an implicit assignment 810 * note: you are not allowed to use to->src 811 * 812 * need to think carefully about the types used in moves 813 * it particular, it would be nice to gen movp rather than movc sometimes. 814 */ 815 Node* 816 ecom(Src *src, Node *nto, Node *n) 817 { 818 Node *left, *right, *tn; 819 Node tl, tr, tto, ttn; 820 Type *t, *tt; 821 Inst *p, *pp; 822 int op; 823 824 if(debug['e']){ 825 print("ecom: %n\n", n); 826 if(nto != nil) 827 print("ecom to: %n\n", nto); 828 } 829 830 if(n->addable < Rcant){ 831 /* 832 * think carefully about the type used here 833 */ 834 if(nto != nil) 835 genmove(src, Mas, n->ty, n, nto); 836 return nto; 837 } 838 839 tl.decl = nil; 840 tr.decl = nil; 841 tto.decl = nil; 842 ttn.decl = nil; 843 844 left = n->left; 845 right = n->right; 846 op = n->op; 847 switch(op){ 848 default: 849 case Oadr: 850 fatal("can't %n in ecom", n); 851 return nto; 852 case Oif: 853 p = bcom(left, 1, nil); 854 ecom(&right->left->src, nto, right->left); 855 if(right->right != nil){ 856 pp = p; 857 p = genrawop(&right->left->src, IJMP, nil, nil, nil); 858 patch(pp, nextinst()); 859 ecom(&right->right->src, nto, right->right); 860 } 861 patch(p, nextinst()); 862 break; 863 case Ocomma: 864 tn = left->left; 865 ecom(&left->src, nil, left); 866 ecom(&right->src, nto, right); 867 tfree(tn); 868 break; 869 case Oname: 870 if(n->addable == Rpc){ 871 if(nto != nil) 872 genmove(src, Mas, n->ty, n, nto); 873 return nto; 874 } 875 fatal("can't %n in ecom", n); 876 break; 877 case Onothing: 878 break; 879 case Oused: 880 if(nto != nil) 881 fatal("superfluous used %n to %n", left, nto); 882 talloc(&tto, left->ty, nil); 883 ecom(&left->src, &tto, left); 884 tfree(&tto); 885 break; 886 case Oas: 887 if(right->ty == tany) 888 right->ty = n->ty; 889 if(left->op == Oname && left->decl->ty == tany){ 890 if(nto == nil) 891 nto = talloc(&tto, right->ty, nil); 892 left = nto; 893 nto = nil; 894 } 895 if(left->op == Oinds){ 896 indsascom(src, nto, n); 897 tfree(&tto); 898 break; 899 } 900 if(left->op == Oslice){ 901 slicelcom(src, nto, n); 902 tfree(&tto); 903 break; 904 } 905 906 if(left->op == Otuple){ 907 if(!tupsaliased(right, left)){ 908 if((tn = tupblk(left)) != nil){ 909 tn->ty = n->ty; 910 ecom(&n->right->src, tn, right); 911 if(nto != nil) 912 genmove(src, Mas, n->ty, tn, nto); 913 tfree(&tto); 914 break; 915 } 916 if((tn = tupblk(right)) != nil){ 917 tn->ty = n->ty; 918 tuplcom(tn, left); 919 if(nto != nil) 920 genmove(src, Mas, n->ty, tn, nto); 921 tfree(&tto); 922 break; 923 } 924 if(nto == nil && right->op == Otuple && left->ty->kind != Tadtpick){ 925 tuplrcom(right, left); 926 tfree(&tto); 927 break; 928 } 929 } 930 if(right->addable >= Ralways 931 || right->op != Oname 932 || tupaliased(right, left)){ 933 talloc(&tr, n->ty, nil); 934 ecom(&n->right->src, &tr, right); 935 right = &tr; 936 } 937 tuplcom(right, n->left); 938 if(nto != nil) 939 genmove(src, Mas, n->ty, right, nto); 940 tfree(&tr); 941 tfree(&tto); 942 break; 943 } 944 945 /* 946 * check for left/right aliasing and build right into temporary 947 */ 948 if(right->op == Otuple){ 949 if(!tupsaliased(left, right) && (tn = tupblk(right)) != nil){ 950 tn->ty = n->ty; 951 right = tn; 952 } 953 else if(left->op != Oname || tupaliased(left, right)) 954 right = ecom(&right->src, talloc(&tr, right->ty, nil), right); 955 } 956 957 /* 958 * think carefully about types here 959 */ 960 if(left->addable >= Rcant) 961 left = eacom(left, &tl, nto); 962 ecom(&n->src, left, right); 963 if(nto != nil) 964 genmove(src, Mas, nto->ty, left, nto); 965 tfree(&tl); 966 tfree(&tr); 967 tfree(&tto); 968 break; 969 case Ochan: 970 if(left && left->addable >= Rcant) 971 left = eacom(left, &tl, nto); 972 genchan(src, left, n->ty->tof, nto); 973 tfree(&tl); 974 break; 975 case Oinds: 976 if(right->addable < Ralways){ 977 if(left->addable >= Rcant) 978 left = eacom(left, &tl, nil); 979 }else if(left->temps <= right->temps){ 980 right = ecom(&right->src, talloc(&tr, right->ty, nil), right); 981 if(left->addable >= Rcant) 982 left = eacom(left, &tl, nil); 983 }else{ 984 left = eacom(left, &tl, nil); 985 right = ecom(&right->src, talloc(&tr, right->ty, nil), right); 986 } 987 genop(&n->src, op, left, right, nto); 988 tfree(&tl); 989 tfree(&tr); 990 break; 991 case Osnd: 992 if(right->addable < Rcant){ 993 if(left->addable >= Rcant) 994 left = eacom(left, &tl, nto); 995 }else if(left->temps < right->temps){ 996 right = eacom(right, &tr, nto); 997 if(left->addable >= Rcant) 998 left = eacom(left, &tl, nil); 999 }else{ 1000 left = eacom(left, &tl, nto); 1001 right = eacom(right, &tr, nil); 1002 } 1003 p = genrawop(&n->src, ISEND, right, nil, left); 1004 p->m.offset = n->ty->size; /* for optimizer */ 1005 if(nto != nil) 1006 genmove(src, Mas, right->ty, right, nto); 1007 tfree(&tl); 1008 tfree(&tr); 1009 break; 1010 case Orcv: 1011 if(nto == nil){ 1012 ecom(&n->src, talloc(&tto, n->ty, nil), n); 1013 tfree(&tto); 1014 return nil; 1015 } 1016 if(left->addable >= Rcant) 1017 left = eacom(left, &tl, nto); 1018 if(left->ty->kind == Tchan){ 1019 p = genrawop(src, IRECV, left, nil, nto); 1020 p->m.offset = n->ty->size; /* for optimizer */ 1021 }else{ 1022 recvacom(src, nto, n); 1023 } 1024 tfree(&tl); 1025 break; 1026 case Ocons: 1027 /* 1028 * another temp which can go with analysis 1029 */ 1030 if(left->addable >= Rcant) 1031 left = eacom(left, &tl, nil); 1032 if(!sameaddr(right, nto)){ 1033 ecom(&right->src, talloc(&tto, n->ty, nto), right); 1034 genmove(src, Mcons, left->ty, left, &tto); 1035 if(!sameaddr(&tto, nto)) 1036 genmove(src, Mas, nto->ty, &tto, nto); 1037 }else 1038 genmove(src, Mcons, left->ty, left, nto); 1039 tfree(&tl); 1040 tfree(&tto); 1041 break; 1042 case Ohd: 1043 if(left->addable >= Rcant) 1044 left = eacom(left, &tl, nto); 1045 genmove(src, Mhd, nto->ty, left, nto); 1046 tfree(&tl); 1047 break; 1048 case Otl: 1049 if(left->addable >= Rcant) 1050 left = eacom(left, &tl, nto); 1051 genmove(src, Mtl, left->ty, left, nto); 1052 tfree(&tl); 1053 break; 1054 case Otuple: 1055 if((tn = tupblk(n)) != nil){ 1056 tn->ty = n->ty; 1057 genmove(src, Mas, n->ty, tn, nto); 1058 break; 1059 } 1060 tupcom(nto, n); 1061 break; 1062 case Oadd: 1063 case Osub: 1064 case Omul: 1065 case Odiv: 1066 case Omod: 1067 case Oand: 1068 case Oor: 1069 case Oxor: 1070 case Olsh: 1071 case Orsh: 1072 case Oexp: 1073 /* 1074 * check for 2 operand forms 1075 */ 1076 if(sameaddr(nto, left)){ 1077 if(right->addable >= Rcant) 1078 right = eacom(right, &tr, nto); 1079 genop(src, op, right, nil, nto); 1080 tfree(&tr); 1081 break; 1082 } 1083 1084 if(opcommute[op] && sameaddr(nto, right) && n->ty != tstring){ 1085 if(left->addable >= Rcant) 1086 left = eacom(left, &tl, nto); 1087 genop(src, opcommute[op], left, nil, nto); 1088 tfree(&tl); 1089 break; 1090 } 1091 1092 if(right->addable < left->addable 1093 && opcommute[op] 1094 && n->ty != tstring){ 1095 op = opcommute[op]; 1096 left = right; 1097 right = n->left; 1098 } 1099 if(left->addable < Ralways){ 1100 if(right->addable >= Rcant) 1101 right = eacom(right, &tr, nto); 1102 }else if(right->temps <= left->temps){ 1103 left = ecom(&left->src, talloc(&tl, left->ty, nto), left); 1104 if(right->addable >= Rcant) 1105 right = eacom(right, &tr, nil); 1106 }else{ 1107 right = eacom(right, &tr, nto); 1108 left = ecom(&left->src, talloc(&tl, left->ty, nil), left); 1109 } 1110 1111 /* 1112 * check for 2 operand forms 1113 */ 1114 if(sameaddr(nto, left)) 1115 genop(src, op, right, nil, nto); 1116 else if(opcommute[op] && sameaddr(nto, right) && n->ty != tstring) 1117 genop(src, opcommute[op], left, nil, nto); 1118 else 1119 genop(src, op, right, left, nto); 1120 tfree(&tl); 1121 tfree(&tr); 1122 break; 1123 case Oaddas: 1124 case Osubas: 1125 case Omulas: 1126 case Odivas: 1127 case Omodas: 1128 case Oexpas: 1129 case Oandas: 1130 case Ooras: 1131 case Oxoras: 1132 case Olshas: 1133 case Orshas: 1134 if(left->op == Oinds){ 1135 indsascom(src, nto, n); 1136 break; 1137 } 1138 if(right->addable < Rcant){ 1139 if(left->addable >= Rcant) 1140 left = eacom(left, &tl, nto); 1141 }else if(left->temps < right->temps){ 1142 right = eacom(right, &tr, nto); 1143 if(left->addable >= Rcant) 1144 left = eacom(left, &tl, nil); 1145 }else{ 1146 left = eacom(left, &tl, nto); 1147 right = eacom(right, &tr, nil); 1148 } 1149 genop(&n->src, op, right, nil, left); 1150 if(nto != nil) 1151 genmove(src, Mas, left->ty, left, nto); 1152 tfree(&tl); 1153 tfree(&tr); 1154 break; 1155 case Olen: 1156 if(left->addable >= Rcant) 1157 left = eacom(left, &tl, nto); 1158 op = -1; 1159 t = left->ty; 1160 if(t == tstring) 1161 op = ILENC; 1162 else if(t->kind == Tarray) 1163 op = ILENA; 1164 else if(t->kind == Tlist) 1165 op = ILENL; 1166 else 1167 fatal("can't len %n", n); 1168 genrawop(src, op, left, nil, nto); 1169 tfree(&tl); 1170 break; 1171 case Oneg: 1172 if(left->addable >= Rcant) 1173 left = eacom(left, &tl, nto); 1174 genop(&n->src, op, left, nil, nto); 1175 tfree(&tl); 1176 break; 1177 case Oinc: 1178 case Odec: 1179 if(left->op == Oinds){ 1180 indsascom(src, nto, n); 1181 break; 1182 } 1183 if(left->addable >= Rcant) 1184 left = eacom(left, &tl, nil); 1185 if(nto != nil) 1186 genmove(src, Mas, left->ty, left, nto); 1187 if(right->addable >= Rcant) 1188 fatal("inc/dec amount not addressable: %n", n); 1189 genop(&n->src, op, right, nil, left); 1190 tfree(&tl); 1191 break; 1192 case Ospawn: 1193 if(left->left->op == Oind) 1194 fpcall(&n->src, op, left, nto); 1195 else 1196 callcom(&n->src, op, left, nto); 1197 break; 1198 case Oraise: 1199 if(left->addable >= Rcant) 1200 left = eacom(left, &tl, nil); 1201 genrawop(&n->src, IRAISE, left, nil, nil); 1202 tfree(&tl); 1203 break; 1204 case Ocall: 1205 if(left->op == Oind) 1206 fpcall(esrc(src, &n->src, nto), op, n, nto); 1207 else 1208 callcom(esrc(src, &n->src, nto), op, n, nto); 1209 break; 1210 case Oref: 1211 t = left->ty; 1212 if(left->op == Oname && left->decl->store == Dfn || left->op == Omdot && left->right->op == Oname && left->right->decl->store == Dfn){ /* create a function reference */ 1213 Decl *d; 1214 Node *mod, *ind; 1215 1216 d = left->decl; 1217 if(left->op == Omdot){ 1218 d = left->right->decl; 1219 mod = left->left; 1220 } 1221 else if(d->eimport != nil) 1222 mod = d->eimport; 1223 else{ 1224 mod = rewrite(mkn(Oself, nil, nil)); 1225 addiface(nil, d); 1226 } 1227 sumark(mod); 1228 talloc(&tto, n->ty, nto); 1229 genrawop(src, INEW, mktn(usetype(tfnptr)), nil, &tto); 1230 tr.src = *src; 1231 tr.op = Oind; 1232 tr.left = &tto; 1233 tr.right = nil; 1234 tr.ty = tany; 1235 sumark(&tr); 1236 ecom(src, &tr, mod); 1237 ind = mkunary(Oind, mkbin(Oadd, dupn(0, src, &tto), mkconst(src, IBY2WD))); 1238 ind->ty = ind->left->ty = ind->left->right->ty = tint; 1239 tr.op = Oas; 1240 tr.left = ind; 1241 tr.right = mkdeclname(src, d); 1242 tr.ty = tr.right->ty = tint; 1243 sumark(&tr); 1244 tr.right->addable = mod->op == Oself && newfnptr ? Rnoff : Roff; 1245 ecom(src, nil, &tr); 1246 if(!sameaddr(&tto, nto)) 1247 genmove(src, Mas, n->ty, &tto, nto); 1248 tfree(&tto); 1249 break; 1250 } 1251 if(left->op == Oname && left->decl->store == Dtype){ 1252 genrawop(src, INEW, mktn(t), nil, nto); 1253 break; 1254 } 1255 if(t->kind == Tadt && t->tags != nil){ 1256 pickdupcom(src, nto, left); 1257 break; 1258 } 1259 1260 tt = t; 1261 if(left->op == Oconst && left->decl->store == Dtag) 1262 t = left->decl->ty->tof; 1263 /* 1264 * could eliminate temp if to does not occur 1265 * in tuple initializer 1266 */ 1267 talloc(&tto, n->ty, nto); 1268 genrawop(src, INEW, mktn(t), nil, &tto); 1269 tr.op = Oind; 1270 tr.left = &tto; 1271 tr.right = nil; 1272 tr.ty = tt; 1273 sumark(&tr); 1274 ecom(src, &tr, left); 1275 if(!sameaddr(&tto, nto)) 1276 genmove(src, Mas, n->ty, &tto, nto); 1277 tfree(&tto); 1278 break; 1279 case Oload: 1280 if(left->addable >= Rcant) 1281 left = eacom(left, &tl, nto); 1282 talloc(&tr, tint, nil); 1283 if(LDT) 1284 genrawop(src, ILOAD, left, right, nto); 1285 else{ 1286 genrawop(src, ILEA, right, nil, &tr); 1287 genrawop(src, ILOAD, left, &tr, nto); 1288 } 1289 tfree(&tl); 1290 tfree(&tr); 1291 break; 1292 case Ocast: 1293 if(left->addable >= Rcant) 1294 left = eacom(left, &tl, nto); 1295 t = left->ty; 1296 if(t->kind == Tfix || n->ty->kind == Tfix){ 1297 op = casttab[t->kind][n->ty->kind]; 1298 if(op == ICVTXX) 1299 genfixcastop(src, op, left, nto); 1300 else{ 1301 tn = sumark(mkrconst(src, scale2(t, n->ty))); 1302 genrawop(src, op, left, tn, nto); 1303 } 1304 } 1305 else 1306 genrawop(src, casttab[t->kind][n->ty->kind], left, nil, nto); 1307 tfree(&tl); 1308 break; 1309 case Oarray: 1310 if(left->addable >= Rcant) 1311 left = eacom(left, &tl, nto); 1312 genrawop(esrc(src, &left->src, nto), arrayz ? INEWAZ : INEWA, left, mktn(n->ty->tof), nto); 1313 if(right != nil) 1314 arraycom(nto, right); 1315 tfree(&tl); 1316 break; 1317 case Oslice: 1318 tn = right->right; 1319 right = right->left; 1320 1321 /* 1322 * make the left node of the slice directly addressable 1323 * therefore, if it's len is taken (via tn), 1324 * left's tree won't be rewritten 1325 */ 1326 if(left->addable >= Rcant) 1327 left = eacom(left, &tl, nil); 1328 1329 if(tn->op == Onothing){ 1330 tn = mkn(Olen, left, nil); 1331 tn->src = *src; 1332 tn->ty = tint; 1333 sumark(tn); 1334 } 1335 if(tn->addable < Ralways){ 1336 if(right->addable >= Rcant) 1337 right = eacom(right, &tr, nil); 1338 }else if(right->temps <= tn->temps){ 1339 tn = ecom(&tn->src, talloc(&ttn, tn->ty, nil), tn); 1340 if(right->addable >= Rcant) 1341 right = eacom(right, &tr, nil); 1342 }else{ 1343 right = eacom(right, &tr, nil); 1344 tn = ecom(&tn->src, talloc(&ttn, tn->ty, nil), tn); 1345 } 1346 op = ISLICEA; 1347 if(nto->ty == tstring) 1348 op = ISLICEC; 1349 1350 /* 1351 * overwrite the destination last, 1352 * since it might be used in computing the slice bounds 1353 */ 1354 if(!sameaddr(left, nto)) 1355 ecom(&left->src, nto, left); 1356 1357 genrawop(src, op, right, tn, nto); 1358 tfree(&tl); 1359 tfree(&tr); 1360 tfree(&ttn); 1361 break; 1362 case Oindx: 1363 if(right->addable < Rcant){ 1364 if(left->addable >= Rcant) 1365 left = eacom(left, &tl, nto); 1366 }else if(left->temps < right->temps){ 1367 right = eacom(right, &tr, nto); 1368 if(left->addable >= Rcant) 1369 left = eacom(left, &tl, nil); 1370 }else{ 1371 left = eacom(left, &tl, nto); 1372 right = eacom(right, &tr, nil); 1373 } 1374 if(nto->addable >= Ralways) 1375 nto = ecom(src, talloc(&tto, nto->ty, nil), nto); 1376 op = IINDX; 1377 switch(left->ty->tof->size){ 1378 case IBY2LG: 1379 op = IINDL; 1380 if(left->ty->tof == treal) 1381 op = IINDF; 1382 break; 1383 case IBY2WD: 1384 op = IINDW; 1385 break; 1386 case 1: 1387 op = IINDB; 1388 break; 1389 } 1390 genrawop(src, op, left, nto, right); 1391 // array[] of {....} [index] frees array too early (before index value used) 1392 // function(...) [index] frees array too early (before index value used) 1393 if(tl.decl != nil) 1394 tfreelater(&tl); 1395 else 1396 tfree(&tl); 1397 tfree(&tr); 1398 tfree(&tto); 1399 break; 1400 case Oind: 1401 n = eacom(n, &tl, nto); 1402 genmove(src, Mas, n->ty, n, nto); 1403 tfree(&tl); 1404 break; 1405 case Onot: 1406 case Oandand: 1407 case Ooror: 1408 case Oeq: 1409 case Oneq: 1410 case Olt: 1411 case Oleq: 1412 case Ogt: 1413 case Ogeq: 1414 p = bcom(n, 1, nil); 1415 genmove(src, Mas, tint, sumark(mkconst(src, 1)), nto); 1416 pp = genrawop(src, IJMP, nil, nil, nil); 1417 patch(p, nextinst()); 1418 genmove(src, Mas, tint, sumark(mkconst(src, 0)), nto); 1419 patch(pp, nextinst()); 1420 break; 1421 case Oself: 1422 if(newfnptr){ 1423 if(nto != nil) 1424 genrawop(src, ISELF, nil, nil, nto); 1425 break; 1426 } 1427 tn = sumark(mkdeclname(src, selfdecl)); 1428 p = genbra(src, Oneq, tn, sumark(mkdeclname(src, nildecl))); 1429 n->op = Oload; 1430 ecom(src, tn, n); 1431 patch(p, nextinst()); 1432 genmove(src, Mas, n->ty, tn, nto); 1433 break; 1434 } 1435 return nto; 1436 } 1437 1438 /* 1439 * compile exp n to yield an addressable expression 1440 * use reg to build a temporary; if t is a temp, it is usable 1441 * if dangle leaves the address dangling, generate into a temporary 1442 * this should only happen with arrays 1443 * 1444 * note that 0adr's are strange as they are only used 1445 * for calculating the addresses of fields within adt's. 1446 * therefore an Oind is the parent or grandparent of the Oadr, 1447 * and we pick off all of the cases where Oadr's argument is not 1448 * addressable by looking from the Oind. 1449 */ 1450 Node* 1451 eacom(Node *n, Node *reg, Node *t) 1452 { 1453 Node *left, *tn; 1454 1455 if(n->op == Ocomma){ 1456 tn = n->left->left; 1457 ecom(&n->left->src, nil, n->left); 1458 n = eacom(n->right, reg, t); 1459 tfree(tn); 1460 return n; 1461 } 1462 1463 if(debug['e'] || debug['E']) 1464 print("eacom: %n\n", n); 1465 1466 left = n->left; 1467 if(n->op != Oind){ 1468 ecom(&n->src, talloc(reg, n->ty, t), n); 1469 reg->src = n->src; 1470 return reg; 1471 } 1472 1473 if(left->op == Oadd && left->right->op == Oconst){ 1474 if(left->left->op == Oadr){ 1475 left->left->left = eacom(left->left->left, reg, t); 1476 sumark(n); 1477 if(n->addable >= Rcant) 1478 fatal("eacom can't make node addressable: %n", n); 1479 return n; 1480 } 1481 talloc(reg, left->left->ty, t); 1482 ecom(&left->left->src, reg, left->left); 1483 left->left->decl = reg->decl; 1484 left->left->addable = Rreg; 1485 left->left = reg; 1486 left->addable = Raadr; 1487 n->addable = Radr; 1488 }else if(left->op == Oadr){ 1489 talloc(reg, left->left->ty, t); 1490 ecom(&left->left->src, reg, left->left); 1491 1492 /* 1493 * sleaze: treat the temp as the type of the field, not the enclosing structure 1494 */ 1495 reg->ty = n->ty; 1496 reg->src = n->src; 1497 return reg; 1498 }else{ 1499 talloc(reg, left->ty, t); 1500 ecom(&left->src, reg, left); 1501 n->left = reg; 1502 n->addable = Radr; 1503 } 1504 return n; 1505 } 1506 1507 /* 1508 * compile an assignment to an array slice 1509 */ 1510 Node* 1511 slicelcom(Src *src, Node *nto, Node *n) 1512 { 1513 Node *left, *right, *v; 1514 Node tl, tr, tv, tu; 1515 1516 tl.decl = nil; 1517 tr.decl = nil; 1518 tv.decl = nil; 1519 tu.decl = nil; 1520 1521 left = n->left->left; 1522 right = n->left->right->left; 1523 v = n->right; 1524 if(right->addable < Ralways){ 1525 if(left->addable >= Rcant) 1526 left = eacom(left, &tl, nto); 1527 }else if(left->temps <= right->temps){ 1528 right = ecom(&right->src, talloc(&tr, right->ty, nto), right); 1529 if(left->addable >= Rcant) 1530 left = eacom(left, &tl, nil); 1531 }else{ 1532 left = eacom(left, &tl, nil); /* dangle on right and v */ 1533 right = ecom(&right->src, talloc(&tr, right->ty, nil), right); 1534 } 1535 1536 switch(n->op){ 1537 case Oas: 1538 if(v->addable >= Rcant) 1539 v = eacom(v, &tv, nil); 1540 break; 1541 } 1542 1543 genrawop(&n->src, ISLICELA, v, right, left); 1544 if(nto != nil) 1545 genmove(src, Mas, n->ty, left, nto); 1546 tfree(&tl); 1547 tfree(&tv); 1548 tfree(&tr); 1549 tfree(&tu); 1550 return nto; 1551 } 1552 1553 /* 1554 * compile an assignment to a string location 1555 */ 1556 Node* 1557 indsascom(Src *src, Node *nto, Node *n) 1558 { 1559 Node *left, *right, *u, *v; 1560 Node tl, tr, tv, tu; 1561 1562 tl.decl = nil; 1563 tr.decl = nil; 1564 tv.decl = nil; 1565 tu.decl = nil; 1566 1567 left = n->left->left; 1568 right = n->left->right; 1569 v = n->right; 1570 if(right->addable < Ralways){ 1571 if(left->addable >= Rcant) 1572 left = eacom(left, &tl, nto); 1573 }else if(left->temps <= right->temps){ 1574 right = ecom(&right->src, talloc(&tr, right->ty, nto), right); 1575 if(left->addable >= Rcant) 1576 left = eacom(left, &tl, nil); 1577 }else{ 1578 left = eacom(left, &tl, nil); /* dangle on right and v */ 1579 right = ecom(&right->src, talloc(&tr, right->ty, nil), right); 1580 } 1581 1582 switch(n->op){ 1583 case Oas: 1584 if(v->addable >= Rcant) 1585 v = eacom(v, &tv, nil); 1586 break; 1587 case Oinc: 1588 case Odec: 1589 if(v->addable >= Rcant) 1590 fatal("inc/dec amount not addable"); 1591 u = talloc(&tu, tint, nil); 1592 genop(&n->left->src, Oinds, left, right, u); 1593 if(nto != nil) 1594 genmove(src, Mas, n->ty, u, nto); 1595 nto = nil; 1596 genop(&n->src, n->op, v, nil, u); 1597 v = u; 1598 break; 1599 case Oaddas: 1600 case Osubas: 1601 case Omulas: 1602 case Odivas: 1603 case Omodas: 1604 case Oexpas: 1605 case Oandas: 1606 case Ooras: 1607 case Oxoras: 1608 case Olshas: 1609 case Orshas: 1610 if(v->addable >= Rcant) 1611 v = eacom(v, &tv, nil); 1612 u = talloc(&tu, tint, nil); 1613 genop(&n->left->src, Oinds, left, right, u); 1614 genop(&n->src, n->op, v, nil, u); 1615 v = u; 1616 break; 1617 } 1618 1619 genrawop(&n->src, IINSC, v, right, left); 1620 tfree(&tl); 1621 tfree(&tv); 1622 tfree(&tr); 1623 tfree(&tu); 1624 if(nto != nil) 1625 genmove(src, Mas, n->ty, v, nto); 1626 return nto; 1627 } 1628 1629 void 1630 callcom(Src *src, int op, Node *n, Node *ret) 1631 { 1632 Node frame, tadd, toff, pass, *a, *mod, *ind, *nfn, *args, tmod, tind, *tn; 1633 Inst *in,*p; 1634 Decl *d, *callee; 1635 long off; 1636 int iop; 1637 1638 args = n->right; 1639 nfn = n->left; 1640 switch(nfn->op){ 1641 case Odot: 1642 callee = nfn->right->decl; 1643 nfn->addable = Rpc; 1644 break; 1645 case Omdot: 1646 callee = nfn->right->decl; 1647 break; 1648 case Oname: 1649 callee = nfn->decl; 1650 break; 1651 default: 1652 callee = nil; 1653 fatal("bad call op in callcom"); 1654 } 1655 if(nfn->addable != Rpc && nfn->addable != Rmpc) 1656 fatal("can't gen call addresses"); 1657 if(nfn->ty->tof != tnone && ret == nil){ 1658 ecom(src, talloc(&tmod, nfn->ty->tof, nil), n); 1659 tfree(&tmod); 1660 return; 1661 } 1662 if(ispoly(callee)) 1663 addfnptrs(callee, 0); 1664 if(nfn->ty->varargs){ 1665 nfn->decl = dupdecl(nfn->right->decl); 1666 nfn->decl->desc = gendesc(nfn->right->decl, idoffsets(nfn->ty->ids, MaxTemp, MaxAlign), nfn->ty->ids); 1667 } 1668 1669 talloc(&frame, tint, nil); 1670 1671 mod = nfn->left; 1672 ind = nfn->right; 1673 tmod.decl = tind.decl = nil; 1674 if(nfn->addable == Rmpc){ 1675 if(mod->addable >= Rcant) 1676 mod = eacom(mod, &tmod, nil); /* dangle always */ 1677 if(ind->op != Oname && ind->addable >= Ralways){ 1678 talloc(&tind, ind->ty, nil); 1679 ecom(&ind->src, &tind, ind); 1680 ind = &tind; 1681 } 1682 else if(ind->decl != nil && ind->decl->store != Darg) 1683 ind->addable = Roff; 1684 } 1685 1686 /* 1687 * stop nested uncalled frames 1688 * otherwise exception handling very complicated 1689 */ 1690 for(a = args; a != nil; a = a->right){ 1691 if(hascall(a->left)){ 1692 tn = mkn(0, nil, nil); 1693 talloc(tn, a->left->ty, nil); 1694 ecom(&a->left->src, tn, a->left); 1695 a->left = tn; 1696 tn->flags |= TEMP; 1697 } 1698 } 1699 1700 /* 1701 * allocate the frame 1702 */ 1703 if(nfn->addable == Rmpc && !nfn->ty->varargs){ 1704 genrawop(src, IMFRAME, mod, ind, &frame); 1705 }else if(nfn->op == Odot){ 1706 genrawop(src, IFRAME, nfn->left, nil, &frame); 1707 }else{ 1708 in = genrawop(src, IFRAME, nil, nil, &frame); 1709 in->sm = Adesc; 1710 in->s.decl = nfn->decl; 1711 } 1712 1713 /* 1714 * build a fake node for the argument area 1715 */ 1716 toff = znode; 1717 tadd = znode; 1718 pass = znode; 1719 toff.op = Oconst; 1720 toff.addable = Rconst; 1721 toff.ty = tint; 1722 tadd.op = Oadd; 1723 tadd.addable = Raadr; 1724 tadd.left = &frame; 1725 tadd.right = &toff; 1726 tadd.ty = tint; 1727 pass.op = Oind; 1728 pass.addable = Radr; 1729 pass.left = &tadd; 1730 1731 /* 1732 * compile all the args 1733 */ 1734 d = nfn->ty->ids; 1735 off = 0; 1736 for(a = args; a != nil; a = a->right){ 1737 off = d->offset; 1738 toff.val = off; 1739 if(d->ty->kind == Tpoly) 1740 pass.ty = a->left->ty; 1741 else 1742 pass.ty = d->ty; 1743 ecom(&a->left->src, &pass, a->left); 1744 d = d->next; 1745 if(a->left->flags & TEMP) 1746 tfree(a->left); 1747 } 1748 if(off > maxstack) 1749 maxstack = off; 1750 1751 /* 1752 * pass return value 1753 */ 1754 if(ret != nil){ 1755 toff.val = REGRET*IBY2WD; 1756 pass.ty = nfn->ty->tof; 1757 p = genrawop(src, ILEA, ret, nil, &pass); 1758 p->m.offset = ret->ty->size; /* for optimizer */ 1759 } 1760 1761 /* 1762 * call it 1763 */ 1764 if(nfn->addable == Rmpc){ 1765 iop = IMCALL; 1766 if(op == Ospawn) 1767 iop = IMSPAWN; 1768 genrawop(src, iop, &frame, ind, mod); 1769 tfree(&tmod); 1770 tfree(&tind); 1771 }else if(nfn->op == Odot){ 1772 iop = ICALL; 1773 if(op == Ospawn) 1774 iop = ISPAWN; 1775 genrawop(src, iop, &frame, nil, nfn->right); 1776 }else{ 1777 iop = ICALL; 1778 if(op == Ospawn) 1779 iop = ISPAWN; 1780 in = genrawop(src, iop, &frame, nil, nil); 1781 in->d.decl = nfn->decl; 1782 in->dm = Apc; 1783 } 1784 tfree(&frame); 1785 } 1786 1787 /* 1788 * initialization code for arrays 1789 * a must be addressable (< Rcant) 1790 */ 1791 void 1792 arraycom(Node *a, Node *elems) 1793 { 1794 Node tindex, fake, tmp, ri, *e, *n, *q, *body, *wild; 1795 Inst *top, *out; 1796 /* Case *c; */ 1797 1798 if(debug['A']) 1799 print("arraycom: %n %n\n", a, elems); 1800 1801 /* c = elems->ty->cse; */ 1802 /* don't use c->wild in case we've been inlined */ 1803 wild = nil; 1804 for(e = elems; e != nil; e = e->right) 1805 for(q = e->left->left; q != nil; q = q->right) 1806 if(q->left->op == Owild) 1807 wild = e->left; 1808 if(wild != nil) 1809 arraydefault(a, wild->right); 1810 1811 tindex = znode; 1812 fake = znode; 1813 talloc(&tmp, tint, nil); 1814 tindex.op = Oindx; 1815 tindex.addable = Rcant; 1816 tindex.left = a; 1817 tindex.right = nil; 1818 tindex.ty = tint; 1819 fake.op = Oind; 1820 fake.addable = Radr; 1821 fake.left = &tmp; 1822 fake.ty = a->ty->tof; 1823 1824 for(e = elems; e != nil; e = e->right){ 1825 /* 1826 * just duplicate the initializer for Oor 1827 */ 1828 for(q = e->left->left; q != nil; q = q->right){ 1829 if(q->left->op == Owild) 1830 continue; 1831 1832 body = e->left->right; 1833 if(q->right != nil) 1834 body = dupn(0, &nosrc, body); 1835 top = nil; 1836 out = nil; 1837 ri.decl = nil; 1838 if(q->left->op == Orange){ 1839 /* 1840 * for(i := q.left.left; i <= q.left.right; i++) 1841 */ 1842 talloc(&ri, tint, nil); 1843 ri.src = q->left->src; 1844 ecom(&q->left->src, &ri, q->left->left); 1845 1846 /* i <= q.left.right; */ 1847 n = mkn(Oleq, &ri, q->left->right); 1848 n->src = q->left->src; 1849 n->ty = tint; 1850 top = nextinst(); 1851 out = bcom(n, 1, nil); 1852 1853 tindex.right = &ri; 1854 }else{ 1855 tindex.right = q->left; 1856 } 1857 1858 tindex.addable = Rcant; 1859 tindex.src = q->left->src; 1860 ecom(&tindex.src, &tmp, &tindex); 1861 1862 ecom(&body->src, &fake, body); 1863 1864 if(q->left->op == Orange){ 1865 /* i++ */ 1866 n = mkbin(Oinc, &ri, sumark(mkconst(&ri.src, 1))); 1867 n->ty = tint; 1868 n->addable = Rcant; 1869 ecom(&n->src, nil, n); 1870 1871 /* jump to test */ 1872 patch(genrawop(&q->left->src, IJMP, nil, nil, nil), top); 1873 patch(out, nextinst()); 1874 tfree(&ri); 1875 } 1876 } 1877 } 1878 tfree(&tmp); 1879 } 1880 1881 /* 1882 * default initialization code for arrays. 1883 * compiles to 1884 * n = len a; 1885 * while(n){ 1886 * n--; 1887 * a[n] = elem; 1888 * } 1889 */ 1890 void 1891 arraydefault(Node *a, Node *elem) 1892 { 1893 Inst *out, *top; 1894 Node n, e, *t; 1895 1896 if(debug['A']) 1897 print("arraydefault: %n %n\n", a, elem); 1898 1899 t = mkn(Olen, a, nil); 1900 t->src = elem->src; 1901 t->ty = tint; 1902 t->addable = Rcant; 1903 talloc(&n, tint, nil); 1904 n.src = elem->src; 1905 ecom(&t->src, &n, t); 1906 1907 top = nextinst(); 1908 out = bcom(&n, 1, nil); 1909 1910 t = mkbin(Odec, &n, sumark(mkconst(&elem->src, 1))); 1911 t->ty = tint; 1912 t->addable = Rcant; 1913 ecom(&t->src, nil, t); 1914 1915 e.decl = nil; 1916 if(elem->addable >= Rcant) 1917 elem = eacom(elem, &e, nil); 1918 1919 t = mkn(Oindx, a, &n); 1920 t->src = elem->src; 1921 t = mkbin(Oas, mkunary(Oind, t), elem); 1922 t->ty = elem->ty; 1923 t->left->ty = elem->ty; 1924 t->left->left->ty = tint; 1925 sumark(t); 1926 ecom(&t->src, nil, t); 1927 1928 patch(genrawop(&t->src, IJMP, nil, nil, nil), top); 1929 1930 tfree(&n); 1931 tfree(&e); 1932 patch(out, nextinst()); 1933 } 1934 1935 void 1936 tupcom(Node *nto, Node *n) 1937 { 1938 Node tadr, tadd, toff, fake, *e; 1939 Decl *d; 1940 1941 if(debug['Y']) 1942 print("tupcom %n\nto %n\n", n, nto); 1943 1944 /* 1945 * build a fake node for the tuple 1946 */ 1947 toff = znode; 1948 tadd = znode; 1949 fake = znode; 1950 tadr = znode; 1951 toff.op = Oconst; 1952 toff.ty = tint; 1953 tadr.op = Oadr; 1954 tadr.left = nto; 1955 tadr.ty = tint; 1956 tadd.op = Oadd; 1957 tadd.left = &tadr; 1958 tadd.right = &toff; 1959 tadd.ty = tint; 1960 fake.op = Oind; 1961 fake.left = &tadd; 1962 sumark(&fake); 1963 if(fake.addable >= Rcant) 1964 fatal("tupcom: bad value exp %n", &fake); 1965 1966 /* 1967 * compile all the exps 1968 */ 1969 d = n->ty->ids; 1970 for(e = n->left; e != nil; e = e->right){ 1971 toff.val = d->offset; 1972 fake.ty = d->ty; 1973 ecom(&e->left->src, &fake, e->left); 1974 d = d->next; 1975 } 1976 } 1977 1978 void 1979 tuplcom(Node *n, Node *nto) 1980 { 1981 Node tadr, tadd, toff, fake, tas, *e, *as; 1982 Decl *d; 1983 1984 if(debug['Y']) 1985 print("tuplcom %n\nto %n\n", n, nto); 1986 1987 /* 1988 * build a fake node for the tuple 1989 */ 1990 toff = znode; 1991 tadd = znode; 1992 fake = znode; 1993 tadr = znode; 1994 toff.op = Oconst; 1995 toff.ty = tint; 1996 tadr.op = Oadr; 1997 tadr.left = n; 1998 tadr.ty = tint; 1999 tadd.op = Oadd; 2000 tadd.left = &tadr; 2001 tadd.right = &toff; 2002 tadd.ty = tint; 2003 fake.op = Oind; 2004 fake.left = &tadd; 2005 sumark(&fake); 2006 if(fake.addable >= Rcant) 2007 fatal("tuplcom: bad value exp for %n", &fake); 2008 2009 /* 2010 * compile all the exps 2011 */ 2012 d = nto->ty->ids; 2013 if(nto->ty->kind == Tadtpick) 2014 d = nto->ty->tof->ids->next; 2015 for(e = nto->left; e != nil; e = e->right){ 2016 as = e->left; 2017 if(as->op != Oname || as->decl != nildecl){ 2018 toff.val = d->offset; 2019 fake.ty = d->ty; 2020 fake.src = as->src; 2021 if(as->addable < Rcant) 2022 genmove(&as->src, Mas, d->ty, &fake, as); 2023 else{ 2024 tas.op = Oas; 2025 tas.ty = d->ty; 2026 tas.src = as->src; 2027 tas.left = as; 2028 tas.right = &fake; 2029 tas.addable = Rcant; 2030 ecom(&tas.src, nil, &tas); 2031 } 2032 } 2033 d = d->next; 2034 } 2035 } 2036 2037 void 2038 tuplrcom(Node *n, Node *nto) 2039 { 2040 Node *s, *d, tas; 2041 Decl *de; 2042 2043 de = nto->ty->ids; 2044 for(s = n->left, d = nto->left; s != nil && d != nil; s = s->right, d = d->right){ 2045 if(d->left->op != Oname || d->left->decl != nildecl){ 2046 tas.op = Oas; 2047 tas.ty = de->ty; 2048 tas.src = s->left->src; 2049 tas.left = d->left; 2050 tas.right = s->left; 2051 sumark(&tas); 2052 ecom(&tas.src, nil, &tas); 2053 } 2054 de = de->next; 2055 } 2056 if(s != nil || d != nil) 2057 fatal("tuplrcom"); 2058 } 2059 2060 /* 2061 * boolean compiler 2062 * fall through when condition == true 2063 */ 2064 Inst* 2065 bcom(Node *n, int iftrue, Inst *b) 2066 { 2067 Inst *bb; 2068 Node tl, tr, *t, *left, *right, *tn; 2069 int op; 2070 2071 if(n->op == Ocomma){ 2072 tn = n->left->left; 2073 ecom(&n->left->src, nil, n->left); 2074 bb = bcom(n->right, iftrue, b); 2075 tfree(tn); 2076 return bb; 2077 } 2078 2079 if(debug['b']) 2080 print("bcom %n %d\n", n, iftrue); 2081 2082 left = n->left; 2083 right = n->right; 2084 op = n->op; 2085 2086 switch(op){ 2087 case Onothing: 2088 return b; 2089 case Onot: 2090 return bcom(n->left, !iftrue, b); 2091 case Oandand: 2092 if(!iftrue) 2093 return oror(n, iftrue, b); 2094 return andand(n, iftrue, b); 2095 case Ooror: 2096 if(!iftrue) 2097 return andand(n, iftrue, b); 2098 return oror(n, iftrue, b); 2099 case Ogt: 2100 case Ogeq: 2101 case Oneq: 2102 case Oeq: 2103 case Olt: 2104 case Oleq: 2105 break; 2106 default: 2107 if(n->ty->kind == Tint){ 2108 right = mkconst(&n->src, 0); 2109 right->addable = Rconst; 2110 left = n; 2111 op = Oneq; 2112 break; 2113 } 2114 fatal("can't bcom %n", n); 2115 return b; 2116 } 2117 2118 if(iftrue) 2119 op = oprelinvert[op]; 2120 2121 if(left->addable < right->addable){ 2122 t = left; 2123 left = right; 2124 right = t; 2125 op = opcommute[op]; 2126 } 2127 2128 tl.decl = nil; 2129 tr.decl = nil; 2130 if(right->addable < Ralways){ 2131 if(left->addable >= Rcant) 2132 left = eacom(left, &tl, nil); 2133 }else if(left->temps <= right->temps){ 2134 right = ecom(&right->src, talloc(&tr, right->ty, nil), right); 2135 if(left->addable >= Rcant) 2136 left = eacom(left, &tl, nil); 2137 }else{ 2138 left = eacom(left, &tl, nil); 2139 right = ecom(&right->src, talloc(&tr, right->ty, nil), right); 2140 } 2141 bb = genbra(&n->src, op, left, right); 2142 bb->branch = b; 2143 tfree(&tl); 2144 tfree(&tr); 2145 return bb; 2146 } 2147 2148 Inst* 2149 andand(Node *n, int iftrue, Inst *b) 2150 { 2151 if(debug['b']) 2152 print("andand %n\n", n); 2153 b = bcom(n->left, iftrue, b); 2154 b = bcom(n->right, iftrue, b); 2155 return b; 2156 } 2157 2158 Inst* 2159 oror(Node *n, int iftrue, Inst *b) 2160 { 2161 Inst *bb; 2162 2163 if(debug['b']) 2164 print("oror %n\n", n); 2165 bb = bcom(n->left, !iftrue, nil); 2166 b = bcom(n->right, iftrue, b); 2167 patch(bb, nextinst()); 2168 return b; 2169 } 2170 2171 /* 2172 * generate code for a recva expression 2173 * this is just a hacked up small alt 2174 */ 2175 void 2176 recvacom(Src *src, Node *nto, Node *n) 2177 { 2178 Label *labs; 2179 Case *c; 2180 Node which, tab, off, add, adr, slot, *left; 2181 Type *talt; 2182 Inst *p; 2183 2184 left = n->left; 2185 2186 labs = allocmem(1 * sizeof *labs); 2187 labs[0].isptr = left->addable >= Rcant; 2188 c = allocmem(sizeof *c); 2189 c->nlab = 1; 2190 c->labs = labs; 2191 talt = mktalt(c); 2192 2193 talloc(&which, tint, nil); 2194 talloc(&tab, talt, nil); 2195 2196 /* 2197 * build the node for the address of each channel, 2198 * the values to send, and the storage fro values received 2199 */ 2200 off = znode; 2201 off.op = Oconst; 2202 off.ty = tint; 2203 off.addable = Rconst; 2204 adr = znode; 2205 adr.op = Oadr; 2206 adr.left = &tab; 2207 adr.ty = tint; 2208 add = znode; 2209 add.op = Oadd; 2210 add.left = &adr; 2211 add.right = &off; 2212 add.ty = tint; 2213 slot = znode; 2214 slot.op = Oind; 2215 slot.left = &add; 2216 sumark(&slot); 2217 2218 /* 2219 * gen the channel 2220 * this sleaze is lying to the garbage collector 2221 */ 2222 off.val = 2*IBY2WD; 2223 if(left->addable < Rcant) 2224 genmove(src, Mas, tint, left, &slot); 2225 else{ 2226 slot.ty = left->ty; 2227 ecom(src, &slot, left); 2228 slot.ty = nil; 2229 } 2230 2231 /* 2232 * gen the value 2233 */ 2234 off.val += IBY2WD; 2235 p = genrawop(&left->src, ILEA, nto, nil, &slot); 2236 p->m.offset = nto->ty->size; /* for optimizer */ 2237 2238 /* 2239 * number of senders and receivers 2240 */ 2241 off.val = 0; 2242 genmove(src, Mas, tint, sumark(mkconst(src, 0)), &slot); 2243 off.val += IBY2WD; 2244 genmove(src, Mas, tint, sumark(mkconst(src, 1)), &slot); 2245 off.val += IBY2WD; 2246 2247 p = genrawop(src, IALT, &tab, nil, &which); 2248 p->m.offset = talt->size; /* for optimizer */ 2249 tfree(&which); 2250 tfree(&tab); 2251 } 2252 2253 /* 2254 * generate code to duplicate an adt with pick fields 2255 * this is just a hacked up small pick 2256 * n is Oind(exp) 2257 */ 2258 void 2259 pickdupcom(Src *src, Node *nto, Node *n) 2260 { 2261 Node *start, *stop, *node, *orig, *dest, tmp, clab; 2262 Case *c; 2263 Inst *j, *jmps, *wild; 2264 Label *labs; 2265 Decl *d, *tg, *stg; 2266 Type *t; 2267 int i, nlab; 2268 char buf[32]; 2269 2270 if(n->op != Oind) 2271 fatal("pickdupcom not Oind: %n" ,n); 2272 2273 t = n->ty; 2274 nlab = t->decl->tag; 2275 2276 /* 2277 * generate global which has case labels 2278 */ 2279 seprint(buf, buf+sizeof(buf), ".c%d", nlabel++); 2280 d = mkids(src, enter(buf, 0), mktype(&src->start, &src->stop, Tcase, nil, nil), nil); 2281 d->init = mkdeclname(src, d); 2282 2283 clab.addable = Rmreg; 2284 clab.left = nil; 2285 clab.right = nil; 2286 clab.op = Oname; 2287 clab.ty = d->ty; 2288 clab.decl = d; 2289 2290 /* 2291 * generate a temp to hold the real value 2292 * then generate a case on the tag 2293 */ 2294 orig = n->left; 2295 talloc(&tmp, orig->ty, nil); 2296 ecom(src, &tmp, orig); 2297 orig = mkunary(Oind, &tmp); 2298 orig->ty = tint; 2299 sumark(orig); 2300 2301 dest = mkunary(Oind, nto); 2302 dest->ty = nto->ty->tof; 2303 sumark(dest); 2304 2305 genrawop(src, ICASE, orig, nil, &clab); 2306 2307 labs = allocmem(nlab * sizeof *labs); 2308 2309 i = 0; 2310 jmps = nil; 2311 for(tg = t->tags; tg != nil; tg = tg->next){ 2312 stg = tg; 2313 for(; tg->next != nil; tg = tg->next) 2314 if(stg->ty != tg->next->ty) 2315 break; 2316 start = sumark(simplify(mkdeclname(src, stg))); 2317 stop = start; 2318 node = start; 2319 if(stg != tg){ 2320 stop = sumark(simplify(mkdeclname(src, tg))); 2321 node = mkbin(Orange, start, stop); 2322 } 2323 2324 labs[i].start = start; 2325 labs[i].stop = stop; 2326 labs[i].node = node; 2327 labs[i++].inst = nextinst(); 2328 2329 genrawop(src, INEW, mktn(tg->ty->tof), nil, nto); 2330 genmove(src, Mas, tg->ty->tof, orig, dest); 2331 2332 j = genrawop(src, IJMP, nil, nil, nil); 2333 j->branch = jmps; 2334 jmps = j; 2335 } 2336 2337 /* 2338 * this should really be a runtime error 2339 */ 2340 wild = genrawop(src, IJMP, nil, nil, nil); 2341 patch(wild, wild); 2342 2343 patch(jmps, nextinst()); 2344 tfree(&tmp); 2345 2346 if(i > nlab) 2347 fatal("overflowed label tab for pickdupcom"); 2348 2349 c = allocmem(sizeof *c); 2350 c->nlab = i; 2351 c->nsnd = 0; 2352 c->labs = labs; 2353 c->iwild = wild; 2354 2355 d->ty->cse = c; 2356 usetype(d->ty); 2357 installids(Dglobal, d); 2358 } 2359 2360 /* 2361 * see if name n occurs anywhere in e 2362 */ 2363 int 2364 tupaliased(Node *n, Node *e) 2365 { 2366 for(;;){ 2367 if(e == nil) 2368 return 0; 2369 if(e->op == Oname && e->decl == n->decl) 2370 return 1; 2371 if(tupaliased(n, e->left)) 2372 return 1; 2373 e = e->right; 2374 } 2375 } 2376 2377 /* 2378 * see if any name in n occurs anywere in e 2379 */ 2380 int 2381 tupsaliased(Node *n, Node *e) 2382 { 2383 for(;;){ 2384 if(n == nil) 2385 return 0; 2386 if(n->op == Oname && tupaliased(n, e)) 2387 return 1; 2388 if(tupsaliased(n->left, e)) 2389 return 1; 2390 n = n->right; 2391 } 2392 } 2393 2394 /* 2395 * put unaddressable constants in the global data area 2396 */ 2397 Decl* 2398 globalconst(Node *n) 2399 { 2400 Decl *d; 2401 Sym *s; 2402 char buf[32]; 2403 2404 seprint(buf, buf+sizeof(buf), ".i.%.8lux", (long)n->val); 2405 s = enter(buf, 0); 2406 d = s->decl; 2407 if(d == nil){ 2408 d = mkids(&n->src, s, tint, nil); 2409 installids(Dglobal, d); 2410 d->init = n; 2411 d->refs++; 2412 } 2413 return d; 2414 } 2415 2416 Decl* 2417 globalBconst(Node *n) 2418 { 2419 Decl *d; 2420 Sym *s; 2421 char buf[32]; 2422 2423 seprint(buf, buf+sizeof(buf), ".B.%.8lux.%8lux", (long)(n->val>>32), (long)n->val); 2424 2425 s = enter(buf, 0); 2426 d = s->decl; 2427 if(d == nil){ 2428 d = mkids(&n->src, s, tbig, nil); 2429 installids(Dglobal, d); 2430 d->init = n; 2431 d->refs++; 2432 } 2433 return d; 2434 } 2435 2436 Decl* 2437 globalbconst(Node *n) 2438 { 2439 Decl *d; 2440 Sym *s; 2441 char buf[32]; 2442 2443 seprint(buf, buf+sizeof(buf), ".b.%.2lux", (long)n->val & 0xff); 2444 s = enter(buf, 0); 2445 d = s->decl; 2446 if(d == nil){ 2447 d = mkids(&n->src, s, tbyte, nil); 2448 installids(Dglobal, d); 2449 d->init = n; 2450 d->refs++; 2451 } 2452 return d; 2453 } 2454 2455 Decl* 2456 globalfconst(Node *n) 2457 { 2458 Decl *d; 2459 Sym *s; 2460 char buf[32]; 2461 ulong dv[2]; 2462 2463 dtocanon(n->rval, dv); 2464 seprint(buf, buf+sizeof(buf), ".f.%.8lux.%8lux", dv[0], dv[1]); 2465 s = enter(buf, 0); 2466 d = s->decl; 2467 if(d == nil){ 2468 d = mkids(&n->src, s, treal, nil); 2469 installids(Dglobal, d); 2470 d->init = n; 2471 d->refs++; 2472 } 2473 return d; 2474 } 2475 2476 Decl* 2477 globalsconst(Node *n) 2478 { 2479 Decl *d; 2480 Sym *s; 2481 2482 s = n->decl->sym; 2483 d = s->decl; 2484 if(d == nil){ 2485 d = mkids(&n->src, s, tstring, nil); 2486 installids(Dglobal, d); 2487 d->init = n; 2488 } 2489 d->refs++; 2490 return d; 2491 } 2492 2493 static Node* 2494 subst(Decl *d, Node *e, Node *n) 2495 { 2496 if(n == nil) 2497 return nil; 2498 if(n->op == Oname){ 2499 if(d == n->decl){ 2500 n = dupn(0, nil, e); 2501 n->ty = d->ty; 2502 } 2503 return n; 2504 } 2505 n->left = subst(d, e, n->left); 2506 n->right = subst(d, e, n->right); 2507 return n; 2508 } 2509 2510 static Node* 2511 putinline(Node *n) 2512 { 2513 Node *e, *tn; 2514 Type *t; 2515 Decl *d; 2516 2517 if(debug['z']) print("inline1: %n\n", n); 2518 if(n->left->op == Oname) 2519 d = n->left->decl; 2520 else 2521 d = n->left->right->decl; 2522 e = d->init; 2523 t = e->ty; 2524 e = dupn(1, &n->src, e->right->left->left); 2525 for(d = t->ids, n = n->right; d != nil && n != nil; d = d->next, n = n->right){ 2526 if(hasside(n->left, 0) && occurs(d, e) != 1){ 2527 tn = talloc(mkn(0, nil, nil), d->ty, nil); 2528 e = mkbin(Ocomma, mkbin(Oas, tn, n->left), subst(d, tn, e)); 2529 e->ty = e->right->ty; 2530 e->left->ty = d->ty; 2531 } 2532 else 2533 e = subst(d, n->left, e); 2534 } 2535 if(d != nil || n != nil) 2536 fatal("bad arg match in putinline()"); 2537 if(debug['z']) print("inline2: %n\n", e); 2538 return e; 2539 } 2540 2541 static void 2542 fpcall(Src *src, int op, Node *n, Node *ret) 2543 { 2544 Node tp, *e, *mod, *ind; 2545 2546 tp.decl = nil; 2547 e = n->left->left; 2548 if(e->addable >= Rcant) 2549 e = eacom(e, &tp, nil); 2550 mod = mkunary(Oind, e); 2551 ind = mkunary(Oind, mkbin(Oadd, dupn(0, src, e), mkconst(src, IBY2WD))); 2552 n->left = mkbin(Omdot, mod, ind); 2553 n->left->ty = e->ty->tof; 2554 mod->ty = ind->ty = ind->left->ty = ind->left->right->ty = tint; 2555 sumark(n); 2556 callcom(src, op, n, ret); 2557 tfree(&tp); 2558 } 2559