1 #include "gc.h" 2 3 void 4 zeroregm(Node *n) 5 { 6 gins(AMOVL, nodconst(0), n); 7 } 8 9 /* do we need to load the address of a vlong? */ 10 int 11 vaddr(Node *n, int a) 12 { 13 switch(n->op) { 14 case ONAME: 15 if(a) 16 return 1; 17 return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC); 18 19 case OCONST: 20 case OREGISTER: 21 case OINDREG: 22 return 1; 23 } 24 return 0; 25 } 26 27 long 28 hi64v(Node *n) 29 { 30 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */ 31 return (long)(n->vconst) & ~0L; 32 else 33 return (long)((uvlong)n->vconst>>32) & ~0L; 34 } 35 36 long 37 lo64v(Node *n) 38 { 39 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */ 40 return (long)((uvlong)n->vconst>>32) & ~0L; 41 else 42 return (long)(n->vconst) & ~0L; 43 } 44 45 Node * 46 hi64(Node *n) 47 { 48 return nodconst(hi64v(n)); 49 } 50 51 Node * 52 lo64(Node *n) 53 { 54 return nodconst(lo64v(n)); 55 } 56 57 static Node * 58 anonreg(void) 59 { 60 Node *n; 61 62 n = new(OREGISTER, Z, Z); 63 n->reg = D_NONE; 64 n->type = types[TLONG]; 65 return n; 66 } 67 68 static Node * 69 regpair(Node *n, Node *t) 70 { 71 Node *r; 72 73 if(n != Z && n->op == OREGPAIR) 74 return n; 75 r = new(OREGPAIR, anonreg(), anonreg()); 76 if(n != Z) 77 r->type = n->type; 78 else 79 r->type = t->type; 80 return r; 81 } 82 83 static void 84 evacaxdx(Node *r) 85 { 86 Node nod1, nod2; 87 88 if(r->reg == D_AX || r->reg == D_DX) { 89 reg[D_AX]++; 90 reg[D_DX]++; 91 /* 92 * this is just an optim that should 93 * check for spill 94 */ 95 r->type = types[TULONG]; 96 regalloc(&nod1, r, Z); 97 nodreg(&nod2, Z, r->reg); 98 gins(AMOVL, &nod2, &nod1); 99 regfree(r); 100 r->reg = nod1.reg; 101 reg[D_AX]--; 102 reg[D_DX]--; 103 } 104 } 105 106 /* lazy instantiation of register pair */ 107 static int 108 instpair(Node *n, Node *l) 109 { 110 int r; 111 112 r = 0; 113 if(n->left->reg == D_NONE) { 114 if(l != Z) { 115 n->left->reg = l->reg; 116 r = 1; 117 } 118 else 119 regalloc(n->left, n->left, Z); 120 } 121 if(n->right->reg == D_NONE) 122 regalloc(n->right, n->right, Z); 123 return r; 124 } 125 126 static void 127 zapreg(Node *n) 128 { 129 if(n->reg != D_NONE) { 130 regfree(n); 131 n->reg = D_NONE; 132 } 133 } 134 135 static void 136 freepair(Node *n) 137 { 138 regfree(n->left); 139 regfree(n->right); 140 } 141 142 /* n is not OREGPAIR, nn is */ 143 void 144 loadpair(Node *n, Node *nn) 145 { 146 Node nod; 147 148 instpair(nn, Z); 149 if(n->op == OCONST) { 150 gins(AMOVL, lo64(n), nn->left); 151 n->xoffset += SZ_LONG; 152 gins(AMOVL, hi64(n), nn->right); 153 n->xoffset -= SZ_LONG; 154 return; 155 } 156 if(!vaddr(n, 0)) { 157 /* steal the right register for the laddr */ 158 nod = regnode; 159 nod.reg = nn->right->reg; 160 lcgen(n, &nod); 161 n = &nod; 162 regind(n, n); 163 n->xoffset = 0; 164 } 165 gins(AMOVL, n, nn->left); 166 n->xoffset += SZ_LONG; 167 gins(AMOVL, n, nn->right); 168 n->xoffset -= SZ_LONG; 169 } 170 171 /* n is OREGPAIR, nn is not */ 172 static void 173 storepair(Node *n, Node *nn, int f) 174 { 175 Node nod; 176 177 if(!vaddr(nn, 0)) { 178 reglcgen(&nod, nn, Z); 179 nn = &nod; 180 } 181 gins(AMOVL, n->left, nn); 182 nn->xoffset += SZ_LONG; 183 gins(AMOVL, n->right, nn); 184 nn->xoffset -= SZ_LONG; 185 if(nn == &nod) 186 regfree(&nod); 187 if(f) 188 freepair(n); 189 } 190 191 /* generate a cast t from n to tt */ 192 static void 193 cast(Node *n, Type *t, Node *nn) 194 { 195 Node *r; 196 197 r = new(OCAST, n, Z); 198 r->type = t; 199 sugen(r, nn, 8); 200 } 201 202 static void 203 swapregs(Node *a, Node *b) 204 { 205 int t; 206 207 t = a->reg; 208 a->reg = b->reg; 209 b->reg = t; 210 } 211 212 static void 213 swappairs(Node *a, Node *b) 214 { 215 swapregs(a->left, b->left); 216 swapregs(a->right, b->right); 217 } 218 219 static int 220 saveme(Node *n) 221 { 222 int r; 223 224 r = n->reg; 225 return r >= D_AX && r <= D_DI; 226 } 227 228 static void 229 saveit(Node *n, Node *t, Node *r) 230 { 231 Node nod; 232 233 if(saveme(n)) { 234 t->reg = n->reg; 235 gins(AMOVL, t, r); 236 r->xoffset += SZ_LONG; 237 if(n->reg == D_AX) { 238 regalloc(&nod, n, Z); 239 regfree(n); 240 n->reg = nod.reg; 241 } 242 } 243 } 244 245 static void 246 restoreit(Node *n, Node *t, Node *r) 247 { 248 if(saveme(n)) { 249 t->reg = n->reg; 250 gins(AMOVL, r, t); 251 r->xoffset += SZ_LONG; 252 } 253 } 254 255 enum 256 { 257 /* 4 only, see WW */ 258 WNONE = 0, 259 WCONST, 260 WADDR, 261 WHARD, 262 }; 263 264 static int 265 whatof(Node *n, int a) 266 { 267 if(n->op == OCONST) 268 return WCONST; 269 return !vaddr(n, a) ? WHARD : WADDR; 270 } 271 272 /* can upgrade an extern to addr for AND */ 273 static int 274 reduxv(Node *n) 275 { 276 return lo64v(n) == 0 || hi64v(n) == 0; 277 } 278 279 int 280 cond(int op) 281 { 282 switch(op) { 283 case OANDAND: 284 case OOROR: 285 case ONOT: 286 return 1; 287 288 case OEQ: 289 case ONE: 290 case OLE: 291 case OLT: 292 case OGE: 293 case OGT: 294 case OHI: 295 case OHS: 296 case OLO: 297 case OLS: 298 return 1; 299 } 300 return 0; 301 } 302 303 /* 304 * for a func operand call it and then return 305 * the safe node 306 */ 307 static Node * 308 vfunc(Node *n, Node *nn) 309 { 310 Node *t; 311 312 if(n->op != OFUNC) 313 return n; 314 t = new(0, Z, Z); 315 if(nn == Z || nn == nodret) 316 nn = n; 317 regsalloc(t, nn); 318 sugen(n, t, 8); 319 return t; 320 } 321 322 static int 323 forcereg(Node *d, int r, int o, Node *t) 324 { 325 int a; 326 327 if(d->reg != D_NONE) 328 diag(Z, "force alloc"); 329 d->reg = r; 330 a = 0; 331 if(reg[r]) { 332 reg[o]++; 333 regalloc(t, d, Z); 334 a = 1; 335 gins(AMOVL, d, t); 336 reg[o]--; 337 } 338 reg[r]++; 339 return a; 340 } 341 342 /* try to steal a reg */ 343 static int 344 getreg(Node **np, Node *t, int r) 345 { 346 Node *n, *p; 347 348 n = *np; 349 if(n->reg == r) { 350 p = new(0, Z, Z); 351 regalloc(p, n, Z); 352 gins(AMOVL, n, p); 353 *t = *n; 354 *np = p; 355 return 1; 356 } 357 return 0; 358 } 359 360 static Node * 361 snarfreg(Node *n, Node *t, int r, Node *d, Node *c) 362 { 363 if(n == Z || n->op != OREGPAIR || (!getreg(&n->left, t, r) && !getreg(&n->right, t, r))) { 364 if(nodreg(t, Z, r)) { 365 regalloc(c, d, Z); 366 gins(AMOVL, t, c); 367 reg[r]++; 368 return c; 369 } 370 reg[r]++; 371 } 372 return Z; 373 } 374 375 enum 376 { 377 Vstart = OEND, 378 379 Vgo, 380 Vamv, 381 Vmv, 382 Vzero, 383 Vop, 384 Vopx, 385 Vins, 386 Vins0, 387 Vinsl, 388 Vinsr, 389 Vinsla, 390 Vinsra, 391 Vinsx, 392 Vmul, 393 Vshll, 394 VT, 395 VF, 396 V_l_lo_f, 397 V_l_hi_f, 398 V_l_lo_t, 399 V_l_hi_t, 400 V_l_lo_u, 401 V_l_hi_u, 402 V_r_lo_f, 403 V_r_hi_f, 404 V_r_lo_t, 405 V_r_hi_t, 406 V_r_lo_u, 407 V_r_hi_u, 408 Vspazz, 409 Vend, 410 411 V_T0, 412 V_T1, 413 V_F0, 414 V_F1, 415 416 V_a0, 417 V_a1, 418 V_f0, 419 V_f1, 420 421 V_p0, 422 V_p1, 423 V_p2, 424 V_p3, 425 V_p4, 426 427 V_s0, 428 V_s1, 429 V_s2, 430 V_s3, 431 V_s4, 432 433 C00, 434 C01, 435 C31, 436 C32, 437 438 O_l_lo, 439 O_l_hi, 440 O_r_lo, 441 O_r_hi, 442 O_t_lo, 443 O_t_hi, 444 O_l, 445 O_r, 446 O_l_rp, 447 O_r_rp, 448 O_t_rp, 449 O_r0, 450 O_r1, 451 O_Zop, 452 453 O_a0, 454 O_a1, 455 456 V_C0, 457 V_C1, 458 459 V_S0, 460 V_S1, 461 462 VOPS = 5, 463 VLEN = 5, 464 VARGS = 2, 465 466 S00 = 0, 467 Sc0, 468 Sc1, 469 Sc2, 470 Sac3, 471 Sac4, 472 S10, 473 474 SAgen = 0, 475 SAclo, 476 SAc32, 477 SAchi, 478 SAdgen, 479 SAdclo, 480 SAdc32, 481 SAdchi, 482 483 B0c = 0, 484 Bca, 485 Bac, 486 487 T0i = 0, 488 Tii, 489 490 Bop0 = 0, 491 Bop1, 492 }; 493 494 /* 495 * _testv: 496 * CMPL lo,$0 497 * JNE true 498 * CMPL hi,$0 499 * JNE true 500 * GOTO false 501 * false: 502 * GOTO code 503 * true: 504 * GOTO patchme 505 * code: 506 */ 507 508 static uchar testi[][VLEN] = 509 { 510 {Vop, ONE, O_l_lo, C00}, 511 {V_s0, Vop, ONE, O_l_hi, C00}, 512 {V_s1, Vgo, V_s2, Vgo, V_s3}, 513 {VF, V_p0, V_p1, VT, V_p2}, 514 {Vgo, V_p3}, 515 {VT, V_p0, V_p1, VF, V_p2}, 516 {Vend}, 517 }; 518 519 /* shift left general case */ 520 static uchar shll00[][VLEN] = 521 { 522 {Vop, OGE, O_r, C32}, 523 {V_s0, Vinsl, ASHLL, O_r, O_l_rp}, 524 {Vins, ASHLL, O_r, O_l_lo, Vgo}, 525 {V_p0, V_s0}, 526 {Vins, ASHLL, O_r, O_l_lo}, 527 {Vins, AMOVL, O_l_lo, O_l_hi}, 528 {Vzero, O_l_lo, V_p0, Vend}, 529 }; 530 531 /* shift left rp, const < 32 */ 532 static uchar shllc0[][VLEN] = 533 { 534 {Vinsl, ASHLL, O_r, O_l_rp}, 535 {Vshll, O_r, O_l_lo, Vend}, 536 }; 537 538 /* shift left rp, const == 32 */ 539 static uchar shllc1[][VLEN] = 540 { 541 {Vins, AMOVL, O_l_lo, O_l_hi}, 542 {Vzero, O_l_lo, Vend}, 543 }; 544 545 /* shift left rp, const > 32 */ 546 static uchar shllc2[][VLEN] = 547 { 548 {Vshll, O_r, O_l_lo}, 549 {Vins, AMOVL, O_l_lo, O_l_hi}, 550 {Vzero, O_l_lo, Vend}, 551 }; 552 553 /* shift left addr, const == 32 */ 554 static uchar shllac3[][VLEN] = 555 { 556 {Vins, AMOVL, O_l_lo, O_t_hi}, 557 {Vzero, O_t_lo, Vend}, 558 }; 559 560 /* shift left addr, const > 32 */ 561 static uchar shllac4[][VLEN] = 562 { 563 {Vins, AMOVL, O_l_lo, O_t_hi}, 564 {Vshll, O_r, O_t_hi}, 565 {Vzero, O_t_lo, Vend}, 566 }; 567 568 /* shift left of constant */ 569 static uchar shll10[][VLEN] = 570 { 571 {Vop, OGE, O_r, C32}, 572 {V_s0, Vins, AMOVL, O_l_lo, O_t_lo}, 573 {Vins, AMOVL, O_l_hi, O_t_hi}, 574 {Vinsl, ASHLL, O_r, O_t_rp}, 575 {Vins, ASHLL, O_r, O_t_lo, Vgo}, 576 {V_p0, V_s0}, 577 {Vins, AMOVL, O_l_lo, O_t_hi}, 578 {V_l_lo_t, Vins, ASHLL, O_r, O_t_hi}, 579 {Vzero, O_t_lo, V_p0, Vend}, 580 }; 581 582 static uchar (*shlltab[])[VLEN] = 583 { 584 shll00, 585 shllc0, 586 shllc1, 587 shllc2, 588 shllac3, 589 shllac4, 590 shll10, 591 }; 592 593 /* shift right general case */ 594 static uchar shrl00[][VLEN] = 595 { 596 {Vop, OGE, O_r, C32}, 597 {V_s0, Vinsr, ASHRL, O_r, O_l_rp}, 598 {Vins, O_a0, O_r, O_l_hi, Vgo}, 599 {V_p0, V_s0}, 600 {Vins, O_a0, O_r, O_l_hi}, 601 {Vins, AMOVL, O_l_hi, O_l_lo}, 602 {V_T1, Vzero, O_l_hi}, 603 {V_F1, Vins, ASARL, C31, O_l_hi}, 604 {V_p0, Vend}, 605 }; 606 607 /* shift right rp, const < 32 */ 608 static uchar shrlc0[][VLEN] = 609 { 610 {Vinsr, ASHRL, O_r, O_l_rp}, 611 {Vins, O_a0, O_r, O_l_hi, Vend}, 612 }; 613 614 /* shift right rp, const == 32 */ 615 static uchar shrlc1[][VLEN] = 616 { 617 {Vins, AMOVL, O_l_hi, O_l_lo}, 618 {V_T1, Vzero, O_l_hi}, 619 {V_F1, Vins, ASARL, C31, O_l_hi}, 620 {Vend}, 621 }; 622 623 /* shift right rp, const > 32 */ 624 static uchar shrlc2[][VLEN] = 625 { 626 {Vins, O_a0, O_r, O_l_hi}, 627 {Vins, AMOVL, O_l_hi, O_l_lo}, 628 {V_T1, Vzero, O_l_hi}, 629 {V_F1, Vins, ASARL, C31, O_l_hi}, 630 {Vend}, 631 }; 632 633 /* shift right addr, const == 32 */ 634 static uchar shrlac3[][VLEN] = 635 { 636 {Vins, AMOVL, O_l_hi, O_t_lo}, 637 {V_T1, Vzero, O_t_hi}, 638 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi}, 639 {V_F1, Vins, ASARL, C31, O_t_hi}, 640 {Vend}, 641 }; 642 643 /* shift right addr, const > 32 */ 644 static uchar shrlac4[][VLEN] = 645 { 646 {Vins, AMOVL, O_l_hi, O_t_lo}, 647 {Vins, O_a0, O_r, O_t_lo}, 648 {V_T1, Vzero, O_t_hi}, 649 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi}, 650 {V_F1, Vins, ASARL, C31, O_t_hi}, 651 {Vend}, 652 }; 653 654 /* shift right of constant */ 655 static uchar shrl10[][VLEN] = 656 { 657 {Vop, OGE, O_r, C32}, 658 {V_s0, Vins, AMOVL, O_l_lo, O_t_lo}, 659 {Vins, AMOVL, O_l_hi, O_t_hi}, 660 {Vinsr, ASHRL, O_r, O_t_rp}, 661 {Vins, O_a0, O_r, O_t_hi, Vgo}, 662 {V_p0, V_s0}, 663 {Vins, AMOVL, O_l_hi, O_t_lo}, 664 {V_l_hi_t, Vins, O_a0, O_r, O_t_lo}, 665 {V_l_hi_u, V_S1}, 666 {V_T1, Vzero, O_t_hi, V_p0}, 667 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi}, 668 {V_F1, Vins, ASARL, C31, O_t_hi}, 669 {Vend}, 670 }; 671 672 static uchar (*shrltab[])[VLEN] = 673 { 674 shrl00, 675 shrlc0, 676 shrlc1, 677 shrlc2, 678 shrlac3, 679 shrlac4, 680 shrl10, 681 }; 682 683 /* shift asop left general case */ 684 static uchar asshllgen[][VLEN] = 685 { 686 {V_a0, V_a1}, 687 {Vop, OGE, O_r, C32}, 688 {V_s0, Vins, AMOVL, O_l_lo, O_r0}, 689 {Vins, AMOVL, O_l_hi, O_r1}, 690 {Vinsla, ASHLL, O_r, O_r0}, 691 {Vins, ASHLL, O_r, O_r0}, 692 {Vins, AMOVL, O_r1, O_l_hi}, 693 {Vins, AMOVL, O_r0, O_l_lo, Vgo}, 694 {V_p0, V_s0}, 695 {Vins, AMOVL, O_l_lo, O_r0}, 696 {Vzero, O_l_lo}, 697 {Vins, ASHLL, O_r, O_r0}, 698 {Vins, AMOVL, O_r0, O_l_hi, V_p0}, 699 {V_f0, V_f1, Vend}, 700 }; 701 702 /* shift asop left, const < 32 */ 703 static uchar asshllclo[][VLEN] = 704 { 705 {V_a0, V_a1}, 706 {Vins, AMOVL, O_l_lo, O_r0}, 707 {Vins, AMOVL, O_l_hi, O_r1}, 708 {Vinsla, ASHLL, O_r, O_r0}, 709 {Vshll, O_r, O_r0}, 710 {Vins, AMOVL, O_r1, O_l_hi}, 711 {Vins, AMOVL, O_r0, O_l_lo}, 712 {V_f0, V_f1, Vend}, 713 }; 714 715 /* shift asop left, const == 32 */ 716 static uchar asshllc32[][VLEN] = 717 { 718 {V_a0}, 719 {Vins, AMOVL, O_l_lo, O_r0}, 720 {Vzero, O_l_lo}, 721 {Vins, AMOVL, O_r0, O_l_hi}, 722 {V_f0, Vend}, 723 }; 724 725 /* shift asop left, const > 32 */ 726 static uchar asshllchi[][VLEN] = 727 { 728 {V_a0}, 729 {Vins, AMOVL, O_l_lo, O_r0}, 730 {Vzero, O_l_lo}, 731 {Vshll, O_r, O_r0}, 732 {Vins, AMOVL, O_r0, O_l_hi}, 733 {V_f0, Vend}, 734 }; 735 736 /* shift asop dest left general case */ 737 static uchar asdshllgen[][VLEN] = 738 { 739 {Vop, OGE, O_r, C32}, 740 {V_s0, Vins, AMOVL, O_l_lo, O_t_lo}, 741 {Vins, AMOVL, O_l_hi, O_t_hi}, 742 {Vinsl, ASHLL, O_r, O_t_rp}, 743 {Vins, ASHLL, O_r, O_t_lo}, 744 {Vins, AMOVL, O_t_hi, O_l_hi}, 745 {Vins, AMOVL, O_t_lo, O_l_lo, Vgo}, 746 {V_p0, V_s0}, 747 {Vins, AMOVL, O_l_lo, O_t_hi}, 748 {Vzero, O_l_lo}, 749 {Vins, ASHLL, O_r, O_t_hi}, 750 {Vzero, O_t_lo}, 751 {Vins, AMOVL, O_t_hi, O_l_hi, V_p0}, 752 {Vend}, 753 }; 754 755 /* shift asop dest left, const < 32 */ 756 static uchar asdshllclo[][VLEN] = 757 { 758 {Vins, AMOVL, O_l_lo, O_t_lo}, 759 {Vins, AMOVL, O_l_hi, O_t_hi}, 760 {Vinsl, ASHLL, O_r, O_t_rp}, 761 {Vshll, O_r, O_t_lo}, 762 {Vins, AMOVL, O_t_hi, O_l_hi}, 763 {Vins, AMOVL, O_t_lo, O_l_lo}, 764 {Vend}, 765 }; 766 767 /* shift asop dest left, const == 32 */ 768 static uchar asdshllc32[][VLEN] = 769 { 770 {Vins, AMOVL, O_l_lo, O_t_hi}, 771 {Vzero, O_t_lo}, 772 {Vins, AMOVL, O_t_hi, O_l_hi}, 773 {Vins, AMOVL, O_t_lo, O_l_lo}, 774 {Vend}, 775 }; 776 777 /* shift asop dest, const > 32 */ 778 static uchar asdshllchi[][VLEN] = 779 { 780 {Vins, AMOVL, O_l_lo, O_t_hi}, 781 {Vzero, O_t_lo}, 782 {Vshll, O_r, O_t_hi}, 783 {Vins, AMOVL, O_t_lo, O_l_lo}, 784 {Vins, AMOVL, O_t_hi, O_l_hi}, 785 {Vend}, 786 }; 787 788 static uchar (*asshlltab[])[VLEN] = 789 { 790 asshllgen, 791 asshllclo, 792 asshllc32, 793 asshllchi, 794 asdshllgen, 795 asdshllclo, 796 asdshllc32, 797 asdshllchi, 798 }; 799 800 /* shift asop right general case */ 801 static uchar asshrlgen[][VLEN] = 802 { 803 {V_a0, V_a1}, 804 {Vop, OGE, O_r, C32}, 805 {V_s0, Vins, AMOVL, O_l_lo, O_r0}, 806 {Vins, AMOVL, O_l_hi, O_r1}, 807 {Vinsra, ASHRL, O_r, O_r0}, 808 {Vinsx, Bop0, O_r, O_r1}, 809 {Vins, AMOVL, O_r0, O_l_lo}, 810 {Vins, AMOVL, O_r1, O_l_hi, Vgo}, 811 {V_p0, V_s0}, 812 {Vins, AMOVL, O_l_hi, O_r0}, 813 {Vinsx, Bop0, O_r, O_r0}, 814 {V_T1, Vzero, O_l_hi}, 815 {Vins, AMOVL, O_r0, O_l_lo}, 816 {V_F1, Vins, ASARL, C31, O_r0}, 817 {V_F1, Vins, AMOVL, O_r0, O_l_hi}, 818 {V_p0, V_f0, V_f1, Vend}, 819 }; 820 821 /* shift asop right, const < 32 */ 822 static uchar asshrlclo[][VLEN] = 823 { 824 {V_a0, V_a1}, 825 {Vins, AMOVL, O_l_lo, O_r0}, 826 {Vins, AMOVL, O_l_hi, O_r1}, 827 {Vinsra, ASHRL, O_r, O_r0}, 828 {Vinsx, Bop0, O_r, O_r1}, 829 {Vins, AMOVL, O_r0, O_l_lo}, 830 {Vins, AMOVL, O_r1, O_l_hi}, 831 {V_f0, V_f1, Vend}, 832 }; 833 834 /* shift asop right, const == 32 */ 835 static uchar asshrlc32[][VLEN] = 836 { 837 {V_a0}, 838 {Vins, AMOVL, O_l_hi, O_r0}, 839 {V_T1, Vzero, O_l_hi}, 840 {Vins, AMOVL, O_r0, O_l_lo}, 841 {V_F1, Vins, ASARL, C31, O_r0}, 842 {V_F1, Vins, AMOVL, O_r0, O_l_hi}, 843 {V_f0, Vend}, 844 }; 845 846 /* shift asop right, const > 32 */ 847 static uchar asshrlchi[][VLEN] = 848 { 849 {V_a0}, 850 {Vins, AMOVL, O_l_hi, O_r0}, 851 {V_T1, Vzero, O_l_hi}, 852 {Vinsx, Bop0, O_r, O_r0}, 853 {Vins, AMOVL, O_r0, O_l_lo}, 854 {V_F1, Vins, ASARL, C31, O_r0}, 855 {V_F1, Vins, AMOVL, O_r0, O_l_hi}, 856 {V_f0, Vend}, 857 }; 858 859 /* shift asop dest right general case */ 860 static uchar asdshrlgen[][VLEN] = 861 { 862 {Vop, OGE, O_r, C32}, 863 {V_s0, Vins, AMOVL, O_l_lo, O_t_lo}, 864 {Vins, AMOVL, O_l_hi, O_t_hi}, 865 {Vinsr, ASHRL, O_r, O_t_rp}, 866 {Vinsx, Bop0, O_r, O_t_hi}, 867 {Vins, AMOVL, O_t_lo, O_l_lo}, 868 {Vins, AMOVL, O_t_hi, O_l_hi, Vgo}, 869 {V_p0, V_s0}, 870 {Vins, AMOVL, O_l_hi, O_t_lo}, 871 {V_T1, Vzero, O_t_hi}, 872 {Vinsx, Bop0, O_r, O_t_lo}, 873 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi}, 874 {V_F1, Vins, ASARL, C31, O_t_hi}, 875 {Vins, AMOVL, O_t_hi, O_l_hi, V_p0}, 876 {Vend}, 877 }; 878 879 /* shift asop dest right, const < 32 */ 880 static uchar asdshrlclo[][VLEN] = 881 { 882 {Vins, AMOVL, O_l_lo, O_t_lo}, 883 {Vins, AMOVL, O_l_hi, O_t_hi}, 884 {Vinsr, ASHRL, O_r, O_t_rp}, 885 {Vinsx, Bop0, O_r, O_t_hi}, 886 {Vins, AMOVL, O_t_lo, O_l_lo}, 887 {Vins, AMOVL, O_t_hi, O_l_hi}, 888 {Vend}, 889 }; 890 891 /* shift asop dest right, const == 32 */ 892 static uchar asdshrlc32[][VLEN] = 893 { 894 {Vins, AMOVL, O_l_hi, O_t_lo}, 895 {V_T1, Vzero, O_t_hi}, 896 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi}, 897 {V_F1, Vins, ASARL, C31, O_t_hi}, 898 {Vins, AMOVL, O_t_lo, O_l_lo}, 899 {Vins, AMOVL, O_t_hi, O_l_hi}, 900 {Vend}, 901 }; 902 903 /* shift asop dest, const > 32 */ 904 static uchar asdshrlchi[][VLEN] = 905 { 906 {Vins, AMOVL, O_l_hi, O_t_lo}, 907 {V_T1, Vzero, O_t_hi}, 908 {Vinsx, Bop0, O_r, O_t_lo}, 909 {V_T1, Vins, AMOVL, O_t_hi, O_l_hi}, 910 {V_T1, Vins, AMOVL, O_t_lo, O_l_lo}, 911 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi}, 912 {V_F1, Vins, ASARL, C31, O_t_hi}, 913 {V_F1, Vins, AMOVL, O_t_lo, O_l_lo}, 914 {V_F1, Vins, AMOVL, O_t_hi, O_l_hi}, 915 {Vend}, 916 }; 917 918 static uchar (*asshrltab[])[VLEN] = 919 { 920 asshrlgen, 921 asshrlclo, 922 asshrlc32, 923 asshrlchi, 924 asdshrlgen, 925 asdshrlclo, 926 asdshrlc32, 927 asdshrlchi, 928 }; 929 930 static uchar shrlargs[] = { ASHRL, 1 }; 931 static uchar sarlargs[] = { ASARL, 0 }; 932 933 /* ++ -- */ 934 static uchar incdec[][VLEN] = 935 { 936 {Vinsx, Bop0, C01, O_l_lo}, 937 {Vinsx, Bop1, C00, O_l_hi, Vend}, 938 }; 939 940 /* ++ -- *p */ 941 static uchar incdecpre[][VLEN] = 942 { 943 {Vins, AMOVL, O_l_lo, O_t_lo}, 944 {Vins, AMOVL, O_l_hi, O_t_hi}, 945 {Vinsx, Bop0, C01, O_t_lo}, 946 {Vinsx, Bop1, C00, O_t_hi}, 947 {Vins, AMOVL, O_t_lo, O_l_lo}, 948 {Vins, AMOVL, O_t_hi, O_l_hi, Vend}, 949 }; 950 951 /* *p ++ -- */ 952 static uchar incdecpost[][VLEN] = 953 { 954 {Vins, AMOVL, O_l_lo, O_t_lo}, 955 {Vins, AMOVL, O_l_hi, O_t_hi}, 956 {Vinsx, Bop0, C01, O_l_lo}, 957 {Vinsx, Bop1, C00, O_l_hi, Vend}, 958 }; 959 960 /* binop rp, rp */ 961 static uchar binop00[][VLEN] = 962 { 963 {Vinsx, Bop0, O_r_lo, O_l_lo}, 964 {Vinsx, Bop1, O_r_hi, O_l_hi, Vend}, 965 {Vend}, 966 }; 967 968 /* binop rp, addr */ 969 static uchar binoptmp[][VLEN] = 970 { 971 {V_a0, Vins, AMOVL, O_r_lo, O_r0}, 972 {Vinsx, Bop0, O_r0, O_l_lo}, 973 {Vins, AMOVL, O_r_hi, O_r0}, 974 {Vinsx, Bop1, O_r0, O_l_hi}, 975 {V_f0, Vend}, 976 }; 977 978 /* binop t = *a op *b */ 979 static uchar binop11[][VLEN] = 980 { 981 {Vins, AMOVL, O_l_lo, O_t_lo}, 982 {Vinsx, Bop0, O_r_lo, O_t_lo}, 983 {Vins, AMOVL, O_l_hi, O_t_hi}, 984 {Vinsx, Bop1, O_r_hi, O_t_hi, Vend}, 985 }; 986 987 /* binop t = rp +- c */ 988 static uchar add0c[][VLEN] = 989 { 990 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo}, 991 {V_r_lo_f, Vamv, Bop0, Bop1}, 992 {Vinsx, Bop1, O_r_hi, O_l_hi}, 993 {Vend}, 994 }; 995 996 /* binop t = rp & c */ 997 static uchar and0c[][VLEN] = 998 { 999 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo}, 1000 {V_r_lo_f, Vins, AMOVL, C00, O_l_lo}, 1001 {V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi}, 1002 {V_r_hi_f, Vins, AMOVL, C00, O_l_hi}, 1003 {Vend}, 1004 }; 1005 1006 /* binop t = rp | c */ 1007 static uchar or0c[][VLEN] = 1008 { 1009 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo}, 1010 {V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi}, 1011 {Vend}, 1012 }; 1013 1014 /* binop t = c - rp */ 1015 static uchar sub10[][VLEN] = 1016 { 1017 {V_a0, Vins, AMOVL, O_l_lo, O_r0}, 1018 {Vinsx, Bop0, O_r_lo, O_r0}, 1019 {Vins, AMOVL, O_l_hi, O_r_lo}, 1020 {Vinsx, Bop1, O_r_hi, O_r_lo}, 1021 {Vspazz, V_f0, Vend}, 1022 }; 1023 1024 /* binop t = c + *b */ 1025 static uchar addca[][VLEN] = 1026 { 1027 {Vins, AMOVL, O_r_lo, O_t_lo}, 1028 {V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo}, 1029 {V_l_lo_f, Vamv, Bop0, Bop1}, 1030 {Vins, AMOVL, O_r_hi, O_t_hi}, 1031 {Vinsx, Bop1, O_l_hi, O_t_hi}, 1032 {Vend}, 1033 }; 1034 1035 /* binop t = c & *b */ 1036 static uchar andca[][VLEN] = 1037 { 1038 {V_l_lo_t, Vins, AMOVL, O_r_lo, O_t_lo}, 1039 {V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo}, 1040 {V_l_lo_f, Vzero, O_t_lo}, 1041 {V_l_hi_t, Vins, AMOVL, O_r_hi, O_t_hi}, 1042 {V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi}, 1043 {V_l_hi_f, Vzero, O_t_hi}, 1044 {Vend}, 1045 }; 1046 1047 /* binop t = c | *b */ 1048 static uchar orca[][VLEN] = 1049 { 1050 {Vins, AMOVL, O_r_lo, O_t_lo}, 1051 {V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo}, 1052 {Vins, AMOVL, O_r_hi, O_t_hi}, 1053 {V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi}, 1054 {Vend}, 1055 }; 1056 1057 /* binop t = c - *b */ 1058 static uchar subca[][VLEN] = 1059 { 1060 {Vins, AMOVL, O_l_lo, O_t_lo}, 1061 {Vins, AMOVL, O_l_hi, O_t_hi}, 1062 {Vinsx, Bop0, O_r_lo, O_t_lo}, 1063 {Vinsx, Bop1, O_r_hi, O_t_hi}, 1064 {Vend}, 1065 }; 1066 1067 /* binop t = *a +- c */ 1068 static uchar addac[][VLEN] = 1069 { 1070 {Vins, AMOVL, O_l_lo, O_t_lo}, 1071 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo}, 1072 {V_r_lo_f, Vamv, Bop0, Bop1}, 1073 {Vins, AMOVL, O_l_hi, O_t_hi}, 1074 {Vinsx, Bop1, O_r_hi, O_t_hi}, 1075 {Vend}, 1076 }; 1077 1078 /* binop t = *a | c */ 1079 static uchar orac[][VLEN] = 1080 { 1081 {Vins, AMOVL, O_l_lo, O_t_lo}, 1082 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo}, 1083 {Vins, AMOVL, O_l_hi, O_t_hi}, 1084 {V_r_hi_t, Vinsx, Bop1, O_r_hi, O_t_hi}, 1085 {Vend}, 1086 }; 1087 1088 /* binop t = *a & c */ 1089 static uchar andac[][VLEN] = 1090 { 1091 {V_r_lo_t, Vins, AMOVL, O_l_lo, O_t_lo}, 1092 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo}, 1093 {V_r_lo_f, Vzero, O_t_lo}, 1094 {V_r_hi_t, Vins, AMOVL, O_l_hi, O_t_hi}, 1095 {V_r_hi_t, Vinsx, Bop0, O_r_hi, O_t_hi}, 1096 {V_r_hi_f, Vzero, O_t_hi}, 1097 {Vend}, 1098 }; 1099 1100 static uchar ADDargs[] = { AADDL, AADCL }; 1101 static uchar ANDargs[] = { AANDL, AANDL }; 1102 static uchar ORargs[] = { AORL, AORL }; 1103 static uchar SUBargs[] = { ASUBL, ASBBL }; 1104 static uchar XORargs[] = { AXORL, AXORL }; 1105 1106 static uchar (*ADDtab[])[VLEN] = 1107 { 1108 add0c, addca, addac, 1109 }; 1110 1111 static uchar (*ANDtab[])[VLEN] = 1112 { 1113 and0c, andca, andac, 1114 }; 1115 1116 static uchar (*ORtab[])[VLEN] = 1117 { 1118 or0c, orca, orac, 1119 }; 1120 1121 static uchar (*SUBtab[])[VLEN] = 1122 { 1123 add0c, subca, addac, 1124 }; 1125 1126 /* mul of const32 */ 1127 static uchar mulc32[][VLEN] = 1128 { 1129 {V_a0, Vop, ONE, O_l_hi, C00}, 1130 {V_s0, Vins, AMOVL, O_r_lo, O_r0}, 1131 {Vins, AMULL, O_r0, O_Zop}, 1132 {Vgo, V_p0, V_s0}, 1133 {Vins, AMOVL, O_l_hi, O_r0}, 1134 {Vmul, O_r_lo, O_r0}, 1135 {Vins, AMOVL, O_r_lo, O_l_hi}, 1136 {Vins, AMULL, O_l_hi, O_Zop}, 1137 {Vins, AADDL, O_r0, O_l_hi}, 1138 {V_f0, V_p0, Vend}, 1139 }; 1140 1141 /* mul of const64 */ 1142 static uchar mulc64[][VLEN] = 1143 { 1144 {V_a0, Vins, AMOVL, O_r_hi, O_r0}, 1145 {Vop, OOR, O_l_hi, O_r0}, 1146 {Vop, ONE, O_r0, C00}, 1147 {V_s0, Vins, AMOVL, O_r_lo, O_r0}, 1148 {Vins, AMULL, O_r0, O_Zop}, 1149 {Vgo, V_p0, V_s0}, 1150 {Vmul, O_r_lo, O_l_hi}, 1151 {Vins, AMOVL, O_l_lo, O_r0}, 1152 {Vmul, O_r_hi, O_r0}, 1153 {Vins, AADDL, O_l_hi, O_r0}, 1154 {Vins, AMOVL, O_r_lo, O_l_hi}, 1155 {Vins, AMULL, O_l_hi, O_Zop}, 1156 {Vins, AADDL, O_r0, O_l_hi}, 1157 {V_f0, V_p0, Vend}, 1158 }; 1159 1160 /* mul general */ 1161 static uchar mull[][VLEN] = 1162 { 1163 {V_a0, Vins, AMOVL, O_r_hi, O_r0}, 1164 {Vop, OOR, O_l_hi, O_r0}, 1165 {Vop, ONE, O_r0, C00}, 1166 {V_s0, Vins, AMOVL, O_r_lo, O_r0}, 1167 {Vins, AMULL, O_r0, O_Zop}, 1168 {Vgo, V_p0, V_s0}, 1169 {Vins, AIMULL, O_r_lo, O_l_hi}, 1170 {Vins, AMOVL, O_l_lo, O_r0}, 1171 {Vins, AIMULL, O_r_hi, O_r0}, 1172 {Vins, AADDL, O_l_hi, O_r0}, 1173 {Vins, AMOVL, O_r_lo, O_l_hi}, 1174 {Vins, AMULL, O_l_hi, O_Zop}, 1175 {Vins, AADDL, O_r0, O_l_hi}, 1176 {V_f0, V_p0, Vend}, 1177 }; 1178 1179 /* cast rp l to rp t */ 1180 static uchar castrp[][VLEN] = 1181 { 1182 {Vmv, O_l, O_t_lo}, 1183 {VT, Vins, AMOVL, O_t_lo, O_t_hi}, 1184 {VT, Vins, ASARL, C31, O_t_hi}, 1185 {VF, Vzero, O_t_hi}, 1186 {Vend}, 1187 }; 1188 1189 /* cast rp l to addr t */ 1190 static uchar castrpa[][VLEN] = 1191 { 1192 {VT, V_a0, Vmv, O_l, O_r0}, 1193 {VT, Vins, AMOVL, O_r0, O_t_lo}, 1194 {VT, Vins, ASARL, C31, O_r0}, 1195 {VT, Vins, AMOVL, O_r0, O_t_hi}, 1196 {VT, V_f0}, 1197 {VF, Vmv, O_l, O_t_lo}, 1198 {VF, Vzero, O_t_hi}, 1199 {Vend}, 1200 }; 1201 1202 static uchar netab0i[][VLEN] = 1203 { 1204 {Vop, ONE, O_l_lo, O_r_lo}, 1205 {V_s0, Vop, ONE, O_l_hi, O_r_hi}, 1206 {V_s1, Vgo, V_s2, Vgo, V_s3}, 1207 {VF, V_p0, V_p1, VT, V_p2}, 1208 {Vgo, V_p3}, 1209 {VT, V_p0, V_p1, VF, V_p2}, 1210 {Vend}, 1211 }; 1212 1213 static uchar netabii[][VLEN] = 1214 { 1215 {V_a0, Vins, AMOVL, O_l_lo, O_r0}, 1216 {Vop, ONE, O_r0, O_r_lo}, 1217 {V_s0, Vins, AMOVL, O_l_hi, O_r0}, 1218 {Vop, ONE, O_r0, O_r_hi}, 1219 {V_s1, Vgo, V_s2, Vgo, V_s3}, 1220 {VF, V_p0, V_p1, VT, V_p2}, 1221 {Vgo, V_p3}, 1222 {VT, V_p0, V_p1, VF, V_p2}, 1223 {V_f0, Vend}, 1224 }; 1225 1226 static uchar cmptab0i[][VLEN] = 1227 { 1228 {Vopx, Bop0, O_l_hi, O_r_hi}, 1229 {V_s0, Vins0, AJNE}, 1230 {V_s1, Vopx, Bop1, O_l_lo, O_r_lo}, 1231 {V_s2, Vgo, V_s3, Vgo, V_s4}, 1232 {VT, V_p1, V_p3}, 1233 {VF, V_p0, V_p2}, 1234 {Vgo, V_p4}, 1235 {VT, V_p0, V_p2}, 1236 {VF, V_p1, V_p3}, 1237 {Vend}, 1238 }; 1239 1240 static uchar cmptabii[][VLEN] = 1241 { 1242 {V_a0, Vins, AMOVL, O_l_hi, O_r0}, 1243 {Vopx, Bop0, O_r0, O_r_hi}, 1244 {V_s0, Vins0, AJNE}, 1245 {V_s1, Vins, AMOVL, O_l_lo, O_r0}, 1246 {Vopx, Bop1, O_r0, O_r_lo}, 1247 {V_s2, Vgo, V_s3, Vgo, V_s4}, 1248 {VT, V_p1, V_p3}, 1249 {VF, V_p0, V_p2}, 1250 {Vgo, V_p4}, 1251 {VT, V_p0, V_p2}, 1252 {VF, V_p1, V_p3}, 1253 {V_f0, Vend}, 1254 }; 1255 1256 static uchar (*NEtab[])[VLEN] = 1257 { 1258 netab0i, netabii, 1259 }; 1260 1261 static uchar (*cmptab[])[VLEN] = 1262 { 1263 cmptab0i, cmptabii, 1264 }; 1265 1266 static uchar GEargs[] = { OGT, OHS }; 1267 static uchar GTargs[] = { OGT, OHI }; 1268 static uchar HIargs[] = { OHI, OHI }; 1269 static uchar HSargs[] = { OHI, OHS }; 1270 1271 /* Big Generator */ 1272 static void 1273 biggen(Node *l, Node *r, Node *t, int true, uchar code[][VLEN], uchar *a) 1274 { 1275 int i, j, g, oc, op, lo, ro, to, xo, *xp; 1276 Type *lt; 1277 Prog *pr[VOPS]; 1278 Node *ot, *tl, *tr, tmps[2]; 1279 uchar *c, (*cp)[VLEN], args[VARGS]; 1280 1281 if(a != nil) 1282 memmove(args, a, VARGS); 1283 //print("biggen %d %d %d\n", args[0], args[1], args[2]); 1284 //if(l) prtree(l, "l"); 1285 //if(r) prtree(r, "r"); 1286 //if(t) prtree(t, "t"); 1287 lo = ro = to = 0; 1288 cp = code; 1289 1290 for (;;) { 1291 c = *cp++; 1292 g = 1; 1293 i = 0; 1294 //print("code %d %d %d %d %d\n", c[0], c[1], c[2], c[3], c[4]); 1295 for(;;) { 1296 switch(op = c[i]) { 1297 case Vgo: 1298 if(g) 1299 gbranch(OGOTO); 1300 i++; 1301 break; 1302 1303 case Vamv: 1304 i += 3; 1305 if(i > VLEN) { 1306 diag(l, "bad Vop"); 1307 return; 1308 } 1309 if(g) 1310 args[c[i - 1]] = args[c[i - 2]]; 1311 break; 1312 1313 case Vzero: 1314 i += 2; 1315 if(i > VLEN) { 1316 diag(l, "bad Vop"); 1317 return; 1318 } 1319 j = i - 1; 1320 goto op; 1321 1322 case Vspazz: // nasty hack to save a reg in SUB 1323 //print("spazz\n"); 1324 if(g) { 1325 //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg); 1326 ot = r->right; 1327 r->right = r->left; 1328 tl = new(0, Z, Z); 1329 *tl = tmps[0]; 1330 r->left = tl; 1331 tmps[0] = *ot; 1332 //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg); 1333 } 1334 i++; 1335 break; 1336 1337 case Vmv: 1338 case Vmul: 1339 case Vshll: 1340 i += 3; 1341 if(i > VLEN) { 1342 diag(l, "bad Vop"); 1343 return; 1344 } 1345 j = i - 2; 1346 goto op; 1347 1348 case Vins0: 1349 i += 2; 1350 if(i > VLEN) { 1351 diag(l, "bad Vop"); 1352 return; 1353 } 1354 gins(c[i - 1], Z, Z); 1355 break; 1356 1357 case Vop: 1358 case Vopx: 1359 case Vins: 1360 case Vinsl: 1361 case Vinsr: 1362 case Vinsla: 1363 case Vinsra: 1364 case Vinsx: 1365 i += 4; 1366 if(i > VLEN) { 1367 diag(l, "bad Vop"); 1368 return; 1369 } 1370 j = i - 2; 1371 goto op; 1372 1373 op: 1374 if(!g) 1375 break; 1376 tl = Z; 1377 tr = Z; 1378 for(; j < i; j++) { 1379 switch(c[j]) { 1380 case C00: 1381 ot = nodconst(0); 1382 break; 1383 case C01: 1384 ot = nodconst(1); 1385 break; 1386 case C31: 1387 ot = nodconst(31); 1388 break; 1389 case C32: 1390 ot = nodconst(32); 1391 break; 1392 1393 case O_l: 1394 case O_l_lo: 1395 ot = l; xp = &lo; xo = 0; 1396 goto op0; 1397 case O_l_hi: 1398 ot = l; xp = &lo; xo = SZ_LONG; 1399 goto op0; 1400 case O_r: 1401 case O_r_lo: 1402 ot = r; xp = &ro; xo = 0; 1403 goto op0; 1404 case O_r_hi: 1405 ot = r; xp = &ro; xo = SZ_LONG; 1406 goto op0; 1407 case O_t_lo: 1408 ot = t; xp = &to; xo = 0; 1409 goto op0; 1410 case O_t_hi: 1411 ot = t; xp = &to; xo = SZ_LONG; 1412 goto op0; 1413 case O_l_rp: 1414 ot = l; 1415 break; 1416 case O_r_rp: 1417 ot = r; 1418 break; 1419 case O_t_rp: 1420 ot = t; 1421 break; 1422 case O_r0: 1423 case O_r1: 1424 ot = &tmps[c[j] - O_r0]; 1425 break; 1426 case O_Zop: 1427 ot = Z; 1428 break; 1429 1430 op0: 1431 switch(ot->op) { 1432 case OCONST: 1433 if(xo) 1434 ot = hi64(ot); 1435 else 1436 ot = lo64(ot); 1437 break; 1438 case OREGPAIR: 1439 if(xo) 1440 ot = ot->right; 1441 else 1442 ot = ot->left; 1443 break; 1444 case OREGISTER: 1445 break; 1446 default: 1447 if(xo != *xp) { 1448 ot->xoffset += xo - *xp; 1449 *xp = xo; 1450 } 1451 } 1452 break; 1453 1454 default: 1455 diag(l, "bad V_lop"); 1456 return; 1457 } 1458 if(tl == nil) 1459 tl = ot; 1460 else 1461 tr = ot; 1462 } 1463 if(op == Vzero) { 1464 zeroregm(tl); 1465 break; 1466 } 1467 oc = c[i - 3]; 1468 if(op == Vinsx || op == Vopx) { 1469 //print("%d -> %d\n", oc, args[oc]); 1470 oc = args[oc]; 1471 } 1472 else { 1473 switch(oc) { 1474 case O_a0: 1475 case O_a1: 1476 oc = args[oc - O_a0]; 1477 break; 1478 } 1479 } 1480 switch(op) { 1481 case Vmul: 1482 mulgen(tr->type, tl, tr); 1483 break; 1484 case Vmv: 1485 gmove(tl, tr); 1486 break; 1487 case Vshll: 1488 shiftit(tr->type, tl, tr); 1489 break; 1490 case Vop: 1491 case Vopx: 1492 gopcode(oc, types[TULONG], tl, tr); 1493 break; 1494 case Vins: 1495 case Vinsx: 1496 gins(oc, tl, tr); 1497 break; 1498 case Vinsl: 1499 gins(oc, tl, tr->right); 1500 p->from.index = tr->left->reg; 1501 break; 1502 case Vinsr: 1503 gins(oc, tl, tr->left); 1504 p->from.index = tr->right->reg; 1505 break; 1506 case Vinsla: 1507 gins(oc, tl, tr + 1); 1508 p->from.index = tr->reg; 1509 break; 1510 case Vinsra: 1511 gins(oc, tl, tr); 1512 p->from.index = (tr + 1)->reg; 1513 break; 1514 } 1515 break; 1516 1517 case VT: 1518 g = true; 1519 i++; 1520 break; 1521 case VF: 1522 g = !true; 1523 i++; 1524 break; 1525 1526 case V_T0: case V_T1: 1527 g = args[op - V_T0]; 1528 i++; 1529 break; 1530 1531 case V_F0: case V_F1: 1532 g = !args[op - V_F0]; 1533 i++; 1534 break; 1535 1536 case V_C0: case V_C1: 1537 if(g) 1538 args[op - V_C0] = 0; 1539 i++; 1540 break; 1541 1542 case V_S0: case V_S1: 1543 if(g) 1544 args[op - V_S0] = 1; 1545 i++; 1546 break; 1547 1548 case V_l_lo_f: 1549 g = lo64v(l) == 0; 1550 i++; 1551 break; 1552 case V_l_hi_f: 1553 g = hi64v(l) == 0; 1554 i++; 1555 break; 1556 case V_l_lo_t: 1557 g = lo64v(l) != 0; 1558 i++; 1559 break; 1560 case V_l_hi_t: 1561 g = hi64v(l) != 0; 1562 i++; 1563 break; 1564 case V_l_lo_u: 1565 g = lo64v(l) >= 0; 1566 i++; 1567 break; 1568 case V_l_hi_u: 1569 g = hi64v(l) >= 0; 1570 i++; 1571 break; 1572 case V_r_lo_f: 1573 g = lo64v(r) == 0; 1574 i++; 1575 break; 1576 case V_r_hi_f: 1577 g = hi64v(r) == 0; 1578 i++; 1579 break; 1580 case V_r_lo_t: 1581 g = lo64v(r) != 0; 1582 i++; 1583 break; 1584 case V_r_hi_t: 1585 g = hi64v(r) != 0; 1586 i++; 1587 break; 1588 case V_r_lo_u: 1589 g = lo64v(r) >= 0; 1590 i++; 1591 break; 1592 case V_r_hi_u: 1593 g = hi64v(r) >= 0; 1594 i++; 1595 break; 1596 1597 case Vend: 1598 goto out; 1599 1600 case V_a0: case V_a1: 1601 if(g) { 1602 lt = l->type; 1603 l->type = types[TULONG]; 1604 regalloc(&tmps[op - V_a0], l, Z); 1605 l->type = lt; 1606 } 1607 i++; 1608 break; 1609 1610 case V_f0: case V_f1: 1611 if(g) 1612 regfree(&tmps[op - V_f0]); 1613 i++; 1614 break; 1615 1616 case V_p0: case V_p1: case V_p2: case V_p3: case V_p4: 1617 if(g) 1618 patch(pr[op - V_p0], pc); 1619 i++; 1620 break; 1621 1622 case V_s0: case V_s1: case V_s2: case V_s3: case V_s4: 1623 if(g) 1624 pr[op - V_s0] = p; 1625 i++; 1626 break; 1627 1628 default: 1629 diag(l, "bad biggen: %d", op); 1630 return; 1631 } 1632 if(i == VLEN || c[i] == 0) 1633 break; 1634 } 1635 } 1636 out: 1637 if(lo) 1638 l->xoffset -= lo; 1639 if(ro) 1640 r->xoffset -= ro; 1641 if(to) 1642 t->xoffset -= to; 1643 } 1644 1645 int 1646 cgen64(Node *n, Node *nn) 1647 { 1648 Type *dt; 1649 uchar *args, (*cp)[VLEN], (**optab)[VLEN]; 1650 int li, ri, lri, dr, si, m, op, sh, cmp, true; 1651 Node *c, *d, *l, *r, *t, *s, nod1, nod2, nod3, nod4, nod5; 1652 1653 if(debug['g']) { 1654 prtree(nn, "cgen64 lhs"); 1655 prtree(n, "cgen64"); 1656 print("AX = %d\n", reg[D_AX]); 1657 } 1658 cmp = 0; 1659 sh = 0; 1660 1661 switch(n->op) { 1662 case ONEG: 1663 d = regpair(nn, n); 1664 sugen(n->left, d, 8); 1665 gins(ANOTL, Z, d->right); 1666 gins(ANEGL, Z, d->left); 1667 gins(ASBBL, nodconst(-1), d->right); 1668 break; 1669 1670 case OCOM: 1671 if(!vaddr(n->left, 0) || !vaddr(nn, 0)) 1672 d = regpair(nn, n); 1673 else 1674 return 0; 1675 sugen(n->left, d, 8); 1676 gins(ANOTL, Z, d->left); 1677 gins(ANOTL, Z, d->right); 1678 break; 1679 1680 case OADD: 1681 optab = ADDtab; 1682 args = ADDargs; 1683 goto twoop; 1684 case OAND: 1685 optab = ANDtab; 1686 args = ANDargs; 1687 goto twoop; 1688 case OOR: 1689 optab = ORtab; 1690 args = ORargs; 1691 goto twoop; 1692 case OSUB: 1693 optab = SUBtab; 1694 args = SUBargs; 1695 goto twoop; 1696 case OXOR: 1697 optab = ORtab; 1698 args = XORargs; 1699 goto twoop; 1700 case OASHL: 1701 sh = 1; 1702 args = nil; 1703 optab = shlltab; 1704 goto twoop; 1705 case OLSHR: 1706 sh = 1; 1707 args = shrlargs; 1708 optab = shrltab; 1709 goto twoop; 1710 case OASHR: 1711 sh = 1; 1712 args = sarlargs; 1713 optab = shrltab; 1714 goto twoop; 1715 case OEQ: 1716 cmp = 1; 1717 args = nil; 1718 optab = nil; 1719 goto twoop; 1720 case ONE: 1721 cmp = 1; 1722 args = nil; 1723 optab = nil; 1724 goto twoop; 1725 case OLE: 1726 cmp = 1; 1727 args = nil; 1728 optab = nil; 1729 goto twoop; 1730 case OLT: 1731 cmp = 1; 1732 args = nil; 1733 optab = nil; 1734 goto twoop; 1735 case OGE: 1736 cmp = 1; 1737 args = nil; 1738 optab = nil; 1739 goto twoop; 1740 case OGT: 1741 cmp = 1; 1742 args = nil; 1743 optab = nil; 1744 goto twoop; 1745 case OHI: 1746 cmp = 1; 1747 args = nil; 1748 optab = nil; 1749 goto twoop; 1750 case OHS: 1751 cmp = 1; 1752 args = nil; 1753 optab = nil; 1754 goto twoop; 1755 case OLO: 1756 cmp = 1; 1757 args = nil; 1758 optab = nil; 1759 goto twoop; 1760 case OLS: 1761 cmp = 1; 1762 args = nil; 1763 optab = nil; 1764 goto twoop; 1765 1766 twoop: 1767 dr = nn != Z && nn->op == OREGPAIR; 1768 l = vfunc(n->left, nn); 1769 if(sh) 1770 r = n->right; 1771 else 1772 r = vfunc(n->right, nn); 1773 1774 li = l->op == ONAME || l->op == OINDREG || l->op == OCONST; 1775 ri = r->op == ONAME || r->op == OINDREG || r->op == OCONST; 1776 1777 #define IMM(l, r) ((l) | ((r) << 1)) 1778 1779 lri = IMM(li, ri); 1780 1781 /* find out what is so easy about some operands */ 1782 if(li) 1783 li = whatof(l, sh | cmp); 1784 if(ri) 1785 ri = whatof(r, cmp); 1786 1787 if(sh) 1788 goto shift; 1789 1790 if(cmp) 1791 goto cmp; 1792 1793 /* evaluate hard subexps, stealing nn if possible. */ 1794 switch(lri) { 1795 case IMM(0, 0): 1796 bin00: 1797 if(l->complex > r->complex) { 1798 if(dr) 1799 t = nn; 1800 else 1801 t = regpair(Z, n); 1802 sugen(l, t, 8); 1803 l = t; 1804 t = regpair(Z, n); 1805 sugen(r, t, 8); 1806 r = t; 1807 } 1808 else { 1809 t = regpair(Z, n); 1810 sugen(r, t, 8); 1811 r = t; 1812 if(dr) 1813 t = nn; 1814 else 1815 t = regpair(Z, n); 1816 sugen(l, t, 8); 1817 l = t; 1818 } 1819 break; 1820 case IMM(0, 1): 1821 if(dr) 1822 t = nn; 1823 else 1824 t = regpair(Z, n); 1825 sugen(l, t, 8); 1826 l = t; 1827 break; 1828 case IMM(1, 0): 1829 if(n->op == OSUB && l->op == OCONST && hi64v(l) == 0) { 1830 lri = IMM(0, 0); 1831 goto bin00; 1832 } 1833 if(dr) 1834 t = nn; 1835 else 1836 t = regpair(Z, n); 1837 sugen(r, t, 8); 1838 r = t; 1839 break; 1840 case IMM(1, 1): 1841 break; 1842 } 1843 1844 #define WW(l, r) ((l) | ((r) << 2)) 1845 d = Z; 1846 dt = nn->type; 1847 nn->type = types[TLONG]; 1848 1849 switch(lri) { 1850 case IMM(0, 0): 1851 biggen(l, r, Z, 0, binop00, args); 1852 break; 1853 case IMM(0, 1): 1854 switch(ri) { 1855 case WNONE: 1856 diag(r, "bad whatof\n"); 1857 break; 1858 case WCONST: 1859 biggen(l, r, Z, 0, optab[B0c], args); 1860 break; 1861 case WHARD: 1862 reglcgen(&nod2, r, Z); 1863 r = &nod2; 1864 /* fall thru */ 1865 case WADDR: 1866 biggen(l, r, Z, 0, binoptmp, args); 1867 if(ri == WHARD) 1868 regfree(r); 1869 break; 1870 } 1871 break; 1872 case IMM(1, 0): 1873 if(n->op == OSUB) { 1874 switch(li) { 1875 case WNONE: 1876 diag(l, "bad whatof\n"); 1877 break; 1878 case WHARD: 1879 reglcgen(&nod2, l, Z); 1880 l = &nod2; 1881 /* fall thru */ 1882 case WADDR: 1883 case WCONST: 1884 biggen(l, r, Z, 0, sub10, args); 1885 break; 1886 } 1887 if(li == WHARD) 1888 regfree(l); 1889 } 1890 else { 1891 switch(li) { 1892 case WNONE: 1893 diag(l, "bad whatof\n"); 1894 break; 1895 case WCONST: 1896 biggen(r, l, Z, 0, optab[B0c], args); 1897 break; 1898 case WHARD: 1899 reglcgen(&nod2, l, Z); 1900 l = &nod2; 1901 /* fall thru */ 1902 case WADDR: 1903 biggen(r, l, Z, 0, binoptmp, args); 1904 if(li == WHARD) 1905 regfree(l); 1906 break; 1907 } 1908 } 1909 break; 1910 case IMM(1, 1): 1911 switch(WW(li, ri)) { 1912 case WW(WCONST, WHARD): 1913 if(r->op == ONAME && n->op == OAND && reduxv(l)) 1914 ri = WADDR; 1915 break; 1916 case WW(WHARD, WCONST): 1917 if(l->op == ONAME && n->op == OAND && reduxv(r)) 1918 li = WADDR; 1919 break; 1920 } 1921 if(li == WHARD) { 1922 reglcgen(&nod3, l, Z); 1923 l = &nod3; 1924 } 1925 if(ri == WHARD) { 1926 reglcgen(&nod2, r, Z); 1927 r = &nod2; 1928 } 1929 d = regpair(nn, n); 1930 instpair(d, Z); 1931 switch(WW(li, ri)) { 1932 case WW(WCONST, WADDR): 1933 case WW(WCONST, WHARD): 1934 biggen(l, r, d, 0, optab[Bca], args); 1935 break; 1936 1937 case WW(WADDR, WCONST): 1938 case WW(WHARD, WCONST): 1939 biggen(l, r, d, 0, optab[Bac], args); 1940 break; 1941 1942 case WW(WADDR, WADDR): 1943 case WW(WADDR, WHARD): 1944 case WW(WHARD, WADDR): 1945 case WW(WHARD, WHARD): 1946 biggen(l, r, d, 0, binop11, args); 1947 break; 1948 1949 default: 1950 diag(r, "bad whatof pair %d %d\n", li, ri); 1951 break; 1952 } 1953 if(li == WHARD) 1954 regfree(l); 1955 if(ri == WHARD) 1956 regfree(r); 1957 break; 1958 } 1959 1960 nn->type = dt; 1961 1962 if(d != Z) 1963 goto finished; 1964 1965 switch(lri) { 1966 case IMM(0, 0): 1967 freepair(r); 1968 /* fall thru */; 1969 case IMM(0, 1): 1970 if(!dr) 1971 storepair(l, nn, 1); 1972 break; 1973 case IMM(1, 0): 1974 if(!dr) 1975 storepair(r, nn, 1); 1976 break; 1977 case IMM(1, 1): 1978 break; 1979 } 1980 return 1; 1981 1982 shift: 1983 c = Z; 1984 1985 /* evaluate hard subexps, stealing nn if possible. */ 1986 /* must also secure CX. not as many optims as binop. */ 1987 switch(lri) { 1988 case IMM(0, 0): 1989 imm00: 1990 if(l->complex + 1 > r->complex) { 1991 if(dr) 1992 t = nn; 1993 else 1994 t = regpair(Z, l); 1995 sugen(l, t, 8); 1996 l = t; 1997 t = &nod1; 1998 c = snarfreg(l, t, D_CX, r, &nod2); 1999 cgen(r, t); 2000 r = t; 2001 } 2002 else { 2003 t = &nod1; 2004 c = snarfreg(nn, t, D_CX, r, &nod2); 2005 cgen(r, t); 2006 r = t; 2007 if(dr) 2008 t = nn; 2009 else 2010 t = regpair(Z, l); 2011 sugen(l, t, 8); 2012 l = t; 2013 } 2014 break; 2015 case IMM(0, 1): 2016 imm01: 2017 if(ri != WCONST) { 2018 lri = IMM(0, 0); 2019 goto imm00; 2020 } 2021 if(dr) 2022 t = nn; 2023 else 2024 t = regpair(Z, n); 2025 sugen(l, t, 8); 2026 l = t; 2027 break; 2028 case IMM(1, 0): 2029 imm10: 2030 if(li != WCONST) { 2031 lri = IMM(0, 0); 2032 goto imm00; 2033 } 2034 t = &nod1; 2035 c = snarfreg(nn, t, D_CX, r, &nod2); 2036 cgen(r, t); 2037 r = t; 2038 break; 2039 case IMM(1, 1): 2040 if(ri != WCONST) { 2041 lri = IMM(1, 0); 2042 goto imm10; 2043 } 2044 if(li == WHARD) { 2045 lri = IMM(0, 1); 2046 goto imm01; 2047 } 2048 break; 2049 } 2050 2051 d = Z; 2052 2053 switch(lri) { 2054 case IMM(0, 0): 2055 biggen(l, r, Z, 0, optab[S00], args); 2056 break; 2057 case IMM(0, 1): 2058 switch(ri) { 2059 case WNONE: 2060 case WADDR: 2061 case WHARD: 2062 diag(r, "bad whatof\n"); 2063 break; 2064 case WCONST: 2065 m = r->vconst & 63; 2066 s = nodconst(m); 2067 if(m < 32) 2068 cp = optab[Sc0]; 2069 else if(m == 32) 2070 cp = optab[Sc1]; 2071 else 2072 cp = optab[Sc2]; 2073 biggen(l, s, Z, 0, cp, args); 2074 break; 2075 } 2076 break; 2077 case IMM(1, 0): 2078 /* left is const */ 2079 d = regpair(nn, n); 2080 instpair(d, Z); 2081 biggen(l, r, d, 0, optab[S10], args); 2082 regfree(r); 2083 break; 2084 case IMM(1, 1): 2085 d = regpair(nn, n); 2086 instpair(d, Z); 2087 switch(WW(li, ri)) { 2088 case WW(WADDR, WCONST): 2089 m = r->vconst & 63; 2090 s = nodconst(m); 2091 if(m < 32) { 2092 loadpair(l, d); 2093 l = d; 2094 cp = optab[Sc0]; 2095 } 2096 else if(m == 32) 2097 cp = optab[Sac3]; 2098 else 2099 cp = optab[Sac4]; 2100 biggen(l, s, d, 0, cp, args); 2101 break; 2102 2103 default: 2104 diag(r, "bad whatof pair %d %d\n", li, ri); 2105 break; 2106 } 2107 break; 2108 } 2109 2110 if(c != Z) { 2111 gins(AMOVL, c, r); 2112 regfree(c); 2113 } 2114 2115 if(d != Z) 2116 goto finished; 2117 2118 switch(lri) { 2119 case IMM(0, 0): 2120 regfree(r); 2121 /* fall thru */ 2122 case IMM(0, 1): 2123 if(!dr) 2124 storepair(l, nn, 1); 2125 break; 2126 case IMM(1, 0): 2127 regfree(r); 2128 break; 2129 case IMM(1, 1): 2130 break; 2131 } 2132 return 1; 2133 2134 cmp: 2135 op = n->op; 2136 /* evaluate hard subexps */ 2137 switch(lri) { 2138 case IMM(0, 0): 2139 if(l->complex > r->complex) { 2140 t = regpair(Z, l); 2141 sugen(l, t, 8); 2142 l = t; 2143 t = regpair(Z, r); 2144 sugen(r, t, 8); 2145 r = t; 2146 } 2147 else { 2148 t = regpair(Z, r); 2149 sugen(r, t, 8); 2150 r = t; 2151 t = regpair(Z, l); 2152 sugen(l, t, 8); 2153 l = t; 2154 } 2155 break; 2156 case IMM(1, 0): 2157 t = r; 2158 r = l; 2159 l = t; 2160 ri = li; 2161 op = invrel[relindex(op)]; 2162 /* fall thru */ 2163 case IMM(0, 1): 2164 t = regpair(Z, l); 2165 sugen(l, t, 8); 2166 l = t; 2167 break; 2168 case IMM(1, 1): 2169 break; 2170 } 2171 2172 true = 1; 2173 optab = cmptab; 2174 switch(op) { 2175 case OEQ: 2176 optab = NEtab; 2177 true = 0; 2178 break; 2179 case ONE: 2180 optab = NEtab; 2181 break; 2182 case OLE: 2183 args = GTargs; 2184 true = 0; 2185 break; 2186 case OGT: 2187 args = GTargs; 2188 break; 2189 case OLS: 2190 args = HIargs; 2191 true = 0; 2192 break; 2193 case OHI: 2194 args = HIargs; 2195 break; 2196 case OLT: 2197 args = GEargs; 2198 true = 0; 2199 break; 2200 case OGE: 2201 args = GEargs; 2202 break; 2203 case OLO: 2204 args = HSargs; 2205 true = 0; 2206 break; 2207 case OHS: 2208 args = HSargs; 2209 break; 2210 default: 2211 diag(n, "bad cmp\n"); 2212 SET(optab); 2213 } 2214 2215 switch(lri) { 2216 case IMM(0, 0): 2217 biggen(l, r, Z, true, optab[T0i], args); 2218 break; 2219 case IMM(0, 1): 2220 case IMM(1, 0): 2221 switch(ri) { 2222 case WNONE: 2223 diag(l, "bad whatof\n"); 2224 break; 2225 case WCONST: 2226 biggen(l, r, Z, true, optab[T0i], args); 2227 break; 2228 case WHARD: 2229 reglcgen(&nod2, r, Z); 2230 r = &nod2; 2231 /* fall thru */ 2232 case WADDR: 2233 biggen(l, r, Z, true, optab[T0i], args); 2234 if(ri == WHARD) 2235 regfree(r); 2236 break; 2237 } 2238 break; 2239 case IMM(1, 1): 2240 if(li == WHARD) { 2241 reglcgen(&nod3, l, Z); 2242 l = &nod3; 2243 } 2244 if(ri == WHARD) { 2245 reglcgen(&nod2, r, Z); 2246 r = &nod2; 2247 } 2248 biggen(l, r, Z, true, optab[Tii], args); 2249 if(li == WHARD) 2250 regfree(l); 2251 if(ri == WHARD) 2252 regfree(r); 2253 break; 2254 } 2255 2256 switch(lri) { 2257 case IMM(0, 0): 2258 freepair(r); 2259 /* fall thru */; 2260 case IMM(0, 1): 2261 case IMM(1, 0): 2262 freepair(l); 2263 break; 2264 case IMM(1, 1): 2265 break; 2266 } 2267 return 1; 2268 2269 case OASMUL: 2270 case OASLMUL: 2271 m = 0; 2272 goto mulop; 2273 2274 case OMUL: 2275 case OLMUL: 2276 m = 1; 2277 goto mulop; 2278 2279 mulop: 2280 dr = nn != Z && nn->op == OREGPAIR; 2281 l = vfunc(n->left, nn); 2282 r = vfunc(n->right, nn); 2283 if(r->op != OCONST) { 2284 if(l->complex > r->complex) { 2285 if(m) { 2286 t = l; 2287 l = r; 2288 r = t; 2289 } 2290 else if(!vaddr(l, 1)) { 2291 reglcgen(&nod5, l, Z); 2292 l = &nod5; 2293 evacaxdx(l); 2294 } 2295 } 2296 t = regpair(Z, n); 2297 sugen(r, t, 8); 2298 r = t; 2299 evacaxdx(r->left); 2300 evacaxdx(r->right); 2301 if(l->complex <= r->complex && !m && !vaddr(l, 1)) { 2302 reglcgen(&nod5, l, Z); 2303 l = &nod5; 2304 evacaxdx(l); 2305 } 2306 } 2307 if(dr) 2308 t = nn; 2309 else 2310 t = regpair(Z, n); 2311 c = Z; 2312 d = Z; 2313 if(!nodreg(&nod1, t->left, D_AX)) { 2314 if(t->left->reg != D_AX){ 2315 t->left->reg = D_AX; 2316 reg[D_AX]++; 2317 }else if(reg[D_AX] == 0) 2318 fatal(Z, "vlong mul AX botch"); 2319 } 2320 if(!nodreg(&nod2, t->right, D_DX)) { 2321 if(t->right->reg != D_DX){ 2322 t->right->reg = D_DX; 2323 reg[D_DX]++; 2324 }else if(reg[D_DX] == 0) 2325 fatal(Z, "vlong mul DX botch"); 2326 } 2327 if(m) 2328 sugen(l, t, 8); 2329 else 2330 loadpair(l, t); 2331 if(t->left->reg != D_AX) { 2332 c = &nod3; 2333 regsalloc(c, t->left); 2334 gmove(&nod1, c); 2335 gmove(t->left, &nod1); 2336 zapreg(t->left); 2337 } 2338 if(t->right->reg != D_DX) { 2339 d = &nod4; 2340 regsalloc(d, t->right); 2341 gmove(&nod2, d); 2342 gmove(t->right, &nod2); 2343 zapreg(t->right); 2344 } 2345 if(c != Z || d != Z) { 2346 s = regpair(Z, n); 2347 s->left = &nod1; 2348 s->right = &nod2; 2349 } 2350 else 2351 s = t; 2352 if(r->op == OCONST) { 2353 if(hi64v(r) == 0) 2354 biggen(s, r, Z, 0, mulc32, nil); 2355 else 2356 biggen(s, r, Z, 0, mulc64, nil); 2357 } 2358 else 2359 biggen(s, r, Z, 0, mull, nil); 2360 instpair(t, Z); 2361 if(c != Z) { 2362 gmove(&nod1, t->left); 2363 gmove(&nod3, &nod1); 2364 } 2365 if(d != Z) { 2366 gmove(&nod2, t->right); 2367 gmove(&nod4, &nod2); 2368 } 2369 if(r->op == OREGPAIR) 2370 freepair(r); 2371 if(!m) 2372 storepair(t, l, 0); 2373 if(l == &nod5) 2374 regfree(l); 2375 if(!dr) { 2376 if(nn != Z) 2377 storepair(t, nn, 1); 2378 else 2379 freepair(t); 2380 } 2381 return 1; 2382 2383 case OASADD: 2384 args = ADDargs; 2385 goto vasop; 2386 case OASAND: 2387 args = ANDargs; 2388 goto vasop; 2389 case OASOR: 2390 args = ORargs; 2391 goto vasop; 2392 case OASSUB: 2393 args = SUBargs; 2394 goto vasop; 2395 case OASXOR: 2396 args = XORargs; 2397 goto vasop; 2398 2399 vasop: 2400 l = n->left; 2401 r = n->right; 2402 dr = nn != Z && nn->op == OREGPAIR; 2403 m = 0; 2404 if(l->complex > r->complex) { 2405 if(!vaddr(l, 1)) { 2406 reglcgen(&nod1, l, Z); 2407 l = &nod1; 2408 } 2409 if(!vaddr(r, 1) || nn != Z || r->op == OCONST) { 2410 if(dr) 2411 t = nn; 2412 else 2413 t = regpair(Z, r); 2414 sugen(r, t, 8); 2415 r = t; 2416 m = 1; 2417 } 2418 } 2419 else { 2420 if(!vaddr(r, 1) || nn != Z || r->op == OCONST) { 2421 if(dr) 2422 t = nn; 2423 else 2424 t = regpair(Z, r); 2425 sugen(r, t, 8); 2426 r = t; 2427 m = 1; 2428 } 2429 if(!vaddr(l, 1)) { 2430 reglcgen(&nod1, l, Z); 2431 l = &nod1; 2432 } 2433 } 2434 if(nn != Z) { 2435 if(n->op == OASSUB) 2436 biggen(l, r, Z, 0, sub10, args); 2437 else 2438 biggen(r, l, Z, 0, binoptmp, args); 2439 storepair(r, l, 0); 2440 } 2441 else { 2442 if(m) 2443 biggen(l, r, Z, 0, binop00, args); 2444 else 2445 biggen(l, r, Z, 0, binoptmp, args); 2446 } 2447 if(l == &nod1) 2448 regfree(&nod1); 2449 if(m) { 2450 if(nn == Z) 2451 freepair(r); 2452 else if(!dr) 2453 storepair(r, nn, 1); 2454 } 2455 return 1; 2456 2457 case OASASHL: 2458 args = nil; 2459 optab = asshlltab; 2460 goto assh; 2461 case OASLSHR: 2462 args = shrlargs; 2463 optab = asshrltab; 2464 goto assh; 2465 case OASASHR: 2466 args = sarlargs; 2467 optab = asshrltab; 2468 goto assh; 2469 2470 assh: 2471 c = Z; 2472 l = n->left; 2473 r = n->right; 2474 if(r->op == OCONST) { 2475 m = r->vconst & 63; 2476 if(m < 32) 2477 m = SAclo; 2478 else if(m == 32) 2479 m = SAc32; 2480 else 2481 m = SAchi; 2482 } 2483 else 2484 m = SAgen; 2485 if(l->complex > r->complex) { 2486 if(!vaddr(l, 0)) { 2487 reglcgen(&nod1, l, Z); 2488 l = &nod1; 2489 } 2490 if(m == SAgen) { 2491 t = &nod2; 2492 if(l->reg == D_CX) { 2493 regalloc(t, r, Z); 2494 gmove(l, t); 2495 l->reg = t->reg; 2496 t->reg = D_CX; 2497 } 2498 else 2499 c = snarfreg(nn, t, D_CX, r, &nod3); 2500 cgen(r, t); 2501 r = t; 2502 } 2503 } 2504 else { 2505 if(m == SAgen) { 2506 t = &nod2; 2507 c = snarfreg(nn, t, D_CX, r, &nod3); 2508 cgen(r, t); 2509 r = t; 2510 } 2511 if(!vaddr(l, 0)) { 2512 reglcgen(&nod1, l, Z); 2513 l = &nod1; 2514 } 2515 } 2516 2517 if(nn != Z) { 2518 m += SAdgen - SAgen; 2519 d = regpair(nn, n); 2520 instpair(d, Z); 2521 biggen(l, r, d, 0, optab[m], args); 2522 if(l == &nod1) { 2523 regfree(&nod1); 2524 l = Z; 2525 } 2526 if(r == &nod2 && c == Z) { 2527 regfree(&nod2); 2528 r = Z; 2529 } 2530 if(d != nn) 2531 storepair(d, nn, 1); 2532 } 2533 else 2534 biggen(l, r, Z, 0, optab[m], args); 2535 2536 if(c != Z) { 2537 gins(AMOVL, c, r); 2538 regfree(c); 2539 } 2540 if(l == &nod1) 2541 regfree(&nod1); 2542 if(r == &nod2) 2543 regfree(&nod2); 2544 return 1; 2545 2546 case OPOSTINC: 2547 args = ADDargs; 2548 cp = incdecpost; 2549 goto vinc; 2550 case OPOSTDEC: 2551 args = SUBargs; 2552 cp = incdecpost; 2553 goto vinc; 2554 case OPREINC: 2555 args = ADDargs; 2556 cp = incdecpre; 2557 goto vinc; 2558 case OPREDEC: 2559 args = SUBargs; 2560 cp = incdecpre; 2561 goto vinc; 2562 2563 vinc: 2564 l = n->left; 2565 if(!vaddr(l, 1)) { 2566 reglcgen(&nod1, l, Z); 2567 l = &nod1; 2568 } 2569 2570 if(nn != Z) { 2571 d = regpair(nn, n); 2572 instpair(d, Z); 2573 biggen(l, Z, d, 0, cp, args); 2574 if(l == &nod1) { 2575 regfree(&nod1); 2576 l = Z; 2577 } 2578 if(d != nn) 2579 storepair(d, nn, 1); 2580 } 2581 else 2582 biggen(l, Z, Z, 0, incdec, args); 2583 2584 if(l == &nod1) 2585 regfree(&nod1); 2586 return 1; 2587 2588 case OCAST: 2589 l = n->left; 2590 if(typev[l->type->etype]) { 2591 if(!vaddr(l, 1)) { 2592 if(l->complex + 1 > nn->complex) { 2593 d = regpair(Z, l); 2594 sugen(l, d, 8); 2595 if(!vaddr(nn, 1)) { 2596 reglcgen(&nod1, nn, Z); 2597 r = &nod1; 2598 } 2599 else 2600 r = nn; 2601 } 2602 else { 2603 if(!vaddr(nn, 1)) { 2604 reglcgen(&nod1, nn, Z); 2605 r = &nod1; 2606 } 2607 else 2608 r = nn; 2609 d = regpair(Z, l); 2610 sugen(l, d, 8); 2611 } 2612 // d->left->type = r->type; 2613 d->left->type = types[TLONG]; 2614 gmove(d->left, r); 2615 freepair(d); 2616 } 2617 else { 2618 if(nn->op != OREGISTER && !vaddr(nn, 1)) { 2619 reglcgen(&nod1, nn, Z); 2620 r = &nod1; 2621 } 2622 else 2623 r = nn; 2624 // l->type = r->type; 2625 l->type = types[TLONG]; 2626 gmove(l, r); 2627 } 2628 if(r != nn) 2629 regfree(r); 2630 } 2631 else { 2632 if(typeu[l->type->etype] || cond(l->op)) 2633 si = TUNSIGNED; 2634 else 2635 si = TSIGNED; 2636 regalloc(&nod1, l, Z); 2637 cgen(l, &nod1); 2638 if(nn->op == OREGPAIR) { 2639 m = instpair(nn, &nod1); 2640 biggen(&nod1, Z, nn, si == TSIGNED, castrp, nil); 2641 } 2642 else { 2643 m = 0; 2644 if(!vaddr(nn, si != TSIGNED)) { 2645 dt = nn->type; 2646 nn->type = types[TLONG]; 2647 reglcgen(&nod2, nn, Z); 2648 nn->type = dt; 2649 nn = &nod2; 2650 } 2651 dt = nn->type; 2652 nn->type = types[TLONG]; 2653 biggen(&nod1, Z, nn, si == TSIGNED, castrpa, nil); 2654 nn->type = dt; 2655 if(nn == &nod2) 2656 regfree(&nod2); 2657 } 2658 if(!m) 2659 regfree(&nod1); 2660 } 2661 return 1; 2662 2663 default: 2664 if(n->op == OREGPAIR) { 2665 storepair(n, nn, 1); 2666 return 1; 2667 } 2668 if(nn->op == OREGPAIR) { 2669 loadpair(n, nn); 2670 return 1; 2671 } 2672 return 0; 2673 } 2674 finished: 2675 if(d != nn) 2676 storepair(d, nn, 1); 2677 return 1; 2678 } 2679 2680 void 2681 testv(Node *n, int true) 2682 { 2683 Type *t; 2684 Node *nn, nod, *b; 2685 2686 if(machcap(Z)) { 2687 b = &nod; 2688 b->op = true ? ONE : OEQ; 2689 b->left = n; 2690 b->right = new(0, Z, Z); 2691 *b->right = *nodconst(0); 2692 b->right->type = n->type; 2693 b->type = types[TLONG]; 2694 cgen64(b, Z); 2695 return; 2696 } 2697 2698 switch(n->op) { 2699 case OINDREG: 2700 case ONAME: 2701 biggen(n, Z, Z, true, testi, nil); 2702 break; 2703 2704 default: 2705 n = vfunc(n, n); 2706 if(n->addable >= INDEXED) { 2707 t = n->type; 2708 n->type = types[TLONG]; 2709 reglcgen(&nod, n, Z); 2710 n->type = t; 2711 n = &nod; 2712 biggen(n, Z, Z, true, testi, nil); 2713 if(n == &nod) 2714 regfree(n); 2715 } 2716 else { 2717 nn = regpair(Z, n); 2718 sugen(n, nn, 8); 2719 biggen(nn, Z, Z, true, testi, nil); 2720 freepair(nn); 2721 } 2722 } 2723 } 2724