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