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