1 #include "gc.h" 2 3 /* ,x/^(print|prtree)\(/i/\/\/ */ 4 5 void 6 cgen(Node *n, Node *nn) 7 { 8 Node *l, *r, *t; 9 Prog *p1; 10 Node nod, nod1, nod2, nod3, nod4; 11 int o, hardleft; 12 long v, curs; 13 vlong c; 14 15 if(debug['g']) { 16 prtree(nn, "cgen lhs"); 17 prtree(n, "cgen"); 18 } 19 if(n == Z || n->type == T) 20 return; 21 if(typesuv[n->type->etype]) { 22 sugen(n, nn, n->type->width); 23 return; 24 } 25 l = n->left; 26 r = n->right; 27 o = n->op; 28 if(n->addable >= INDEXED) { 29 if(nn == Z) { 30 switch(o) { 31 default: 32 nullwarn(Z, Z); 33 break; 34 case OINDEX: 35 nullwarn(l, r); 36 break; 37 } 38 return; 39 } 40 gmove(n, nn); 41 return; 42 } 43 curs = cursafe; 44 45 if(l->complex >= FNX) 46 if(r != Z && r->complex >= FNX) 47 switch(o) { 48 default: 49 if(cond(o) && typesuv[l->type->etype]) 50 break; 51 52 regret(&nod, r); 53 cgen(r, &nod); 54 55 regsalloc(&nod1, r); 56 gmove(&nod, &nod1); 57 58 regfree(&nod); 59 nod = *n; 60 nod.right = &nod1; 61 62 cgen(&nod, nn); 63 return; 64 65 case OFUNC: 66 case OCOMMA: 67 case OANDAND: 68 case OOROR: 69 case OCOND: 70 case ODOT: 71 break; 72 } 73 74 hardleft = l->addable < INDEXED || l->complex >= FNX; 75 switch(o) { 76 default: 77 diag(n, "unknown op in cgen: %O", o); 78 break; 79 80 case ONEG: 81 case OCOM: 82 if(nn == Z) { 83 nullwarn(l, Z); 84 break; 85 } 86 regalloc(&nod, l, nn); 87 cgen(l, &nod); 88 gopcode(o, n->type, Z, &nod); 89 gmove(&nod, nn); 90 regfree(&nod); 91 break; 92 93 case OAS: 94 if(typefd[n->type->etype]) { 95 cgen(r, &fregnode0); 96 if(nn != Z) 97 gins(AFMOVD, &fregnode0, &fregnode0); 98 if(l->addable < INDEXED) { 99 reglcgen(&nod, l, Z); 100 gmove(&fregnode0, &nod); 101 regfree(&nod); 102 } else 103 gmove(&fregnode0, l); 104 if(nn != Z) 105 gmove(&fregnode0, nn); 106 return; 107 } 108 if(l->op == OBIT) 109 goto bitas; 110 if(!hardleft) { 111 if(nn != Z || r->addable < INDEXED) { 112 if(r->complex >= FNX && nn == Z) 113 regret(&nod, r); 114 else 115 regalloc(&nod, r, nn); 116 cgen(r, &nod); 117 gmove(&nod, l); 118 if(nn != Z) 119 gmove(&nod, nn); 120 regfree(&nod); 121 } else 122 gmove(r, l); 123 break; 124 } 125 if(l->complex >= r->complex) { 126 if(l->op == OINDEX && r->op == OCONST) { 127 gmove(r, l); 128 break; 129 } 130 reglcgen(&nod1, l, Z); 131 if(r->addable >= INDEXED) { 132 gmove(r, &nod1); 133 if(nn != Z) 134 gmove(r, nn); 135 regfree(&nod1); 136 break; 137 } 138 regalloc(&nod, r, nn); 139 cgen(r, &nod); 140 } else { 141 regalloc(&nod, r, nn); 142 cgen(r, &nod); 143 reglcgen(&nod1, l, Z); 144 } 145 gmove(&nod, &nod1); 146 regfree(&nod); 147 regfree(&nod1); 148 break; 149 150 bitas: 151 n = l->left; 152 regalloc(&nod, r, nn); 153 if(l->complex >= r->complex) { 154 reglcgen(&nod1, n, Z); 155 cgen(r, &nod); 156 } else { 157 cgen(r, &nod); 158 reglcgen(&nod1, n, Z); 159 } 160 regalloc(&nod2, n, Z); 161 gmove(&nod1, &nod2); 162 bitstore(l, &nod, &nod1, &nod2, nn); 163 break; 164 165 case OBIT: 166 if(nn == Z) { 167 nullwarn(l, Z); 168 break; 169 } 170 bitload(n, &nod, Z, Z, nn); 171 gmove(&nod, nn); 172 regfree(&nod); 173 break; 174 175 case OLSHR: 176 case OASHL: 177 case OASHR: 178 if(nn == Z) { 179 nullwarn(l, r); 180 break; 181 } 182 if(r->op == OCONST) { 183 if(r->vconst == 0) { 184 cgen(l, nn); 185 break; 186 } 187 regalloc(&nod, l, nn); 188 cgen(l, &nod); 189 if(o == OASHL && r->vconst == 1) 190 gopcode(OADD, n->type, &nod, &nod); 191 else 192 gopcode(o, n->type, r, &nod); 193 gmove(&nod, nn); 194 regfree(&nod); 195 break; 196 } 197 198 /* 199 * get nod to be D_CX 200 */ 201 if(nodreg(&nod, nn, D_CX)) { 202 regsalloc(&nod1, n); 203 gmove(&nod, &nod1); 204 cgen(n, &nod); /* probably a bug */ 205 gmove(&nod, nn); 206 gmove(&nod1, &nod); 207 break; 208 } 209 reg[D_CX]++; 210 if(nn->op == OREGISTER && nn->reg == D_CX) 211 regalloc(&nod1, l, Z); 212 else 213 regalloc(&nod1, l, nn); 214 if(r->complex >= l->complex) { 215 cgen(r, &nod); 216 cgen(l, &nod1); 217 } else { 218 cgen(l, &nod1); 219 cgen(r, &nod); 220 } 221 gopcode(o, n->type, &nod, &nod1); 222 gmove(&nod1, nn); 223 regfree(&nod); 224 regfree(&nod1); 225 break; 226 227 case OADD: 228 case OSUB: 229 case OOR: 230 case OXOR: 231 case OAND: 232 if(nn == Z) { 233 nullwarn(l, r); 234 break; 235 } 236 if(typefd[n->type->etype]) 237 goto fop; 238 if(r->op == OCONST) { 239 if(r->vconst == 0 && o != OAND) { 240 cgen(l, nn); 241 break; 242 } 243 } 244 if(n->op == OADD && l->op == OASHL && l->right->op == OCONST 245 && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) { 246 c = l->right->vconst; 247 if(c > 0 && c <= 3) { 248 if(l->left->complex >= r->complex) { 249 regalloc(&nod, l->left, nn); 250 cgen(l->left, &nod); 251 if(r->addable < INDEXED) { 252 regalloc(&nod1, r, Z); 253 cgen(r, &nod1); 254 genmuladd(&nod, &nod, 1 << c, &nod1); 255 regfree(&nod1); 256 } 257 else 258 genmuladd(&nod, &nod, 1 << c, r); 259 } 260 else { 261 regalloc(&nod, r, nn); 262 cgen(r, &nod); 263 regalloc(&nod1, l->left, Z); 264 cgen(l->left, &nod1); 265 genmuladd(&nod, &nod1, 1 << c, &nod); 266 regfree(&nod1); 267 } 268 gmove(&nod, nn); 269 regfree(&nod); 270 break; 271 } 272 } 273 if(r->addable >= INDEXED) { 274 regalloc(&nod, l, nn); 275 cgen(l, &nod); 276 gopcode(o, n->type, r, &nod); 277 gmove(&nod, nn); 278 regfree(&nod); 279 break; 280 } 281 if(l->complex >= r->complex) { 282 regalloc(&nod, l, nn); 283 cgen(l, &nod); 284 regalloc(&nod1, r, Z); 285 cgen(r, &nod1); 286 gopcode(o, n->type, &nod1, &nod); 287 } else { 288 regalloc(&nod1, r, nn); 289 cgen(r, &nod1); 290 regalloc(&nod, l, Z); 291 cgen(l, &nod); 292 gopcode(o, n->type, &nod1, &nod); 293 } 294 gmove(&nod, nn); 295 regfree(&nod); 296 regfree(&nod1); 297 break; 298 299 case OLMOD: 300 case OMOD: 301 case OLMUL: 302 case OLDIV: 303 case OMUL: 304 case ODIV: 305 if(nn == Z) { 306 nullwarn(l, r); 307 break; 308 } 309 if(typefd[n->type->etype]) 310 goto fop; 311 if(r->op == OCONST) { 312 SET(v); 313 switch(o) { 314 case ODIV: 315 case OMOD: 316 c = r->vconst; 317 if(c < 0) 318 c = -c; 319 v = log2(c); 320 if(v < 0) 321 break; 322 /* fall thru */ 323 case OMUL: 324 case OLMUL: 325 regalloc(&nod, l, nn); 326 cgen(l, &nod); 327 switch(o) { 328 case OMUL: 329 case OLMUL: 330 mulgen(n->type, r, &nod); 331 break; 332 case ODIV: 333 sdiv2(r->vconst, v, l, &nod); 334 break; 335 case OMOD: 336 smod2(r->vconst, v, l, &nod); 337 break; 338 } 339 gmove(&nod, nn); 340 regfree(&nod); 341 goto done; 342 case OLDIV: 343 c = r->vconst; 344 if((c & 0x80000000) == 0) 345 break; 346 regalloc(&nod1, l, Z); 347 cgen(l, &nod1); 348 regalloc(&nod, l, nn); 349 zeroregm(&nod); 350 gins(ACMPL, &nod1, nodconst(c)); 351 gins(ASBBL, nodconst(-1), &nod); 352 regfree(&nod1); 353 gmove(&nod, nn); 354 regfree(&nod); 355 goto done; 356 } 357 } 358 359 if(o == OMUL) { 360 if(l->addable >= INDEXED) { 361 t = l; 362 l = r; 363 r = t; 364 } 365 /* should favour AX */ 366 regalloc(&nod, l, nn); 367 cgen(l, &nod); 368 if(r->addable < INDEXED) { 369 regalloc(&nod1, r, Z); 370 cgen(r, &nod1); 371 gopcode(OMUL, n->type, &nod1, &nod); 372 regfree(&nod1); 373 }else 374 gopcode(OMUL, n->type, r, &nod); /* addressible */ 375 gmove(&nod, nn); 376 regfree(&nod); 377 break; 378 } 379 380 /* 381 * get nod to be D_AX 382 * get nod1 to be D_DX 383 */ 384 if(nodreg(&nod, nn, D_AX)) { 385 regsalloc(&nod2, n); 386 gmove(&nod, &nod2); 387 v = reg[D_AX]; 388 reg[D_AX] = 0; 389 390 if(isreg(l, D_AX)) { 391 nod3 = *n; 392 nod3.left = &nod2; 393 cgen(&nod3, nn); 394 } else 395 if(isreg(r, D_AX)) { 396 nod3 = *n; 397 nod3.right = &nod2; 398 cgen(&nod3, nn); 399 } else 400 cgen(n, nn); 401 402 gmove(&nod2, &nod); 403 reg[D_AX] = v; 404 break; 405 } 406 if(nodreg(&nod1, nn, D_DX)) { 407 regsalloc(&nod2, n); 408 gmove(&nod1, &nod2); 409 v = reg[D_DX]; 410 reg[D_DX] = 0; 411 412 if(isreg(l, D_DX)) { 413 nod3 = *n; 414 nod3.left = &nod2; 415 cgen(&nod3, nn); 416 } else 417 if(isreg(r, D_DX)) { 418 nod3 = *n; 419 nod3.right = &nod2; 420 cgen(&nod3, nn); 421 } else 422 cgen(n, nn); 423 424 gmove(&nod2, &nod1); 425 reg[D_DX] = v; 426 break; 427 } 428 reg[D_AX]++; 429 430 if(r->op == OCONST && (o == ODIV || o == OLDIV)) { 431 reg[D_DX]++; 432 if(l->addable < INDEXED) { 433 regalloc(&nod2, l, Z); 434 cgen(l, &nod2); 435 l = &nod2; 436 } 437 if(o == ODIV) 438 sdivgen(l, r, &nod, &nod1); 439 else 440 udivgen(l, r, &nod, &nod1); 441 gmove(&nod1, nn); 442 if(l == &nod2) 443 regfree(l); 444 goto freeaxdx; 445 } 446 447 if(l->complex >= r->complex) { 448 cgen(l, &nod); 449 reg[D_DX]++; 450 if(o == ODIV || o == OMOD) 451 gins(ACDQ, Z, Z); 452 if(o == OLDIV || o == OLMOD) 453 zeroregm(&nod1); 454 if(r->addable < INDEXED || r->op == OCONST) { 455 regsalloc(&nod3, r); 456 cgen(r, &nod3); 457 gopcode(o, n->type, &nod3, Z); 458 } else 459 gopcode(o, n->type, r, Z); 460 } else { 461 regsalloc(&nod3, r); 462 cgen(r, &nod3); 463 cgen(l, &nod); 464 reg[D_DX]++; 465 if(o == ODIV || o == OMOD) 466 gins(ACDQ, Z, Z); 467 if(o == OLDIV || o == OLMOD) 468 zeroregm(&nod1); 469 gopcode(o, n->type, &nod3, Z); 470 } 471 if(o == OMOD || o == OLMOD) 472 gmove(&nod1, nn); 473 else 474 gmove(&nod, nn); 475 freeaxdx: 476 regfree(&nod); 477 regfree(&nod1); 478 break; 479 480 case OASLSHR: 481 case OASASHL: 482 case OASASHR: 483 if(r->op == OCONST) 484 goto asand; 485 if(l->op == OBIT) 486 goto asbitop; 487 if(typefd[n->type->etype]) 488 goto asfop; 489 490 /* 491 * get nod to be D_CX 492 */ 493 if(nodreg(&nod, nn, D_CX)) { 494 regsalloc(&nod1, n); 495 gmove(&nod, &nod1); 496 cgen(n, &nod); 497 if(nn != Z) 498 gmove(&nod, nn); 499 gmove(&nod1, &nod); 500 break; 501 } 502 reg[D_CX]++; 503 504 if(r->complex >= l->complex) { 505 cgen(r, &nod); 506 if(hardleft) 507 reglcgen(&nod1, l, Z); 508 else 509 nod1 = *l; 510 } else { 511 if(hardleft) 512 reglcgen(&nod1, l, Z); 513 else 514 nod1 = *l; 515 cgen(r, &nod); 516 } 517 518 gopcode(o, l->type, &nod, &nod1); 519 regfree(&nod); 520 if(nn != Z) 521 gmove(&nod1, nn); 522 if(hardleft) 523 regfree(&nod1); 524 break; 525 526 case OASAND: 527 case OASADD: 528 case OASSUB: 529 case OASXOR: 530 case OASOR: 531 asand: 532 if(l->op == OBIT) 533 goto asbitop; 534 if(typefd[n->type->etype]||typefd[r->type->etype]) 535 goto asfop; 536 if(l->complex >= r->complex) { 537 if(hardleft) 538 reglcgen(&nod, l, Z); 539 else 540 nod = *l; 541 if(r->op != OCONST) { 542 regalloc(&nod1, r, nn); 543 cgen(r, &nod1); 544 gopcode(o, l->type, &nod1, &nod); 545 regfree(&nod1); 546 } else 547 gopcode(o, l->type, r, &nod); 548 } else { 549 regalloc(&nod1, r, nn); 550 cgen(r, &nod1); 551 if(hardleft) 552 reglcgen(&nod, l, Z); 553 else 554 nod = *l; 555 gopcode(o, l->type, &nod1, &nod); 556 regfree(&nod1); 557 } 558 if(nn != Z) 559 gmove(&nod, nn); 560 if(hardleft) 561 regfree(&nod); 562 break; 563 564 case OASLMUL: 565 case OASLDIV: 566 case OASLMOD: 567 case OASMUL: 568 case OASDIV: 569 case OASMOD: 570 if(l->op == OBIT) 571 goto asbitop; 572 if(typefd[n->type->etype]||typefd[r->type->etype]) 573 goto asfop; 574 if(r->op == OCONST) { 575 SET(v); 576 switch(o) { 577 case OASDIV: 578 case OASMOD: 579 c = r->vconst; 580 if(c < 0) 581 c = -c; 582 v = log2(c); 583 if(v < 0) 584 break; 585 /* fall thru */ 586 case OASMUL: 587 case OASLMUL: 588 if(hardleft) 589 reglcgen(&nod2, l, Z); 590 else 591 nod2 = *l; 592 regalloc(&nod, l, nn); 593 cgen(&nod2, &nod); 594 switch(o) { 595 case OASMUL: 596 case OASLMUL: 597 mulgen(n->type, r, &nod); 598 break; 599 case OASDIV: 600 sdiv2(r->vconst, v, l, &nod); 601 break; 602 case OASMOD: 603 smod2(r->vconst, v, l, &nod); 604 break; 605 } 606 havev: 607 gmove(&nod, &nod2); 608 if(nn != Z) 609 gmove(&nod, nn); 610 if(hardleft) 611 regfree(&nod2); 612 regfree(&nod); 613 goto done; 614 case OASLDIV: 615 c = r->vconst; 616 if((c & 0x80000000) == 0) 617 break; 618 if(hardleft) 619 reglcgen(&nod2, l, Z); 620 else 621 nod2 = *l; 622 regalloc(&nod1, l, nn); 623 cgen(&nod2, &nod1); 624 regalloc(&nod, l, nn); 625 zeroregm(&nod); 626 gins(ACMPL, &nod1, nodconst(c)); 627 gins(ASBBL, nodconst(-1), &nod); 628 regfree(&nod1); 629 goto havev; 630 } 631 } 632 633 if(o == OASMUL) { 634 /* should favour AX */ 635 regalloc(&nod, l, nn); 636 if(r->complex >= FNX) { 637 regalloc(&nod1, r, Z); 638 cgen(r, &nod1); 639 r = &nod1; 640 } 641 if(hardleft) 642 reglcgen(&nod2, l, Z); 643 else 644 nod2 = *l; 645 cgen(&nod2, &nod); 646 if(r->addable < INDEXED) { 647 if(r->complex < FNX) { 648 regalloc(&nod1, r, Z); 649 cgen(r, &nod1); 650 } 651 gopcode(OASMUL, n->type, &nod1, &nod); 652 regfree(&nod1); 653 } 654 else 655 gopcode(OASMUL, n->type, r, &nod); 656 if(r == &nod1) 657 regfree(r); 658 gmove(&nod, &nod2); 659 if(nn != Z) 660 gmove(&nod, nn); 661 regfree(&nod); 662 if(hardleft) 663 regfree(&nod2); 664 break; 665 } 666 667 /* 668 * get nod to be D_AX 669 * get nod1 to be D_DX 670 */ 671 if(nodreg(&nod, nn, D_AX)) { 672 regsalloc(&nod2, n); 673 gmove(&nod, &nod2); 674 v = reg[D_AX]; 675 reg[D_AX] = 0; 676 677 if(isreg(l, D_AX)) { 678 nod3 = *n; 679 nod3.left = &nod2; 680 cgen(&nod3, nn); 681 } else 682 if(isreg(r, D_AX)) { 683 nod3 = *n; 684 nod3.right = &nod2; 685 cgen(&nod3, nn); 686 } else 687 cgen(n, nn); 688 689 gmove(&nod2, &nod); 690 reg[D_AX] = v; 691 break; 692 } 693 if(nodreg(&nod1, nn, D_DX)) { 694 regsalloc(&nod2, n); 695 gmove(&nod1, &nod2); 696 v = reg[D_DX]; 697 reg[D_DX] = 0; 698 699 if(isreg(l, D_DX)) { 700 nod3 = *n; 701 nod3.left = &nod2; 702 cgen(&nod3, nn); 703 } else 704 if(isreg(r, D_DX)) { 705 nod3 = *n; 706 nod3.right = &nod2; 707 cgen(&nod3, nn); 708 } else 709 cgen(n, nn); 710 711 gmove(&nod2, &nod1); 712 reg[D_DX] = v; 713 break; 714 } 715 reg[D_AX]++; 716 reg[D_DX]++; 717 718 if(l->complex >= r->complex) { 719 if(hardleft) 720 reglcgen(&nod2, l, Z); 721 else 722 nod2 = *l; 723 cgen(&nod2, &nod); 724 if(r->op == OCONST) { 725 switch(o) { 726 case OASDIV: 727 sdivgen(&nod2, r, &nod, &nod1); 728 goto divdone; 729 case OASLDIV: 730 udivgen(&nod2, r, &nod, &nod1); 731 divdone: 732 gmove(&nod1, &nod2); 733 if(nn != Z) 734 gmove(&nod1, nn); 735 goto freelxaxdx; 736 } 737 } 738 if(o == OASDIV || o == OASMOD) 739 gins(ACDQ, Z, Z); 740 if(o == OASLDIV || o == OASLMOD) 741 zeroregm(&nod1); 742 if(r->addable < INDEXED || r->op == OCONST || 743 !typeil[r->type->etype]) { 744 regalloc(&nod3, r, Z); 745 cgen(r, &nod3); 746 gopcode(o, l->type, &nod3, Z); 747 regfree(&nod3); 748 } else 749 gopcode(o, n->type, r, Z); 750 } else { 751 regalloc(&nod3, r, Z); 752 cgen(r, &nod3); 753 if(hardleft) 754 reglcgen(&nod2, l, Z); 755 else 756 nod2 = *l; 757 cgen(&nod2, &nod); 758 if(o == OASDIV || o == OASMOD) 759 gins(ACDQ, Z, Z); 760 if(o == OASLDIV || o == OASLMOD) 761 zeroregm(&nod1); 762 gopcode(o, l->type, &nod3, Z); 763 regfree(&nod3); 764 } 765 if(o == OASMOD || o == OASLMOD) { 766 gmove(&nod1, &nod2); 767 if(nn != Z) 768 gmove(&nod1, nn); 769 } else { 770 gmove(&nod, &nod2); 771 if(nn != Z) 772 gmove(&nod, nn); 773 } 774 freelxaxdx: 775 if(hardleft) 776 regfree(&nod2); 777 regfree(&nod); 778 regfree(&nod1); 779 break; 780 781 fop: 782 if(l->complex >= r->complex) { 783 cgen(l, &fregnode0); 784 if(r->addable < INDEXED) { 785 cgen(r, &fregnode0); 786 fgopcode(o, &fregnode0, &fregnode1, 1, 0); 787 } else 788 fgopcode(o, r, &fregnode0, 0, 0); 789 } else { 790 cgen(r, &fregnode0); 791 if(l->addable < INDEXED) { 792 cgen(l, &fregnode0); 793 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 794 } else 795 fgopcode(o, l, &fregnode0, 0, 1); 796 } 797 gmove(&fregnode0, nn); 798 break; 799 800 asfop: 801 if(l->complex >= r->complex) { 802 if(hardleft) 803 reglcgen(&nod, l, Z); 804 else 805 nod = *l; 806 cgen(r, &fregnode0); 807 } else { 808 cgen(r, &fregnode0); 809 if(hardleft) 810 reglcgen(&nod, l, Z); 811 else 812 nod = *l; 813 } 814 if(!typefd[l->type->etype]) { 815 gmove(&nod, &fregnode0); 816 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 817 } else 818 fgopcode(o, &nod, &fregnode0, 0, 1); 819 if(nn != Z) 820 gins(AFMOVD, &fregnode0, &fregnode0); 821 gmove(&fregnode0, &nod); 822 if(nn != Z) 823 gmove(&fregnode0, nn); 824 if(hardleft) 825 regfree(&nod); 826 break; 827 828 asbitop: 829 regalloc(&nod4, n, nn); 830 if(l->complex >= r->complex) { 831 bitload(l, &nod, &nod1, &nod2, &nod4); 832 regalloc(&nod3, r, Z); 833 cgen(r, &nod3); 834 } else { 835 regalloc(&nod3, r, Z); 836 cgen(r, &nod3); 837 bitload(l, &nod, &nod1, &nod2, &nod4); 838 } 839 gmove(&nod, &nod4); 840 841 if(typefd[nod3.type->etype]) 842 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 843 else { 844 Node onod; 845 846 /* incredible grot ... */ 847 onod = nod3; 848 onod.op = o; 849 onod.complex = 2; 850 onod.addable = 0; 851 onod.type = tfield; 852 onod.left = &nod4; 853 onod.right = &nod3; 854 cgen(&onod, Z); 855 } 856 regfree(&nod3); 857 gmove(&nod4, &nod); 858 regfree(&nod4); 859 bitstore(l, &nod, &nod1, &nod2, nn); 860 break; 861 862 case OADDR: 863 if(nn == Z) { 864 nullwarn(l, Z); 865 break; 866 } 867 lcgen(l, nn); 868 break; 869 870 case OFUNC: 871 if(l->complex >= FNX) { 872 if(l->op != OIND) 873 diag(n, "bad function call"); 874 875 regret(&nod, l->left); 876 cgen(l->left, &nod); 877 regsalloc(&nod1, l->left); 878 gmove(&nod, &nod1); 879 regfree(&nod); 880 881 nod = *n; 882 nod.left = &nod2; 883 nod2 = *l; 884 nod2.left = &nod1; 885 nod2.complex = 1; 886 cgen(&nod, nn); 887 888 return; 889 } 890 gargs(r, &nod, &nod1); 891 if(l->addable < INDEXED) { 892 reglcgen(&nod, l, nn); 893 nod.op = OREGISTER; 894 gopcode(OFUNC, n->type, Z, &nod); 895 regfree(&nod); 896 } else 897 gopcode(OFUNC, n->type, Z, l); 898 if(REGARG && reg[REGARG]) 899 reg[REGARG]--; 900 if(nn != Z) { 901 regret(&nod, n); 902 gmove(&nod, nn); 903 regfree(&nod); 904 } else 905 if(typefd[n->type->etype]) 906 gins(AFMOVDP, &fregnode0, &fregnode0); 907 break; 908 909 case OIND: 910 if(nn == Z) { 911 nullwarn(l, Z); 912 break; 913 } 914 regialloc(&nod, n, nn); 915 r = l; 916 while(r->op == OADD) 917 r = r->right; 918 if(sconst(r)) { 919 v = r->vconst; 920 r->vconst = 0; 921 cgen(l, &nod); 922 nod.xoffset += v; 923 r->vconst = v; 924 } else 925 cgen(l, &nod); 926 regind(&nod, n); 927 gmove(&nod, nn); 928 regfree(&nod); 929 break; 930 931 case OEQ: 932 case ONE: 933 case OLE: 934 case OLT: 935 case OGE: 936 case OGT: 937 case OLO: 938 case OLS: 939 case OHI: 940 case OHS: 941 if(nn == Z) { 942 nullwarn(l, r); 943 break; 944 } 945 boolgen(n, 1, nn); 946 break; 947 948 case OANDAND: 949 case OOROR: 950 boolgen(n, 1, nn); 951 if(nn == Z) 952 patch(p, pc); 953 break; 954 955 case ONOT: 956 if(nn == Z) { 957 nullwarn(l, Z); 958 break; 959 } 960 boolgen(n, 1, nn); 961 break; 962 963 case OCOMMA: 964 cgen(l, Z); 965 cgen(r, nn); 966 break; 967 968 case OCAST: 969 if(nn == Z) { 970 nullwarn(l, Z); 971 break; 972 } 973 /* 974 * convert from types l->n->nn 975 */ 976 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) { 977 /* both null, gen l->nn */ 978 cgen(l, nn); 979 break; 980 } 981 if(typev[l->type->etype]) { 982 cgen64(n, nn); 983 break; 984 } 985 regalloc(&nod, l, nn); 986 cgen(l, &nod); 987 regalloc(&nod1, n, &nod); 988 gmove(&nod, &nod1); 989 gmove(&nod1, nn); 990 regfree(&nod1); 991 regfree(&nod); 992 break; 993 994 case ODOT: 995 sugen(l, nodrat, l->type->width); 996 if(nn == Z) 997 break; 998 warn(n, "non-interruptable temporary"); 999 nod = *nodrat; 1000 if(!r || r->op != OCONST) { 1001 diag(n, "DOT and no offset"); 1002 break; 1003 } 1004 nod.xoffset += (long)r->vconst; 1005 nod.type = n->type; 1006 cgen(&nod, nn); 1007 break; 1008 1009 case OCOND: 1010 bcgen(l, 1); 1011 p1 = p; 1012 cgen(r->left, nn); 1013 gbranch(OGOTO); 1014 patch(p1, pc); 1015 p1 = p; 1016 cgen(r->right, nn); 1017 patch(p1, pc); 1018 break; 1019 1020 case OPOSTINC: 1021 case OPOSTDEC: 1022 v = 1; 1023 if(l->type->etype == TIND) 1024 v = l->type->link->width; 1025 if(o == OPOSTDEC) 1026 v = -v; 1027 if(l->op == OBIT) 1028 goto bitinc; 1029 if(nn == Z) 1030 goto pre; 1031 1032 if(hardleft) 1033 reglcgen(&nod, l, Z); 1034 else 1035 nod = *l; 1036 1037 if(typefd[n->type->etype]) 1038 goto fltinc; 1039 gmove(&nod, nn); 1040 gopcode(OADD, n->type, nodconst(v), &nod); 1041 if(hardleft) 1042 regfree(&nod); 1043 break; 1044 1045 case OPREINC: 1046 case OPREDEC: 1047 v = 1; 1048 if(l->type->etype == TIND) 1049 v = l->type->link->width; 1050 if(o == OPREDEC) 1051 v = -v; 1052 if(l->op == OBIT) 1053 goto bitinc; 1054 1055 pre: 1056 if(hardleft) 1057 reglcgen(&nod, l, Z); 1058 else 1059 nod = *l; 1060 if(typefd[n->type->etype]) 1061 goto fltinc; 1062 gopcode(OADD, n->type, nodconst(v), &nod); 1063 if(nn != Z) 1064 gmove(&nod, nn); 1065 if(hardleft) 1066 regfree(&nod); 1067 break; 1068 1069 fltinc: 1070 gmove(&nod, &fregnode0); 1071 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) 1072 gins(AFMOVD, &fregnode0, &fregnode0); 1073 gins(AFLD1, Z, Z); 1074 if(v < 0) 1075 fgopcode(OSUB, &fregnode0, &fregnode1, 1, 0); 1076 else 1077 fgopcode(OADD, &fregnode0, &fregnode1, 1, 0); 1078 if(nn != Z && (o == OPREINC || o == OPREDEC)) 1079 gins(AFMOVD, &fregnode0, &fregnode0); 1080 gmove(&fregnode0, &nod); 1081 if(hardleft) 1082 regfree(&nod); 1083 break; 1084 1085 bitinc: 1086 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) { 1087 bitload(l, &nod, &nod1, &nod2, Z); 1088 gmove(&nod, nn); 1089 gopcode(OADD, tfield, nodconst(v), &nod); 1090 bitstore(l, &nod, &nod1, &nod2, Z); 1091 break; 1092 } 1093 bitload(l, &nod, &nod1, &nod2, nn); 1094 gopcode(OADD, tfield, nodconst(v), &nod); 1095 bitstore(l, &nod, &nod1, &nod2, nn); 1096 break; 1097 } 1098 done: 1099 cursafe = curs; 1100 } 1101 1102 void 1103 reglcgen(Node *t, Node *n, Node *nn) 1104 { 1105 Node *r; 1106 long v; 1107 1108 regialloc(t, n, nn); 1109 if(n->op == OIND) { 1110 r = n->left; 1111 while(r->op == OADD) 1112 r = r->right; 1113 if(sconst(r)) { 1114 v = r->vconst; 1115 r->vconst = 0; 1116 lcgen(n, t); 1117 t->xoffset += v; 1118 r->vconst = v; 1119 regind(t, n); 1120 return; 1121 } 1122 } 1123 lcgen(n, t); 1124 regind(t, n); 1125 } 1126 1127 void 1128 lcgen(Node *n, Node *nn) 1129 { 1130 Prog *p1; 1131 Node nod; 1132 1133 if(debug['g']) { 1134 prtree(nn, "lcgen lhs"); 1135 prtree(n, "lcgen"); 1136 } 1137 if(n == Z || n->type == T) 1138 return; 1139 if(nn == Z) { 1140 nn = &nod; 1141 regalloc(&nod, n, Z); 1142 } 1143 switch(n->op) { 1144 default: 1145 if(n->addable < INDEXED) { 1146 diag(n, "unknown op in lcgen: %O", n->op); 1147 break; 1148 } 1149 gopcode(OADDR, n->type, n, nn); 1150 break; 1151 1152 case OCOMMA: 1153 cgen(n->left, n->left); 1154 lcgen(n->right, nn); 1155 break; 1156 1157 case OIND: 1158 cgen(n->left, nn); 1159 break; 1160 1161 case OCOND: 1162 bcgen(n->left, 1); 1163 p1 = p; 1164 lcgen(n->right->left, nn); 1165 gbranch(OGOTO); 1166 patch(p1, pc); 1167 p1 = p; 1168 lcgen(n->right->right, nn); 1169 patch(p1, pc); 1170 break; 1171 } 1172 } 1173 1174 void 1175 bcgen(Node *n, int true) 1176 { 1177 1178 if(n->type == T) 1179 gbranch(OGOTO); 1180 else 1181 boolgen(n, true, Z); 1182 } 1183 1184 void 1185 boolgen(Node *n, int true, Node *nn) 1186 { 1187 int o; 1188 Prog *p1, *p2; 1189 Node *l, *r, nod, nod1; 1190 long curs; 1191 1192 if(debug['g']) { 1193 prtree(nn, "boolgen lhs"); 1194 prtree(n, "boolgen"); 1195 } 1196 curs = cursafe; 1197 l = n->left; 1198 r = n->right; 1199 switch(n->op) { 1200 1201 default: 1202 if(typev[n->type->etype]) { 1203 testv(n, true); 1204 goto com; 1205 } 1206 o = ONE; 1207 if(true) 1208 o = OEQ; 1209 if(typefd[n->type->etype]) { 1210 if(n->addable < INDEXED) { 1211 cgen(n, &fregnode0); 1212 gins(AFLDZ, Z, Z); 1213 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 1214 } else { 1215 gins(AFLDZ, Z, Z); 1216 fgopcode(o, n, &fregnode0, 0, 1); 1217 } 1218 goto com; 1219 } 1220 /* bad, 13 is address of external that becomes constant */ 1221 if(n->addable >= INDEXED && n->addable != 13) { 1222 gopcode(o, n->type, n, nodconst(0)); 1223 goto com; 1224 } 1225 regalloc(&nod, n, nn); 1226 cgen(n, &nod); 1227 gopcode(o, n->type, &nod, nodconst(0)); 1228 regfree(&nod); 1229 goto com; 1230 1231 case OCONST: 1232 o = vconst(n); 1233 if(!true) 1234 o = !o; 1235 gbranch(OGOTO); 1236 if(o) { 1237 p1 = p; 1238 gbranch(OGOTO); 1239 patch(p1, pc); 1240 } 1241 goto com; 1242 1243 case OCOMMA: 1244 cgen(l, Z); 1245 boolgen(r, true, nn); 1246 break; 1247 1248 case ONOT: 1249 boolgen(l, !true, nn); 1250 break; 1251 1252 case OCOND: 1253 bcgen(l, 1); 1254 p1 = p; 1255 bcgen(r->left, true); 1256 p2 = p; 1257 gbranch(OGOTO); 1258 patch(p1, pc); 1259 p1 = p; 1260 bcgen(r->right, !true); 1261 patch(p2, pc); 1262 p2 = p; 1263 gbranch(OGOTO); 1264 patch(p1, pc); 1265 patch(p2, pc); 1266 goto com; 1267 1268 case OANDAND: 1269 if(!true) 1270 goto caseor; 1271 1272 caseand: 1273 bcgen(l, true); 1274 p1 = p; 1275 bcgen(r, !true); 1276 p2 = p; 1277 patch(p1, pc); 1278 gbranch(OGOTO); 1279 patch(p2, pc); 1280 goto com; 1281 1282 case OOROR: 1283 if(!true) 1284 goto caseand; 1285 1286 caseor: 1287 bcgen(l, !true); 1288 p1 = p; 1289 bcgen(r, !true); 1290 p2 = p; 1291 gbranch(OGOTO); 1292 patch(p1, pc); 1293 patch(p2, pc); 1294 goto com; 1295 1296 case OEQ: 1297 case ONE: 1298 case OLE: 1299 case OLT: 1300 case OGE: 1301 case OGT: 1302 case OHI: 1303 case OHS: 1304 case OLO: 1305 case OLS: 1306 o = n->op; 1307 if(typev[l->type->etype]) { 1308 if(!true) 1309 n->op = comrel[relindex(o)]; 1310 cgen64(n, Z); 1311 goto com; 1312 } 1313 if(true) 1314 o = comrel[relindex(o)]; 1315 if(l->complex >= FNX && r->complex >= FNX) { 1316 regret(&nod, r); 1317 cgen(r, &nod); 1318 regsalloc(&nod1, r); 1319 gmove(&nod, &nod1); 1320 regfree(&nod); 1321 nod = *n; 1322 nod.right = &nod1; 1323 boolgen(&nod, true, nn); 1324 break; 1325 } 1326 if(typefd[l->type->etype]) { 1327 if(l->complex >= r->complex) { 1328 cgen(l, &fregnode0); 1329 if(r->addable < INDEXED) { 1330 cgen(r, &fregnode0); 1331 o = invrel[relindex(o)]; 1332 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 1333 } else 1334 fgopcode(o, r, &fregnode0, 0, 1); 1335 } else { 1336 o = invrel[relindex(o)]; 1337 cgen(r, &fregnode0); 1338 if(l->addable < INDEXED) { 1339 cgen(l, &fregnode0); 1340 o = invrel[relindex(o)]; 1341 fgopcode(o, &fregnode0, &fregnode1, 1, 1); 1342 } else 1343 fgopcode(o, l, &fregnode0, 0, 1); 1344 } 1345 goto com; 1346 } 1347 if(l->op == OCONST) { 1348 o = invrel[relindex(o)]; 1349 /* bad, 13 is address of external that becomes constant */ 1350 if(r->addable < INDEXED || r->addable == 13) { 1351 regalloc(&nod, r, nn); 1352 cgen(r, &nod); 1353 gopcode(o, l->type, &nod, l); 1354 regfree(&nod); 1355 } else 1356 gopcode(o, l->type, r, l); 1357 goto com; 1358 } 1359 if(l->complex >= r->complex) { 1360 regalloc(&nod, l, nn); 1361 cgen(l, &nod); 1362 if(r->addable < INDEXED) { 1363 regalloc(&nod1, r, Z); 1364 cgen(r, &nod1); 1365 gopcode(o, l->type, &nod, &nod1); 1366 regfree(&nod1); 1367 } else 1368 gopcode(o, l->type, &nod, r); 1369 regfree(&nod); 1370 goto com; 1371 } 1372 regalloc(&nod, r, nn); 1373 cgen(r, &nod); 1374 if(l->addable < INDEXED || l->addable == 13) { 1375 regalloc(&nod1, l, Z); 1376 cgen(l, &nod1); 1377 if(typechlp[l->type->etype]) 1378 gopcode(o, types[TINT], &nod1, &nod); 1379 else 1380 gopcode(o, l->type, &nod1, &nod); 1381 regfree(&nod1); 1382 } else 1383 gopcode(o, l->type, l, &nod); 1384 regfree(&nod); 1385 1386 com: 1387 if(nn != Z) { 1388 p1 = p; 1389 gmove(nodconst(1L), nn); 1390 gbranch(OGOTO); 1391 p2 = p; 1392 patch(p1, pc); 1393 gmove(nodconst(0L), nn); 1394 patch(p2, pc); 1395 } 1396 break; 1397 } 1398 cursafe = curs; 1399 } 1400 1401 void 1402 sugen(Node *n, Node *nn, long w) 1403 { 1404 Prog *p1; 1405 Node nod0, nod1, nod2, nod3, nod4, *h, *l, *r; 1406 Type *t; 1407 int c, v, x; 1408 1409 if(n == Z || n->type == T) 1410 return; 1411 if(debug['g']) { 1412 prtree(nn, "sugen lhs"); 1413 prtree(n, "sugen"); 1414 } 1415 if(nn == nodrat) 1416 if(w > nrathole) 1417 nrathole = w; 1418 switch(n->op) { 1419 case OIND: 1420 if(nn == Z) { 1421 nullwarn(n->left, Z); 1422 break; 1423 } 1424 1425 default: 1426 goto copy; 1427 1428 case OCONST: 1429 if(n->type && typev[n->type->etype]) { 1430 if(nn == Z) { 1431 nullwarn(n->left, Z); 1432 break; 1433 } 1434 1435 if(nn->op == OREGPAIR) { 1436 loadpair(n, nn); 1437 break; 1438 } 1439 else if(!vaddr(nn, 0)) { 1440 t = nn->type; 1441 nn->type = types[TLONG]; 1442 reglcgen(&nod1, nn, Z); 1443 nn->type = t; 1444 1445 gmove(lo64(n), &nod1); 1446 nod1.xoffset += SZ_LONG; 1447 gmove(hi64(n), &nod1); 1448 regfree(&nod1); 1449 } 1450 else { 1451 gins(AMOVL, lo64(n), nn); 1452 nn->xoffset += SZ_LONG; 1453 gins(AMOVL, hi64(n), nn); 1454 nn->xoffset -= SZ_LONG; 1455 break; 1456 } 1457 break; 1458 } 1459 goto copy; 1460 1461 case ODOT: 1462 l = n->left; 1463 sugen(l, nodrat, l->type->width); 1464 if(nn == Z) 1465 break; 1466 warn(n, "non-interruptable temporary"); 1467 nod1 = *nodrat; 1468 r = n->right; 1469 if(!r || r->op != OCONST) { 1470 diag(n, "DOT and no offset"); 1471 break; 1472 } 1473 nod1.xoffset += (long)r->vconst; 1474 nod1.type = n->type; 1475 sugen(&nod1, nn, w); 1476 break; 1477 1478 case OSTRUCT: 1479 /* 1480 * rewrite so lhs has no fn call 1481 */ 1482 if(nn != Z && side(nn)) { 1483 nod1 = *n; 1484 nod1.type = typ(TIND, n->type); 1485 regret(&nod2, &nod1); 1486 lcgen(nn, &nod2); 1487 regsalloc(&nod0, &nod1); 1488 cgen(&nod2, &nod0); 1489 regfree(&nod2); 1490 1491 nod1 = *n; 1492 nod1.op = OIND; 1493 nod1.left = &nod0; 1494 nod1.right = Z; 1495 nod1.complex = 1; 1496 1497 sugen(n, &nod1, w); 1498 return; 1499 } 1500 1501 r = n->left; 1502 for(t = n->type->link; t != T; t = t->down) { 1503 l = r; 1504 if(r->op == OLIST) { 1505 l = r->left; 1506 r = r->right; 1507 } 1508 if(nn == Z) { 1509 cgen(l, nn); 1510 continue; 1511 } 1512 /* 1513 * hand craft *(&nn + o) = l 1514 */ 1515 nod0 = znode; 1516 nod0.op = OAS; 1517 nod0.type = t; 1518 nod0.left = &nod1; 1519 nod0.right = nil; 1520 1521 nod1 = znode; 1522 nod1.op = OIND; 1523 nod1.type = t; 1524 nod1.left = &nod2; 1525 1526 nod2 = znode; 1527 nod2.op = OADD; 1528 nod2.type = typ(TIND, t); 1529 nod2.left = &nod3; 1530 nod2.right = &nod4; 1531 1532 nod3 = znode; 1533 nod3.op = OADDR; 1534 nod3.type = nod2.type; 1535 nod3.left = nn; 1536 1537 nod4 = znode; 1538 nod4.op = OCONST; 1539 nod4.type = nod2.type; 1540 nod4.vconst = t->offset; 1541 1542 ccom(&nod0); 1543 acom(&nod0); 1544 xcom(&nod0); 1545 nod0.addable = 0; 1546 nod0.right = l; 1547 1548 /* prtree(&nod0, "hand craft"); /* */ 1549 cgen(&nod0, Z); 1550 } 1551 break; 1552 1553 case OAS: 1554 if(nn == Z) { 1555 if(n->addable < INDEXED) 1556 sugen(n->right, n->left, w); 1557 break; 1558 } 1559 1560 sugen(n->right, nodrat, w); 1561 warn(n, "non-interruptable temporary"); 1562 sugen(nodrat, n->left, w); 1563 sugen(nodrat, nn, w); 1564 break; 1565 1566 case OFUNC: 1567 if(nn == Z) { 1568 sugen(n, nodrat, w); 1569 break; 1570 } 1571 h = nn; 1572 if(nn->op == OREGPAIR) { 1573 regsalloc(&nod1, nn); 1574 nn = &nod1; 1575 } 1576 if(nn->op != OIND) { 1577 nn = new1(OADDR, nn, Z); 1578 nn->type = types[TIND]; 1579 nn->addable = 0; 1580 } else 1581 nn = nn->left; 1582 n = new(OFUNC, n->left, new(OLIST, nn, n->right)); 1583 n->type = types[TVOID]; 1584 n->left->type = types[TVOID]; 1585 cgen(n, Z); 1586 if(h->op == OREGPAIR) 1587 loadpair(nn->left, h); 1588 break; 1589 1590 case OCOND: 1591 bcgen(n->left, 1); 1592 p1 = p; 1593 sugen(n->right->left, nn, w); 1594 gbranch(OGOTO); 1595 patch(p1, pc); 1596 p1 = p; 1597 sugen(n->right->right, nn, w); 1598 patch(p1, pc); 1599 break; 1600 1601 case OCOMMA: 1602 cgen(n->left, Z); 1603 sugen(n->right, nn, w); 1604 break; 1605 } 1606 return; 1607 1608 copy: 1609 if(nn == Z) { 1610 switch(n->op) { 1611 case OASADD: 1612 case OASSUB: 1613 case OASAND: 1614 case OASOR: 1615 case OASXOR: 1616 1617 case OASMUL: 1618 case OASLMUL: 1619 1620 1621 case OASASHL: 1622 case OASASHR: 1623 case OASLSHR: 1624 break; 1625 1626 case OPOSTINC: 1627 case OPOSTDEC: 1628 case OPREINC: 1629 case OPREDEC: 1630 break; 1631 1632 default: 1633 return; 1634 } 1635 } 1636 1637 if(n->complex >= FNX && nn != nil && nn->complex >= FNX) { 1638 t = nn->type; 1639 nn->type = types[TLONG]; 1640 regialloc(&nod1, nn, Z); 1641 lcgen(nn, &nod1); 1642 regsalloc(&nod2, nn); 1643 nn->type = t; 1644 1645 gins(AMOVL, &nod1, &nod2); 1646 regfree(&nod1); 1647 1648 nod2.type = typ(TIND, t); 1649 1650 nod1 = nod2; 1651 nod1.op = OIND; 1652 nod1.left = &nod2; 1653 nod1.right = Z; 1654 nod1.complex = 1; 1655 nod1.type = t; 1656 1657 sugen(n, &nod1, w); 1658 return; 1659 } 1660 1661 x = 0; 1662 v = w == 8; 1663 if(v) { 1664 c = cursafe; 1665 if(n->left != Z && n->left->complex >= FNX 1666 && n->right != Z && n->right->complex >= FNX) { 1667 // warn(n, "toughie"); 1668 regsalloc(&nod1, n->right); 1669 cgen(n->right, &nod1); 1670 nod2 = *n; 1671 nod2.right = &nod1; 1672 cgen(&nod2, nn); 1673 cursafe = c; 1674 return; 1675 } 1676 if(cgen64(n, nn)) { 1677 cursafe = c; 1678 return; 1679 } 1680 if(n->op == OCOM) { 1681 n = n->left; 1682 x = 1; 1683 } 1684 } 1685 1686 /* botch, need to save in .safe */ 1687 c = 0; 1688 if(n->complex > nn->complex) { 1689 t = n->type; 1690 n->type = types[TLONG]; 1691 if(v) { 1692 regalloc(&nod0, n, Z); 1693 if(!vaddr(n, 0)) { 1694 reglcgen(&nod1, n, Z); 1695 n->type = t; 1696 n = &nod1; 1697 } 1698 else 1699 n->type = t; 1700 } 1701 else { 1702 nodreg(&nod1, n, D_SI); 1703 if(reg[D_SI]) { 1704 gins(APUSHL, &nod1, Z); 1705 c |= 1; 1706 reg[D_SI]++; 1707 } 1708 lcgen(n, &nod1); 1709 n->type = t; 1710 } 1711 1712 t = nn->type; 1713 nn->type = types[TLONG]; 1714 if(v) { 1715 if(!vaddr(nn, 0)) { 1716 reglcgen(&nod2, nn, Z); 1717 nn->type = t; 1718 nn = &nod2; 1719 } 1720 else 1721 nn->type = t; 1722 } 1723 else { 1724 nodreg(&nod2, nn, D_DI); 1725 if(reg[D_DI]) { 1726 gins(APUSHL, &nod2, Z); 1727 c |= 2; 1728 reg[D_DI]++; 1729 } 1730 lcgen(nn, &nod2); 1731 nn->type = t; 1732 } 1733 } else { 1734 t = nn->type; 1735 nn->type = types[TLONG]; 1736 if(v) { 1737 regalloc(&nod0, nn, Z); 1738 if(!vaddr(nn, 0)) { 1739 reglcgen(&nod2, nn, Z); 1740 nn->type = t; 1741 nn = &nod2; 1742 } 1743 else 1744 nn->type = t; 1745 } 1746 else { 1747 nodreg(&nod2, nn, D_DI); 1748 if(reg[D_DI]) { 1749 gins(APUSHL, &nod2, Z); 1750 c |= 2; 1751 reg[D_DI]++; 1752 } 1753 lcgen(nn, &nod2); 1754 nn->type = t; 1755 } 1756 1757 t = n->type; 1758 n->type = types[TLONG]; 1759 if(v) { 1760 if(!vaddr(n, 0)) { 1761 reglcgen(&nod1, n, Z); 1762 n->type = t; 1763 n = &nod1; 1764 } 1765 else 1766 n->type = t; 1767 } 1768 else { 1769 nodreg(&nod1, n, D_SI); 1770 if(reg[D_SI]) { 1771 gins(APUSHL, &nod1, Z); 1772 c |= 1; 1773 reg[D_SI]++; 1774 } 1775 lcgen(n, &nod1); 1776 n->type = t; 1777 } 1778 } 1779 if(v) { 1780 gins(AMOVL, n, &nod0); 1781 if(x) 1782 gins(ANOTL, Z, &nod0); 1783 gins(AMOVL, &nod0, nn); 1784 n->xoffset += SZ_LONG; 1785 nn->xoffset += SZ_LONG; 1786 gins(AMOVL, n, &nod0); 1787 if(x) 1788 gins(ANOTL, Z, &nod0); 1789 gins(AMOVL, &nod0, nn); 1790 n->xoffset -= SZ_LONG; 1791 nn->xoffset -= SZ_LONG; 1792 if(nn == &nod2) 1793 regfree(&nod2); 1794 if(n == &nod1) 1795 regfree(&nod1); 1796 regfree(&nod0); 1797 return; 1798 } 1799 nodreg(&nod3, n, D_CX); 1800 if(reg[D_CX]) { 1801 gins(APUSHL, &nod3, Z); 1802 c |= 4; 1803 reg[D_CX]++; 1804 } 1805 gins(AMOVL, nodconst(w/SZ_LONG), &nod3); 1806 gins(ACLD, Z, Z); 1807 gins(AREP, Z, Z); 1808 gins(AMOVSL, Z, Z); 1809 if(c & 4) { 1810 gins(APOPL, Z, &nod3); 1811 reg[D_CX]--; 1812 } 1813 if(c & 2) { 1814 gins(APOPL, Z, &nod2); 1815 reg[nod2.reg]--; 1816 } 1817 if(c & 1) { 1818 gins(APOPL, Z, &nod1); 1819 reg[nod1.reg]--; 1820 } 1821 } 1822