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