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