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  }