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