Exemple #1
0
void
myp2tree(NODE *p)
{
	struct symtab *sp, sps;
	static int dblxor, fltxor;

	if (p->n_op == UMINUS && (p->n_type == FLOAT || p->n_type == DOUBLE)) {
		/* Store xor code for sign change */
		if (dblxor == 0) {
			dblxor = getlab();
			fltxor = getlab();
			sps.stype = LDOUBLE;
			sps.squal = CON >> TSHIFT;
			sps.sflags = sps.sclass = 0;
			sps.sname = sps.soname = "";
			sps.slevel = 1;
			sps.sap = NULL;
			sps.soffset = dblxor;
			locctr(DATA, &sps);
			defloc(&sps);
			printf("\t.long 0,0x80000000,0,0\n");
			printf(LABFMT ":\n", fltxor);
			printf("\t.long 0x80000000,0,0,0\n");
		}
		p->n_label = p->n_type == FLOAT ? fltxor : dblxor;
		return;
	}
Exemple #2
0
void
myp2tree(NODE *p)
{
	struct symtab *sp;

	if (p->n_op != FCON) 
		return;

	/* Write float constants to memory */
 
	sp = IALLOC(sizeof(struct symtab));
	sp->sclass = STATIC;
	sp->sap = 0;
	sp->slevel = 1; /* fake numeric label */
	sp->soffset = getlab();
	sp->sflags = 0;
	sp->stype = p->n_type;
	sp->squal = (CON >> TSHIFT);

	defloc(sp);
	ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p);

	p->n_op = NAME;
	p->n_lval = 0;
	p->n_sp = sp;

}
Exemple #3
0
void
myp2tree(NODE *p)
{
	struct symtab *sp;
	int o = p->n_op;

	if (o != FCON) 
		return;

	sp = inlalloc(sizeof(struct symtab));
	sp->sclass = STATIC;
	sp->ssue = 0;
	sp->slevel = 1; /* fake numeric label */
	sp->soffset = getlab();
	sp->sflags = 0;
	sp->stype = p->n_type;
	sp->squal = (CON >> TSHIFT);

	defloc(sp);
	ninval(0, sp->ssue->suesize, p);

	p->n_op = NAME;
	p->n_lval = 0;
	p->n_sp = sp;

}
Exemple #4
0
efcode(){
	/* code for the end of a function */

	if( strftn ){  /* copy output (in r0) to caller */
		register struct symtab *p;
		register int stlab;
		register int count;
		int size;

		p = &stab[curftn];

		deflab( retlab );

		stlab = getlab();
		printf( "	mov	$L%d,r1\n", stlab );
		size = tsize( DECREF(p->stype), p->dimoff, p->sizoff ) / SZCHAR;
		count = size/2;
		while( count-- ) {
			printf( "	mov	(r0)+,(r1)+\n" );
			}
		printf( "	mov	$L%d,r0\n", stlab );
		printf( "	.bss\nL%d:	.=.+%d.\n	.text\n", stlab, size );
		/* turn off strftn flag, so return sequence will be generated */
		strftn = 0;
		}
	branch( retlab );
	p2bend();
	}
Exemple #5
0
/*
 * Find number of beginning 0's in a word of type t.
 * t should be deunsigned.
 */
