github.com/hongwozai/go-src-1.4.3@v0.0.0-20191127132709-dc3fce3dbccb/src/cmd/gc/align.c (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include <u.h> 6 #include <libc.h> 7 #include "go.h" 8 9 /* 10 * machine size and rounding 11 * alignment is dictated around 12 * the size of a pointer, set in betypeinit 13 * (see ../6g/galign.c). 14 */ 15 16 static int defercalc; 17 18 vlong 19 rnd(vlong o, vlong r) 20 { 21 if(r < 1 || r > 8 || (r&(r-1)) != 0) 22 fatal("rnd"); 23 return (o+r-1)&~(r-1); 24 } 25 26 static void 27 offmod(Type *t) 28 { 29 Type *f; 30 int32 o; 31 32 o = 0; 33 for(f=t->type; f!=T; f=f->down) { 34 if(f->etype != TFIELD) 35 fatal("offmod: not TFIELD: %lT", f); 36 f->width = o; 37 o += widthptr; 38 if(o >= MAXWIDTH) { 39 yyerror("interface too large"); 40 o = widthptr; 41 } 42 } 43 } 44 45 static vlong 46 widstruct(Type *errtype, Type *t, vlong o, int flag) 47 { 48 Type *f; 49 int64 w; 50 int32 maxalign; 51 52 maxalign = flag; 53 if(maxalign < 1) 54 maxalign = 1; 55 for(f=t->type; f!=T; f=f->down) { 56 if(f->etype != TFIELD) 57 fatal("widstruct: not TFIELD: %lT", f); 58 if(f->type == T) { 59 // broken field, just skip it so that other valid fields 60 // get a width. 61 continue; 62 } 63 dowidth(f->type); 64 if(f->type->align > maxalign) 65 maxalign = f->type->align; 66 if(f->type->width < 0) 67 fatal("invalid width %lld", f->type->width); 68 w = f->type->width; 69 if(f->type->align > 0) 70 o = rnd(o, f->type->align); 71 f->width = o; // really offset for TFIELD 72 if(f->nname != N) { 73 // this same stackparam logic is in addrescapes 74 // in typecheck.c. usually addrescapes runs after 75 // widstruct, in which case we could drop this, 76 // but function closure functions are the exception. 77 if(f->nname->stackparam) { 78 f->nname->stackparam->xoffset = o; 79 f->nname->xoffset = 0; 80 } else 81 f->nname->xoffset = o; 82 } 83 o += w; 84 if(o >= MAXWIDTH) { 85 yyerror("type %lT too large", errtype); 86 o = 8; // small but nonzero 87 } 88 } 89 // final width is rounded 90 if(flag) 91 o = rnd(o, maxalign); 92 t->align = maxalign; 93 94 // type width only includes back to first field's offset 95 if(t->type == T) 96 t->width = 0; 97 else 98 t->width = o - t->type->width; 99 return o; 100 } 101 102 void 103 dowidth(Type *t) 104 { 105 int32 et; 106 int64 w; 107 int lno; 108 Type *t1; 109 110 if(widthptr == 0) 111 fatal("dowidth without betypeinit"); 112 113 if(t == T) 114 return; 115 116 if(t->width > 0) 117 return; 118 119 if(t->width == -2) { 120 lno = lineno; 121 lineno = t->lineno; 122 if(!t->broke) { 123 t->broke = 1; 124 yyerror("invalid recursive type %T", t); 125 } 126 t->width = 0; 127 lineno = lno; 128 return; 129 } 130 131 // break infinite recursion if the broken recursive type 132 // is referenced again 133 if(t->broke && t->width == 0) 134 return; 135 136 // defer checkwidth calls until after we're done 137 defercalc++; 138 139 lno = lineno; 140 lineno = t->lineno; 141 t->width = -2; 142 t->align = 0; 143 144 et = t->etype; 145 switch(et) { 146 case TFUNC: 147 case TCHAN: 148 case TMAP: 149 case TSTRING: 150 break; 151 152 default: 153 /* simtype == 0 during bootstrap */ 154 if(simtype[t->etype] != 0) 155 et = simtype[t->etype]; 156 break; 157 } 158 159 w = 0; 160 switch(et) { 161 default: 162 fatal("dowidth: unknown type: %T", t); 163 break; 164 165 /* compiler-specific stuff */ 166 case TINT8: 167 case TUINT8: 168 case TBOOL: // bool is int8 169 w = 1; 170 break; 171 case TINT16: 172 case TUINT16: 173 w = 2; 174 break; 175 case TINT32: 176 case TUINT32: 177 case TFLOAT32: 178 w = 4; 179 break; 180 case TINT64: 181 case TUINT64: 182 case TFLOAT64: 183 case TCOMPLEX64: 184 w = 8; 185 t->align = widthreg; 186 break; 187 case TCOMPLEX128: 188 w = 16; 189 t->align = widthreg; 190 break; 191 case TPTR32: 192 w = 4; 193 checkwidth(t->type); 194 break; 195 case TPTR64: 196 w = 8; 197 checkwidth(t->type); 198 break; 199 case TUNSAFEPTR: 200 w = widthptr; 201 break; 202 case TINTER: // implemented as 2 pointers 203 w = 2*widthptr; 204 t->align = widthptr; 205 offmod(t); 206 break; 207 case TCHAN: // implemented as pointer 208 w = widthptr; 209 checkwidth(t->type); 210 211 // make fake type to check later to 212 // trigger channel argument check. 213 t1 = typ(TCHANARGS); 214 t1->type = t; 215 checkwidth(t1); 216 break; 217 case TCHANARGS: 218 t1 = t->type; 219 dowidth(t->type); // just in case 220 if(t1->type->width >= (1<<16)) 221 yyerror("channel element type too large (>64kB)"); 222 t->width = 1; 223 break; 224 case TMAP: // implemented as pointer 225 w = widthptr; 226 checkwidth(t->type); 227 checkwidth(t->down); 228 break; 229 case TFORW: // should have been filled in 230 if(!t->broke) 231 yyerror("invalid recursive type %T", t); 232 w = 1; // anything will do 233 break; 234 case TANY: 235 // dummy type; should be replaced before use. 236 if(!debug['A']) 237 fatal("dowidth any"); 238 w = 1; // anything will do 239 break; 240 case TSTRING: 241 if(sizeof_String == 0) 242 fatal("early dowidth string"); 243 w = sizeof_String; 244 t->align = widthptr; 245 break; 246 case TARRAY: 247 if(t->type == T) 248 break; 249 if(t->bound >= 0) { 250 uint64 cap; 251 252 dowidth(t->type); 253 if(t->type->width != 0) { 254 cap = (MAXWIDTH-1) / t->type->width; 255 if(t->bound > cap) 256 yyerror("type %lT larger than address space", t); 257 } 258 w = t->bound * t->type->width; 259 t->align = t->type->align; 260 } 261 else if(t->bound == -1) { 262 w = sizeof_Array; 263 checkwidth(t->type); 264 t->align = widthptr; 265 } 266 else if(t->bound == -100) { 267 if(!t->broke) { 268 yyerror("use of [...] array outside of array literal"); 269 t->broke = 1; 270 } 271 } 272 else 273 fatal("dowidth %T", t); // probably [...]T 274 break; 275 276 case TSTRUCT: 277 if(t->funarg) 278 fatal("dowidth fn struct %T", t); 279 w = widstruct(t, t, 0, 1); 280 break; 281 282 case TFUNC: 283 // make fake type to check later to 284 // trigger function argument computation. 285 t1 = typ(TFUNCARGS); 286 t1->type = t; 287 checkwidth(t1); 288 289 // width of func type is pointer 290 w = widthptr; 291 break; 292 293 case TFUNCARGS: 294 // function is 3 cated structures; 295 // compute their widths as side-effect. 296 t1 = t->type; 297 w = widstruct(t->type, *getthis(t1), 0, 0); 298 w = widstruct(t->type, *getinarg(t1), w, widthreg); 299 w = widstruct(t->type, *getoutarg(t1), w, widthreg); 300 t1->argwid = w; 301 if(w%widthreg) 302 warn("bad type %T %d\n", t1, w); 303 t->align = 1; 304 break; 305 } 306 307 if(widthptr == 4 && w != (int32)w) 308 yyerror("type %T too large", t); 309 310 t->width = w; 311 if(t->align == 0) { 312 if(w > 8 || (w&(w-1)) != 0) 313 fatal("invalid alignment for %T", t); 314 t->align = w; 315 } 316 lineno = lno; 317 318 if(defercalc == 1) 319 resumecheckwidth(); 320 else 321 --defercalc; 322 } 323 324 /* 325 * when a type's width should be known, we call checkwidth 326 * to compute it. during a declaration like 327 * 328 * type T *struct { next T } 329 * 330 * it is necessary to defer the calculation of the struct width 331 * until after T has been initialized to be a pointer to that struct. 332 * similarly, during import processing structs may be used 333 * before their definition. in those situations, calling 334 * defercheckwidth() stops width calculations until 335 * resumecheckwidth() is called, at which point all the 336 * checkwidths that were deferred are executed. 337 * dowidth should only be called when the type's size 338 * is needed immediately. checkwidth makes sure the 339 * size is evaluated eventually. 340 */ 341 typedef struct TypeList TypeList; 342 struct TypeList { 343 Type *t; 344 TypeList *next; 345 }; 346 347 static TypeList *tlfree; 348 static TypeList *tlq; 349 350 void 351 checkwidth(Type *t) 352 { 353 TypeList *l; 354 355 if(t == T) 356 return; 357 358 // function arg structs should not be checked 359 // outside of the enclosing function. 360 if(t->funarg) 361 fatal("checkwidth %T", t); 362 363 if(!defercalc) { 364 dowidth(t); 365 return; 366 } 367 if(t->deferwidth) 368 return; 369 t->deferwidth = 1; 370 371 l = tlfree; 372 if(l != nil) 373 tlfree = l->next; 374 else 375 l = mal(sizeof *l); 376 377 l->t = t; 378 l->next = tlq; 379 tlq = l; 380 } 381 382 void 383 defercheckwidth(void) 384 { 385 // we get out of sync on syntax errors, so don't be pedantic. 386 if(defercalc && nerrors == 0) 387 fatal("defercheckwidth"); 388 defercalc = 1; 389 } 390 391 void 392 resumecheckwidth(void) 393 { 394 TypeList *l; 395 396 if(!defercalc) 397 fatal("resumecheckwidth"); 398 for(l = tlq; l != nil; l = tlq) { 399 l->t->deferwidth = 0; 400 tlq = l->next; 401 dowidth(l->t); 402 l->next = tlfree; 403 tlfree = l; 404 } 405 defercalc = 0; 406 } 407 408 void 409 typeinit(void) 410 { 411 int i, etype, sameas; 412 Type *t; 413 Sym *s, *s1; 414 415 if(widthptr == 0) 416 fatal("typeinit before betypeinit"); 417 418 for(i=0; i<NTYPE; i++) 419 simtype[i] = i; 420 421 types[TPTR32] = typ(TPTR32); 422 dowidth(types[TPTR32]); 423 424 types[TPTR64] = typ(TPTR64); 425 dowidth(types[TPTR64]); 426 427 t = typ(TUNSAFEPTR); 428 types[TUNSAFEPTR] = t; 429 t->sym = pkglookup("Pointer", unsafepkg); 430 t->sym->def = typenod(t); 431 432 dowidth(types[TUNSAFEPTR]); 433 434 tptr = TPTR32; 435 if(widthptr == 8) 436 tptr = TPTR64; 437 438 for(i=TINT8; i<=TUINT64; i++) 439 isint[i] = 1; 440 isint[TINT] = 1; 441 isint[TUINT] = 1; 442 isint[TUINTPTR] = 1; 443 444 isfloat[TFLOAT32] = 1; 445 isfloat[TFLOAT64] = 1; 446 447 iscomplex[TCOMPLEX64] = 1; 448 iscomplex[TCOMPLEX128] = 1; 449 450 isptr[TPTR32] = 1; 451 isptr[TPTR64] = 1; 452 453 isforw[TFORW] = 1; 454 455 issigned[TINT] = 1; 456 issigned[TINT8] = 1; 457 issigned[TINT16] = 1; 458 issigned[TINT32] = 1; 459 issigned[TINT64] = 1; 460 461 /* 462 * initialize okfor 463 */ 464 for(i=0; i<NTYPE; i++) { 465 if(isint[i] || i == TIDEAL) { 466 okforeq[i] = 1; 467 okforcmp[i] = 1; 468 okforarith[i] = 1; 469 okforadd[i] = 1; 470 okforand[i] = 1; 471 okforconst[i] = 1; 472 issimple[i] = 1; 473 minintval[i] = mal(sizeof(*minintval[i])); 474 maxintval[i] = mal(sizeof(*maxintval[i])); 475 } 476 if(isfloat[i]) { 477 okforeq[i] = 1; 478 okforcmp[i] = 1; 479 okforadd[i] = 1; 480 okforarith[i] = 1; 481 okforconst[i] = 1; 482 issimple[i] = 1; 483 minfltval[i] = mal(sizeof(*minfltval[i])); 484 maxfltval[i] = mal(sizeof(*maxfltval[i])); 485 } 486 if(iscomplex[i]) { 487 okforeq[i] = 1; 488 okforadd[i] = 1; 489 okforarith[i] = 1; 490 okforconst[i] = 1; 491 issimple[i] = 1; 492 } 493 } 494 495 issimple[TBOOL] = 1; 496 497 okforadd[TSTRING] = 1; 498 499 okforbool[TBOOL] = 1; 500 501 okforcap[TARRAY] = 1; 502 okforcap[TCHAN] = 1; 503 504 okforconst[TBOOL] = 1; 505 okforconst[TSTRING] = 1; 506 507 okforlen[TARRAY] = 1; 508 okforlen[TCHAN] = 1; 509 okforlen[TMAP] = 1; 510 okforlen[TSTRING] = 1; 511 512 okforeq[TPTR32] = 1; 513 okforeq[TPTR64] = 1; 514 okforeq[TUNSAFEPTR] = 1; 515 okforeq[TINTER] = 1; 516 okforeq[TCHAN] = 1; 517 okforeq[TSTRING] = 1; 518 okforeq[TBOOL] = 1; 519 okforeq[TMAP] = 1; // nil only; refined in typecheck 520 okforeq[TFUNC] = 1; // nil only; refined in typecheck 521 okforeq[TARRAY] = 1; // nil slice only; refined in typecheck 522 okforeq[TSTRUCT] = 1; // it's complicated; refined in typecheck 523 524 okforcmp[TSTRING] = 1; 525 526 for(i=0; i<nelem(okfor); i++) 527 okfor[i] = okfornone; 528 529 // binary 530 okfor[OADD] = okforadd; 531 okfor[OAND] = okforand; 532 okfor[OANDAND] = okforbool; 533 okfor[OANDNOT] = okforand; 534 okfor[ODIV] = okforarith; 535 okfor[OEQ] = okforeq; 536 okfor[OGE] = okforcmp; 537 okfor[OGT] = okforcmp; 538 okfor[OLE] = okforcmp; 539 okfor[OLT] = okforcmp; 540 okfor[OMOD] = okforand; 541 okfor[OMUL] = okforarith; 542 okfor[ONE] = okforeq; 543 okfor[OOR] = okforand; 544 okfor[OOROR] = okforbool; 545 okfor[OSUB] = okforarith; 546 okfor[OXOR] = okforand; 547 okfor[OLSH] = okforand; 548 okfor[ORSH] = okforand; 549 550 // unary 551 okfor[OCOM] = okforand; 552 okfor[OMINUS] = okforarith; 553 okfor[ONOT] = okforbool; 554 okfor[OPLUS] = okforarith; 555 556 // special 557 okfor[OCAP] = okforcap; 558 okfor[OLEN] = okforlen; 559 560 // comparison 561 iscmp[OLT] = 1; 562 iscmp[OGT] = 1; 563 iscmp[OGE] = 1; 564 iscmp[OLE] = 1; 565 iscmp[OEQ] = 1; 566 iscmp[ONE] = 1; 567 568 mpatofix(maxintval[TINT8], "0x7f"); 569 mpatofix(minintval[TINT8], "-0x80"); 570 mpatofix(maxintval[TINT16], "0x7fff"); 571 mpatofix(minintval[TINT16], "-0x8000"); 572 mpatofix(maxintval[TINT32], "0x7fffffff"); 573 mpatofix(minintval[TINT32], "-0x80000000"); 574 mpatofix(maxintval[TINT64], "0x7fffffffffffffff"); 575 mpatofix(minintval[TINT64], "-0x8000000000000000"); 576 577 mpatofix(maxintval[TUINT8], "0xff"); 578 mpatofix(maxintval[TUINT16], "0xffff"); 579 mpatofix(maxintval[TUINT32], "0xffffffff"); 580 mpatofix(maxintval[TUINT64], "0xffffffffffffffff"); 581 582 /* f is valid float if min < f < max. (min and max are not themselves valid.) */ 583 mpatoflt(maxfltval[TFLOAT32], "33554431p103"); /* 2^24-1 p (127-23) + 1/2 ulp*/ 584 mpatoflt(minfltval[TFLOAT32], "-33554431p103"); 585 mpatoflt(maxfltval[TFLOAT64], "18014398509481983p970"); /* 2^53-1 p (1023-52) + 1/2 ulp */ 586 mpatoflt(minfltval[TFLOAT64], "-18014398509481983p970"); 587 588 maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32]; 589 minfltval[TCOMPLEX64] = minfltval[TFLOAT32]; 590 maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64]; 591 minfltval[TCOMPLEX128] = minfltval[TFLOAT64]; 592 593 /* for walk to use in error messages */ 594 types[TFUNC] = functype(N, nil, nil); 595 596 /* types used in front end */ 597 // types[TNIL] got set early in lexinit 598 types[TIDEAL] = typ(TIDEAL); 599 types[TINTER] = typ(TINTER); 600 601 /* simple aliases */ 602 simtype[TMAP] = tptr; 603 simtype[TCHAN] = tptr; 604 simtype[TFUNC] = tptr; 605 simtype[TUNSAFEPTR] = tptr; 606 607 /* pick up the backend typedefs */ 608 for(i=0; typedefs[i].name; i++) { 609 s = lookup(typedefs[i].name); 610 s1 = pkglookup(typedefs[i].name, builtinpkg); 611 612 etype = typedefs[i].etype; 613 if(etype < 0 || etype >= nelem(types)) 614 fatal("typeinit: %s bad etype", s->name); 615 sameas = typedefs[i].sameas; 616 if(sameas < 0 || sameas >= nelem(types)) 617 fatal("typeinit: %s bad sameas", s->name); 618 simtype[etype] = sameas; 619 minfltval[etype] = minfltval[sameas]; 620 maxfltval[etype] = maxfltval[sameas]; 621 minintval[etype] = minintval[sameas]; 622 maxintval[etype] = maxintval[sameas]; 623 624 t = types[etype]; 625 if(t != T) 626 fatal("typeinit: %s already defined", s->name); 627 628 t = typ(etype); 629 t->sym = s1; 630 631 dowidth(t); 632 types[etype] = t; 633 s1->def = typenod(t); 634 } 635 636 Array_array = rnd(0, widthptr); 637 Array_nel = rnd(Array_array+widthptr, widthint); 638 Array_cap = rnd(Array_nel+widthint, widthint); 639 sizeof_Array = rnd(Array_cap+widthint, widthptr); 640 641 // string is same as slice wo the cap 642 sizeof_String = rnd(Array_nel+widthint, widthptr); 643 644 dowidth(types[TSTRING]); 645 dowidth(idealstring); 646 } 647 648 /* 649 * compute total size of f's in/out arguments. 650 */ 651 int 652 argsize(Type *t) 653 { 654 Iter save; 655 Type *fp; 656 int64 w, x; 657 658 w = 0; 659 660 fp = structfirst(&save, getoutarg(t)); 661 while(fp != T) { 662 x = fp->width + fp->type->width; 663 if(x > w) 664 w = x; 665 fp = structnext(&save); 666 } 667 668 fp = funcfirst(&save, t); 669 while(fp != T) { 670 x = fp->width + fp->type->width; 671 if(x > w) 672 w = x; 673 fp = funcnext(&save); 674 } 675 676 w = (w+widthptr-1) & ~(widthptr-1); 677 if((int)w != w) 678 fatal("argsize too big"); 679 return w; 680 }