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  }