The Go Programming Language

Text file src/cmd/gc/align.c

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

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.