1 #include "gc.h" 2 3 void 4 cgen(Node *n, Node *nn) 5 { 6 Node *l, *r; 7 Prog *p1; 8 Node nod, nod1, nod2; 9 int o; 10 long v, curs; 11 12 if(debug['g']) { 13 prtree(nn, "cgen lhs"); 14 prtree(n, "cgen"); 15 } 16 if(n == Z || n->type == T) 17 return; 18 if(typesu[n->type->etype]) { 19 sugen(n, nn, n->type->width); 20 return; 21 } 22 l = n->left; 23 r = n->right; 24 o = n->op; 25 if(n->addable >= INDEXED) { 26 if(nn == Z) { 27 switch(o) { 28 default: 29 nullwarn(Z, Z); 30 break; 31 case OINDEX: 32 nullwarn(l, r); 33 break; 34 } 35 return; 36 } 37 gmove(n, nn); 38 return; 39 } 40 curs = cursafe; 41 42 if(n->complex >= FNX) 43 if(l->complex >= FNX) 44 if(r != Z && r->complex >= FNX) 45 switch(o) { 46 default: 47 regret(&nod, r); 48 cgen(r, &nod); 49 50 regsalloc(&nod1, r); 51 gmove(&nod, &nod1); 52 53 regfree(&nod); 54 nod = *n; 55 nod.right = &nod1; 56 57 cgen(&nod, nn); 58 return; 59 60 case OFUNC: 61 case OCOMMA: 62 case OANDAND: 63 case OOROR: 64 case OCOND: 65 case ODOT: 66 break; 67 } 68 69 switch(o) { 70 default: 71 diag(n, "unknown op in cgen: %O", o); 72 break; 73 74 case OAS: 75 if(typefd[n->type->etype]) { 76 diag(n, "no floating"); 77 return; 78 } 79 if(l->op == OBIT) 80 goto bitas; 81 if(l->addable >= INDEXED) { 82 if(nn != Z || r->addable < INDEXED) { 83 if(r->complex >= FNX && nn == Z) 84 regret(&nod, r); 85 else 86 regalloc(&nod, r, nn); 87 cgen(r, &nod); 88 gmove(&nod, l); 89 if(nn != Z) 90 gmove(&nod, nn); 91 regfree(&nod); 92 } else 93 gmove(r, l); 94 break; 95 } 96 if(l->complex >= r->complex) { 97 reglcgen(&nod1, l, Z); 98 if(r->addable >= INDEXED) { 99 gmove(r, &nod1); 100 if(nn != Z) 101 gmove(r, nn); 102 regfree(&nod1); 103 break; 104 } 105 regalloc(&nod, r, nn); 106 cgen(r, &nod); 107 } else { 108 regalloc(&nod, r, nn); 109 cgen(r, &nod); 110 reglcgen(&nod1, l, Z); 111 } 112 gmove(&nod, &nod1); 113 regfree(&nod); 114 regfree(&nod1); 115 break; 116 117 bitas: 118 n = l->left; 119 regalloc(&nod, r, nn); 120 if(l->complex >= r->complex) { 121 reglcgen(&nod1, n, Z); 122 cgen(r, &nod); 123 } else { 124 cgen(r, &nod); 125 reglcgen(&nod1, n, Z); 126 } 127 regalloc(&nod2, n, Z); 128 gopcode(OAS, &nod1, Z, &nod2); 129 bitstore(l, &nod, &nod1, &nod2, nn); 130 break; 131 132 case OBIT: 133 if(nn == Z) { 134 nullwarn(l, Z); 135 break; 136 } 137 bitload(n, &nod, Z, Z, nn); 138 gmove(&nod, nn); 139 regfree(&nod); 140 break; 141 142 case OLSHR: 143 case OASHL: 144 case OASHR: 145 case OADD: 146 case OSUB: 147 case OOR: 148 case OXOR: 149 case OAND: 150 /* 151 * immediate operands 152 */ 153 if(nn != Z) 154 if(r->op == OCONST) 155 if(!typefd[n->type->etype]) { 156 cgen(l, nn); 157 if(r->vconst == 0) 158 if(o != OAND) 159 break; 160 if(nn != Z) 161 gopcode(o, r, Z, nn); 162 break; 163 } 164 165 case OLMOD: 166 case OMOD: 167 case OLMUL: 168 case OLDIV: 169 case OMUL: 170 case ODIV: 171 if(nn == Z) { 172 nullwarn(l, r); 173 break; 174 } 175 if(typefd[n->type->etype]) 176 goto fop; 177 if(l->complex >= r->complex) { 178 regalloc(&nod, l, nn); 179 cgen(l, &nod); 180 regalloc(&nod1, r, Z); 181 cgen(r, &nod1); 182 gopcode(o, &nod1, Z, &nod); 183 } else { 184 regalloc(&nod1, r, nn); 185 cgen(r, &nod1); 186 regalloc(&nod, l, Z); 187 cgen(l, &nod); 188 gopcode(o, &nod1, Z, &nod); 189 } 190 gmove(&nod, nn); 191 regfree(&nod); 192 regfree(&nod1); 193 break; 194 195 case OASLSHR: 196 case OASASHL: 197 case OASASHR: 198 case OASAND: 199 case OASADD: 200 case OASSUB: 201 case OASXOR: 202 case OASOR: 203 case OASLMUL: 204 case OASLDIV: 205 case OASLMOD: 206 case OASMUL: 207 case OASDIV: 208 case OASMOD: 209 if(typefd[n->type->etype]) 210 goto asfop; 211 if(l->complex >= r->complex) { 212 if(l->addable < INDEXED) 213 reglcgen(&nod2, l, Z); 214 else 215 nod2 = *l; 216 regalloc(&nod1, r, Z); 217 cgen(r, &nod1); 218 } else { 219 regalloc(&nod1, r, Z); 220 cgen(r, &nod1); 221 if(l->addable < INDEXED) 222 reglcgen(&nod2, l, Z); 223 else 224 nod2 = *l; 225 } 226 227 regalloc(&nod, n, nn); 228 gmove(&nod2, &nod); 229 gopcode(o, &nod1, Z, &nod); 230 gmove(&nod, &nod2); 231 if(nn != Z) 232 gmove(&nod, nn); 233 regfree(&nod); 234 regfree(&nod1); 235 if(l->addable < INDEXED) 236 regfree(&nod2); 237 break; 238 239 fop: 240 diag(n, "no floating"); 241 break; 242 243 asfop: 244 diag(n, "no floating"); 245 break; 246 247 case OADDR: 248 if(nn == Z) { 249 nullwarn(l, Z); 250 break; 251 } 252 lcgen(l, nn); 253 break; 254 255 case OFUNC: 256 if(l->complex >= FNX) { 257 if(l->op != OIND) 258 diag(n, "bad function call"); 259 260 regret(&nod, l->left); 261 cgen(l->left, &nod); 262 regsalloc(&nod1, l->left); 263 gmove(&nod, &nod1); 264 regfree(&nod); 265 266 nod = *n; 267 nod.left = &nod2; 268 nod2 = *l; 269 nod2.left = &nod1; 270 nod2.complex = 1; 271 cgen(&nod, nn); 272 273 return; 274 } 275 gargs(r, &nod, &nod1); 276 if(l->addable < INDEXED) { 277 reglcgen(&nod, l, nn); 278 gopcode(OFUNC, Z, Z, &nod); 279 regfree(&nod); 280 } else 281 gopcode(OFUNC, Z, Z, l); 282 if(REGARG && reg[REGARG]) 283 reg[REGARG]--; 284 if(nn != Z) { 285 regret(&nod, n); 286 gmove(&nod, nn); 287 regfree(&nod); 288 } 289 break; 290 291 case OIND: 292 if(nn == Z) { 293 nullwarn(l, Z); 294 break; 295 } 296 regialloc(&nod, n, nn); 297 r = l; 298 while(r->op == OADD) 299 r = r->right; 300 if(sconst(r)) { 301 v = r->vconst; 302 r->vconst = 0; 303 cgen(l, &nod); 304 nod.xoffset += v; 305 r->vconst = v; 306 } else 307 cgen(l, &nod); 308 regind(&nod, n); 309 gmove(&nod, nn); 310 regfree(&nod); 311 break; 312 313 case OEQ: 314 case ONE: 315 case OLE: 316 case OLT: 317 case OGE: 318 case OGT: 319 case OLO: 320 case OLS: 321 case OHI: 322 case OHS: 323 if(nn == Z) { 324 nullwarn(l, r); 325 break; 326 } 327 boolgen(n, 1, nn); 328 break; 329 330 case OANDAND: 331 case OOROR: 332 boolgen(n, 1, nn); 333 if(nn == Z) 334 patch(p, pc); 335 break; 336 337 case ONOT: 338 if(nn == Z) { 339 nullwarn(l, Z); 340 break; 341 } 342 boolgen(n, 1, nn); 343 break; 344 345 case OCOMMA: 346 cgen(l, Z); 347 cgen(r, nn); 348 break; 349 350 case OCAST: 351 if(nn == Z) { 352 nullwarn(l, Z); 353 break; 354 } 355 /* 356 * convert from types l->n->nn 357 */ 358 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) { 359 /* both null, gen l->nn */ 360 cgen(l, nn); 361 break; 362 } 363 regalloc(&nod, l, nn); 364 cgen(l, &nod); 365 regalloc(&nod1, n, &nod); 366 gmove(&nod, &nod1); 367 gmove(&nod1, nn); 368 regfree(&nod1); 369 regfree(&nod); 370 break; 371 372 case ODOT: 373 sugen(l, nodrat, l->type->width); 374 if(nn != Z) { 375 warn(n, "non-interruptable temporary"); 376 nod = *nodrat; 377 if(!r || r->op != OCONST) { 378 diag(n, "DOT and no offset"); 379 break; 380 } 381 nod.xoffset += r->vconst; 382 nod.type = n->type; 383 cgen(&nod, nn); 384 } 385 break; 386 387 case OCOND: 388 bcgen(l, 1); 389 p1 = p; 390 cgen(r->left, nn); 391 gbranch(OGOTO); 392 patch(p1, pc); 393 p1 = p; 394 cgen(r->right, nn); 395 patch(p1, pc); 396 break; 397 398 case OPOSTINC: 399 case OPOSTDEC: 400 v = 1; 401 if(l->type->etype == TIND) 402 v = l->type->link->width; 403 if(o == OPOSTDEC) 404 v = -v; 405 if(l->op == OBIT) 406 goto bitinc; 407 if(nn == Z) 408 goto pre; 409 410 if(l->addable < INDEXED) 411 reglcgen(&nod2, l, Z); 412 else 413 nod2 = *l; 414 415 regalloc(&nod, l, nn); 416 gmove(&nod2, &nod); 417 regalloc(&nod1, l, Z); 418 if(typefd[l->type->etype]) { 419 diag(n, "no floating"); 420 } else 421 gopcode(OADD, nodconst(v), &nod, &nod1); 422 gmove(&nod1, &nod2); 423 424 regfree(&nod); 425 regfree(&nod1); 426 if(l->addable < INDEXED) 427 regfree(&nod2); 428 break; 429 430 case OPREINC: 431 case OPREDEC: 432 v = 1; 433 if(l->type->etype == TIND) 434 v = l->type->link->width; 435 if(o == OPREDEC) 436 v = -v; 437 if(l->op == OBIT) 438 goto bitinc; 439 440 pre: 441 if(l->addable < INDEXED) 442 reglcgen(&nod2, l, Z); 443 else 444 nod2 = *l; 445 446 regalloc(&nod, l, nn); 447 gmove(&nod2, &nod); 448 if(typefd[l->type->etype]) { 449 diag(n, "no floating"); 450 } else 451 gopcode(OADD, nodconst(v), Z, &nod); 452 gmove(&nod, &nod2); 453 454 regfree(&nod); 455 if(l->addable < INDEXED) 456 regfree(&nod2); 457 break; 458 459 bitinc: 460 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) 461 diag(n, "botch"); 462 bitload(l, &nod, &nod1, &nod2, nn); 463 gopcode(OADD, nodconst(v), Z, &nod); 464 bitstore(l, &nod, &nod1, &nod2, nn); 465 break; 466 } 467 cursafe = curs; 468 } 469 470 void 471 reglcgen(Node *t, Node *n, Node *nn) 472 { 473 Node *r; 474 long v; 475 476 regialloc(t, n, nn); 477 if(n->op == OIND) { 478 r = n->left; 479 while(r->op == OADD) 480 r = r->right; 481 if(sconst(r)) { 482 v = r->vconst; 483 r->vconst = 0; 484 lcgen(n, t); 485 t->xoffset += v; 486 r->vconst = v; 487 regind(t, n); 488 return; 489 } 490 } 491 lcgen(n, t); 492 regind(t, n); 493 } 494 495 void 496 lcgen(Node *n, Node *nn) 497 { 498 Prog *p1; 499 Node nod; 500 501 if(debug['g']) { 502 prtree(nn, "lcgen lhs"); 503 prtree(n, "lcgen"); 504 } 505 if(n == Z || n->type == T) 506 return; 507 if(nn == Z) { 508 nn = &nod; 509 regalloc(&nod, n, Z); 510 } 511 switch(n->op) { 512 default: 513 if(n->addable < INDEXED) { 514 diag(n, "unknown op in lcgen: %O", n->op); 515 break; 516 } 517 gopcode(OADDR, n, Z, nn); 518 break; 519 520 case OCOMMA: 521 cgen(n->left, n->left); 522 lcgen(n->right, nn); 523 break; 524 525 case OIND: 526 cgen(n->left, nn); 527 break; 528 529 case OCOND: 530 bcgen(n->left, 1); 531 p1 = p; 532 lcgen(n->right->left, nn); 533 gbranch(OGOTO); 534 patch(p1, pc); 535 p1 = p; 536 lcgen(n->right->right, nn); 537 patch(p1, pc); 538 break; 539 } 540 } 541 542 void 543 bcgen(Node *n, int true) 544 { 545 546 if(n->type == T) 547 gbranch(OGOTO); 548 else 549 boolgen(n, true, Z); 550 } 551 552 void 553 boolgen(Node *n, int true, Node *nn) 554 { 555 int o; 556 Prog *p1, *p2; 557 Node *l, *r, nod, nod1; 558 long curs; 559 560 if(debug['g']) { 561 prtree(nn, "boolgen lhs"); 562 prtree(n, "boolgen"); 563 } 564 curs = cursafe; 565 l = n->left; 566 r = n->right; 567 switch(n->op) { 568 569 default: 570 regalloc(&nod, n, nn); 571 cgen(n, &nod); 572 o = ONE; 573 if(true) 574 o = comrel[relindex(o)]; 575 if(typefd[n->type->etype]) { 576 diag(n, "no floating"); 577 } else 578 gopcode(o, &nod, Z, nodconst(0L)); 579 regfree(&nod); 580 goto com; 581 582 case OCONST: 583 o = vconst(n); 584 if(!true) 585 o = !o; 586 gbranch(OGOTO); 587 if(o) { 588 p1 = p; 589 gbranch(OGOTO); 590 patch(p1, pc); 591 } 592 goto com; 593 594 case OCOMMA: 595 cgen(l, Z); 596 boolgen(r, true, nn); 597 break; 598 599 case ONOT: 600 boolgen(l, !true, nn); 601 break; 602 603 case OCOND: 604 bcgen(l, 1); 605 p1 = p; 606 bcgen(r->left, true); 607 p2 = p; 608 gbranch(OGOTO); 609 patch(p1, pc); 610 p1 = p; 611 bcgen(r->right, !true); 612 patch(p2, pc); 613 p2 = p; 614 gbranch(OGOTO); 615 patch(p1, pc); 616 patch(p2, pc); 617 goto com; 618 619 case OANDAND: 620 if(!true) 621 goto caseor; 622 623 caseand: 624 bcgen(l, true); 625 p1 = p; 626 bcgen(r, !true); 627 p2 = p; 628 patch(p1, pc); 629 gbranch(OGOTO); 630 patch(p2, pc); 631 goto com; 632 633 case OOROR: 634 if(!true) 635 goto caseand; 636 637 caseor: 638 bcgen(l, !true); 639 p1 = p; 640 bcgen(r, !true); 641 p2 = p; 642 gbranch(OGOTO); 643 patch(p1, pc); 644 patch(p2, pc); 645 goto com; 646 647 case OEQ: 648 case ONE: 649 case OLE: 650 case OLT: 651 case OGE: 652 case OGT: 653 case OHI: 654 case OHS: 655 case OLO: 656 case OLS: 657 o = n->op; 658 if(true) 659 o = comrel[relindex(o)]; 660 if(l->complex >= FNX && r->complex >= FNX) { 661 regret(&nod, r); 662 cgen(r, &nod); 663 regsalloc(&nod1, r); 664 gmove(&nod, &nod1); 665 regfree(&nod); 666 nod = *n; 667 nod.right = &nod1; 668 boolgen(&nod, true, nn); 669 break; 670 } 671 if(typefd[l->type->etype]) { 672 diag(n, "no floating"); 673 break; 674 } 675 if(l->op == OCONST) { 676 regalloc(&nod, r, nn); 677 cgen(r, &nod); 678 gopcode(o, l, Z, &nod); 679 regfree(&nod); 680 goto com; 681 } 682 if(r->op == OCONST) { 683 o = invrel[relindex(o)]; 684 regalloc(&nod, l, nn); 685 cgen(l, &nod); 686 gopcode(o, r, Z, &nod); 687 regfree(&nod); 688 goto com; 689 } 690 if(l->complex >= r->complex) { 691 regalloc(&nod1, l, nn); 692 cgen(l, &nod1); 693 regalloc(&nod, r, Z); 694 cgen(r, &nod); 695 } else { 696 regalloc(&nod, r, nn); 697 cgen(r, &nod); 698 regalloc(&nod1, l, Z); 699 cgen(l, &nod1); 700 } 701 gopcode(o, &nod1, Z, &nod); 702 regfree(&nod); 703 regfree(&nod1); 704 705 com: 706 if(nn != Z) { 707 p1 = p; 708 gmove(nodconst(1L), nn); 709 gbranch(OGOTO); 710 p2 = p; 711 patch(p1, pc); 712 gmove(nodconst(0L), nn); 713 patch(p2, pc); 714 } 715 break; 716 } 717 cursafe = curs; 718 } 719 720 void 721 sugen(Node *n, Node *nn, long w) 722 { 723 Prog *p1; 724 Node nod0, nod1, nod2, nod3, nod4, *l, *r; 725 Type *t; 726 long pc1; 727 int i, m, c; 728 729 if(n == Z || n->type == T) 730 return; 731 if(debug['g']) { 732 prtree(nn, "sugen lhs"); 733 prtree(n, "sugen"); 734 } 735 if(nn == nodrat) 736 if(w > nrathole) 737 nrathole = w; 738 switch(n->op) { 739 case OIND: 740 if(nn == Z) { 741 nullwarn(n->left, Z); 742 break; 743 } 744 745 default: 746 goto copy; 747 748 case ODOT: 749 l = n->left; 750 sugen(l, nodrat, l->type->width); 751 if(nn != Z) { 752 warn(n, "non-interruptable temporary"); 753 nod1 = *nodrat; 754 r = n->right; 755 if(!r || r->op != OCONST) { 756 diag(n, "DOT and no offset"); 757 break; 758 } 759 nod1.xoffset += r->vconst; 760 nod1.type = n->type; 761 sugen(&nod1, nn, w); 762 } 763 break; 764 765 case OSTRUCT: 766 /* 767 * rewrite so lhs has no fn call 768 */ 769 if(nn != Z && nn->complex >= FNX) { 770 nod1 = *n; 771 nod1.type = typ(TIND, n->type); 772 regret(&nod2, &nod1); 773 lcgen(nn, &nod2); 774 regsalloc(&nod0, &nod1); 775 gopcode(OAS, &nod2, Z, &nod0); 776 regfree(&nod2); 777 778 nod1 = *n; 779 nod1.op = OIND; 780 nod1.left = &nod0; 781 nod1.right = Z; 782 nod1.complex = 1; 783 784 sugen(n, &nod1, w); 785 return; 786 } 787 788 r = n->left; 789 for(t = n->type->link; t != T; t = t->down) { 790 l = r; 791 if(r->op == OLIST) { 792 l = r->left; 793 r = r->right; 794 } 795 if(nn == Z) { 796 cgen(l, nn); 797 continue; 798 } 799 /* 800 * hand craft *(&nn + o) = l 801 */ 802 nod0 = znode; 803 nod0.op = OAS; 804 nod0.type = t; 805 nod0.left = &nod1; 806 nod0.right = l; 807 808 nod1 = znode; 809 nod1.op = OIND; 810 nod1.type = t; 811 nod1.left = &nod2; 812 813 nod2 = znode; 814 nod2.op = OADD; 815 nod2.type = typ(TIND, t); 816 nod2.left = &nod3; 817 nod2.right = &nod4; 818 819 nod3 = znode; 820 nod3.op = OADDR; 821 nod3.type = nod2.type; 822 nod3.left = nn; 823 824 nod4 = znode; 825 nod4.op = OCONST; 826 nod4.type = nod2.type; 827 nod4.vconst = t->offset; 828 829 ccom(&nod0); 830 acom(&nod0); 831 xcom(&nod0); 832 nod0.addable = 0; 833 834 /* prtree(&nod0, "hand craft"); /* */ 835 cgen(&nod0, Z); 836 } 837 break; 838 839 case OAS: 840 if(nn == Z) { 841 if(n->addable < INDEXED) 842 sugen(n->right, n->left, w); 843 break; 844 } 845 /* BOTCH -- functions can clobber rathole */ 846 sugen(n->right, nodrat, w); 847 warn(n, "non-interruptable temporary"); 848 sugen(nodrat, n->left, w); 849 sugen(nodrat, nn, w); 850 break; 851 852 case OFUNC: 853 if(nn == Z) { 854 sugen(n, nodrat, w); 855 break; 856 } 857 if(nn->op != OIND) { 858 nn = new1(OADDR, nn, Z); 859 nn->type = types[TIND]; 860 nn->addable = 0; 861 } else 862 nn = nn->left; 863 n = new(OFUNC, n->left, new(OLIST, nn, n->right)); 864 n->type = types[TVOID]; 865 n->left->type = types[TVOID]; 866 cgen(n, Z); 867 break; 868 869 case OCOND: 870 bcgen(n->left, 1); 871 p1 = p; 872 sugen(n->right->left, nn, w); 873 gbranch(OGOTO); 874 patch(p1, pc); 875 p1 = p; 876 sugen(n->right->right, nn, w); 877 patch(p1, pc); 878 break; 879 880 case OCOMMA: 881 cgen(n->left, Z); 882 sugen(n->right, nn, w); 883 break; 884 } 885 return; 886 887 copy: 888 if(nn == Z) 889 return; 890 if(n->complex >= FNX && nn->complex >= FNX) { 891 diag(n, "Ah, come on. Is that you, Rob?"); 892 return; 893 } 894 895 if(n->complex > nn->complex) { 896 t = n->type; 897 n->type = types[TLONG]; 898 reglcgen(&nod1, n, Z); 899 n->type = t; 900 901 t = nn->type; 902 nn->type = types[TLONG]; 903 reglcgen(&nod2, nn, Z); 904 nn->type = t; 905 } else { 906 t = nn->type; 907 nn->type = types[TLONG]; 908 reglcgen(&nod2, nn, Z); 909 nn->type = t; 910 911 t = n->type; 912 n->type = types[TLONG]; 913 reglcgen(&nod1, n, Z); 914 n->type = t; 915 } 916 917 w /= SZ_LONG; 918 if(w <= 5) { 919 layout(&nod1, &nod2, w, 0, Z); 920 goto out; 921 } 922 923 /* 924 * minimize space for unrolling loop 925 * 3,4,5 times. (6 or more is never minimum) 926 * if small structure, try 2 also. 927 */ 928 c = 0; /* set */ 929 m = 100; 930 i = 3; 931 if(w <= 15) 932 i = 2; 933 for(; i<=5; i++) 934 if(i + w%i <= m) { 935 c = i; 936 m = c + w%c; 937 } 938 939 regalloc(&nod3, ®node, Z); 940 layout(&nod1, &nod2, w%c, w/c, &nod3); 941 942 pc1 = pc; 943 layout(&nod1, &nod2, c, 0, Z); 944 945 gopcode(OSUB, nodconst(1L), Z, &nod3); 946 nod1.op = OREGISTER; 947 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1); 948 nod2.op = OREGISTER; 949 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2); 950 951 gopcode(OEQ, &nod3, Z, Z); 952 p->as = ACMPIBGE; 953 patch(p, pc1); 954 955 regfree(&nod3); 956 out: 957 regfree(&nod1); 958 regfree(&nod2); 959 } 960 961 void 962 layout(Node *f, Node *t, int c, int cv, Node *cn) 963 { 964 Node t1, t2; 965 966 while(c > 3) { 967 layout(f, t, 2, 0, Z); 968 c -= 2; 969 } 970 971 regalloc(&t1, ®node, Z); 972 regalloc(&t2, ®node, Z); 973 if(c > 0) { 974 gmove(f, &t1); 975 f->xoffset += SZ_LONG; 976 } 977 if(cn != Z) 978 gmove(nodconst(cv), cn); 979 if(c > 1) { 980 gmove(f, &t2); 981 f->xoffset += SZ_LONG; 982 } 983 if(c > 0) { 984 gmove(&t1, t); 985 t->xoffset += SZ_LONG; 986 } 987 if(c > 2) { 988 gmove(f, &t1); 989 f->xoffset += SZ_LONG; 990 } 991 if(c > 1) { 992 gmove(&t2, t); 993 t->xoffset += SZ_LONG; 994 } 995 if(c > 2) { 996 gmove(&t1, t); 997 t->xoffset += SZ_LONG; 998 } 999 regfree(&t1); 1000 regfree(&t2); 1001 } 1002