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