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