github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/cmd/6g/gsubr.c (about) 1 // Derived from Inferno utils/6c/txt.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.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 <u.h> 32 #include <libc.h> 33 #include "gg.h" 34 #include "../../pkg/runtime/funcdata.h" 35 36 // TODO(rsc): Can make this bigger if we move 37 // the text segment up higher in 6l for all GOOS. 38 // At the same time, can raise StackBig in ../../pkg/runtime/stack.h. 39 vlong unmappedzero = 4096; 40 41 void 42 clearp(Prog *p) 43 { 44 p->as = AEND; 45 p->from.type = D_NONE; 46 p->from.index = D_NONE; 47 p->to.type = D_NONE; 48 p->to.index = D_NONE; 49 p->loc = pcloc; 50 pcloc++; 51 } 52 53 static int ddumped; 54 static Prog *dfirst; 55 static Prog *dpc; 56 57 /* 58 * generate and return proc with p->as = as, 59 * linked into program. pc is next instruction. 60 */ 61 Prog* 62 prog(int as) 63 { 64 Prog *p; 65 66 if(as == ADATA || as == AGLOBL) { 67 if(ddumped) 68 fatal("already dumped data"); 69 if(dpc == nil) { 70 dpc = mal(sizeof(*dpc)); 71 dfirst = dpc; 72 } 73 p = dpc; 74 dpc = mal(sizeof(*dpc)); 75 p->link = dpc; 76 } else { 77 p = pc; 78 pc = mal(sizeof(*pc)); 79 clearp(pc); 80 p->link = pc; 81 } 82 83 if(lineno == 0) { 84 if(debug['K']) 85 warn("prog: line 0"); 86 } 87 88 p->as = as; 89 p->lineno = lineno; 90 return p; 91 } 92 93 void 94 dumpdata(void) 95 { 96 ddumped = 1; 97 if(dfirst == nil) 98 return; 99 newplist(); 100 *pc = *dfirst; 101 pc = dpc; 102 clearp(pc); 103 } 104 105 /* 106 * generate a branch. 107 * t is ignored. 108 * likely values are for branch prediction: 109 * -1 unlikely 110 * 0 no opinion 111 * +1 likely 112 */ 113 Prog* 114 gbranch(int as, Type *t, int likely) 115 { 116 Prog *p; 117 118 USED(t); 119 120 p = prog(as); 121 p->to.type = D_BRANCH; 122 p->to.u.branch = P; 123 if(as != AJMP && likely != 0) { 124 p->from.type = D_CONST; 125 p->from.offset = likely > 0; 126 } 127 return p; 128 } 129 130 /* 131 * patch previous branch to jump to to. 132 */ 133 void 134 patch(Prog *p, Prog *to) 135 { 136 if(p->to.type != D_BRANCH) 137 fatal("patch: not a branch"); 138 p->to.u.branch = to; 139 p->to.offset = to->loc; 140 } 141 142 Prog* 143 unpatch(Prog *p) 144 { 145 Prog *q; 146 147 if(p->to.type != D_BRANCH) 148 fatal("unpatch: not a branch"); 149 q = p->to.u.branch; 150 p->to.u.branch = P; 151 p->to.offset = 0; 152 return q; 153 } 154 155 /* 156 * start a new Prog list. 157 */ 158 Plist* 159 newplist(void) 160 { 161 Plist *pl; 162 163 pl = mal(sizeof(*pl)); 164 if(plist == nil) 165 plist = pl; 166 else 167 plast->link = pl; 168 plast = pl; 169 170 pc = mal(sizeof(*pc)); 171 clearp(pc); 172 pl->firstpc = pc; 173 174 return pl; 175 } 176 177 void 178 gused(Node *n) 179 { 180 gins(ANOP, n, N); // used 181 } 182 183 Prog* 184 gjmp(Prog *to) 185 { 186 Prog *p; 187 188 p = gbranch(AJMP, T, 0); 189 if(to != P) 190 patch(p, to); 191 return p; 192 } 193 194 void 195 ggloblnod(Node *nam) 196 { 197 Prog *p; 198 199 p = gins(AGLOBL, nam, N); 200 p->lineno = nam->lineno; 201 p->from.gotype = ngotype(nam); 202 p->to.sym = S; 203 p->to.type = D_CONST; 204 p->to.offset = nam->type->width; 205 if(nam->readonly) 206 p->from.scale = RODATA; 207 if(nam->type != T && !haspointers(nam->type)) 208 p->from.scale |= NOPTR; 209 } 210 211 void 212 gtrack(Sym *s) 213 { 214 Prog *p; 215 216 p = gins(AUSEFIELD, N, N); 217 p->from.type = D_EXTERN; 218 p->from.index = D_NONE; 219 p->from.sym = s; 220 } 221 222 void 223 gargsize(vlong size) 224 { 225 Node n1, n2; 226 227 nodconst(&n1, types[TINT32], PCDATA_ArgSize); 228 nodconst(&n2, types[TINT32], size); 229 gins(APCDATA, &n1, &n2); 230 } 231 232 void 233 ggloblsym(Sym *s, int32 width, int dupok, int rodata) 234 { 235 Prog *p; 236 237 p = gins(AGLOBL, N, N); 238 p->from.type = D_EXTERN; 239 p->from.index = D_NONE; 240 p->from.sym = s; 241 p->to.type = D_CONST; 242 p->to.index = D_NONE; 243 p->to.offset = width; 244 if(dupok) 245 p->from.scale |= DUPOK; 246 if(rodata) 247 p->from.scale |= RODATA; 248 } 249 250 int 251 isfat(Type *t) 252 { 253 if(t != T) 254 switch(t->etype) { 255 case TSTRUCT: 256 case TARRAY: 257 case TSTRING: 258 case TINTER: // maybe remove later 259 return 1; 260 } 261 return 0; 262 } 263 264 /* 265 * naddr of func generates code for address of func. 266 * if using opcode that can take address implicitly, 267 * call afunclit to fix up the argument. 268 */ 269 void 270 afunclit(Addr *a, Node *n) 271 { 272 if(a->type == D_ADDR && a->index == D_EXTERN) { 273 a->type = D_EXTERN; 274 a->index = D_NONE; 275 a->sym = n->sym; 276 } 277 } 278 279 static int resvd[] = 280 { 281 D_DI, // for movstring 282 D_SI, // for movstring 283 284 D_AX, // for divide 285 D_CX, // for shift 286 D_DX, // for divide 287 D_SP, // for stack 288 }; 289 290 void 291 ginit(void) 292 { 293 int i; 294 295 for(i=0; i<nelem(reg); i++) 296 reg[i] = 1; 297 for(i=D_AX; i<=D_R15; i++) 298 reg[i] = 0; 299 for(i=D_X0; i<=D_X15; i++) 300 reg[i] = 0; 301 302 for(i=0; i<nelem(resvd); i++) 303 reg[resvd[i]]++; 304 } 305 306 void 307 gclean(void) 308 { 309 int i; 310 311 for(i=0; i<nelem(resvd); i++) 312 reg[resvd[i]]--; 313 314 for(i=D_AX; i<=D_R15; i++) 315 if(reg[i]) 316 yyerror("reg %R left allocated\n", i); 317 for(i=D_X0; i<=D_X15; i++) 318 if(reg[i]) 319 yyerror("reg %R left allocated\n", i); 320 } 321 322 int32 323 anyregalloc(void) 324 { 325 int i, j; 326 327 for(i=D_AX; i<=D_R15; i++) { 328 if(reg[i] == 0) 329 goto ok; 330 for(j=0; j<nelem(resvd); j++) 331 if(resvd[j] == i) 332 goto ok; 333 return 1; 334 ok:; 335 } 336 return 0; 337 } 338 339 static uintptr regpc[D_R15+1 - D_AX]; 340 341 /* 342 * allocate register of type t, leave in n. 343 * if o != N, o is desired fixed register. 344 * caller must regfree(n). 345 */ 346 void 347 regalloc(Node *n, Type *t, Node *o) 348 { 349 int i, et; 350 351 if(t == T) 352 fatal("regalloc: t nil"); 353 et = simtype[t->etype]; 354 355 switch(et) { 356 case TINT8: 357 case TUINT8: 358 case TINT16: 359 case TUINT16: 360 case TINT32: 361 case TUINT32: 362 case TINT64: 363 case TUINT64: 364 case TPTR32: 365 case TPTR64: 366 case TBOOL: 367 if(o != N && o->op == OREGISTER) { 368 i = o->val.u.reg; 369 if(i >= D_AX && i <= D_R15) 370 goto out; 371 } 372 for(i=D_AX; i<=D_R15; i++) 373 if(reg[i] == 0) { 374 regpc[i-D_AX] = (uintptr)getcallerpc(&n); 375 goto out; 376 } 377 378 flusherrors(); 379 for(i=0; i+D_AX<=D_R15; i++) 380 print("%d %p\n", i, regpc[i]); 381 fatal("out of fixed registers"); 382 383 case TFLOAT32: 384 case TFLOAT64: 385 if(o != N && o->op == OREGISTER) { 386 i = o->val.u.reg; 387 if(i >= D_X0 && i <= D_X15) 388 goto out; 389 } 390 for(i=D_X0; i<=D_X15; i++) 391 if(reg[i] == 0) 392 goto out; 393 fatal("out of floating registers"); 394 395 case TCOMPLEX64: 396 case TCOMPLEX128: 397 tempname(n, t); 398 return; 399 } 400 fatal("regalloc: unknown type %T", t); 401 return; 402 403 out: 404 reg[i]++; 405 nodreg(n, t, i); 406 } 407 408 void 409 regfree(Node *n) 410 { 411 int i; 412 413 if(n->op == ONAME) 414 return; 415 if(n->op != OREGISTER && n->op != OINDREG) 416 fatal("regfree: not a register"); 417 i = n->val.u.reg; 418 if(i == D_SP) 419 return; 420 if(i < 0 || i >= nelem(reg)) 421 fatal("regfree: reg out of range"); 422 if(reg[i] <= 0) 423 fatal("regfree: reg not allocated"); 424 reg[i]--; 425 if(reg[i] == 0 && D_AX <= i && i <= D_R15) 426 regpc[i - D_AX] = 0; 427 } 428 429 /* 430 * initialize n to be register r of type t. 431 */ 432 void 433 nodreg(Node *n, Type *t, int r) 434 { 435 if(t == T) 436 fatal("nodreg: t nil"); 437 438 memset(n, 0, sizeof(*n)); 439 n->op = OREGISTER; 440 n->addable = 1; 441 ullmancalc(n); 442 n->val.u.reg = r; 443 n->type = t; 444 } 445 446 /* 447 * initialize n to be indirect of register r; n is type t. 448 */ 449 void 450 nodindreg(Node *n, Type *t, int r) 451 { 452 nodreg(n, t, r); 453 n->op = OINDREG; 454 } 455 456 Node* 457 nodarg(Type *t, int fp) 458 { 459 Node *n; 460 Type *first; 461 Iter savet; 462 463 // entire argument struct, not just one arg 464 if(t->etype == TSTRUCT && t->funarg) { 465 n = nod(ONAME, N, N); 466 n->sym = lookup(".args"); 467 n->type = t; 468 first = structfirst(&savet, &t); 469 if(first == nil) 470 fatal("nodarg: bad struct"); 471 if(first->width == BADWIDTH) 472 fatal("nodarg: offset not computed for %T", t); 473 n->xoffset = first->width; 474 n->addable = 1; 475 goto fp; 476 } 477 478 if(t->etype != TFIELD) 479 fatal("nodarg: not field %T", t); 480 481 n = nod(ONAME, N, N); 482 n->type = t->type; 483 n->sym = t->sym; 484 485 if(t->width == BADWIDTH) 486 fatal("nodarg: offset not computed for %T", t); 487 n->xoffset = t->width; 488 n->addable = 1; 489 n->orig = t->nname; 490 491 fp: 492 // Rewrite argument named _ to __, 493 // or else the assignment to _ will be 494 // discarded during code generation. 495 if(isblank(n)) 496 n->sym = lookup("__"); 497 498 switch(fp) { 499 case 0: // output arg 500 n->op = OINDREG; 501 n->val.u.reg = D_SP; 502 break; 503 504 case 1: // input arg 505 n->class = PPARAM; 506 break; 507 508 case 2: // offset output arg 509 fatal("shouldn't be used"); 510 n->op = OINDREG; 511 n->val.u.reg = D_SP; 512 n->xoffset += types[tptr]->width; 513 break; 514 } 515 n->typecheck = 1; 516 return n; 517 } 518 519 /* 520 * generate 521 * as $c, reg 522 */ 523 void 524 gconreg(int as, vlong c, int reg) 525 { 526 Node nr; 527 528 nodreg(&nr, types[TINT64], reg); 529 ginscon(as, c, &nr); 530 } 531 532 /* 533 * generate 534 * as $c, n 535 */ 536 void 537 ginscon(int as, vlong c, Node *n2) 538 { 539 Node n1, ntmp; 540 541 nodconst(&n1, types[TINT64], c); 542 543 if(as != AMOVQ && (c < -1LL<<31 || c >= 1LL<<31)) { 544 // cannot have 64-bit immediokate in ADD, etc. 545 // instead, MOV into register first. 546 regalloc(&ntmp, types[TINT64], N); 547 gins(AMOVQ, &n1, &ntmp); 548 gins(as, &ntmp, n2); 549 regfree(&ntmp); 550 return; 551 } 552 gins(as, &n1, n2); 553 } 554 555 #define CASE(a,b) (((a)<<16)|((b)<<0)) 556 557 /* 558 * Is this node a memory operand? 559 */ 560 int 561 ismem(Node *n) 562 { 563 switch(n->op) { 564 case OITAB: 565 case OLEN: 566 case OCAP: 567 case OINDREG: 568 case ONAME: 569 case OPARAM: 570 case OCLOSUREVAR: 571 return 1; 572 case OADDR: 573 if(flag_largemodel) 574 return 1; 575 break; 576 } 577 return 0; 578 } 579 580 /* 581 * set up nodes representing 2^63 582 */ 583 Node bigi; 584 Node bigf; 585 586 void 587 bignodes(void) 588 { 589 static int did; 590 591 if(did) 592 return; 593 did = 1; 594 595 nodconst(&bigi, types[TUINT64], 1); 596 mpshiftfix(bigi.val.u.xval, 63); 597 598 bigf = bigi; 599 bigf.type = types[TFLOAT64]; 600 bigf.val.ctype = CTFLT; 601 bigf.val.u.fval = mal(sizeof *bigf.val.u.fval); 602 mpmovefixflt(bigf.val.u.fval, bigi.val.u.xval); 603 } 604 605 /* 606 * generate move: 607 * t = f 608 * hard part is conversions. 609 */ 610 // TODO: lost special constants for floating point. XORPD for 0.0? 611 void 612 gmove(Node *f, Node *t) 613 { 614 int a, ft, tt; 615 Type *cvt; 616 Node r1, r2, r3, r4, zero, one, con; 617 Prog *p1, *p2; 618 619 if(debug['M']) 620 print("gmove %lN -> %lN\n", f, t); 621 622 ft = simsimtype(f->type); 623 tt = simsimtype(t->type); 624 cvt = t->type; 625 626 if(iscomplex[ft] || iscomplex[tt]) { 627 complexmove(f, t); 628 return; 629 } 630 631 // cannot have two memory operands 632 if(ismem(f) && ismem(t)) 633 goto hard; 634 635 // convert constant to desired type 636 if(f->op == OLITERAL) { 637 convconst(&con, t->type, &f->val); 638 f = &con; 639 ft = tt; // so big switch will choose a simple mov 640 641 // some constants can't move directly to memory. 642 if(ismem(t)) { 643 // float constants come from memory. 644 if(isfloat[tt]) 645 goto hard; 646 647 // 64-bit immediates are really 32-bit sign-extended 648 // unless moving into a register. 649 if(isint[tt]) { 650 if(mpcmpfixfix(con.val.u.xval, minintval[TINT32]) < 0) 651 goto hard; 652 if(mpcmpfixfix(con.val.u.xval, maxintval[TINT32]) > 0) 653 goto hard; 654 } 655 } 656 } 657 658 // value -> value copy, only one memory operand. 659 // figure out the instruction to use. 660 // break out of switch for one-instruction gins. 661 // goto rdst for "destination must be register". 662 // goto hard for "convert to cvt type first". 663 // otherwise handle and return. 664 665 switch(CASE(ft, tt)) { 666 default: 667 fatal("gmove %lT -> %lT", f->type, t->type); 668 669 /* 670 * integer copy and truncate 671 */ 672 case CASE(TINT8, TINT8): // same size 673 case CASE(TINT8, TUINT8): 674 case CASE(TUINT8, TINT8): 675 case CASE(TUINT8, TUINT8): 676 case CASE(TINT16, TINT8): // truncate 677 case CASE(TUINT16, TINT8): 678 case CASE(TINT32, TINT8): 679 case CASE(TUINT32, TINT8): 680 case CASE(TINT64, TINT8): 681 case CASE(TUINT64, TINT8): 682 case CASE(TINT16, TUINT8): 683 case CASE(TUINT16, TUINT8): 684 case CASE(TINT32, TUINT8): 685 case CASE(TUINT32, TUINT8): 686 case CASE(TINT64, TUINT8): 687 case CASE(TUINT64, TUINT8): 688 a = AMOVB; 689 break; 690 691 case CASE(TINT16, TINT16): // same size 692 case CASE(TINT16, TUINT16): 693 case CASE(TUINT16, TINT16): 694 case CASE(TUINT16, TUINT16): 695 case CASE(TINT32, TINT16): // truncate 696 case CASE(TUINT32, TINT16): 697 case CASE(TINT64, TINT16): 698 case CASE(TUINT64, TINT16): 699 case CASE(TINT32, TUINT16): 700 case CASE(TUINT32, TUINT16): 701 case CASE(TINT64, TUINT16): 702 case CASE(TUINT64, TUINT16): 703 a = AMOVW; 704 break; 705 706 case CASE(TINT32, TINT32): // same size 707 case CASE(TINT32, TUINT32): 708 case CASE(TUINT32, TINT32): 709 case CASE(TUINT32, TUINT32): 710 a = AMOVL; 711 break; 712 713 case CASE(TINT64, TINT32): // truncate 714 case CASE(TUINT64, TINT32): 715 case CASE(TINT64, TUINT32): 716 case CASE(TUINT64, TUINT32): 717 a = AMOVQL; 718 break; 719 720 case CASE(TINT64, TINT64): // same size 721 case CASE(TINT64, TUINT64): 722 case CASE(TUINT64, TINT64): 723 case CASE(TUINT64, TUINT64): 724 a = AMOVQ; 725 break; 726 727 /* 728 * integer up-conversions 729 */ 730 case CASE(TINT8, TINT16): // sign extend int8 731 case CASE(TINT8, TUINT16): 732 a = AMOVBWSX; 733 goto rdst; 734 case CASE(TINT8, TINT32): 735 case CASE(TINT8, TUINT32): 736 a = AMOVBLSX; 737 goto rdst; 738 case CASE(TINT8, TINT64): 739 case CASE(TINT8, TUINT64): 740 a = AMOVBQSX; 741 goto rdst; 742 743 case CASE(TUINT8, TINT16): // zero extend uint8 744 case CASE(TUINT8, TUINT16): 745 a = AMOVBWZX; 746 goto rdst; 747 case CASE(TUINT8, TINT32): 748 case CASE(TUINT8, TUINT32): 749 a = AMOVBLZX; 750 goto rdst; 751 case CASE(TUINT8, TINT64): 752 case CASE(TUINT8, TUINT64): 753 a = AMOVBQZX; 754 goto rdst; 755 756 case CASE(TINT16, TINT32): // sign extend int16 757 case CASE(TINT16, TUINT32): 758 a = AMOVWLSX; 759 goto rdst; 760 case CASE(TINT16, TINT64): 761 case CASE(TINT16, TUINT64): 762 a = AMOVWQSX; 763 goto rdst; 764 765 case CASE(TUINT16, TINT32): // zero extend uint16 766 case CASE(TUINT16, TUINT32): 767 a = AMOVWLZX; 768 goto rdst; 769 case CASE(TUINT16, TINT64): 770 case CASE(TUINT16, TUINT64): 771 a = AMOVWQZX; 772 goto rdst; 773 774 case CASE(TINT32, TINT64): // sign extend int32 775 case CASE(TINT32, TUINT64): 776 a = AMOVLQSX; 777 goto rdst; 778 779 case CASE(TUINT32, TINT64): // zero extend uint32 780 case CASE(TUINT32, TUINT64): 781 // AMOVL into a register zeros the top of the register, 782 // so this is not always necessary, but if we rely on AMOVL 783 // the optimizer is almost certain to screw with us. 784 a = AMOVLQZX; 785 goto rdst; 786 787 /* 788 * float to integer 789 */ 790 case CASE(TFLOAT32, TINT32): 791 a = ACVTTSS2SL; 792 goto rdst; 793 794 case CASE(TFLOAT64, TINT32): 795 a = ACVTTSD2SL; 796 goto rdst; 797 798 case CASE(TFLOAT32, TINT64): 799 a = ACVTTSS2SQ; 800 goto rdst; 801 802 case CASE(TFLOAT64, TINT64): 803 a = ACVTTSD2SQ; 804 goto rdst; 805 806 case CASE(TFLOAT32, TINT16): 807 case CASE(TFLOAT32, TINT8): 808 case CASE(TFLOAT32, TUINT16): 809 case CASE(TFLOAT32, TUINT8): 810 case CASE(TFLOAT64, TINT16): 811 case CASE(TFLOAT64, TINT8): 812 case CASE(TFLOAT64, TUINT16): 813 case CASE(TFLOAT64, TUINT8): 814 // convert via int32. 815 cvt = types[TINT32]; 816 goto hard; 817 818 case CASE(TFLOAT32, TUINT32): 819 case CASE(TFLOAT64, TUINT32): 820 // convert via int64. 821 cvt = types[TINT64]; 822 goto hard; 823 824 case CASE(TFLOAT32, TUINT64): 825 case CASE(TFLOAT64, TUINT64): 826 // algorithm is: 827 // if small enough, use native float64 -> int64 conversion. 828 // otherwise, subtract 2^63, convert, and add it back. 829 a = ACVTTSS2SQ; 830 if(ft == TFLOAT64) 831 a = ACVTTSD2SQ; 832 bignodes(); 833 regalloc(&r1, types[ft], N); 834 regalloc(&r2, types[tt], t); 835 regalloc(&r3, types[ft], N); 836 regalloc(&r4, types[tt], N); 837 gins(optoas(OAS, f->type), f, &r1); 838 gins(optoas(OCMP, f->type), &bigf, &r1); 839 p1 = gbranch(optoas(OLE, f->type), T, +1); 840 gins(a, &r1, &r2); 841 p2 = gbranch(AJMP, T, 0); 842 patch(p1, pc); 843 gins(optoas(OAS, f->type), &bigf, &r3); 844 gins(optoas(OSUB, f->type), &r3, &r1); 845 gins(a, &r1, &r2); 846 gins(AMOVQ, &bigi, &r4); 847 gins(AXORQ, &r4, &r2); 848 patch(p2, pc); 849 gmove(&r2, t); 850 regfree(&r4); 851 regfree(&r3); 852 regfree(&r2); 853 regfree(&r1); 854 return; 855 856 /* 857 * integer to float 858 */ 859 case CASE(TINT32, TFLOAT32): 860 a = ACVTSL2SS; 861 goto rdst; 862 863 864 case CASE(TINT32, TFLOAT64): 865 a = ACVTSL2SD; 866 goto rdst; 867 868 case CASE(TINT64, TFLOAT32): 869 a = ACVTSQ2SS; 870 goto rdst; 871 872 case CASE(TINT64, TFLOAT64): 873 a = ACVTSQ2SD; 874 goto rdst; 875 876 case CASE(TINT16, TFLOAT32): 877 case CASE(TINT16, TFLOAT64): 878 case CASE(TINT8, TFLOAT32): 879 case CASE(TINT8, TFLOAT64): 880 case CASE(TUINT16, TFLOAT32): 881 case CASE(TUINT16, TFLOAT64): 882 case CASE(TUINT8, TFLOAT32): 883 case CASE(TUINT8, TFLOAT64): 884 // convert via int32 885 cvt = types[TINT32]; 886 goto hard; 887 888 case CASE(TUINT32, TFLOAT32): 889 case CASE(TUINT32, TFLOAT64): 890 // convert via int64. 891 cvt = types[TINT64]; 892 goto hard; 893 894 case CASE(TUINT64, TFLOAT32): 895 case CASE(TUINT64, TFLOAT64): 896 // algorithm is: 897 // if small enough, use native int64 -> uint64 conversion. 898 // otherwise, halve (rounding to odd?), convert, and double. 899 a = ACVTSQ2SS; 900 if(tt == TFLOAT64) 901 a = ACVTSQ2SD; 902 nodconst(&zero, types[TUINT64], 0); 903 nodconst(&one, types[TUINT64], 1); 904 regalloc(&r1, f->type, f); 905 regalloc(&r2, t->type, t); 906 regalloc(&r3, f->type, N); 907 regalloc(&r4, f->type, N); 908 gmove(f, &r1); 909 gins(ACMPQ, &r1, &zero); 910 p1 = gbranch(AJLT, T, +1); 911 gins(a, &r1, &r2); 912 p2 = gbranch(AJMP, T, 0); 913 patch(p1, pc); 914 gmove(&r1, &r3); 915 gins(ASHRQ, &one, &r3); 916 gmove(&r1, &r4); 917 gins(AANDL, &one, &r4); 918 gins(AORQ, &r4, &r3); 919 gins(a, &r3, &r2); 920 gins(optoas(OADD, t->type), &r2, &r2); 921 patch(p2, pc); 922 gmove(&r2, t); 923 regfree(&r4); 924 regfree(&r3); 925 regfree(&r2); 926 regfree(&r1); 927 return; 928 929 /* 930 * float to float 931 */ 932 case CASE(TFLOAT32, TFLOAT32): 933 a = AMOVSS; 934 break; 935 936 case CASE(TFLOAT64, TFLOAT64): 937 a = AMOVSD; 938 break; 939 940 case CASE(TFLOAT32, TFLOAT64): 941 a = ACVTSS2SD; 942 goto rdst; 943 944 case CASE(TFLOAT64, TFLOAT32): 945 a = ACVTSD2SS; 946 goto rdst; 947 } 948 949 gins(a, f, t); 950 return; 951 952 rdst: 953 // requires register destination 954 regalloc(&r1, t->type, t); 955 gins(a, f, &r1); 956 gmove(&r1, t); 957 regfree(&r1); 958 return; 959 960 hard: 961 // requires register intermediate 962 regalloc(&r1, cvt, t); 963 gmove(f, &r1); 964 gmove(&r1, t); 965 regfree(&r1); 966 return; 967 } 968 969 int 970 samaddr(Node *f, Node *t) 971 { 972 973 if(f->op != t->op) 974 return 0; 975 976 switch(f->op) { 977 case OREGISTER: 978 if(f->val.u.reg != t->val.u.reg) 979 break; 980 return 1; 981 } 982 return 0; 983 } 984 985 /* 986 * generate one instruction: 987 * as f, t 988 */ 989 Prog* 990 gins(int as, Node *f, Node *t) 991 { 992 // Node nod; 993 int32 w; 994 Prog *p; 995 Addr af, at; 996 997 // if(f != N && f->op == OINDEX) { 998 // regalloc(&nod, ®node, Z); 999 // v = constnode.vconst; 1000 // cgen(f->right, &nod); 1001 // constnode.vconst = v; 1002 // idx.reg = nod.reg; 1003 // regfree(&nod); 1004 // } 1005 // if(t != N && t->op == OINDEX) { 1006 // regalloc(&nod, ®node, Z); 1007 // v = constnode.vconst; 1008 // cgen(t->right, &nod); 1009 // constnode.vconst = v; 1010 // idx.reg = nod.reg; 1011 // regfree(&nod); 1012 // } 1013 1014 switch(as) { 1015 case AMOVB: 1016 case AMOVW: 1017 case AMOVL: 1018 case AMOVQ: 1019 case AMOVSS: 1020 case AMOVSD: 1021 if(f != N && t != N && samaddr(f, t)) 1022 return nil; 1023 break; 1024 1025 case ALEAQ: 1026 if(f != N && isconst(f, CTNIL)) { 1027 fatal("gins LEAQ nil %T", f->type); 1028 } 1029 break; 1030 } 1031 1032 memset(&af, 0, sizeof af); 1033 memset(&at, 0, sizeof at); 1034 if(f != N) 1035 naddr(f, &af, 1); 1036 if(t != N) 1037 naddr(t, &at, 1); 1038 p = prog(as); 1039 if(f != N) 1040 p->from = af; 1041 if(t != N) 1042 p->to = at; 1043 if(debug['g']) 1044 print("%P\n", p); 1045 1046 w = 0; 1047 switch(as) { 1048 case AMOVB: 1049 w = 1; 1050 break; 1051 case AMOVW: 1052 w = 2; 1053 break; 1054 case AMOVL: 1055 w = 4; 1056 break; 1057 case AMOVQ: 1058 w = 8; 1059 break; 1060 } 1061 if(w != 0 && ((f != N && af.width < w) || (t != N && at.width > w))) { 1062 dump("f", f); 1063 dump("t", t); 1064 fatal("bad width: %P (%d, %d)\n", p, af.width, at.width); 1065 } 1066 1067 return p; 1068 } 1069 1070 /* 1071 * generate code to compute n; 1072 * make a refer to result. 1073 */ 1074 void 1075 naddr(Node *n, Addr *a, int canemitcode) 1076 { 1077 a->scale = 0; 1078 a->index = D_NONE; 1079 a->type = D_NONE; 1080 a->gotype = S; 1081 a->node = N; 1082 a->width = 0; 1083 if(n == N) 1084 return; 1085 1086 if(n->type != T && n->type->etype != TIDEAL) { 1087 dowidth(n->type); 1088 a->width = n->type->width; 1089 } 1090 1091 switch(n->op) { 1092 default: 1093 fatal("naddr: bad %O %D", n->op, a); 1094 break; 1095 1096 case OREGISTER: 1097 a->type = n->val.u.reg; 1098 a->sym = S; 1099 break; 1100 1101 // case OINDEX: 1102 // case OIND: 1103 // naddr(n->left, a); 1104 // if(a->type >= D_AX && a->type <= D_DI) 1105 // a->type += D_INDIR; 1106 // else 1107 // if(a->type == D_CONST) 1108 // a->type = D_NONE+D_INDIR; 1109 // else 1110 // if(a->type == D_ADDR) { 1111 // a->type = a->index; 1112 // a->index = D_NONE; 1113 // } else 1114 // goto bad; 1115 // if(n->op == OINDEX) { 1116 // a->index = idx.reg; 1117 // a->scale = n->scale; 1118 // } 1119 // break; 1120 1121 case OINDREG: 1122 a->type = n->val.u.reg+D_INDIR; 1123 a->sym = n->sym; 1124 a->offset = n->xoffset; 1125 if(a->offset != (int32)a->offset) 1126 yyerror("offset %lld too large for OINDREG", a->offset); 1127 break; 1128 1129 case OPARAM: 1130 // n->left is PHEAP ONAME for stack parameter. 1131 // compute address of actual parameter on stack. 1132 a->etype = simtype[n->left->type->etype]; 1133 a->width = n->left->type->width; 1134 a->offset = n->xoffset; 1135 a->sym = n->left->sym; 1136 a->type = D_PARAM; 1137 a->node = n->left->orig; 1138 break; 1139 1140 case OCLOSUREVAR: 1141 a->type = D_DX+D_INDIR; 1142 a->sym = S; 1143 a->offset = n->xoffset; 1144 break; 1145 1146 case OCFUNC: 1147 naddr(n->left, a, canemitcode); 1148 a->sym = n->left->sym; 1149 break; 1150 1151 case ONAME: 1152 a->etype = 0; 1153 if(n->type != T) 1154 a->etype = simtype[n->type->etype]; 1155 a->offset = n->xoffset; 1156 a->sym = n->sym; 1157 a->node = n->orig; 1158 //if(a->node >= (Node*)&n) 1159 // fatal("stack node"); 1160 if(a->sym == S) 1161 a->sym = lookup(".noname"); 1162 if(n->method) { 1163 if(n->type != T) 1164 if(n->type->sym != S) 1165 if(n->type->sym->pkg != nil) 1166 a->sym = pkglookup(a->sym->name, n->type->sym->pkg); 1167 } 1168 1169 switch(n->class) { 1170 default: 1171 fatal("naddr: ONAME class %S %d\n", n->sym, n->class); 1172 case PEXTERN: 1173 a->type = D_EXTERN; 1174 break; 1175 case PAUTO: 1176 a->type = D_AUTO; 1177 break; 1178 case PPARAM: 1179 case PPARAMOUT: 1180 a->type = D_PARAM; 1181 break; 1182 case PFUNC: 1183 a->index = D_EXTERN; 1184 a->type = D_ADDR; 1185 a->width = widthptr; 1186 a->sym = funcsym(a->sym); 1187 break; 1188 } 1189 break; 1190 1191 case OLITERAL: 1192 switch(n->val.ctype) { 1193 default: 1194 fatal("naddr: const %lT", n->type); 1195 break; 1196 case CTFLT: 1197 a->type = D_FCONST; 1198 a->u.dval = mpgetflt(n->val.u.fval); 1199 break; 1200 case CTINT: 1201 case CTRUNE: 1202 a->sym = S; 1203 a->type = D_CONST; 1204 a->offset = mpgetfix(n->val.u.xval); 1205 break; 1206 case CTSTR: 1207 datagostring(n->val.u.sval, a); 1208 break; 1209 case CTBOOL: 1210 a->sym = S; 1211 a->type = D_CONST; 1212 a->offset = n->val.u.bval; 1213 break; 1214 case CTNIL: 1215 a->sym = S; 1216 a->type = D_CONST; 1217 a->offset = 0; 1218 break; 1219 } 1220 break; 1221 1222 case OADDR: 1223 naddr(n->left, a, canemitcode); 1224 a->width = widthptr; 1225 if(a->type >= D_INDIR) { 1226 a->type -= D_INDIR; 1227 break; 1228 } 1229 if(a->type == D_EXTERN || a->type == D_STATIC || 1230 a->type == D_AUTO || a->type == D_PARAM) 1231 if(a->index == D_NONE) { 1232 a->index = a->type; 1233 a->type = D_ADDR; 1234 break; 1235 } 1236 fatal("naddr: OADDR\n"); 1237 1238 case OITAB: 1239 // itable of interface value 1240 naddr(n->left, a, canemitcode); 1241 if(a->type == D_CONST && a->offset == 0) 1242 break; // itab(nil) 1243 a->etype = tptr; 1244 a->width = widthptr; 1245 break; 1246 1247 case OLEN: 1248 // len of string or slice 1249 naddr(n->left, a, canemitcode); 1250 if(a->type == D_CONST && a->offset == 0) 1251 break; // len(nil) 1252 a->etype = simtype[TUINT]; 1253 a->offset += Array_nel; 1254 a->width = widthint; 1255 break; 1256 1257 case OCAP: 1258 // cap of string or slice 1259 naddr(n->left, a, canemitcode); 1260 if(a->type == D_CONST && a->offset == 0) 1261 break; // cap(nil) 1262 a->etype = simtype[TUINT]; 1263 a->offset += Array_cap; 1264 a->width = widthint; 1265 break; 1266 1267 // case OADD: 1268 // if(n->right->op == OLITERAL) { 1269 // v = n->right->vconst; 1270 // naddr(n->left, a, canemitcode); 1271 // } else 1272 // if(n->left->op == OLITERAL) { 1273 // v = n->left->vconst; 1274 // naddr(n->right, a, canemitcode); 1275 // } else 1276 // goto bad; 1277 // a->offset += v; 1278 // break; 1279 1280 } 1281 } 1282 1283 /* 1284 * return Axxx for Oxxx on type t. 1285 */ 1286 int 1287 optoas(int op, Type *t) 1288 { 1289 int a; 1290 1291 if(t == T) 1292 fatal("optoas: t is nil"); 1293 1294 a = AGOK; 1295 switch(CASE(op, simtype[t->etype])) { 1296 default: 1297 fatal("optoas: no entry %O-%T", op, t); 1298 break; 1299 1300 case CASE(OADDR, TPTR32): 1301 a = ALEAL; 1302 break; 1303 1304 case CASE(OADDR, TPTR64): 1305 a = ALEAQ; 1306 break; 1307 1308 case CASE(OEQ, TBOOL): 1309 case CASE(OEQ, TINT8): 1310 case CASE(OEQ, TUINT8): 1311 case CASE(OEQ, TINT16): 1312 case CASE(OEQ, TUINT16): 1313 case CASE(OEQ, TINT32): 1314 case CASE(OEQ, TUINT32): 1315 case CASE(OEQ, TINT64): 1316 case CASE(OEQ, TUINT64): 1317 case CASE(OEQ, TPTR32): 1318 case CASE(OEQ, TPTR64): 1319 case CASE(OEQ, TFLOAT32): 1320 case CASE(OEQ, TFLOAT64): 1321 a = AJEQ; 1322 break; 1323 1324 case CASE(ONE, TBOOL): 1325 case CASE(ONE, TINT8): 1326 case CASE(ONE, TUINT8): 1327 case CASE(ONE, TINT16): 1328 case CASE(ONE, TUINT16): 1329 case CASE(ONE, TINT32): 1330 case CASE(ONE, TUINT32): 1331 case CASE(ONE, TINT64): 1332 case CASE(ONE, TUINT64): 1333 case CASE(ONE, TPTR32): 1334 case CASE(ONE, TPTR64): 1335 case CASE(ONE, TFLOAT32): 1336 case CASE(ONE, TFLOAT64): 1337 a = AJNE; 1338 break; 1339 1340 case CASE(OLT, TINT8): 1341 case CASE(OLT, TINT16): 1342 case CASE(OLT, TINT32): 1343 case CASE(OLT, TINT64): 1344 a = AJLT; 1345 break; 1346 1347 case CASE(OLT, TUINT8): 1348 case CASE(OLT, TUINT16): 1349 case CASE(OLT, TUINT32): 1350 case CASE(OLT, TUINT64): 1351 a = AJCS; 1352 break; 1353 1354 case CASE(OLE, TINT8): 1355 case CASE(OLE, TINT16): 1356 case CASE(OLE, TINT32): 1357 case CASE(OLE, TINT64): 1358 a = AJLE; 1359 break; 1360 1361 case CASE(OLE, TUINT8): 1362 case CASE(OLE, TUINT16): 1363 case CASE(OLE, TUINT32): 1364 case CASE(OLE, TUINT64): 1365 a = AJLS; 1366 break; 1367 1368 case CASE(OGT, TINT8): 1369 case CASE(OGT, TINT16): 1370 case CASE(OGT, TINT32): 1371 case CASE(OGT, TINT64): 1372 a = AJGT; 1373 break; 1374 1375 case CASE(OGT, TUINT8): 1376 case CASE(OGT, TUINT16): 1377 case CASE(OGT, TUINT32): 1378 case CASE(OGT, TUINT64): 1379 case CASE(OLT, TFLOAT32): 1380 case CASE(OLT, TFLOAT64): 1381 a = AJHI; 1382 break; 1383 1384 case CASE(OGE, TINT8): 1385 case CASE(OGE, TINT16): 1386 case CASE(OGE, TINT32): 1387 case CASE(OGE, TINT64): 1388 a = AJGE; 1389 break; 1390 1391 case CASE(OGE, TUINT8): 1392 case CASE(OGE, TUINT16): 1393 case CASE(OGE, TUINT32): 1394 case CASE(OGE, TUINT64): 1395 case CASE(OLE, TFLOAT32): 1396 case CASE(OLE, TFLOAT64): 1397 a = AJCC; 1398 break; 1399 1400 case CASE(OCMP, TBOOL): 1401 case CASE(OCMP, TINT8): 1402 case CASE(OCMP, TUINT8): 1403 a = ACMPB; 1404 break; 1405 1406 case CASE(OCMP, TINT16): 1407 case CASE(OCMP, TUINT16): 1408 a = ACMPW; 1409 break; 1410 1411 case CASE(OCMP, TINT32): 1412 case CASE(OCMP, TUINT32): 1413 case CASE(OCMP, TPTR32): 1414 a = ACMPL; 1415 break; 1416 1417 case CASE(OCMP, TINT64): 1418 case CASE(OCMP, TUINT64): 1419 case CASE(OCMP, TPTR64): 1420 a = ACMPQ; 1421 break; 1422 1423 case CASE(OCMP, TFLOAT32): 1424 a = AUCOMISS; 1425 break; 1426 1427 case CASE(OCMP, TFLOAT64): 1428 a = AUCOMISD; 1429 break; 1430 1431 case CASE(OAS, TBOOL): 1432 case CASE(OAS, TINT8): 1433 case CASE(OAS, TUINT8): 1434 a = AMOVB; 1435 break; 1436 1437 case CASE(OAS, TINT16): 1438 case CASE(OAS, TUINT16): 1439 a = AMOVW; 1440 break; 1441 1442 case CASE(OAS, TINT32): 1443 case CASE(OAS, TUINT32): 1444 case CASE(OAS, TPTR32): 1445 a = AMOVL; 1446 break; 1447 1448 case CASE(OAS, TINT64): 1449 case CASE(OAS, TUINT64): 1450 case CASE(OAS, TPTR64): 1451 a = AMOVQ; 1452 break; 1453 1454 case CASE(OAS, TFLOAT32): 1455 a = AMOVSS; 1456 break; 1457 1458 case CASE(OAS, TFLOAT64): 1459 a = AMOVSD; 1460 break; 1461 1462 case CASE(OADD, TINT8): 1463 case CASE(OADD, TUINT8): 1464 a = AADDB; 1465 break; 1466 1467 case CASE(OADD, TINT16): 1468 case CASE(OADD, TUINT16): 1469 a = AADDW; 1470 break; 1471 1472 case CASE(OADD, TINT32): 1473 case CASE(OADD, TUINT32): 1474 case CASE(OADD, TPTR32): 1475 a = AADDL; 1476 break; 1477 1478 case CASE(OADD, TINT64): 1479 case CASE(OADD, TUINT64): 1480 case CASE(OADD, TPTR64): 1481 a = AADDQ; 1482 break; 1483 1484 case CASE(OADD, TFLOAT32): 1485 a = AADDSS; 1486 break; 1487 1488 case CASE(OADD, TFLOAT64): 1489 a = AADDSD; 1490 break; 1491 1492 case CASE(OSUB, TINT8): 1493 case CASE(OSUB, TUINT8): 1494 a = ASUBB; 1495 break; 1496 1497 case CASE(OSUB, TINT16): 1498 case CASE(OSUB, TUINT16): 1499 a = ASUBW; 1500 break; 1501 1502 case CASE(OSUB, TINT32): 1503 case CASE(OSUB, TUINT32): 1504 case CASE(OSUB, TPTR32): 1505 a = ASUBL; 1506 break; 1507 1508 case CASE(OSUB, TINT64): 1509 case CASE(OSUB, TUINT64): 1510 case CASE(OSUB, TPTR64): 1511 a = ASUBQ; 1512 break; 1513 1514 case CASE(OSUB, TFLOAT32): 1515 a = ASUBSS; 1516 break; 1517 1518 case CASE(OSUB, TFLOAT64): 1519 a = ASUBSD; 1520 break; 1521 1522 case CASE(OINC, TINT8): 1523 case CASE(OINC, TUINT8): 1524 a = AINCB; 1525 break; 1526 1527 case CASE(OINC, TINT16): 1528 case CASE(OINC, TUINT16): 1529 a = AINCW; 1530 break; 1531 1532 case CASE(OINC, TINT32): 1533 case CASE(OINC, TUINT32): 1534 case CASE(OINC, TPTR32): 1535 a = AINCL; 1536 break; 1537 1538 case CASE(OINC, TINT64): 1539 case CASE(OINC, TUINT64): 1540 case CASE(OINC, TPTR64): 1541 a = AINCQ; 1542 break; 1543 1544 case CASE(ODEC, TINT8): 1545 case CASE(ODEC, TUINT8): 1546 a = ADECB; 1547 break; 1548 1549 case CASE(ODEC, TINT16): 1550 case CASE(ODEC, TUINT16): 1551 a = ADECW; 1552 break; 1553 1554 case CASE(ODEC, TINT32): 1555 case CASE(ODEC, TUINT32): 1556 case CASE(ODEC, TPTR32): 1557 a = ADECL; 1558 break; 1559 1560 case CASE(ODEC, TINT64): 1561 case CASE(ODEC, TUINT64): 1562 case CASE(ODEC, TPTR64): 1563 a = ADECQ; 1564 break; 1565 1566 case CASE(OMINUS, TINT8): 1567 case CASE(OMINUS, TUINT8): 1568 a = ANEGB; 1569 break; 1570 1571 case CASE(OMINUS, TINT16): 1572 case CASE(OMINUS, TUINT16): 1573 a = ANEGW; 1574 break; 1575 1576 case CASE(OMINUS, TINT32): 1577 case CASE(OMINUS, TUINT32): 1578 case CASE(OMINUS, TPTR32): 1579 a = ANEGL; 1580 break; 1581 1582 case CASE(OMINUS, TINT64): 1583 case CASE(OMINUS, TUINT64): 1584 case CASE(OMINUS, TPTR64): 1585 a = ANEGQ; 1586 break; 1587 1588 case CASE(OAND, TINT8): 1589 case CASE(OAND, TUINT8): 1590 a = AANDB; 1591 break; 1592 1593 case CASE(OAND, TINT16): 1594 case CASE(OAND, TUINT16): 1595 a = AANDW; 1596 break; 1597 1598 case CASE(OAND, TINT32): 1599 case CASE(OAND, TUINT32): 1600 case CASE(OAND, TPTR32): 1601 a = AANDL; 1602 break; 1603 1604 case CASE(OAND, TINT64): 1605 case CASE(OAND, TUINT64): 1606 case CASE(OAND, TPTR64): 1607 a = AANDQ; 1608 break; 1609 1610 case CASE(OOR, TINT8): 1611 case CASE(OOR, TUINT8): 1612 a = AORB; 1613 break; 1614 1615 case CASE(OOR, TINT16): 1616 case CASE(OOR, TUINT16): 1617 a = AORW; 1618 break; 1619 1620 case CASE(OOR, TINT32): 1621 case CASE(OOR, TUINT32): 1622 case CASE(OOR, TPTR32): 1623 a = AORL; 1624 break; 1625 1626 case CASE(OOR, TINT64): 1627 case CASE(OOR, TUINT64): 1628 case CASE(OOR, TPTR64): 1629 a = AORQ; 1630 break; 1631 1632 case CASE(OXOR, TINT8): 1633 case CASE(OXOR, TUINT8): 1634 a = AXORB; 1635 break; 1636 1637 case CASE(OXOR, TINT16): 1638 case CASE(OXOR, TUINT16): 1639 a = AXORW; 1640 break; 1641 1642 case CASE(OXOR, TINT32): 1643 case CASE(OXOR, TUINT32): 1644 case CASE(OXOR, TPTR32): 1645 a = AXORL; 1646 break; 1647 1648 case CASE(OXOR, TINT64): 1649 case CASE(OXOR, TUINT64): 1650 case CASE(OXOR, TPTR64): 1651 a = AXORQ; 1652 break; 1653 1654 case CASE(OLROT, TINT8): 1655 case CASE(OLROT, TUINT8): 1656 a = AROLB; 1657 break; 1658 1659 case CASE(OLROT, TINT16): 1660 case CASE(OLROT, TUINT16): 1661 a = AROLW; 1662 break; 1663 1664 case CASE(OLROT, TINT32): 1665 case CASE(OLROT, TUINT32): 1666 case CASE(OLROT, TPTR32): 1667 a = AROLL; 1668 break; 1669 1670 case CASE(OLROT, TINT64): 1671 case CASE(OLROT, TUINT64): 1672 case CASE(OLROT, TPTR64): 1673 a = AROLQ; 1674 break; 1675 1676 case CASE(OLSH, TINT8): 1677 case CASE(OLSH, TUINT8): 1678 a = ASHLB; 1679 break; 1680 1681 case CASE(OLSH, TINT16): 1682 case CASE(OLSH, TUINT16): 1683 a = ASHLW; 1684 break; 1685 1686 case CASE(OLSH, TINT32): 1687 case CASE(OLSH, TUINT32): 1688 case CASE(OLSH, TPTR32): 1689 a = ASHLL; 1690 break; 1691 1692 case CASE(OLSH, TINT64): 1693 case CASE(OLSH, TUINT64): 1694 case CASE(OLSH, TPTR64): 1695 a = ASHLQ; 1696 break; 1697 1698 case CASE(ORSH, TUINT8): 1699 a = ASHRB; 1700 break; 1701 1702 case CASE(ORSH, TUINT16): 1703 a = ASHRW; 1704 break; 1705 1706 case CASE(ORSH, TUINT32): 1707 case CASE(ORSH, TPTR32): 1708 a = ASHRL; 1709 break; 1710 1711 case CASE(ORSH, TUINT64): 1712 case CASE(ORSH, TPTR64): 1713 a = ASHRQ; 1714 break; 1715 1716 case CASE(ORSH, TINT8): 1717 a = ASARB; 1718 break; 1719 1720 case CASE(ORSH, TINT16): 1721 a = ASARW; 1722 break; 1723 1724 case CASE(ORSH, TINT32): 1725 a = ASARL; 1726 break; 1727 1728 case CASE(ORSH, TINT64): 1729 a = ASARQ; 1730 break; 1731 1732 case CASE(ORROTC, TINT8): 1733 case CASE(ORROTC, TUINT8): 1734 a = ARCRB; 1735 break; 1736 1737 case CASE(ORROTC, TINT16): 1738 case CASE(ORROTC, TUINT16): 1739 a = ARCRW; 1740 break; 1741 1742 case CASE(ORROTC, TINT32): 1743 case CASE(ORROTC, TUINT32): 1744 a = ARCRL; 1745 break; 1746 1747 case CASE(ORROTC, TINT64): 1748 case CASE(ORROTC, TUINT64): 1749 a = ARCRQ; 1750 break; 1751 1752 case CASE(OHMUL, TINT8): 1753 case CASE(OMUL, TINT8): 1754 case CASE(OMUL, TUINT8): 1755 a = AIMULB; 1756 break; 1757 1758 case CASE(OHMUL, TINT16): 1759 case CASE(OMUL, TINT16): 1760 case CASE(OMUL, TUINT16): 1761 a = AIMULW; 1762 break; 1763 1764 case CASE(OHMUL, TINT32): 1765 case CASE(OMUL, TINT32): 1766 case CASE(OMUL, TUINT32): 1767 case CASE(OMUL, TPTR32): 1768 a = AIMULL; 1769 break; 1770 1771 case CASE(OHMUL, TINT64): 1772 case CASE(OMUL, TINT64): 1773 case CASE(OMUL, TUINT64): 1774 case CASE(OMUL, TPTR64): 1775 a = AIMULQ; 1776 break; 1777 1778 case CASE(OHMUL, TUINT8): 1779 a = AMULB; 1780 break; 1781 1782 case CASE(OHMUL, TUINT16): 1783 a = AMULW; 1784 break; 1785 1786 case CASE(OHMUL, TUINT32): 1787 case CASE(OHMUL, TPTR32): 1788 a = AMULL; 1789 break; 1790 1791 case CASE(OHMUL, TUINT64): 1792 case CASE(OHMUL, TPTR64): 1793 a = AMULQ; 1794 break; 1795 1796 case CASE(OMUL, TFLOAT32): 1797 a = AMULSS; 1798 break; 1799 1800 case CASE(OMUL, TFLOAT64): 1801 a = AMULSD; 1802 break; 1803 1804 case CASE(ODIV, TINT8): 1805 case CASE(OMOD, TINT8): 1806 a = AIDIVB; 1807 break; 1808 1809 case CASE(ODIV, TUINT8): 1810 case CASE(OMOD, TUINT8): 1811 a = ADIVB; 1812 break; 1813 1814 case CASE(ODIV, TINT16): 1815 case CASE(OMOD, TINT16): 1816 a = AIDIVW; 1817 break; 1818 1819 case CASE(ODIV, TUINT16): 1820 case CASE(OMOD, TUINT16): 1821 a = ADIVW; 1822 break; 1823 1824 case CASE(ODIV, TINT32): 1825 case CASE(OMOD, TINT32): 1826 a = AIDIVL; 1827 break; 1828 1829 case CASE(ODIV, TUINT32): 1830 case CASE(ODIV, TPTR32): 1831 case CASE(OMOD, TUINT32): 1832 case CASE(OMOD, TPTR32): 1833 a = ADIVL; 1834 break; 1835 1836 case CASE(ODIV, TINT64): 1837 case CASE(OMOD, TINT64): 1838 a = AIDIVQ; 1839 break; 1840 1841 case CASE(ODIV, TUINT64): 1842 case CASE(ODIV, TPTR64): 1843 case CASE(OMOD, TUINT64): 1844 case CASE(OMOD, TPTR64): 1845 a = ADIVQ; 1846 break; 1847 1848 case CASE(OEXTEND, TINT16): 1849 a = ACWD; 1850 break; 1851 1852 case CASE(OEXTEND, TINT32): 1853 a = ACDQ; 1854 break; 1855 1856 case CASE(OEXTEND, TINT64): 1857 a = ACQO; 1858 break; 1859 1860 case CASE(ODIV, TFLOAT32): 1861 a = ADIVSS; 1862 break; 1863 1864 case CASE(ODIV, TFLOAT64): 1865 a = ADIVSD; 1866 break; 1867 1868 } 1869 return a; 1870 } 1871 1872 enum 1873 { 1874 ODynam = 1<<0, 1875 OAddable = 1<<1, 1876 }; 1877 1878 static Node clean[20]; 1879 static int cleani = 0; 1880 1881 int 1882 xgen(Node *n, Node *a, int o) 1883 { 1884 regalloc(a, types[tptr], N); 1885 1886 if(o & ODynam) 1887 if(n->addable) 1888 if(n->op != OINDREG) 1889 if(n->op != OREGISTER) 1890 return 1; 1891 1892 agen(n, a); 1893 return 0; 1894 } 1895 1896 void 1897 sudoclean(void) 1898 { 1899 if(clean[cleani-1].op != OEMPTY) 1900 regfree(&clean[cleani-1]); 1901 if(clean[cleani-2].op != OEMPTY) 1902 regfree(&clean[cleani-2]); 1903 cleani -= 2; 1904 } 1905 1906 /* 1907 * generate code to compute address of n, 1908 * a reference to a (perhaps nested) field inside 1909 * an array or struct. 1910 * return 0 on failure, 1 on success. 1911 * on success, leaves usable address in a. 1912 * 1913 * caller is responsible for calling sudoclean 1914 * after successful sudoaddable, 1915 * to release the register used for a. 1916 */ 1917 int 1918 sudoaddable(int as, Node *n, Addr *a) 1919 { 1920 int o, i; 1921 int64 oary[10]; 1922 int64 v, w; 1923 Node n1, n2, n3, n4, *nn, *l, *r; 1924 Node *reg, *reg1; 1925 Prog *p1; 1926 Type *t; 1927 1928 if(n->type == T) 1929 return 0; 1930 1931 switch(n->op) { 1932 case OLITERAL: 1933 if(!isconst(n, CTINT)) 1934 break; 1935 v = mpgetfix(n->val.u.xval); 1936 if(v >= 32000 || v <= -32000) 1937 break; 1938 goto lit; 1939 1940 case ODOT: 1941 case ODOTPTR: 1942 cleani += 2; 1943 reg = &clean[cleani-1]; 1944 reg1 = &clean[cleani-2]; 1945 reg->op = OEMPTY; 1946 reg1->op = OEMPTY; 1947 goto odot; 1948 1949 case OINDEX: 1950 return 0; 1951 // disabled: OINDEX case is now covered by agenr 1952 // for a more suitable register allocation pattern. 1953 if(n->left->type->etype == TSTRING) 1954 return 0; 1955 goto oindex; 1956 } 1957 return 0; 1958 1959 lit: 1960 switch(as) { 1961 default: 1962 return 0; 1963 case AADDB: case AADDW: case AADDL: case AADDQ: 1964 case ASUBB: case ASUBW: case ASUBL: case ASUBQ: 1965 case AANDB: case AANDW: case AANDL: case AANDQ: 1966 case AORB: case AORW: case AORL: case AORQ: 1967 case AXORB: case AXORW: case AXORL: case AXORQ: 1968 case AINCB: case AINCW: case AINCL: case AINCQ: 1969 case ADECB: case ADECW: case ADECL: case ADECQ: 1970 case AMOVB: case AMOVW: case AMOVL: case AMOVQ: 1971 break; 1972 } 1973 1974 cleani += 2; 1975 reg = &clean[cleani-1]; 1976 reg1 = &clean[cleani-2]; 1977 reg->op = OEMPTY; 1978 reg1->op = OEMPTY; 1979 naddr(n, a, 1); 1980 goto yes; 1981 1982 odot: 1983 o = dotoffset(n, oary, &nn); 1984 if(nn == N) 1985 goto no; 1986 1987 if(nn->addable && o == 1 && oary[0] >= 0) { 1988 // directly addressable set of DOTs 1989 n1 = *nn; 1990 n1.type = n->type; 1991 n1.xoffset += oary[0]; 1992 naddr(&n1, a, 1); 1993 goto yes; 1994 } 1995 1996 regalloc(reg, types[tptr], N); 1997 n1 = *reg; 1998 n1.op = OINDREG; 1999 if(oary[0] >= 0) { 2000 agen(nn, reg); 2001 n1.xoffset = oary[0]; 2002 } else { 2003 cgen(nn, reg); 2004 cgen_checknil(reg); 2005 n1.xoffset = -(oary[0]+1); 2006 } 2007 2008 for(i=1; i<o; i++) { 2009 if(oary[i] >= 0) 2010 fatal("can't happen"); 2011 gins(AMOVQ, &n1, reg); 2012 cgen_checknil(reg); 2013 n1.xoffset = -(oary[i]+1); 2014 } 2015 2016 a->type = D_NONE; 2017 a->index = D_NONE; 2018 naddr(&n1, a, 1); 2019 goto yes; 2020 2021 oindex: 2022 l = n->left; 2023 r = n->right; 2024 if(l->ullman >= UINF && r->ullman >= UINF) 2025 return 0; 2026 2027 // set o to type of array 2028 o = 0; 2029 if(isptr[l->type->etype]) 2030 fatal("ptr ary"); 2031 if(l->type->etype != TARRAY) 2032 fatal("not ary"); 2033 if(l->type->bound < 0) 2034 o |= ODynam; 2035 2036 w = n->type->width; 2037 if(isconst(r, CTINT)) 2038 goto oindex_const; 2039 2040 switch(w) { 2041 default: 2042 return 0; 2043 case 1: 2044 case 2: 2045 case 4: 2046 case 8: 2047 break; 2048 } 2049 2050 cleani += 2; 2051 reg = &clean[cleani-1]; 2052 reg1 = &clean[cleani-2]; 2053 reg->op = OEMPTY; 2054 reg1->op = OEMPTY; 2055 2056 // load the array (reg) 2057 if(l->ullman > r->ullman) { 2058 if(xgen(l, reg, o)) 2059 o |= OAddable; 2060 } 2061 2062 // load the index (reg1) 2063 t = types[TUINT64]; 2064 if(issigned[r->type->etype]) 2065 t = types[TINT64]; 2066 regalloc(reg1, t, N); 2067 regalloc(&n3, r->type, reg1); 2068 cgen(r, &n3); 2069 gmove(&n3, reg1); 2070 regfree(&n3); 2071 2072 // load the array (reg) 2073 if(l->ullman <= r->ullman) { 2074 if(xgen(l, reg, o)) 2075 o |= OAddable; 2076 } 2077 2078 // check bounds 2079 if(!debug['B'] && !n->bounded) { 2080 // check bounds 2081 n4.op = OXXX; 2082 t = types[simtype[TUINT]]; 2083 if(o & ODynam) { 2084 if(o & OAddable) { 2085 n2 = *l; 2086 n2.xoffset += Array_nel; 2087 n2.type = types[simtype[TUINT]]; 2088 } else { 2089 n2 = *reg; 2090 n2.xoffset = Array_nel; 2091 n2.op = OINDREG; 2092 n2.type = types[simtype[TUINT]]; 2093 } 2094 } else { 2095 if(is64(r->type)) 2096 t = types[TUINT64]; 2097 nodconst(&n2, types[TUINT64], l->type->bound); 2098 } 2099 gins(optoas(OCMP, t), reg1, &n2); 2100 p1 = gbranch(optoas(OLT, t), T, +1); 2101 if(n4.op != OXXX) 2102 regfree(&n4); 2103 ginscall(panicindex, -1); 2104 patch(p1, pc); 2105 } 2106 2107 if(o & ODynam) { 2108 if(o & OAddable) { 2109 n2 = *l; 2110 n2.xoffset += Array_array; 2111 n2.type = types[tptr]; 2112 gmove(&n2, reg); 2113 } else { 2114 n2 = *reg; 2115 n2.op = OINDREG; 2116 n2.xoffset = Array_array; 2117 n2.type = types[tptr]; 2118 gmove(&n2, reg); 2119 } 2120 } 2121 2122 if(o & OAddable) { 2123 naddr(reg1, a, 1); 2124 a->offset = 0; 2125 a->scale = w; 2126 a->index = a->type; 2127 a->type = reg->val.u.reg + D_INDIR; 2128 } else { 2129 naddr(reg1, a, 1); 2130 a->offset = 0; 2131 a->scale = w; 2132 a->index = a->type; 2133 a->type = reg->val.u.reg + D_INDIR; 2134 } 2135 2136 goto yes; 2137 2138 oindex_const: 2139 // index is constant 2140 // can check statically and 2141 // can multiply by width statically 2142 2143 v = mpgetfix(r->val.u.xval); 2144 2145 if(sudoaddable(as, l, a)) 2146 goto oindex_const_sudo; 2147 2148 cleani += 2; 2149 reg = &clean[cleani-1]; 2150 reg1 = &clean[cleani-2]; 2151 reg->op = OEMPTY; 2152 reg1->op = OEMPTY; 2153 2154 if(o & ODynam) { 2155 regalloc(reg, types[tptr], N); 2156 agen(l, reg); 2157 2158 if(!debug['B'] && !n->bounded) { 2159 n1 = *reg; 2160 n1.op = OINDREG; 2161 n1.type = types[tptr]; 2162 n1.xoffset = Array_nel; 2163 nodconst(&n2, types[TUINT64], v); 2164 gins(optoas(OCMP, types[simtype[TUINT]]), &n1, &n2); 2165 p1 = gbranch(optoas(OGT, types[simtype[TUINT]]), T, +1); 2166 ginscall(panicindex, -1); 2167 patch(p1, pc); 2168 } 2169 2170 n1 = *reg; 2171 n1.op = OINDREG; 2172 n1.type = types[tptr]; 2173 n1.xoffset = Array_array; 2174 gmove(&n1, reg); 2175 2176 n2 = *reg; 2177 n2.op = OINDREG; 2178 n2.xoffset = v*w; 2179 a->type = D_NONE; 2180 a->index = D_NONE; 2181 naddr(&n2, a, 1); 2182 goto yes; 2183 } 2184 2185 igen(l, &n1, N); 2186 if(n1.op == OINDREG) { 2187 *reg = n1; 2188 reg->op = OREGISTER; 2189 } 2190 n1.xoffset += v*w; 2191 a->type = D_NONE; 2192 a->index= D_NONE; 2193 naddr(&n1, a, 1); 2194 goto yes; 2195 2196 oindex_const_sudo: 2197 if((o & ODynam) == 0) { 2198 // array indexed by a constant 2199 a->offset += v*w; 2200 goto yes; 2201 } 2202 2203 // slice indexed by a constant 2204 if(!debug['B'] && !n->bounded) { 2205 a->offset += Array_nel; 2206 nodconst(&n2, types[TUINT64], v); 2207 p1 = gins(optoas(OCMP, types[simtype[TUINT]]), N, &n2); 2208 p1->from = *a; 2209 p1 = gbranch(optoas(OGT, types[simtype[TUINT]]), T, +1); 2210 ginscall(panicindex, -1); 2211 patch(p1, pc); 2212 a->offset -= Array_nel; 2213 } 2214 2215 a->offset += Array_array; 2216 reg = &clean[cleani-1]; 2217 if(reg->op == OEMPTY) 2218 regalloc(reg, types[tptr], N); 2219 2220 p1 = gins(AMOVQ, N, reg); 2221 p1->from = *a; 2222 2223 n2 = *reg; 2224 n2.op = OINDREG; 2225 n2.xoffset = v*w; 2226 a->type = D_NONE; 2227 a->index = D_NONE; 2228 naddr(&n2, a, 1); 2229 goto yes; 2230 2231 yes: 2232 return 1; 2233 2234 no: 2235 sudoclean(); 2236 return 0; 2237 }