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, nod3, nod4; 9 int o, hardleft; 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(typesuv[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(l->complex >= FNX) 43 if(r != Z && r->complex >= FNX) 44 switch(o) { 45 default: 46 regret(&nod, r); 47 cgen(r, &nod); 48 49 regsalloc(&nod1, r); 50 gmove(&nod, &nod1); 51 52 regfree(&nod); 53 nod = *n; 54 nod.right = &nod1; 55 56 cgen(&nod, nn); 57 return; 58 59 case OFUNC: 60 case OCOMMA: 61 case OANDAND: 62 case OOROR: 63 case OCOND: 64 case ODOT: 65 break; 66 } 67 68 hardleft = l->addable < INDEXED || l->complex >= FNX; 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 cgen(r, &fregnode0); 77 if(nn != Z) 78 gins(AFMOVD, &fregnode0, &fregnode0); 79 if(l->addable < INDEXED) { 80 reglcgen(&nod, l, Z); 81 gmove(&fregnode0, &nod); 82 regfree(&nod); 83 } else 84 gmove(&fregnode0, l); 85 if(nn != Z) 86 gmove(&fregnode0, nn); 87 return; 88 } 89 if(l->op == OBIT) 90 goto bitas; 91 if(!hardleft) { 92 if(nn != Z || r->addable < INDEXED) { 93 if(r->complex >= FNX && nn == Z) 94 regret(&nod, r); 95 else 96 regalloc(&nod, r, nn); 97 cgen(r, &nod); 98 gmove(&nod, l); 99 if(nn != Z) 100 gmove(&nod, nn); 101 regfree(&nod); 102 } else 103 gmove(r, l); 104 break; 105 } 106 if(l->complex >= r->complex) { 107 if(l->op == OINDEX && r->op == OCONST) { 108 gmove(r, l); 109 break; 110 } 111 reglcgen(&nod1, l, Z); 112 if(r->addable >= INDEXED) { 113 gmove(r, &nod1); 114 if(nn != Z) 115 gmove(r, nn); 116 regfree(&nod1); 117 break; 118 } 119 regalloc(&nod, r, nn); 120 cgen(r, &nod); 121 } else { 122 regalloc(&nod, r, nn); 123 cgen(r, &nod); 124 reglcgen(&nod1, l, Z); 125 } 126 gmove(&nod, &nod1); 127 regfree(&nod); 128 regfree(&nod1); 129 break; 130 131 bitas: 132 n = l->left; 133 regalloc(&nod, r, nn); 134 if(l->complex >= r->complex) { 135 reglcgen(&nod1, n, Z); 136 cgen(r, &nod); 137 } else { 138 cgen(r, &nod); 139 reglcgen(&nod1, n, Z); 140 } 141 regalloc(&nod2, n, Z); 142 gmove(&nod1, &nod2); 143 bitstore(l, &nod, &nod1, &nod2, nn); 144 break; 145 146 case OBIT: 147 if(nn == Z) { 148 nullwarn(l, Z); 149 break; 150 } 151 bitload(n, &nod, Z, Z, nn); 152 gmove(&nod, nn); 153 regfree(&nod); 154 break; 155 156 case OLSHR: 157 case OASHL: 158 case OASHR: 159 if(nn == Z) { 160 nullwarn(l, r); 161 break; 162 } 163 if(r->op == OCONST) { 164 if(r->vconst == 0) { 165 cgen(l, nn); 166 break; 167 } 168 regalloc(&nod, l, nn); 169 cgen(l, &nod); 170 gopcode(o, n->type, r, &nod); 171 gmove(&nod, nn); 172 regfree(&nod); 173 break; 174 } 175 176 /* 177 * get nod to be D_CX 178 */ 179 if(nodreg(&nod, nn, D_CX)) { 180 regsalloc(&nod1, n); 181 gmove(&nod, &nod1); 182 cgen(n, &nod); /* probably a bug */ 183 gmove(&nod, nn); 184 gmove(&nod1, &nod); 185 break; 186 } 187 reg[D_CX]++; 188 if(nn->op == OREGISTER && nn->reg == D_CX) 189 regalloc(&nod1, l, Z); 190 else 191 regalloc(&nod1, l, nn); 192 if(r->complex >= l->complex) { 193 cgen(r, &nod); 194 cgen(l, &nod1); 195 } else { 196 cgen(l, &nod1); 197 cgen(r, &nod); 198 } 199 gopcode(o, n->type, &nod, &nod1); 200 gmove(&nod1, nn); 201 regfree(&nod); 202 regfree(&nod1); 203 break; 204 205 case OADD: 206 case OSUB: 207 case OOR: 208 case OXOR: 209 case OAND: 210 if(nn == Z) { 211 nullwarn(l, r); 212 break; 213 } 214 if(typefd[n->type->etype]) 215 goto fop; 216 if(r->op == OCONST) { 217 if(r->vconst == 0 && o != OAND) { 218 cgen(l, nn); 219 break; 220 } 221 } 222 if(r->addable >= INDEXED) { 223 regalloc(&nod, l, nn); 224 cgen(l, &nod); 225 gopcode(o, n->type, r, &nod); 226 gmove(&nod, nn); 227 regfree(&nod); 228 break; 229 } 230 if(l->complex >= r->complex) { 231 regalloc(&nod, l, nn); 232 cgen(l, &nod); 233 regalloc(&nod1, r, Z); 234 cgen(r, &nod1); 235 gopcode(o, n->type, &nod1, &nod); 236 } else { 237 regalloc(&nod1, r, nn); 238 cgen(r, &nod1); 239 regalloc(&nod, l, Z); 240 cgen(l, &nod); 241 gopcode(o, n->type, &nod1, &nod); 242 } 243 gmove(&nod, nn); 244 regfree(&nod); 245 regfree(&nod1); 246 break; 247 248 case OLMOD: 249 case OMOD: 250 case OLMUL: 251 case OLDIV: 252 case OMUL: 253 case ODIV: 254 if(nn == Z) { 255 nullwarn(l, r); 256 break; 257 } 258 if(typefd[n->type->etype]) 259 goto fop; 260 if(o == OMUL && r->op == OCONST) { 261 regalloc(&nod, l, nn); 262 cgen(l, &nod); 263 gopcode(o, n->type, r, &nod); 264 gmove(&nod, nn); 265 regfree(&nod); 266 break; 267 } 268 /* 269 * get nod to be D_AX 270 * get nod1 to be D_DX 271 */ 272 if(nodreg(&nod, nn, D_AX)) { 273 regsalloc(&nod2, n); 274 gmove(&nod, &nod2); 275 v = reg[D_AX]; 276 reg[D_AX] = 0; 277 278 if(isreg(l, D_AX)) { 279 nod3 = *n; 280 nod3.left = &nod2; 281 cgen(&nod3, nn); 282 } else 283 if(isreg(r, D_AX)) { 284 nod3 = *n; 285 nod3.right = &nod2; 286 cgen(&nod3, nn); 287 } else 288 cgen(n, nn); 289 290 gmove(&nod2, &nod); 291 reg[D_AX] = v; 292 break; 293 } 294 if(nodreg(&nod1, nn, D_DX)) { 295 regsalloc(&nod2, n); 296 gmove(&nod1, &nod2); 297 v = reg[D_DX]; 298 reg[D_DX] = 0; 299 300 if(isreg(l, D_DX)) { 301 nod3 = *n; 302 nod3.left = &nod2; 303 cgen(&nod3, nn); 304 } else 305 if(isreg(r, D_DX)) { 306 nod3 = *n; 307 nod3.right = &nod2; 308 cgen(&nod3, nn); 309 } else 310 cgen(n, nn); 311 312 gmove(&nod2, &nod1); 313 reg[D_DX] = v; 314 break; 315 } 316 reg[D_AX]++; 317 318 if(l->complex >= r->complex) { 319 cgen(l, &nod); 320 reg[D_DX]++; 321 if(o == ODIV || o == OMOD) 322 gins(ACDQ, Z, Z); 323 if(o == OLDIV || o == OLMOD) 324 gins(AMOVL, nodconst(0), &nod1); 325 if(r->addable < INDEXED || r->op == OCONST) { 326 regsalloc(&nod3, r); 327 cgen(r, &nod3); 328 gopcode(o, n->type, &nod3, Z); 329 } else 330 gopcode(o, n->type, r, Z); 331 } else { 332 regsalloc(&nod3, r); 333 cgen(r, &nod3); 334 cgen(l, &nod); 335 reg[D_DX]++; 336 if(o == ODIV || o == OMOD) 337 gins(ACDQ, Z, Z); 338 if(o == OLDIV || o == OLMOD) 339 gins(AMOVL, nodconst(0), &nod1); 340 gopcode(o, n->type, &nod3, Z); 341 } 342 if(o == OMOD || o == OLMOD) 343 gmove(&nod1, nn); 344 else 345 gmove(&nod, nn); 346 regfree(&nod); 347 regfree(&nod1); 348 break; 349 350 case OASLSHR: 351 case OASASHL: 352 case OASASHR: 353 if(r->op == OCONST) 354 goto asand; 355 if(l->op == OBIT) 356 goto asbitop; 357 if(typefd[n->type->etype]) 358 goto asfop; 359 360 /* 361 * get nod to be D_CX 362 */ 363 if(nodreg(&nod, nn, D_CX)) { 364 regsalloc(&nod1, n); 365 gmove(&nod, &nod1); 366 cgen(n, &nod); 367 if(nn != Z) 368 gmove(&nod, nn); 369 gmove(&nod1, &nod); 370 break; 371 } 372 reg[D_CX]++; 373 374 if(r->complex >= l->complex) { 375 cgen(r, &nod); 376 if(hardleft) 377 reglcgen(&nod1, l, Z); 378 else 379 nod1 = *l; 380 } else { 381 if(hardleft) 382 reglcgen(&nod1, l, Z); 383 else 384 nod1 = *l; 385 cgen(r, &nod); 386 } 387 388 gopcode(o, l->type, &nod, &nod1); 389 regfree(&nod); 390 if(nn != Z) 391 gmove(&nod1, nn); 392 if(hardleft) 393 regfree(&nod1); 394 break; 395 396 case OASAND: 397 case OASADD: 398 case OASSUB: 399 case OASXOR: 400 case OASOR: 401 asand: 402 if(l->op == OBIT) 403 goto asbitop; 404 if(typefd[n->type->etype]) 405 goto asfop; 406 if(l->complex >= r->complex) { 407 if(hardleft) 408 reglcgen(&nod, l, Z); 409 else 410 nod = *l; 411 if(r->op != OCONST) { 412 regalloc(&nod1, r, nn); 413 cgen(r, &nod1); 414 gopcode(o, l->type, &nod1, &nod); 415 regfree(&nod1); 416 } else 417 gopcode(o, l->type, r, &nod); 418 } else { 419 regalloc(&nod1, r, nn); 420 cgen(r, &nod1); 421 if(hardleft) 422 reglcgen(&nod, l, Z); 423 else 424 nod = *l; 425 gopcode(o, l->type, &nod1, &nod); 426 regfree(&nod1); 427 } 428 if(nn != Z) 429 gmove(&nod, nn); 430 if(hardleft) 431 regfree(&nod); 432 break; 433 434 case OASLMUL: 435 case OASLDIV: 436 case OASLMOD: 437 case OASMUL: 438 case OASDIV: 439 case OASMOD: 440 if(l->op == OBIT) 441 goto asbitop; 442 if(typefd[n->type->etype]) 443 goto asfop; 444 if(o == OASMUL && r->op == OCONST) { 445 if(hardleft) 446 reglcgen(&nod2, l, Z); 447 else 448 nod2 = *l; 449 regalloc(&nod, l, nn); 450 cgen(&nod2, &nod); 451 gopcode(o, l->type, r, &nod); 452 gmove(&nod, &nod2); 453 if(nn != Z) 454 gmove(&nod, nn); 455 if(hardleft) 456 regfree(&nod2); 457 regfree(&nod); 458 break; 459 } 460 /* 461 * get nod to be D_AX 462 * get nod1 to be D_DX 463 */ 464 if(nodreg(&nod, nn, D_AX)) { 465 regsalloc(&nod2, n); 466 gmove(&nod, &nod2); 467 v = reg[D_AX]; 468 reg[D_AX] = 0; 469 470 if(isreg(l, D_AX)) { 471 nod3 = *n; 472 nod3.left = &nod2; 473 cgen(&nod3, nn); 474 } else 475 if(isreg(r, D_AX)) { 476 nod3 = *n; 477 nod3.right = &nod2; 478 cgen(&nod3, nn); 479 } else 480 cgen(n, nn); 481 482 gmove(&nod2, &nod); 483 reg[D_AX] = v; 484 break; 485 } 486 if(nodreg(&nod1, nn, D_DX)) { 487 regsalloc(&nod2, n); 488 gmove(&nod1, &nod2); 489 v = reg[D_DX]; 490 reg[D_DX] = 0; 491 492 if(isreg(l, D_DX)) { 493 nod3 = *n; 494 nod3.left = &nod2; 495 cgen(&nod3, nn); 496 } else 497 if(isreg(r, D_DX)) { 498 nod3 = *n; 499 nod3.right = &nod2; 500 cgen(&nod3, nn); 501 } else 502 cgen(n, nn); 503 504 gmove(&nod2, &nod1); 505 reg[D_DX] = v; 506 break; 507 } 508 reg[D_AX]++; 509 reg[D_DX]++; 510 511 if(l->complex >= r->complex) { 512 if(hardleft) 513 reglcgen(&nod2, l, Z); 514 else 515 nod2 = *l; 516 cgen(&nod2, &nod); 517 if(o == OASDIV || o == OASMOD) 518 gins(ACDQ, Z, Z); 519 if(o == OASLDIV || o == OASLMOD) 520 gins(AMOVL, nodconst(0), &nod1); 521 if(r->addable < INDEXED || r->op == OCONST || 522 !typeil[r->type->etype]) { 523 regalloc(&nod3, r, Z); 524 cgen(r, &nod3); 525 gopcode(o, l->type, &nod3, Z); 526 regfree(&nod3); 527 } else 528 gopcode(o, n->type, r, Z); 529 } else { 530 regalloc(&nod3, r, Z); 531 cgen(r, &nod3); 532 if(hardleft) 533 reglcgen(&nod2, l, Z); 534 else 535 nod2 = *l; 536 cgen(&nod2, &nod); 537 if(o == OASDIV || o == OASMOD) 538 gins(ACDQ, Z, Z); 539 if(o == OASLDIV || o == OASLMOD) 540 gins(AMOVL, nodconst(0), &nod1); 541 gopcode(o, l->type, &nod3, Z); 542 regfree(&nod3); 543 } 544 if(o == OASMOD || o == OASLMOD) { 545 gmove(&nod1, &nod2); 546 if(nn != Z) 547 gmove(&nod1, nn); 548 } else { 549 gmove(&nod, &nod2); 550 if(nn != Z) 551 gmove(&nod, nn); 552 } 553 if(hardleft) 554 regfree(&nod2); 555 regfree(&nod); 556 regfree(&nod1); 557 break; 558 559 fop: 560 if(l->complex >= r->complex) { 561 cgen(l, &fregnode0); 562 if(r->addable < INDEXED) { 563 cgen(r, &fregnode0); 564 fgopcode(o, &fregnode0, &fregnode1, 1, 0); 565 } else 566 fgopcode(o, r, &fregnode0, 0, 0); 567 } else { 568 cgen(r, &fregnode0); 569 if(l->addable < INDEXED) { 570 cgen(l, &fregnode0); 571 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 572 } else 573 fgopcode(o, l, &fregnode0, 0, 1); 574 } 575 gmove(&fregnode0, nn); 576 break; 577 578 asfop: 579 if(l->complex >= r->complex) { 580 if(hardleft) 581 reglcgen(&nod, l, Z); 582 else 583 nod = *l; 584 cgen(r, &fregnode0); 585 } else { 586 cgen(r, &fregnode0); 587 if(hardleft) 588 reglcgen(&nod, l, Z); 589 else 590 nod = *l; 591 } 592 if(!typefd[l->type->etype]) { 593 gmove(&nod, &fregnode0); 594 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 595 } else 596 fgopcode(o, &nod, &fregnode0, 0, 1); 597 if(nn != Z) 598 gins(AFMOVD, &fregnode0, &fregnode0); 599 gmove(&fregnode0, &nod); 600 if(nn != Z) 601 gmove(&fregnode0, nn); 602 if(hardleft) 603 regfree(&nod); 604 break; 605 606 asbitop: 607 regalloc(&nod4, n, nn); 608 if(l->complex >= r->complex) { 609 bitload(l, &nod, &nod1, &nod2, &nod4); 610 regalloc(&nod3, r, Z); 611 cgen(r, &nod3); 612 } else { 613 regalloc(&nod3, r, Z); 614 cgen(r, &nod3); 615 bitload(l, &nod, &nod1, &nod2, &nod4); 616 } 617 gmove(&nod, &nod4); 618 619 if(typefd[nod3.type->etype]) 620 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 621 else { 622 Node onod; 623 624 /* incredible grot ... */ 625 onod = nod3; 626 onod.op = o; 627 onod.complex = 2; 628 onod.addable = 0; 629 onod.type = tfield; 630 onod.left = &nod4; 631 onod.right = &nod3; 632 cgen(&onod, Z); 633 } 634 regfree(&nod3); 635 gmove(&nod4, &nod); 636 regfree(&nod4); 637 bitstore(l, &nod, &nod1, &nod2, nn); 638 break; 639 640 case OADDR: 641 if(nn == Z) { 642 nullwarn(l, Z); 643 break; 644 } 645 lcgen(l, nn); 646 break; 647 648 case OFUNC: 649 if(l->complex >= FNX) { 650 if(l->op != OIND) 651 diag(n, "bad function call"); 652 653 regret(&nod, l->left); 654 cgen(l->left, &nod); 655 regsalloc(&nod1, l->left); 656 gmove(&nod, &nod1); 657 regfree(&nod); 658 659 nod = *n; 660 nod.left = &nod2; 661 nod2 = *l; 662 nod2.left = &nod1; 663 nod2.complex = 1; 664 cgen(&nod, nn); 665 666 return; 667 } 668 gargs(r, &nod, &nod1); 669 if(l->addable < INDEXED) { 670 reglcgen(&nod, l, nn); 671 nod.op = OREGISTER; 672 gopcode(OFUNC, n->type, Z, &nod); 673 regfree(&nod); 674 } else 675 gopcode(OFUNC, n->type, Z, l); 676 if(REGARG && reg[REGARG]) 677 reg[REGARG]--; 678 if(nn != Z) { 679 regret(&nod, n); 680 gmove(&nod, nn); 681 regfree(&nod); 682 } else 683 if(typefd[n->type->etype]) 684 gins(AFMOVDP, &fregnode0, &fregnode0); 685 break; 686 687 case OIND: 688 if(nn == Z) { 689 nullwarn(l, Z); 690 break; 691 } 692 regialloc(&nod, n, nn); 693 r = l; 694 while(r->op == OADD) 695 r = r->right; 696 if(sconst(r)) { 697 v = r->vconst; 698 r->vconst = 0; 699 cgen(l, &nod); 700 nod.xoffset += v; 701 r->vconst = v; 702 } else 703 cgen(l, &nod); 704 regind(&nod, n); 705 gmove(&nod, nn); 706 regfree(&nod); 707 break; 708 709 case OEQ: 710 case ONE: 711 case OLE: 712 case OLT: 713 case OGE: 714 case OGT: 715 case OLO: 716 case OLS: 717 case OHI: 718 case OHS: 719 if(nn == Z) { 720 nullwarn(l, r); 721 break; 722 } 723 boolgen(n, 1, nn); 724 break; 725 726 case OANDAND: 727 case OOROR: 728 boolgen(n, 1, nn); 729 if(nn == Z) 730 patch(p, pc); 731 break; 732 733 case ONOT: 734 if(nn == Z) { 735 nullwarn(l, Z); 736 break; 737 } 738 boolgen(n, 1, nn); 739 break; 740 741 case OCOMMA: 742 cgen(l, Z); 743 cgen(r, nn); 744 break; 745 746 case OCAST: 747 if(nn == Z) { 748 nullwarn(l, Z); 749 break; 750 } 751 /* 752 * convert from types l->n->nn 753 */ 754 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) { 755 /* both null, gen l->nn */ 756 cgen(l, nn); 757 break; 758 } 759 regalloc(&nod, l, nn); 760 cgen(l, &nod); 761 regalloc(&nod1, n, &nod); 762 gmove(&nod, &nod1); 763 gmove(&nod1, nn); 764 regfree(&nod1); 765 regfree(&nod); 766 break; 767 768 case ODOT: 769 sugen(l, nodrat, l->type->width); 770 if(nn == Z) 771 break; 772 warn(n, "non-interruptable temporary"); 773 nod = *nodrat; 774 if(!r || r->op != OCONST) { 775 diag(n, "DOT and no offset"); 776 break; 777 } 778 nod.xoffset += (long)r->vconst; 779 nod.type = n->type; 780 cgen(&nod, nn); 781 break; 782 783 case OCOND: 784 bcgen(l, 1); 785 p1 = p; 786 cgen(r->left, nn); 787 gbranch(OGOTO); 788 patch(p1, pc); 789 p1 = p; 790 cgen(r->right, nn); 791 patch(p1, pc); 792 break; 793 794 case OPOSTINC: 795 case OPOSTDEC: 796 v = 1; 797 if(l->type->etype == TIND) 798 v = l->type->link->width; 799 if(o == OPOSTDEC) 800 v = -v; 801 if(l->op == OBIT) 802 goto bitinc; 803 if(nn == Z) 804 goto pre; 805 806 if(hardleft) 807 reglcgen(&nod, l, Z); 808 else 809 nod = *l; 810 811 if(typefd[n->type->etype]) 812 goto fltinc; 813 gmove(&nod, nn); 814 gopcode(OADD, n->type, nodconst(v), &nod); 815 if(hardleft) 816 regfree(&nod); 817 break; 818 819 case OPREINC: 820 case OPREDEC: 821 v = 1; 822 if(l->type->etype == TIND) 823 v = l->type->link->width; 824 if(o == OPREDEC) 825 v = -v; 826 if(l->op == OBIT) 827 goto bitinc; 828 829 pre: 830 if(hardleft) 831 reglcgen(&nod, l, Z); 832 else 833 nod = *l; 834 if(typefd[n->type->etype]) 835 goto fltinc; 836 gopcode(OADD, n->type, nodconst(v), &nod); 837 if(nn != Z) 838 gmove(&nod, nn); 839 if(hardleft) 840 regfree(&nod); 841 break; 842 843 fltinc: 844 gmove(&nod, &fregnode0); 845 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) 846 gins(AFMOVD, &fregnode0, &fregnode0); 847 gins(AFLD1, Z, Z); 848 if(v < 0) 849 fgopcode(OSUB, &fregnode0, &fregnode1, 1, 0); 850 else 851 fgopcode(OADD, &fregnode0, &fregnode1, 1, 0); 852 if(nn != Z && (o == OPREINC || o == OPREDEC)) 853 gins(AFMOVD, &fregnode0, &fregnode0); 854 gmove(&fregnode0, &nod); 855 if(hardleft) 856 regfree(&nod); 857 break; 858 859 bitinc: 860 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) { 861 bitload(l, &nod, &nod1, &nod2, Z); 862 gmove(&nod, nn); 863 gopcode(OADD, tfield, nodconst(v), &nod); 864 bitstore(l, &nod, &nod1, &nod2, Z); 865 break; 866 } 867 bitload(l, &nod, &nod1, &nod2, nn); 868 gopcode(OADD, tfield, nodconst(v), &nod); 869 bitstore(l, &nod, &nod1, &nod2, nn); 870 break; 871 } 872 cursafe = curs; 873 } 874 875 void 876 reglcgen(Node *t, Node *n, Node *nn) 877 { 878 Node *r; 879 long v; 880 881 regialloc(t, n, nn); 882 if(n->op == OIND) { 883 r = n->left; 884 while(r->op == OADD) 885 r = r->right; 886 if(sconst(r)) { 887 v = r->vconst; 888 r->vconst = 0; 889 lcgen(n, t); 890 t->xoffset += v; 891 r->vconst = v; 892 regind(t, n); 893 return; 894 } 895 } 896 lcgen(n, t); 897 regind(t, n); 898 } 899 900 void 901 lcgen(Node *n, Node *nn) 902 { 903 Prog *p1; 904 Node nod; 905 906 if(debug['g']) { 907 prtree(nn, "lcgen lhs"); 908 prtree(n, "lcgen"); 909 } 910 if(n == Z || n->type == T) 911 return; 912 if(nn == Z) { 913 nn = &nod; 914 regalloc(&nod, n, Z); 915 } 916 switch(n->op) { 917 default: 918 if(n->addable < INDEXED) { 919 diag(n, "unknown op in lcgen: %O", n->op); 920 break; 921 } 922 gopcode(OADDR, n->type, n, nn); 923 break; 924 925 case OCOMMA: 926 cgen(n->left, n->left); 927 lcgen(n->right, nn); 928 break; 929 930 case OIND: 931 cgen(n->left, nn); 932 break; 933 934 case OCOND: 935 bcgen(n->left, 1); 936 p1 = p; 937 lcgen(n->right->left, nn); 938 gbranch(OGOTO); 939 patch(p1, pc); 940 p1 = p; 941 lcgen(n->right->right, nn); 942 patch(p1, pc); 943 break; 944 } 945 } 946 947 void 948 bcgen(Node *n, int true) 949 { 950 951 if(n->type == T) 952 gbranch(OGOTO); 953 else 954 boolgen(n, true, Z); 955 } 956 957 void 958 boolgen(Node *n, int true, Node *nn) 959 { 960 int o; 961 Prog *p1, *p2; 962 Node *l, *r, nod, nod1; 963 long curs; 964 965 if(debug['g']) { 966 prtree(nn, "boolgen lhs"); 967 prtree(n, "boolgen"); 968 } 969 curs = cursafe; 970 l = n->left; 971 r = n->right; 972 switch(n->op) { 973 974 default: 975 o = ONE; 976 if(true) 977 o = OEQ; 978 if(typefd[n->type->etype]) { 979 if(n->addable < INDEXED) { 980 cgen(n, &fregnode0); 981 gins(AFLDZ, Z, Z); 982 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 983 } else { 984 gins(AFLDZ, Z, Z); 985 fgopcode(o, n, &fregnode0, 0, 1); 986 } 987 goto com; 988 } 989 /* bad, 13 is address of external that becomes constant */ 990 if(n->addable >= INDEXED && n->addable != 13) { 991 gopcode(o, n->type, n, nodconst(0)); 992 goto com; 993 } 994 regalloc(&nod, n, nn); 995 cgen(n, &nod); 996 gopcode(o, n->type, &nod, nodconst(0)); 997 regfree(&nod); 998 goto com; 999 1000 case OCONST: 1001 o = vconst(n); 1002 if(!true) 1003 o = !o; 1004 gbranch(OGOTO); 1005 if(o) { 1006 p1 = p; 1007 gbranch(OGOTO); 1008 patch(p1, pc); 1009 } 1010 goto com; 1011 1012 case OCOMMA: 1013 cgen(l, Z); 1014 boolgen(r, true, nn); 1015 break; 1016 1017 case ONOT: 1018 boolgen(l, !true, nn); 1019 break; 1020 1021 case OCOND: 1022 bcgen(l, 1); 1023 p1 = p; 1024 bcgen(r->left, true); 1025 p2 = p; 1026 gbranch(OGOTO); 1027 patch(p1, pc); 1028 p1 = p; 1029 bcgen(r->right, !true); 1030 patch(p2, pc); 1031 p2 = p; 1032 gbranch(OGOTO); 1033 patch(p1, pc); 1034 patch(p2, pc); 1035 goto com; 1036 1037 case OANDAND: 1038 if(!true) 1039 goto caseor; 1040 1041 caseand: 1042 bcgen(l, true); 1043 p1 = p; 1044 bcgen(r, !true); 1045 p2 = p; 1046 patch(p1, pc); 1047 gbranch(OGOTO); 1048 patch(p2, pc); 1049 goto com; 1050 1051 case OOROR: 1052 if(!true) 1053 goto caseand; 1054 1055 caseor: 1056 bcgen(l, !true); 1057 p1 = p; 1058 bcgen(r, !true); 1059 p2 = p; 1060 gbranch(OGOTO); 1061 patch(p1, pc); 1062 patch(p2, pc); 1063 goto com; 1064 1065 case OEQ: 1066 case ONE: 1067 case OLE: 1068 case OLT: 1069 case OGE: 1070 case OGT: 1071 case OHI: 1072 case OHS: 1073 case OLO: 1074 case OLS: 1075 o = n->op; 1076 if(true) 1077 o = comrel[relindex(o)]; 1078 if(l->complex >= FNX && r->complex >= FNX) { 1079 regret(&nod, r); 1080 cgen(r, &nod); 1081 regsalloc(&nod1, r); 1082 gmove(&nod, &nod1); 1083 regfree(&nod); 1084 nod = *n; 1085 nod.right = &nod1; 1086 boolgen(&nod, true, nn); 1087 break; 1088 } 1089 if(typefd[l->type->etype]) { 1090 if(l->complex >= r->complex) { 1091 cgen(l, &fregnode0); 1092 if(r->addable < INDEXED) { 1093 cgen(r, &fregnode0); 1094 o = invrel[relindex(o)]; 1095 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 1096 } else 1097 fgopcode(o, r, &fregnode0, 0, 1); 1098 } else { 1099 o = invrel[relindex(o)]; 1100 cgen(r, &fregnode0); 1101 if(l->addable < INDEXED) { 1102 cgen(l, &fregnode0); 1103 o = invrel[relindex(o)]; 1104 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 1105 } else 1106 fgopcode(o, l, &fregnode0, 0, 1); 1107 } 1108 goto com; 1109 } 1110 if(l->op == OCONST) { 1111 o = invrel[relindex(o)]; 1112 /* bad, 13 is address of external that becomes constant */ 1113 if(r->addable < INDEXED || r->addable == 13) { 1114 regalloc(&nod, r, nn); 1115 cgen(r, &nod); 1116 gopcode(o, l->type, &nod, l); 1117 regfree(&nod); 1118 } else 1119 gopcode(o, l->type, r, l); 1120 goto com; 1121 } 1122 if(l->complex >= r->complex) { 1123 regalloc(&nod, l, nn); 1124 cgen(l, &nod); 1125 if(r->addable < INDEXED) { 1126 regalloc(&nod1, r, Z); 1127 cgen(r, &nod1); 1128 gopcode(o, l->type, &nod, &nod1); 1129 regfree(&nod1); 1130 } else 1131 gopcode(o, l->type, &nod, r); 1132 regfree(&nod); 1133 goto com; 1134 } 1135 regalloc(&nod, r, nn); 1136 cgen(r, &nod); 1137 if(l->addable < INDEXED || l->addable == 13) { 1138 regalloc(&nod1, l, Z); 1139 cgen(l, &nod1); 1140 gopcode(o, l->type, &nod1, &nod); 1141 regfree(&nod1); 1142 } else 1143 gopcode(o, l->type, l, &nod); 1144 regfree(&nod); 1145 1146 com: 1147 if(nn != Z) { 1148 p1 = p; 1149 gmove(nodconst(1L), nn); 1150 gbranch(OGOTO); 1151 p2 = p; 1152 patch(p1, pc); 1153 gmove(nodconst(0L), nn); 1154 patch(p2, pc); 1155 } 1156 break; 1157 } 1158 cursafe = curs; 1159 } 1160 1161 void 1162 sugen(Node *n, Node *nn, long w) 1163 { 1164 Prog *p1; 1165 Node nod0, nod1, nod2, nod3, nod4, *l, *r; 1166 Type *t; 1167 int c; 1168 1169 if(n == Z || n->type == T) 1170 return; 1171 if(debug['g']) { 1172 prtree(nn, "sugen lhs"); 1173 prtree(n, "sugen"); 1174 } 1175 if(nn == nodrat) 1176 if(w > nrathole) 1177 nrathole = w; 1178 switch(n->op) { 1179 case OIND: 1180 if(nn == Z) { 1181 nullwarn(n->left, Z); 1182 break; 1183 } 1184 1185 default: 1186 goto copy; 1187 1188 case OCONST: 1189 if(n->type && typev[n->type->etype]) { 1190 if(nn == Z) { 1191 nullwarn(n->left, Z); 1192 break; 1193 } 1194 1195 switch(nn->op) { 1196 default: 1197 t = nn->type; 1198 nn->type = types[TLONG]; 1199 reglcgen(&nod1, nn, Z); 1200 nn->type = t; 1201 1202 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */ 1203 gmove(nodconst((long)(n->vconst>>32)), &nod1); 1204 else 1205 gmove(nodconst((long)(n->vconst)), &nod1); 1206 nod1.xoffset += SZ_LONG; 1207 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */ 1208 gmove(nodconst((long)(n->vconst)), &nod1); 1209 else 1210 gmove(nodconst((long)(n->vconst>>32)), &nod1); 1211 1212 regfree(&nod1); 1213 break; 1214 1215 case ONAME: 1216 case OINDREG: 1217 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */ 1218 gins(AMOVL, nodconst((long)(n->vconst>>32)), nn); 1219 else 1220 gins(AMOVL, nodconst((long)(n->vconst)), nn); 1221 nn->xoffset += SZ_LONG; 1222 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */ 1223 gins(AMOVL, nodconst((long)(n->vconst)), nn); 1224 else 1225 gins(AMOVL, nodconst((long)(n->vconst>>32)), nn); 1226 nn->xoffset -= SZ_LONG; 1227 break; 1228 } 1229 break; 1230 } 1231 goto copy; 1232 1233 case ODOT: 1234 l = n->left; 1235 sugen(l, nodrat, l->type->width); 1236 if(nn == Z) 1237 break; 1238 warn(n, "non-interruptable temporary"); 1239 nod1 = *nodrat; 1240 r = n->right; 1241 if(!r || r->op != OCONST) { 1242 diag(n, "DOT and no offset"); 1243 break; 1244 } 1245 nod1.xoffset += (long)r->vconst; 1246 nod1.type = n->type; 1247 sugen(&nod1, nn, w); 1248 break; 1249 1250 case OSTRUCT: 1251 /* 1252 * rewrite so lhs has no fn call 1253 */ 1254 if(nn != Z && side(nn)) { 1255 nod1 = *n; 1256 nod1.type = typ(TIND, n->type); 1257 regret(&nod2, &nod1); 1258 lcgen(nn, &nod2); 1259 regsalloc(&nod0, &nod1); 1260 cgen(&nod2, &nod0); 1261 regfree(&nod2); 1262 1263 nod1 = *n; 1264 nod1.op = OIND; 1265 nod1.left = &nod0; 1266 nod1.right = Z; 1267 nod1.complex = 1; 1268 1269 sugen(n, &nod1, w); 1270 return; 1271 } 1272 1273 r = n->left; 1274 for(t = n->type->link; t != T; t = t->down) { 1275 l = r; 1276 if(r->op == OLIST) { 1277 l = r->left; 1278 r = r->right; 1279 } 1280 if(nn == Z) { 1281 cgen(l, nn); 1282 continue; 1283 } 1284 /* 1285 * hand craft *(&nn + o) = l 1286 */ 1287 nod0 = znode; 1288 nod0.op = OAS; 1289 nod0.type = t; 1290 nod0.left = &nod1; 1291 nod0.right = nil; 1292 1293 nod1 = znode; 1294 nod1.op = OIND; 1295 nod1.type = t; 1296 nod1.left = &nod2; 1297 1298 nod2 = znode; 1299 nod2.op = OADD; 1300 nod2.type = typ(TIND, t); 1301 nod2.left = &nod3; 1302 nod2.right = &nod4; 1303 1304 nod3 = znode; 1305 nod3.op = OADDR; 1306 nod3.type = nod2.type; 1307 nod3.left = nn; 1308 1309 nod4 = znode; 1310 nod4.op = OCONST; 1311 nod4.type = nod2.type; 1312 nod4.vconst = t->offset; 1313 1314 ccom(&nod0); 1315 acom(&nod0); 1316 xcom(&nod0); 1317 nod0.addable = 0; 1318 nod0.right = l; 1319 1320 /* prtree(&nod0, "hand craft"); /* */ 1321 cgen(&nod0, Z); 1322 } 1323 break; 1324 1325 case OAS: 1326 if(nn == Z) { 1327 if(n->addable < INDEXED) 1328 sugen(n->right, n->left, w); 1329 break; 1330 } 1331 1332 sugen(n->right, nodrat, w); 1333 warn(n, "non-interruptable temporary"); 1334 sugen(nodrat, n->left, w); 1335 sugen(nodrat, nn, w); 1336 break; 1337 1338 case OFUNC: 1339 if(nn == Z) { 1340 sugen(n, nodrat, w); 1341 break; 1342 } 1343 if(nn->op != OIND) { 1344 nn = new1(OADDR, nn, Z); 1345 nn->type = types[TIND]; 1346 nn->addable = 0; 1347 } else 1348 nn = nn->left; 1349 n = new(OFUNC, n->left, new(OLIST, nn, n->right)); 1350 n->type = types[TVOID]; 1351 n->left->type = types[TVOID]; 1352 cgen(n, Z); 1353 break; 1354 1355 case OCOND: 1356 bcgen(n->left, 1); 1357 p1 = p; 1358 sugen(n->right->left, nn, w); 1359 gbranch(OGOTO); 1360 patch(p1, pc); 1361 p1 = p; 1362 sugen(n->right->right, nn, w); 1363 patch(p1, pc); 1364 break; 1365 1366 case OCOMMA: 1367 cgen(n->left, Z); 1368 sugen(n->right, nn, w); 1369 break; 1370 } 1371 return; 1372 1373 copy: 1374 if(nn == Z) 1375 return; 1376 if(n->complex >= FNX && nn->complex >= FNX) { 1377 t = nn->type; 1378 nn->type = types[TLONG]; 1379 regialloc(&nod1, nn, Z); 1380 lcgen(nn, &nod1); 1381 regsalloc(&nod2, nn); 1382 nn->type = t; 1383 1384 gins(AMOVL, &nod1, &nod2); 1385 regfree(&nod1); 1386 1387 nod2.type = typ(TIND, t); 1388 1389 nod1 = nod2; 1390 nod1.op = OIND; 1391 nod1.left = &nod2; 1392 nod1.right = Z; 1393 nod1.complex = 1; 1394 nod1.type = t; 1395 1396 sugen(n, &nod1, w); 1397 return; 1398 } 1399 1400 /* most common case of vlong variables */ 1401 if((n->op == ONAME || n->op == OINDREG) && 1402 (nn->op == ONAME || nn->op == OINDREG) && w == 8) { 1403 n->type = types[TLONG]; 1404 regalloc(&nod1, n, Z); 1405 gins(AMOVL, n, &nod1); 1406 gins(AMOVL, &nod1, nn); 1407 n->xoffset += SZ_LONG; 1408 nn->xoffset += SZ_LONG; 1409 gins(AMOVL, n, &nod1); 1410 gins(AMOVL, &nod1, nn); 1411 n->xoffset -= SZ_LONG; 1412 nn->xoffset -= SZ_LONG; 1413 regfree(&nod1); 1414 return; 1415 } 1416 1417 /* botch, need to save in .safe */ 1418 c = 0; 1419 if(n->complex > nn->complex) { 1420 t = n->type; 1421 n->type = types[TLONG]; 1422 nodreg(&nod1, n, D_SI); 1423 if(reg[D_SI]) { 1424 gins(APUSHL, &nod1, Z); 1425 c |= 1; 1426 reg[D_SI]++; 1427 } 1428 lcgen(n, &nod1); 1429 n->type = t; 1430 1431 t = nn->type; 1432 nn->type = types[TLONG]; 1433 nodreg(&nod2, nn, D_DI); 1434 if(reg[D_DI]) { 1435 gins(APUSHL, &nod2, Z); 1436 c |= 2; 1437 reg[D_DI]++; 1438 } 1439 lcgen(nn, &nod2); 1440 nn->type = t; 1441 } else { 1442 t = nn->type; 1443 nn->type = types[TLONG]; 1444 nodreg(&nod1, nn, D_DI); 1445 if(reg[D_DI]) { 1446 gins(APUSHL, &nod1, Z); 1447 c |= 1; 1448 reg[D_DI]++; 1449 } 1450 lcgen(nn, &nod1); 1451 nn->type = t; 1452 1453 t = n->type; 1454 n->type = types[TLONG]; 1455 nodreg(&nod2, n, D_SI); 1456 if(reg[D_SI]) { 1457 gins(APUSHL, &nod2, Z); 1458 c |= 2; 1459 reg[D_SI]++; 1460 } 1461 lcgen(n, &nod2); 1462 n->type = t; 1463 } 1464 nodreg(&nod3, n, D_CX); 1465 if(reg[D_CX]) { 1466 gins(APUSHL, &nod3, Z); 1467 c |= 4; 1468 reg[D_CX]++; 1469 } 1470 gins(AMOVL, nodconst(w/SZ_LONG), &nod3); 1471 gins(ACLD, Z, Z); 1472 gins(AREP, Z, Z); 1473 gins(AMOVSL, Z, Z); 1474 if(c & 4) { 1475 gins(APOPL, Z, &nod3); 1476 reg[D_CX]--; 1477 } 1478 if(c & 2) { 1479 gins(APOPL, Z, &nod2); 1480 reg[nod2.reg]--; 1481 } 1482 if(c & 1) { 1483 gins(APOPL, Z, &nod1); 1484 reg[nod1.reg]--; 1485 } 1486 } 1487