static NODE *
builtin_ff(NODE *f, NODE *a, TWORD t)
{
	NODE *t101, *t102;
	NODE *rn, *p;
	int l15, l16, l17;
	int sz;

	tfree(f);
	t = ctype(t);
	sz = (int)tsize(t, 0, 0)+1;

	t101 = tempnode(0, INT, 0, 0);
	t102 = tempnode(0, t, 0, 0);
	l15 = getlab();
	l16 = getlab();
	l17 = getlab();
	rn = buildtree(ASSIGN, ccopy(t101), bcon(0));
	rn = cmop(rn, buildtree(ASSIGN, ccopy(t102), a));

	p = buildtree(CBRANCH, buildtree(EQ, ccopy(t102), bcon(0)), bcon(l15));
	rn = cmop(rn, p);

	rn = cmop(rn, buildtree(INCR, ccopy(t101), bcon(1)));

	rn = cmop(rn, lblnod(l16));

	p = buildtree(CBRANCH, buildtree(GE, ccopy(t101), bcon(sz)), bcon(l15));
	rn = cmop(rn, p);

	p = buildtree(CBRANCH,
	    buildtree(EQ, buildtree(AND, ccopy(t102), bcon(1)),
	    bcon(0)), bcon(l17));
	rn = cmop(rn, p);

	rn = cmop(rn, block(GOTO, bcon(l15), NIL, INT, 0, 0));

	rn = cmop(rn, lblnod(l17));
	rn = cmop(rn, buildtree(RSEQ, t102, bcon(1)));

	rn = cmop(rn, buildtree(INCR, ccopy(t101), bcon(1)));

	rn = cmop(rn, block(GOTO, bcon(l16), NIL, INT, 0, 0));
	rn = cmop(rn, lblnod(l15));
	return cmop(rn, t101);
}
Exemple #6
0
void
myp2tree(NODE *p)
{
	struct attr *ap;
	struct symtab *sp, sps;
	static int dblxor, fltxor;
	int codeatyp(NODE *);

	if (p->n_op == STCALL || p->n_op == USTCALL) {
		/* save struct encoding */
		p->n_ap = attr_add(p->n_ap,
		    ap = attr_new(ATTR_AMD64_CMPLRET, 1));
		ap->iarg(0) = codeatyp(p);
	}

	if (p->n_op == UMINUS && (p->n_type == FLOAT || p->n_type == DOUBLE)) {
		/* Store xor code for sign change */
		if (dblxor == 0) {
			dblxor = getlab();
			fltxor = getlab();
			sps.stype = LDOUBLE;
			sps.squal = CON >> TSHIFT;
			sps.sflags = sps.sclass = 0;
			sps.sname = "";
			sps.slevel = 1;
			sps.sap = NULL;
			sps.soffset = dblxor;
			locctr(DATA, &sps);
			defloc(&sps);
			printf("\t.long 0,0x80000000,0,0\n");
			printf(LABFMT ":\n", fltxor);
			printf("\t.long 0x80000000,0,0,0\n");
		}
		p->n_ap = attr_add(p->n_ap,
		    ap = attr_new(ATTR_AMD64_XORLBL, 1));
		ap->iarg(0) = p->n_type == FLOAT ? fltxor : dblxor;
		return;
	}
Exemple #7
0
void
myp2tree(NODE *p)
{
	struct symtab *sp;
	NODE *l, *r;
	int o = p->n_op;

	switch (o) {
	case NAME: /* reading from a name must be done with a subroutine */
		if (p->n_type != CHAR && p->n_type != UCHAR)
			break;
		l = buildtree(ADDROF, ccopy(p), NIL);
		r = block(NAME, NIL, NIL, INT, 0, 0);

		r->n_sp = lookup(addname("__nova_rbyte"), SNORMAL);
		if (r->n_sp->sclass == SNULL) {
			r->n_sp->sclass = EXTERN;
			r->n_sp->stype = INCREF(p->n_type)+(FTN-PTR);
		}
		r->n_type = r->n_sp->stype;
		r = clocal(r);
		r = optim(buildtree(CALL, r, l));
		*p = *r;
		nfree(r);
		break;

	case FCON:
		sp = tmpalloc(sizeof(struct symtab));
		sp->sclass = STATIC;
		sp->sap = 0;
		sp->slevel = 1; /* fake numeric label */
		sp->soffset = getlab();
		sp->sflags = 0;
		sp->stype = p->n_type;
		sp->squal = (CON >> TSHIFT);

		defloc(sp);
		ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p);

		p->n_op = NAME;
		p->n_lval = 0;
		p->n_sp = sp;
	}
}
Exemple #8
0
static char *
tistack(void)
{
	struct symtab *sp, *sp2;
	char buf[12];
	NODE *q;
	char *n;

	/* allocate space on stack */
	snprintf(buf, 12, "%d", getlab());
	n = addname(buf);
	sp = lookup(n, 0);
	sp2 = tisp;
	q = block(TYPE, NIL, NIL, sp2->stype, sp2->sdf, sp2->sap);
	q->n_sp = sp;
	nidcl2(q, AUTO, 0);
	nfree(q);
	return n;
}
Exemple #9
0
void
myp2tree(NODE *p)
{
	struct symtab *sp;
	NODE *l;

	if (cdope(p->n_op) & CALLFLG) {
		if (p->n_left->n_op == ADDROF &&
		    p->n_left->n_left->n_op == NAME) {
			p->n_left = nfree(p->n_left);
			l = p->n_left;
			l->n_op = ICON;
			if (l->n_sp->sclass != STATIC &&
			    l->n_sp->sclass != USTATIC)
				l->n_sp =
				    picsymtab(l->n_sp->sname, "@PLTPC", "");
		}
	}

	if (p->n_op != FCON)
		return;

	sp = IALLOC(sizeof(struct symtab));
	sp->sclass = STATIC;
	sp->sap = 0;
	sp->slevel = 1; /* fake numeric label */
	sp->soffset = getlab();
	sp->sflags = 0;
	sp->stype = p->n_type;
	sp->squal = (CON >> TSHIFT);
	sp->sname = NULL;

	locctr(DATA, sp);
	defloc(sp);
	ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p);

	p->n_op = NAME;
	slval(p, 0);
	p->n_sp = sp;

}
Exemple #10
0
walkheap(int start, int limit)
{
	int label;

	if( start > limit ) return;
	printf("	cmpl	r0,$%d\n",  heapsw[start].sval);
	printf("	jeql	" LBLFMT "\n", heapsw[start].slab);
	if( (2*start) > limit ) {
		printf("	jbr 	" LBLFMT "\n", heapsw[0].slab);
		return;
	}
	if( (2*start+1) <= limit ) {
		label = getlab();
		printf("	jgtr	" LBLFMT "\n", label);
	} else
		printf("	jgtr	" LBLFMT "\n", heapsw[0].slab);
	walkheap( 2*start, limit);
	if( (2*start+1) <= limit ) {
		deflab1(label);
		walkheap( 2*start+1, limit);
	}
}
Exemple #11
0
/*
 * special handling before tree is written out.
 */
