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