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