void
myp2tree(NODE *p)
{
	struct symtab *sp;
	union dimfun *df;
	union arglist *al;
	NODE *q;
	int i;

	switch (p->n_op) {
	case MOD:
	case DIV:
		if (p->n_type == LONG || p->n_type == ULONG) {
			/* Swap arguments for hardops() later */
			q = p->n_left;
			p->n_left = p->n_right;
			p->n_right = q;
		}
		break;

	case CALL:
	case STCALL:
		/*
		 * inform pass2 about varargs.
		 * store first variadic argument number in n_stalign
		 * in the CM node.
		 */
		if (p->n_right->n_op != CM)
			break; /* nothing to care about */
		df = p->n_left->n_df;
		if (df && (al = df->dfun)) {
			for (i = 0; i < 6; i++, al++) {
				if (al->type == TELLIPSIS || al->type == TNULL)
					break;
			}
			p->n_right->n_stalign = al->type == TELLIPSIS ? i : 0;
		} else
			p->n_right->n_stalign = 0;
		break;

	case FCON:
		/* Write float constants to memory */
		sp = inlalloc(sizeof(struct symtab));
		sp->sclass = STATIC;
		sp->ssue = 0;
		sp->slevel = 1; /* fake numeric label */
		sp->soffset = getlab();
		sp->sflags = 0;
		sp->stype = p->n_type;
		sp->squal = (CON >> TSHIFT);

		defloc(sp);
		ninval(0, sp->ssue->suesize, p);

		p->n_op = NAME;
		p->n_lval = 0;
		p->n_sp = sp;
		break;
	}

}
Exemple #12
0
genswitch(register struct sw *p, int n)
{
	/*	p points to an array of structures, each consisting
		of a constant value and a label.
		The first is >=0 if there is a default label;
		its value is the label number
		The entries p[1] to p[n] are the nontrivial cases
		*/
	register i;
	register CONSZ j, range;
	register dlab, swlab;

	range = p[n].sval-p[1].sval;

	if( range>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */

		swlab = getlab();
		dlab = p->slab >= 0 ? p->slab : getlab();

		/* already in r0 */
		printf("	casel	r0,$%ld,$%ld\n", p[1].sval, range);
		deflab1(swlab);
		for( i=1,j=p[1].sval; i<=n; j++) {
			printf("	.word	" LABFMT "-" LABFMT "\n",
			    (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab),
				swlab);
			}

		if( p->slab >= 0 ) branch( dlab );
		else deflab1(dlab);
		return;

		}

	if( n>8 ) {	/* heap switch */

		heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab();
		makeheap(p, n, 1);	/* build heap */

		walkheap(1, n);	/* produce code */

		if( p->slab >= 0 )
			branch( dlab );
		else
			deflab1(dlab);
		return;
	}

	/* debugging code */

	/* out for the moment
	if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );
	*/

	/* simple switch code */

	for( i=1; i<=n; ++i ){
		/* already in r0 */

		printf( "	cmpl	r0,$" );
		printf( CONFMT, p[i].sval );
		printf( "\n	jeql	" LBLFMT "\n", p[i].slab );
		}

	if( p->slab>=0 ) branch( p->slab );
}