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