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