Example #1
0
/*
 * compute total size of f's in/out arguments.
 */
int
argsize(Type *t)
{
	Iter save;
	Type *fp;
	int64 w, x;

	w = 0;

	fp = structfirst(&save, getoutarg(t));
	while(fp != T) {
		x = fp->width + fp->type->width;
		if(x > w)
			w = x;
		fp = structnext(&save);
	}

	fp = funcfirst(&save, t);
	while(fp != T) {
		x = fp->width + fp->type->width;
		if(x > w)
			w = x;
		fp = funcnext(&save);
	}

	w = (w+widthptr-1) & ~(widthptr-1);
	if((int)w != w)
		fatal("argsize too big");
	return w;
}
Example #2
0
File: align.c Project: 8l/go-learn
/*
 * compute total size of f's in/out arguments.
 */
int
argsize(Type *t)
{
	Iter save;
	Type *fp;
	int w, x;

	w = 0;

	fp = structfirst(&save, getoutarg(t));
	while(fp != T) {
		x = fp->width + fp->type->width;
		if(x > w)
			w = x;
		fp = structnext(&save);
	}

	fp = funcfirst(&save, t);
	while(fp != T) {
		x = fp->width + fp->type->width;
		if(x > w)
			w = x;
		fp = funcnext(&save);
	}

	w = (w+7) & ~7;
	return w;
}
Example #3
0
static void
setoutvar(void)
{
	Type *t;
	Node *n;
	Addr a;
	Iter save;
	Bits bit;
	int z;

	t = structfirst(&save, getoutarg(curfn->type));
	while(t != T) {
		n = nodarg(t, 1);
		a = zprog.from;
		naddr(n, &a, 0);
		bit = mkvar(R, &a);
		for(z=0; z<BITS; z++)
			ovar.b[z] |= bit.b[z];
		t = structnext(&save);
	}
//if(bany(&ovar))
//print("ovars = %Q\n", ovar);
}
Example #4
0
void
dowidth(Type *t)
{
	int32 et;
	int64 w;
	int lno;
	Type *t1;

	if(widthptr == 0)
		fatal("dowidth without betypeinit");

	if(t == T)
		return;

	if(t->width > 0)
		return;

	if(t->width == -2) {
		lno = lineno;
		lineno = t->lineno;
		if(!t->broke)
			yyerror("invalid recursive type %T", t);
		t->width = 0;
		lineno = lno;
		return;
	}

	// defer checkwidth calls until after we're done
	defercalc++;

	lno = lineno;
	lineno = t->lineno;
	t->width = -2;
	t->align = 0;

	et = t->etype;
	switch(et) {
	case TFUNC:
	case TCHAN:
	case TMAP:
	case TSTRING:
		break;

	default:
		/* simtype == 0 during bootstrap */
		if(simtype[t->etype] != 0)
			et = simtype[t->etype];
		break;
	}

	w = 0;
	switch(et) {
	default:
		fatal("dowidth: unknown type: %T", t);
		break;

	/* compiler-specific stuff */
	case TINT8:
	case TUINT8:
	case TBOOL:		// bool is int8
		w = 1;
		break;
	case TINT16:
	case TUINT16:
		w = 2;
		break;
	case TINT32:
	case TUINT32:
	case TFLOAT32:
		w = 4;
		break;
	case TINT64:
	case TUINT64:
	case TFLOAT64:
	case TCOMPLEX64:
		w = 8;
		t->align = widthreg;
		break;
	case TCOMPLEX128:
		w = 16;
		t->align = widthreg;
		break;
	case TPTR32:
		w = 4;
		checkwidth(t->type);
		break;
	case TPTR64:
		w = 8;
		checkwidth(t->type);
		break;
	case TUNSAFEPTR:
		w = widthptr;
		break;
	case TINTER:		// implemented as 2 pointers
		w = 2*widthptr;
		t->align = widthptr;
		offmod(t);
		break;
	case TCHAN:		// implemented as pointer
		w = widthptr;
		checkwidth(t->type);

		// make fake type to check later to
		// trigger channel argument check.
		t1 = typ(TCHANARGS);
		t1->type = t;
		checkwidth(t1);
		break;
	case TCHANARGS:
		t1 = t->type;
		dowidth(t->type);	// just in case
		if(t1->type->width >= (1<<16))
			yyerror("channel element type too large (>64kB)");
		t->width = 1;
		break;
	case TMAP:		// implemented as pointer
		w = widthptr;
		checkwidth(t->type);
		checkwidth(t->down);
		break;
	case TFORW:		// should have been filled in
		if(!t->broke)
			yyerror("invalid recursive type %T", t);
		w = 1;	// anything will do
		break;
	case TANY:
		// dummy type; should be replaced before use.
		if(!debug['A'])
			fatal("dowidth any");
		w = 1;	// anything will do
		break;
	case TSTRING:
		if(sizeof_String == 0)
			fatal("early dowidth string");
		w = sizeof_String;
		t->align = widthptr;
		break;
	case TARRAY:
		if(t->type == T)
			break;
		if(t->bound >= 0) {
			uint64 cap;

			dowidth(t->type);
			if(t->type->width != 0) {
				cap = (MAXWIDTH-1) / t->type->width;
				if(t->bound > cap)
					yyerror("type %lT larger than address space", t);
			}
			w = t->bound * t->type->width;
			t->align = t->type->align;
		}
		else if(t->bound == -1) {
			w = sizeof_Array;
			checkwidth(t->type);
			t->align = widthptr;
		}
		else if(t->bound == -100) {
			if(!t->broke) {
				yyerror("use of [...] array outside of array literal");
				t->broke = 1;
			}
		}
		else
			fatal("dowidth %T", t);	// probably [...]T
		break;

	case TSTRUCT:
		if(t->funarg)
			fatal("dowidth fn struct %T", t);
		w = widstruct(t, t, 0, 1);
		break;

	case TFUNC:
		// make fake type to check later to
		// trigger function argument computation.
		t1 = typ(TFUNCARGS);
		t1->type = t;
		checkwidth(t1);

		// width of func type is pointer
		w = widthptr;
		break;

	case TFUNCARGS:
		// function is 3 cated structures;
		// compute their widths as side-effect.
		t1 = t->type;
		w = widstruct(t->type, *getthis(t1), 0, 0);
		w = widstruct(t->type, *getinarg(t1), w, widthreg);
		w = widstruct(t->type, *getoutarg(t1), w, widthreg);
		t1->argwid = w;
		if(w%widthreg)
			warn("bad type %T %d\n", t1, w);
		t->align = 1;
		break;
	}

	if(widthptr == 4 && w != (int32)w)
		yyerror("type %T too large", t);

	t->width = w;
	if(t->align == 0) {
		if(w > 8 || (w&(w-1)) != 0)
			fatal("invalid alignment for %T", t);
		t->align = w;
	}
	lineno = lno;

	if(defercalc == 1)
		resumecheckwidth();
	else
		--defercalc;
}
Example #5
0
File: align.c Project: 8l/go-learn
void
dowidth(Type *t)
{
	int32 et;
	uint32 w;
	int lno;
	Type *t1;

	if(maxround == 0 || widthptr == 0)
		fatal("dowidth without betypeinit");

	if(t == T)
		return;

	if(t->width > 0)
		return;

	if(t->width == -2) {
		lno = lineno;
		lineno = t->lineno;
		yyerror("invalid recursive type %T", t);
		t->width = 0;
		lineno = lno;
		return;
	}

	// defer checkwidth calls until after we're done
	defercalc++;

	lno = lineno;
	lineno = t->lineno;
	t->width = -2;

	et = t->etype;
	switch(et) {
	case TFUNC:
	case TCHAN:
	case TMAP:
	case TSTRING:
		break;

	default:
		/* simtype == 0 during bootstrap */
		if(simtype[t->etype] != 0)
			et = simtype[t->etype];
		break;
	}

	w = 0;
	switch(et) {
	default:
		fatal("dowidth: unknown type: %T", t);
		break;

	/* compiler-specific stuff */
	case TINT8:
	case TUINT8:
	case TBOOL:		// bool is int8
		w = 1;
		break;
	case TINT16:
	case TUINT16:
		w = 2;
		break;
	case TINT32:
	case TUINT32:
	case TFLOAT32:
		w = 4;
		break;
	case TINT64:
	case TUINT64:
	case TFLOAT64:
		w = 8;
		break;
	case TPTR32:
		w = 4;
		checkwidth(t->type);
		break;
	case TPTR64:
		w = 8;
		checkwidth(t->type);
		break;
	case TDDD:
		w = 2*widthptr;
		break;
	case TINTER:		// implemented as 2 pointers
		w = 2*widthptr;
		offmod(t);
		break;
	case TCHAN:		// implemented as pointer
		w = widthptr;
		checkwidth(t->type);
		break;
	case TMAP:		// implemented as pointer
		w = widthptr;
		checkwidth(t->type);
		checkwidth(t->down);
		break;
	case TFORW:		// should have been filled in
	case TANY:
		// dummy type; should be replaced before use.
		if(!debug['A'])
			fatal("dowidth any");
		w = 1;	// anything will do
		break;
	case TSTRING:
		if(sizeof_String == 0)
			fatal("early dowidth string");
		w = sizeof_String;
		break;
	case TARRAY:
		if(t->type == T)
			break;
		if(t->bound >= 0) {
			dowidth(t->type);
			w = t->bound * t->type->width;
			if(w == 0)
				w = maxround;
		}
		else if(t->bound == -1) {
			w = sizeof_Array;
			checkwidth(t->type);
		}
		else
			fatal("dowidth %T", t);	// probably [...]T
		break;

	case TSTRUCT:
		if(t->funarg)
			fatal("dowidth fn struct %T", t);
		w = widstruct(t, 0, 1);
		if(w == 0)
			w = maxround;
		break;

	case TFUNC:
		// make fake type to check later to
		// trigger function argument computation.
		t1 = typ(TFUNCARGS);
		t1->type = t;
		checkwidth(t1);

		// width of func type is pointer
		w = widthptr;
		break;

	case TFUNCARGS:
		// function is 3 cated structures;
		// compute their widths as side-effect.
		t1 = t->type;
		w = widstruct(*getthis(t1), 0, 0);
		w = widstruct(*getinarg(t1), w, 1);
		w = widstruct(*getoutarg(t1), w, 1);
		t1->argwid = w;
		break;
	}

	t->width = w;
	lineno = lno;

	if(defercalc == 1)
		resumecheckwidth();
	else
		--defercalc;
}