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