Example #1
0
void
gextern(Sym *s, Node *a, int32_t o, int32_t w)
{
	if(0 && a->op == OCONST && typev[a->type->etype]) {
		gpseudo(ADATA, s, lo64(a));
		p->from.offset += o;
		p->from.scale = 4;
		gpseudo(ADATA, s, hi64(a));
		p->from.offset += o + 4;
		p->from.scale = 4;
		return;
	}
	gpseudo(ADATA, s, a);
	p->from.offset += o;
	p->from.scale = w;
	switch(p->to.type) {
	default:
		p->to.index = p->to.type;
		p->to.type = D_ADDR;
	case D_CONST:
	case D_FCONST:
	case D_ADDR:
		break;
	}
}
Example #2
0
void
codgen(Node *n, Node *nn)
{
	Prog *sp;

	argoff = 0;
	inargs = 0;
	for(;; nn = nn->left) {
		if(nn == Z) {
			diag(Z, "cant find function name");
			return;
		}
		if(nn->op == ONAME)
			break;
	}
	nearln = nn->lineno;
	gpseudo(ATEXT, nn->sym, D_CONST, stkoff);
	sp = p;

	retok = 0;
	gen(n);
	if(!retok)
		if(thisfn->link->etype != TVOID)
			warn(Z, "no return at end of function: %s", nn->sym->name);

	noretval(3);
	gbranch(ORETURN);
	if(!debug['N'] || debug['R'] || debug['P'])
		regopt(sp);
}
Example #3
0
void
codgen(Node *n, Node *nn)
{
	Prog *sp;
	Node *n1, nod, nod1;

	cursafe = 0;
	curarg = 0;
	maxargsafe = 0;

	/*
	 * isolate name
	 */
	for(n1 = nn;; n1 = n1->left) {
		if(n1 == Z) {
			diag(nn, "cant find function name");
			return;
		}
		if(n1->op == ONAME)
			break;
	}
	nearln = nn->lineno;
	gpseudo(ATEXT, n1->sym, nodconst(stkoff));
	sp = p;
	sp->reg |= ALLTHUMBS;	/* denotes thumb code */

	/*
	 * isolate first argument
	 */
	if(REGARG >= 0) {
		if(typesuv[thisfn->link->etype]) {
			nod1 = *nodret->left;
			nodreg(&nod, &nod1, REGARG);
			gopcode(OAS, &nod, Z, &nod1);
		} else
		if(firstarg && typechlp[firstargtype->etype]) {
			nod1 = *nodret->left;
			nod1.sym = firstarg;
			nod1.type = firstargtype;
			nod1.xoffset = align(0, firstargtype, Aarg1);
			nod1.etype = firstargtype->etype;
			nodreg(&nod, &nod1, REGARG);
			gopcode(OAS, &nod, Z, &nod1);
		}
	}

	retok = 0;
	gen(n);
	if(!retok)
		if(thisfn->link->etype != TVOID)
			warn(Z, "no return at end of function: %s", n1->sym->name);
	noretval(3);
	gbranch(ORETURN);

	if(!debug['N'] || debug['R'] || debug['P'])
		regopt(sp);

	sp->to.offset += maxargsafe;
}
Example #4
0
File: sgen.c Project: 8l/go-learn
Prog*
gtext(Sym *s, int32 stkoff)
{
	gpseudo(ATEXT, s, nodconst(stkoff));
	p->to.type = D_CONST2;
	p->to.offset2 = argsize();
	return p;
}
Example #5
0
void
gextern(Sym *s, Node *a, long o, long w)
{
	if(a->op == OCONST && typev[a->type->etype]) {
		if(align(0, types[TCHAR], Aarg1))	/* isbigendian */
			gpseudo(ADATA, s, nod32const(a->vconst>>32));
		else
			gpseudo(ADATA, s, nod32const(a->vconst));
		p->from.offset += o;
		p->reg = 4;
		if(align(0, types[TCHAR], Aarg1))	/* isbigendian */
			gpseudo(ADATA, s, nod32const(a->vconst));
		else
			gpseudo(ADATA, s, nod32const(a->vconst>>32));
		p->from.offset += o + 4;
		p->reg = 4;
		return;
	}
Example #6
0
void
gextern(Sym *s, Node *a, int32 o, int32 w)
{

	if(a->op == OCONST && typev[a->type->etype]) {
		if(isbigendian)
			gpseudo(ADATA, s, nod32const(a->vconst>>32));
		else
			gpseudo(ADATA, s, nod32const(a->vconst));
		p->from.offset += o;
		p->reg = 4;
		if(isbigendian)
			gpseudo(ADATA, s, nod32const(a->vconst));
		else
			gpseudo(ADATA, s, nod32const(a->vconst>>32));
		p->from.offset += o + 4;
		p->reg = 4;
		return;
	}
Example #7
0
void
sextern(Sym *s, Node *a, long o, long w)
{
	long e, lw;

	for(e=0; e<w; e+=NSNAME) {
		lw = NSNAME;
		if(w-e < lw)
			lw = w-e;
		gpseudo(ADATA, s, nodconst(0));
		p->from.offset += o+e;
		p->reg = lw;
		p->to.type = D_SCONST;
		memmove(p->to.sval, a->cstring+e, lw);
	}
}
Example #8
0
File: swt.c Project: rosrad/go-rep
void
sextern(Sym *s, Node *a, int32 o, int32 w)
{
	int32 e, lw;

	for(e=0; e<w; e+=NSNAME) {
		lw = NSNAME;
		if(w-e < lw)
			lw = w-e;
		gpseudo(ADATA, s, nodconst(0L));
		p->from.offset += o+e;
		p->from.scale = lw;
		p->to.type = D_SCONST;
		memmove(p->to.u.sval, a->cstring+e, lw);
	}
}
Example #9
0
File: swt.c Project: 8l/inferno
long
outstring(char *s, long n)
{
	long r;

	r = nstring;
	while(n) {
		string[mnstring] = *s++;
		mnstring++;
		nstring++;
		if(mnstring >= NSNAME) {
			gpseudo(ADATA, symstring, D_SCONST, 0L);
			memmove(p->to.sval, string, NSNAME);
			p->from.offset = nstring - NSNAME;
			p->from.displace = NSNAME;
			mnstring = 0;
		}
		n--;
	}
	return r;
}
Example #10
0
int32_t
outstring(char *s, int32_t n)
{
	int32_t r;

	r = nstring;
	while(n) {
		string[mnstring] = *s++;
		mnstring++;
		nstring++;
		if(mnstring >= NSNAME) {
			gpseudo(ADATA, symstring, nodconst(0L));
			p->from.offset += nstring - NSNAME;
			p->reg = NSNAME;
			p->to.type = D_SCONST;
			memmove(p->to.sval, string, NSNAME);
			mnstring = 0;
		}
		n--;
	}
	return r;
}
Example #11
0
File: swt.c Project: rosrad/go-rep
int32
outstring(char *s, int32 n)
{
	int32 r;

	if(suppress)
		return nstring;
	r = nstring;
	while(n) {
		string[mnstring] = *s++;
		mnstring++;
		nstring++;
		if(mnstring >= NSNAME) {
			gpseudo(ADATA, symstring, nodconst(0L));
			p->from.offset += nstring - NSNAME;
			p->from.scale = NSNAME;
			p->to.type = D_SCONST;
			memmove(p->to.u.sval, string, NSNAME);
			mnstring = 0;
		}
		n--;
	}
	return r;
}
Example #12
0
File: swt.c Project: 8l/inferno
			/* else binary */
void
swit1(C1 *q, int nc, long def, int g, Node *n)
{
	C1 *r, *s;
	int i, l, m, y;
	long v, range;
	Prog *sp1, *sp2;

	/* note that g and g+1 are not allocated */
	if(nc <= N1)
		goto linear;
	y = 23*nc/100 + 5;	/* number of cases needed to make */
	if(y < N2)		/* direct switch worthwile */
		y = N2;				/* try to do better than n**2 here */
	for(m=nc; m>=y; m--) {			/* m is number of cases */
		s = q+nc;
		r = s-m;
		for(l=nc-m; l>=0; l--) {	/* l is base of contig cases */
			s--;
			range = s->val - r->val;
			if(range > 0 && range <= N3*m)
				goto direct;
			r--;
		}
	}

	/*
	 * divide and conquer
	 */
	i = nc / 2;
	r = q+i;
	v = r->val;
	/* compare median */
	if(v >= -128 && v < 128) {
		gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
		gopcode(OEQ, n->type, g, n, g+1, n);
	} else
		gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
	gbranch(OLT);
	sp1 = p;
	gbranch(OGT);
	sp2 = p;
	gbranch(OGOTO);
	patch(p, r->label);

	patch(sp1, pc);
	swit1(q, i, def, g, n);

	patch(sp2, pc);
	swit1(r+1, nc-i-1, def, g, n);
	return;

direct:
	/* compare low bound */
	v = r->val;
	if(v >= -128 && v < 128) {
		gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
		gopcode(OEQ, n->type, g, n, g+1, n);
	} else
		gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
	gbranch(OLT);
	sp1 = p;

	/* compare high bound */
	v = s->val;
	if(v >= -128 && v < 128) {
		gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
		gopcode(OEQ, n->type, g, n, g+1, n);
	} else
		gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
	gbranch(OGT);
	sp2 = p;

	/* switch */
	v = r->val;
	gpseudo(AMOVW, symstatic, D_R0, 0L);
	p->from.offset = nstatic - v*2;
	p->from.index = g|I_INDEX1;
	p->from.scale = 5;
	nextpc();
	p->as = ACASEW;

	/* table */
	for(i=0; i<=range; i++) {
		gbranch(OCASE);
		if(v == r->val) {
			patch(p, r->label);
			r++;
		} else
			patch(p, def);
		p->from.type = D_STATIC;
		p->from.sym = symstatic;
		p->from.offset = nstatic;
		nstatic += types[TSHORT]->width;
		v++;
	}
	gbranch(OGOTO);
	patch(p, def);
	if(r != s+1)
		print("smelly direct switch\n");

	if(l > 0) {
		patch(sp1, pc);
		swit1(q, l, def, g, n);
	} else
		patch(sp1, def);

	m += l;
	if(m < nc) {
		patch(sp2, pc);
		swit1(q+m, nc-m, def, g, n);
	} else
		patch(sp2, def);
	return;


linear:
	for(i=0; i<nc; i++) {
		v = q->val;
		if(v >= -128 && v < 128) {
			gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);
			gopcode(OEQ, n->type, g+1, n, g, n);
		} else
			gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));
		gbranch(OEQ);
		patch(p, q->label);
		q++;
	}
	gbranch(OGOTO);
	patch(p, def);
}