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