예제 #1
0
파일: code.c 프로젝트: Sciumo/pcc
void
bfcode(struct symtab **sp, int n)
{
	struct symtab *sp2;
	NODE *p, *q;
	int i;

	if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
		/* Move return address into temporary */
		p = tempnode(0, INT, 0, 0);
		strtemp = regno(p);
		q = block(REG, 0, 0, INT, 0, 0);
		regno(q) = R1;
		ecomp(buildtree(ASSIGN, p, q));
	}
	if (xtemps == 0)
		return;

	/* put arguments in temporaries */
	for (i = 0; i < n; i++) {
		if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY ||
		    cisreg(sp[i]->stype) == 0)
			continue;
		if (cqual(sp[i]->stype, sp[i]->squal) & VOL)
			continue;
		sp2 = sp[i];
		p = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->sap);
		p = buildtree(ASSIGN, p, nametree(sp2));
		sp[i]->soffset = regno(p->n_left);
		sp[i]->sflags |= STNODE;
		ecomp(p);
	}

}
예제 #2
0
/*
 * Evaluate AND/OR/ER.  p1 and p2 are pointers to ti struct.
 */
static NODE *
gcc_andorer(int op, NODE *p1, NODE *p2)
{
	char *n = tistack();
	NODE *p, *t1, *t2, *p3;

	t1 = tempnode(0, p1->n_type, p1->n_df, p1->n_ap);
	t2 = tempnode(0, p2->n_type, p2->n_df, p2->n_ap);

	p1 = buildtree(ASSIGN, ccopy(t1), p1);
	p2 = buildtree(ASSIGN, ccopy(t2), p2);
	p = buildtree(COMOP, p1, p2);

	p3 = buildtree(ADDROF, eve(bdty(NAME, n)), NIL);
	p1 = buildtree(ASSIGN, structref(ccopy(p3), STREF, hiti),
	    buildtree(op, structref(ccopy(t1), STREF, hiti),
	    structref(ccopy(t2), STREF, hiti)));
	p = buildtree(COMOP, p, p1);
	p1 = buildtree(ASSIGN, structref(ccopy(p3), STREF, loti),
	    buildtree(op, structref(t1, STREF, loti),
	    structref(t2, STREF, loti)));
	p = buildtree(COMOP, p, p1);
	p = buildtree(COMOP, p, buildtree(UMUL, p3, NIL));
	return p;
}
예제 #3
0
/* setup a float param on the stack
 * used by bfcode() */
static void
param_float(struct symtab *sym, int *argofsp, int dotemps)
{
	NODE *p, *q, *t;
	int tmpnr;

	/*
	 * we have to dump the float from the general register
	 * into a temp, since the register allocator doesn't like
	 * floats to be in CLASSA.  This may not work for -xtemps.
	 */

	t = tempnode(0, INT, 0, 0);
	tmpnr = regno(t);
	q = block(REG, NIL, NIL, INT, 0, 0);
	q->n_rval = R0 + (*argofsp)++;
	p = buildtree(ASSIGN, t, q);
	ecomp(p);

	if (dotemps) {
		sym->soffset = tmpnr;
		sym->sflags |= STNODE;
	} else {
		q = tempnode(tmpnr, sym->stype, sym->sdf, sym->sap);
		p = nametree(sym);
		p = buildtree(ASSIGN, p, q);
		ecomp(p);
	}
}
예제 #4
0
파일: code.c 프로젝트: Sciumo/pcc
void
efcode(void)
{
	TWORD t;
	NODE *p, *q;

	/* code for the end of a function */
	if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
		return;

	t = PTR+BTYPE(cftnsp->stype);
	/* Create struct assignment */
	q = tempnode(strtemp, t, 0, cftnsp->sap);
	q = buildtree(UMUL, q, NIL);
	p = block(REG, NIL, NIL, t, 0, cftnsp->sap);
	regno(p) = R0;
	p = buildtree(UMUL, p, NIL);
	p = buildtree(ASSIGN, q, p);
	ecomp(p);

	/* put hidden arg in r0 on return */
	q = tempnode(strtemp, INT, 0, 0);
	p = block(REG, NIL, NIL, INT, 0, 0);
	regno(p) = R0;
        ecomp(buildtree(ASSIGN, p, q));
}
예제 #5
0
/*
 * code for the beginning of a function; a is an array of
 * indices in stab for the arguments; n is the number
 */
void
bfcode(struct symtab **sp, int cnt)
{
	NODE *p, *q;
	int i, n;

	if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
		uerror("no struct return yet");
	}
	/* recalculate the arg offset and create TEMP moves */
	for (n = 1, i = 0; i < cnt; i++) {
		if (n < 8) {
			p = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->ssue);
			q = block(REG, NIL, NIL,
			    sp[i]->stype, sp[i]->sdf, sp[i]->ssue);
			q->n_rval = n;
			p = buildtree(ASSIGN, p, q);
			sp[i]->soffset = regno(p->n_left);
			sp[i]->sflags |= STNODE;
			ecomp(p);
		} else {
			sp[i]->soffset += SZINT * n;
			if (xtemps) {
				/* put stack args in temps if optimizing */
				p = tempnode(0, sp[i]->stype,
				    sp[i]->sdf, sp[i]->ssue);
				p = buildtree(ASSIGN, p, nametree(sp[i]));
				sp[i]->soffset = regno(p->n_left);
				sp[i]->sflags |= STNODE;
				ecomp(p);
			}
		}
		n += szty(sp[i]->stype);
	}
}
예제 #6
0
static NODE *
builtin_va_arg(const struct bitable *bt, NODE *a)
{
    NODE *p, *q, *r, *rv;
    int sz, nodnum;

    /* create a copy to a temp node of current ap */
    p = ccopy(a->n_left);
    q = tempnode(0, p->n_type, p->n_df, p->n_ap);
    nodnum = regno(q);
    rv = buildtree(ASSIGN, q, p);

    r = a->n_right;
    sz = (int)tsize(r->n_type, r->n_df, r->n_ap)/SZCHAR;
    /* add one to ap */
#ifdef BACKAUTO
    rv = buildtree(COMOP, rv , buildtree(PLUSEQ, a->n_left, bcon(sz)));
#else
#error fix wrong eval order in builtin_va_arg
    ecomp(buildtree(MINUSEQ, a->n_left, bcon(sz)));
#endif

    nfree(a->n_right);
    nfree(a);
    r = tempnode(nodnum, INCREF(r->n_type), r->n_df, r->n_ap);
    return buildtree(COMOP, rv, buildtree(UMUL, r, NIL));

}
예제 #7
0
void
bfcode(struct symtab **sp, int cnt)
{
	int i, off;
	NODE *p, *q;
	struct symtab *sym;

	/* Process the first six arguments. */
	for (i=0; i < cnt && i < 6; i++) {
		sym = sp[i];
		q = block(REG, NIL, NIL, sym->stype, sym->sdf, sym->sap);
		q->n_rval = RETREG_PRE(sym->stype) + i;
		p = tempnode(0, sym->stype, sym->sdf, sym->sap);
		sym->soffset = regno(p);
		sym->sflags |= STNODE;
		p = buildtree(ASSIGN, p, q);
		ecomp(p);
	}

	/* Process the remaining arguments. */
	for (off = V9RESERVE; i < cnt; i++) {
		sym = sp[i];
		p = tempnode(0, sym->stype, sym->sdf, sym->sap);
		off = ALIGN(off, (tlen(p) - 1));
		sym->soffset = off * SZCHAR;
		off += tlen(p);
		p = buildtree(ASSIGN, p, nametree(sym));
		sym->soffset = regno(p->n_left);
		sym->sflags |= STNODE;
		ecomp(p);
	}
}
예제 #8
0
파일: code.c 프로젝트: JamesLinus/pcc
/*
 * code for the end of a function
 * deals with struct return here
 */
void
efcode(void)
{
	NODE *p, *q;
	int tempnr;
	int ty;

	if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
		return;

	ty = cftnsp->stype - FTN;

	q = block(REG, NIL, NIL, INCREF(ty), 0, cftnsp->sap);
	q->n_rval = V0;
	p = tempnode(0, INCREF(ty), 0, cftnsp->sap);
	tempnr = regno(p);
	p = buildtree(ASSIGN, p, q);
	ecomp(p);

	q = tempnode(tempnr, INCREF(ty), 0, cftnsp->sap);
	q = buildtree(UMUL, q, NIL);

	p = tempnode(rvnr, INCREF(ty), 0, cftnsp->sap);
	p = buildtree(UMUL, p, NIL);

	p = buildtree(ASSIGN, p, q);
	ecomp(p);

	q = tempnode(rvnr, INCREF(ty), 0, cftnsp->sap);
	p = block(REG, NIL, NIL, INCREF(ty), 0, cftnsp->sap);
	p->n_rval = V0;
	p = buildtree(ASSIGN, p, q);
	ecomp(p);
}
예제 #9
0
파일: code.c 프로젝트: JamesLinus/pcc
static NODE *
moveargs(NODE *p, int *regp)
{
        NODE *r, **rp;
	int lastreg;
	int reg;

        if (p->n_op == CM) {
                p->n_left = moveargs(p->n_left, regp);
                r = p->n_right;
		rp = &p->n_right;
        } else {
		r = p;
		rp = &p;
	}

 	lastreg = A0 + nargregs - 1;
        reg = *regp;

	if (reg > lastreg && r->n_op != STARG)
		*rp = block(FUNARG, r, NIL, r->n_type, r->n_df, r->n_ap);
	else if (r->n_op == STARG) {
		*rp = movearg_struct(r, p, regp);
	} else if (DEUNSIGN(r->n_type) == LONGLONG) {
		*rp = movearg_64bit(r, regp);
	} else if (r->n_type == DOUBLE || r->n_type == LDOUBLE) {
		/* XXX bounce in and out of temporary to change to longlong */
		NODE *t1 = tempnode(0, LONGLONG, 0, 0);
		int tmpnr = regno(t1);
		NODE *t2 = tempnode(tmpnr, r->n_type, r->n_df, r->n_ap);
		t1 =  movearg_64bit(t1, regp);
		r = block(ASSIGN, t2, r, r->n_type, r->n_df, r->n_ap);
		if (p->n_op == CM) {
			p->n_left = buildtree(CM, p->n_left, t1);
			p->n_right = r;
		} else {
			p = buildtree(CM, t1, r);
		}
	} else if (r->n_type == FLOAT) {
		/* XXX bounce in and out of temporary to change to int */
		NODE *t1 = tempnode(0, INT, 0, 0);
		int tmpnr = regno(t1);
		NODE *t2 = tempnode(tmpnr, r->n_type, r->n_df, r->n_ap);
		t1 =  movearg_32bit(t1, regp);
		r = block(ASSIGN, t2, r, r->n_type, r->n_df, r->n_ap);
		if (p->n_op == CM) {
			p->n_left = buildtree(CM, p->n_left, t1);
			p->n_right = r;
		} else {
			p = buildtree(CM, t1, r);
		}
	} else {
		*rp = movearg_32bit(r, regp);
	}

	return p;
}
예제 #10
0
파일: code.c 프로젝트: rheoli/pcc
/*
 * code for the end of a function
 * deals with struct return here
 * The return value is in (or pointed to by) RETREG.
 */
void
efcode(void)
{
	struct symtab *sp;
	extern int gotnr;
	TWORD t;
	NODE *p, *r, *l;
	int typ, ssz, rno;

	gotnr = 0;	/* new number for next fun */
	sp = cftnsp;
	t = DECREF(sp->stype);
	if (t != STRTY && t != UNIONTY)
		return;

	/* XXX should have one routine for this */
	ngpr = nsse = 0;
	if ((typ = argtyp(t, sp->sdf, sp->sap)) == STRREG || typ == STRCPX) {
		/* Cast to long pointer and move to the registers */
		/* XXX can overrun struct size */
		/* XXX check carefully for SSE members */

		if ((ssz = tsize(t, sp->sdf, sp->sap)) > SZLONG*2)
			cerror("efcode1");

		if (typ == STRCPX) {
			t = DOUBLE;
			rno = XMM0;
		} else {
			t = LONG;
			rno = RAX;
		}
		if (ssz > SZLONG) {
			p = block(REG, NIL, NIL, INCREF(t), 0, 0);
			regno(p) = RAX;
			p = buildtree(UMUL, buildtree(PLUS, p, bcon(1)), NIL);
			ecomp(movtoreg(p, rno+1));
		}
		p = block(REG, NIL, NIL, INCREF(t), 0, 0);
		regno(p) = RAX;
		p = buildtree(UMUL, p, NIL);
		ecomp(movtoreg(p, rno));
	} else if (typ == STRMEM) {
		r = block(REG, NIL, NIL, INCREF(t), sp->sdf, sp->sap);
		regno(r) = RAX;
		r = buildtree(UMUL, r, NIL);
		l = tempnode(stroffset, INCREF(t), sp->sdf, sp->sap);
		l = buildtree(UMUL, l, NIL);
		ecomp(buildtree(ASSIGN, l, r));
		l = block(REG, NIL, NIL, LONG, 0, 0);
		regno(l) = RAX;
		r = tempnode(stroffset, LONG, 0, 0);
		ecomp(buildtree(ASSIGN, l, r));
	} else
		cerror("efcode");
}
예제 #11
0
NODE *
mips_builtin_va_arg(NODE *f, NODE *a, TWORD t)
{
	NODE *p, *q, *r;
	int sz, tmpnr;

	/* check num args and type */
	if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
	    !ISPTR(a->n_left->n_type) || a->n_right->n_op != TYPE)
		goto bad;

	r = a->n_right;

	/* get type size */
	sz = tsize(r->n_type, r->n_df, r->n_ap) / SZCHAR;
	if (sz < SZINT/SZCHAR) {
		werror("%s%s promoted to int when passed through ...",
			r->n_type & 1 ? "unsigned " : "",
			DEUNSIGN(r->n_type) == SHORT ? "short" : "char");
		sz = SZINT/SZCHAR;
	}

	/* alignment */
	p = tcopy(a->n_left);
	if (sz > SZINT/SZCHAR && r->n_type != UNIONTY && r->n_type != STRTY) {
		p = buildtree(PLUS, p, bcon(7));
		p = block(AND, p, bcon(-8), p->n_type, p->n_df, p->n_ap);
	}

	/* create a copy to a temp node */
	q = tempnode(0, p->n_type, p->n_df, p->n_ap);
	tmpnr = regno(q);
	p = buildtree(ASSIGN, q, p);

	q = tempnode(tmpnr, p->n_type, p->n_df,p->n_ap);
	q = buildtree(PLUS, q, bcon(sz));
	q = buildtree(ASSIGN, a->n_left, q);

	q = buildtree(COMOP, p, q);

	nfree(a->n_right);
	nfree(a);
	nfree(f); 

	p = tempnode(tmpnr, INCREF(r->n_type), r->n_df, r->n_ap);
	p = buildtree(UMUL, p, NIL);
	p = buildtree(COMOP, q, p);

	return p;

bad:
	uerror("bad argument to __builtin_va_arg");
	return bcon(0);
}
예제 #12
0
파일: code.c 프로젝트: rheoli/pcc
/*
 * Sort arglist so that register assignments ends up last.
 */
static int
argsort(NODE *p)
{
	NODE *q, *r;
	int rv = 0;

	if (p->n_op != CM) {
		if (p->n_op == ASSIGN && p->n_left->n_op == REG &&
		    coptype(p->n_right->n_op) != LTYPE) {
			q = tempnode(0, p->n_type, p->n_df, p->n_ap);
			r = ccopy(q);
			p->n_right = buildtree(COMOP,
			    buildtree(ASSIGN, q, p->n_right), r);
		}
		return rv;
	}
	if (p->n_right->n_op == CM) {
		/* fixup for small structs in regs */
		q = p->n_right->n_left;
		p->n_right->n_left = p->n_left;
		p->n_left = p->n_right;
		p->n_right = p->n_left->n_right;
		p->n_left->n_right = q;
	}
	if (p->n_right->n_op == ASSIGN && p->n_right->n_left->n_op == REG &&
	    coptype(p->n_right->n_right->n_op) != LTYPE) {
		/* move before everything to avoid reg trashing */
		q = tempnode(0, p->n_right->n_type,
		    p->n_right->n_df, p->n_right->n_ap);
		r = ccopy(q);
		p->n_right->n_right = buildtree(COMOP,
		    buildtree(ASSIGN, q, p->n_right->n_right), r);
	}
	if (p->n_right->n_op == ASSIGN && p->n_right->n_left->n_op == REG) {
		if (p->n_left->n_op == CM &&
		    p->n_left->n_right->n_op == STASG) {
			q = p->n_left->n_right;
			p->n_left->n_right = p->n_right;
			p->n_right = q;
			rv = 1;
		} else if (p->n_left->n_op == STASG) {
			q = p->n_left;
			p->n_left = p->n_right;
			p->n_right = q;
			rv = 1;
		}
	}
	return rv | argsort(p->n_left);
}
예제 #13
0
/*
 * replace an alloca function with direct allocation on stack.
 * return a destination temp node.
 */
static NODE *
builtin_alloca(const struct bitable *bt, NODE *a)
{
    NODE *t, *u;

#ifdef notyet
    if (xnobuiltins)
        return NULL;
#endif

    t = tempnode(0, VOID|PTR, 0, 0);
    u = tempnode(regno(t), VOID|PTR, 0, 0);
    spalloc(t, a, SZCHAR);
    return u;
}
예제 #14
0
파일: local.c 프로젝트: newgenius/LiteBSD
/*
 * The "initial exec" tls model.
 */
static NODE *
tlsinitialexec(NODE *p)
{
	NODE *q, *r, *s;
	char *s1, *s2;

	/*
	 * movq %fs:0,%rax
	 * addq x@GOTTPOFF(%rip),%rax
	 */

	q = bcon(0);
	q->n_type = STRTY;

	s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap));
	r = mkx("=r", r);
	r = block(XASM, r, q, INT, 0, 0);

	s1 = "movq %%fs:0,%0\n\taddq ";
	s2 = "@GOTTPOFF(%%rip),%0";
	if (attr_find(p->n_sp->sap, ATTR_SONAME) == NULL) {
		p->n_sp->sap = attr_add(p->n_sp->sap, attr_new(ATTR_SONAME, 1));
		p->n_sp->sap->sarg(0) = p->n_sp->sname;
	}
	r->n_name = mk3str(s1,
	    attr_find(p->n_sp->sap, ATTR_SONAME)->sarg(0), s2);

	r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap);
	r = buildtree(UMUL, r, NIL);
	tfree(p);
	return r;
}
예제 #15
0
파일: code.c 프로젝트: JamesLinus/pcc
/*
 * code for the end of a function
 * deals with struct return here
 */
void
efcode(void)
{
	NODE *p, *q;
//	int sz;

#if 0
	/* restore ac3 */
	p = block(REG, 0, 0, INT, 0, 0);
	regno(p) = 3;
	q = tempnode(ac3temp, INT, 0, 0);
	ecomp(buildtree(ASSIGN, p, q));
#endif


	if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
		return;
cerror("efcode");
	/* address of return struct is in eax */
	/* create a call to memcpy() */
	/* will get the result in eax */
	p = block(REG, NIL, NIL, CHAR+PTR, 0, 0);
//	p->n_rval = EAX;
	q = block(OREG, NIL, NIL, CHAR+PTR, 0, 0);
//	q->n_rval = EBP;
	q->n_lval = 8; /* return buffer offset */
	p = block(CM, q, p, INT, 0, 0);
//	sz = (tsize(STRTY, cftnsp->sdf, cftnsp->ssue)+SZCHAR-1)/SZCHAR;
//	p = block(CM, p, bcon(sz), INT, 0, 0);
	p->n_right->n_name = "";
	p = block(CALL, bcon(0), p, CHAR+PTR, 0, 0);
	p->n_left->n_name = "memcpy";
	p = clocal(p);
	send_passt(IP_NODE, p);
}
예제 #16
0
/*
 * Fixup arguments to pass pointer-to-struct as first argument.
 *
 * called from funcode().
 */
static NODE *
retstruct(NODE *p)
{
	NODE *l, *r, *t, *q;
	TWORD ty;

	l = p->n_left;
	r = p->n_right;

	ty = DECREF(l->n_type) - FTN;

//      assert(tsize(ty, l->n_df, l->n_ap) == SZINT);

	/* structure assign */
	q = tempnode(0, ty, l->n_df, l->n_ap);
	q = buildtree(ADDROF, q, NIL);

	/* insert hidden assignment at beginning of list */
	if (r->n_op != CM) {
		p->n_right = block(CM, q, r, INCREF(ty), l->n_df, l->n_ap);
	} else {
		for (t = r; t->n_left->n_op == CM; t = t->n_left)
			;
		t->n_left = block(CM, q, t->n_left, INCREF(ty),
			    l->n_df, l->n_ap);
	}

	return p;
}
예제 #17
0
파일: code.c 프로젝트: JamesLinus/pcc
/*
 * Called with a function call with arguments as argument.
 * This is done early in buildtree() and only done once.
 */
NODE *
funcode(NODE *p)
{
	int regnum = A0;
	NODE *l, *r, *t, *q;
	int ty;

	l = p->n_left;
	r = p->n_right;

	/*
	 * if returning a structure, make the first argument
	 * a hidden pointer to return structure.
	 */
	ty = DECREF(l->n_type);
	if (ty == STRTY+FTN || ty == UNIONTY+FTN) {
		ty = DECREF(l->n_type) - FTN;
		q = tempnode(0, ty, l->n_df, l->n_ap);
		q = buildtree(ADDROF, q, NIL);
		if (r->n_op != CM) {
			p->n_right = block(CM, q, r, INCREF(ty),
			    l->n_df, l->n_ap);
		} else {
			for (t = r; t->n_left->n_op == CM; t = t->n_left)
				;
			t->n_left = block(CM, q, t->n_left, INCREF(ty),
			    l->n_df, l->n_ap);
		}
	}

	p->n_right = moveargs(p->n_right, &regnum);

	return p;
}
예제 #18
0
파일: code.c 프로젝트: JamesLinus/pcc
/*
 * code for the beginning of a function; a is an array of
 * indices in symtab for the arguments; n is the number
 */
void
bfcode(struct symtab **sp, int cnt)
{
	struct symtab *sp2;
	NODE *n;
	int i;

	if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
		/* Function returns struct, adjust arg offset */
		for (i = 0; i < cnt; i++) 
			sp[i]->soffset += SZPOINT(INT);
	}

	if (xtemps == 0)
		return;

	/* put arguments in temporaries */
	for (i = 0; i < cnt; i++) {
		if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY ||
		    cisreg(sp[i]->stype) == 0)
			continue;
		sp2 = sp[i];
		n = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->sap);
		n = buildtree(ASSIGN, n, nametree(sp2));
		sp[i]->soffset = regno(n->n_left);
		sp[i]->sflags |= STNODE;
		ecomp(n);
	}
}
예제 #19
0
/*
 * The "initial exec" tls model.
 */
static NODE *
tlsinitialexec(NODE *p)
{
	NODE *q, *r, *s;
	char *s1, *s2;

	/*
	 * movq %fs:0,%rax
	 * addq x@GOTTPOFF(%rip),%rax
	 */

	q = bcon(0);
	q->n_type = STRTY;

	s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap));
	r = mkx("=r", r);
	r = block(XASM, r, q, INT, 0, 0);

	s1 = "movq %%fs:0,%0\n\taddq ";
	s2 = "@GOTTPOFF(%%rip),%0";
	if (p->n_sp->soname == NULL)
		p->n_sp->soname = p->n_sp->sname;
	r->n_name = mk3str(s1, p->n_sp->soname, s2);

	r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap);
	r = buildtree(UMUL, r, NIL);
	tfree(p);
	return r;
}
예제 #20
0
/*
 * Create a reference for an extern variable.
 */
static NODE *
picext(NODE *p)
{
	NODE *q, *r;
	struct symtab *sp;
	char *name;

	q = tempnode(gotnr, PTR|VOID, 0, 0);
	name = getexname(p->n_sp);

#ifdef notdef
	struct attr *ga;
	if ((ga = attr_find(p->n_sp->sap, GCC_ATYP_VISIBILITY)) &&
	    strcmp(ga->sarg(0), "hidden") == 0) {
		/* For hidden vars use GOTOFF */
		sp = picsymtab("", name, "@GOTOFF");
		r = xbcon(0, sp, INT);
		q = buildtree(PLUS, q, r);
		q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
		q->n_sp = p->n_sp; /* for init */
		nfree(p);
		return q;
	}
#endif

	sp = picsymtab("", name, "@GOT");
	r = xbcon(0, sp, INT);
	q = buildtree(PLUS, q, r);
	q = block(UMUL, q, 0, PTR|VOID, 0, 0);
	q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
	q->n_sp = p->n_sp; /* for init */
	nfree(p);
	return q;
}
예제 #21
0
/*
 * replace an alloca function with direct allocation on stack.
 * return a destination temp node.
 */
static NODE *
builtin_alloca(NODE *f, NODE *a, TWORD rt)
{
	NODE *t, *u;

#ifdef notyet
	if (xnobuiltins)
		return NULL;
#endif

	t = tempnode(0, VOID|PTR, 0, 0);
	u = tempnode(regno(t), VOID|PTR, 0, 0);
	spalloc(t, a, SZCHAR);
	tfree(f);
	return u;
}
예제 #22
0
static NODE *
picstatic(NODE *p)
{
	NODE *q, *r;
	struct symtab *sp;

	q = tempnode(gotnr, PTR|VOID, 0, 0);
	if (p->n_sp->slevel > 0) {
		char buf[32];
		if ((p->n_sp->sflags & SMASK) == SSTRING)
			p->n_sp->sflags |= SASG;
		snprintf(buf, 32, LABFMT, (int)p->n_sp->soffset);
		sp = picsymtab("", buf, "@GOT");
	} else {
		sp = picsymtab("", getsoname(p->n_sp), "@GOT");
	}
	
	sp->sclass = STATIC;
	sp->stype = p->n_sp->stype;
	r = xbcon(0, sp, INT);
	q = buildtree(PLUS, q, r);
	q = block(UMUL, q, 0, PTR|VOID, 0, 0);
	q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
	q->n_sp = p->n_sp; /* for init */
	nfree(p);
	return q;
}
예제 #23
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);
}
예제 #24
0
파일: code.c 프로젝트: ajinkya93/netbsd-src
void
bfcode(struct symtab **sp, int n)
{
	struct symtab *sp2;
	NODE *p, *q;
	int i, argbase, sz;

	if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
		/* Move return address into temporary */
		p = tempnode(0, INT, 0, 0);
		strtemp = regno(p);
		q = block(REG, 0, 0, INT, 0, 0);
		regno(q) = R1;
		ecomp(buildtree(ASSIGN, p, q));
	}

	/* correct arg alignment XXX should be done somewhere else */
	argbase = ARGINIT;
	for (i = 0; i < n; i++) {
		sp2 = sp[i];
		sz = tsize(sp2->stype, sp2->sdf, sp2->sap);

		SETOFF(sz, SZINT);
		sp2->soffset = argbase;
		argbase += sz;
	}

	if (xtemps == 0)
		return;

	/* put arguments in temporaries */
	for (i = 0; i < n; i++) {
		if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY ||
		    cisreg(sp[i]->stype) == 0)
			continue;
		if (cqual(sp[i]->stype, sp[i]->squal) & VOL)
			continue;
		sp2 = sp[i];
		p = tempnode(0, sp[i]->stype, sp[i]->sdf, sp[i]->sap);
		p = buildtree(ASSIGN, p, nametree(sp2));
		sp[i]->soffset = regno(p->n_left);
		sp[i]->sflags |= STNODE;
		ecomp(p);
	}

}
예제 #25
0
/* called from moveargs() */
static NODE *
movearg_float(NODE *p, int *regp)
{
	NODE *q, *r;
	TWORD ty = INCREF(p->n_type);
	int tmpnr;

	/*
	 * Floats are passed in the general registers for
	 * compatibily with libraries compiled to handle soft-float.
	 */

	if (xtemps) {
		/* bounce on TOS */
		r = block(REG, NIL, NIL, ty, p->n_df, p->n_ap);
		regno(r) = SP;
		r = block(PLUS, r, bcon(-4), ty, p->n_df, p->n_ap);
		r = block(UMUL, r, NIL, p->n_type, p->n_df, p->n_ap);
		r = buildtree(ASSIGN, r, p);
		ecomp(r);

		/* bounce into temp */
		r = block(REG, NIL, NIL, PTR+INT, 0, 0);
		regno(r) = SP;
		r = block(PLUS, r, bcon(-8), PTR+INT, 0, 0);
		r = block(UMUL, r, NIL, INT, 0, 0);
		q = tempnode(0, INT, 0, 0);
		tmpnr = regno(q);
		r = buildtree(ASSIGN, q, r);
		ecomp(r);
	} else {
		/* copy directly into temp */
		q = tempnode(0, p->n_type, p->n_df, p->n_ap);
		tmpnr = regno(q);
		r = buildtree(ASSIGN, q, p);
		ecomp(r);
	}

	/* copy from temp to register parameter */
	r = tempnode(tmpnr, INT, 0, 0);
	q = block(REG, NIL, NIL, INT, 0, 0);
	regno(q) = (*regp)++;
	p = buildtree(ASSIGN, q, r);

	return p;
}
예제 #26
0
/*
 * replace an alloca function with direct allocation on stack.
 * return a destination temp node.
 */
static NODE *
builtin_alloca(NODE *f, NODE *a, TWORD rt)
{
	struct symtab *sp;
	NODE *t, *u;

#ifdef notyet
	if (xnobuiltins)
		return NULL;
#endif
	sp = f->n_sp;

	t = tempnode(0, VOID|PTR, 0, MKAP(INT) /* XXX */);
	u = tempnode(regno(t), VOID|PTR, 0, MKAP(INT) /* XXX */);
	spalloc(t, a, SZCHAR);
	tfree(f);
	return u;
}
예제 #27
0
파일: code.c 프로젝트: paploo/pcc
/*
 * code for the beginning of a function; 'a' is an array of
 * indices in symtab for the arguments; n is the number
 */
void
bfcode(struct symtab **a, int cnt)
{
	struct symtab *sp;
	NODE *p, *q;
	int i, n, sz;

	if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
		/* Function returns struct, adjust arg offset */
		for (i = 0; i < n; i++)
			a[i]->soffset += SZPOINT(LONG);
	}

	/* recalculate the arg offset and create TEMP moves */
	for (n = 0, i = 0; i < cnt; i++) {
		sp = a[i];

		sz = szty(sp->stype);
		if (n % sz)
			n++;	/* XXX LDOUBLE */

		if (n < 4) {
			p = tempnode(0, sp->stype, sp->sdf, sp->ssue);
			/* TODO p->n_left->n_lval = -(32 + n * 4); */
			q = block(REG, NIL, NIL, sp->stype, sp->sdf, sp->ssue);
			q->n_rval = argreg(sp->stype, &n);
			p = buildtree(ASSIGN, p, q);
			sp->soffset = regno(p->n_left);
			sp->sflags |= STNODE;
			ecomp(p);
		} else {
			sp->soffset += SZINT * n;
			if (xtemps) {
				/* put stack args in temps if optimizing */
				p = tempnode(0, sp->stype, sp->sdf, sp->ssue);
				p = buildtree(ASSIGN, p, buildtree(NAME, 0, 0));
				sp->soffset = regno(p->n_left);
				sp->sflags |= STNODE;
				ecomp(p);
			}
		}
	}
}
예제 #28
0
파일: code.c 프로젝트: JamesLinus/pcc
/* Put a symbol in a temporary
 * used by bfcode() and its helpers */
static void
putintemp(struct symtab *sym)
{
	NODE *p;
	p = tempnode(0, sym->stype, sym->sdf, sym->sap);
	p = buildtree(ASSIGN, p, nametree(sym));
	sym->soffset = regno(p->n_left);
	sym->sflags |= STNODE;
	ecomp(p);
}
예제 #29
0
/* called from moveargs() */
static NODE *
movearg_double(NODE *p, int *regp)
{
	NODE *q, *r;
	TWORD ty = INCREF(p->n_type);
	int tmpnr;

	if (xtemps) {
		/* bounce on TOS */
		r = block(REG, NIL, NIL, ty, p->n_df, p->n_ap);
		regno(r) = SP;
		r = block(PLUS, r, bcon(-8), ty, p->n_df, p->n_ap);
		r = block(UMUL, r, NIL, p->n_type, p->n_df, p->n_ap);
		r = buildtree(ASSIGN, r, p);
		ecomp(r);

		/* bounce into temp */
		r = block(REG, NIL, NIL, PTR+LONGLONG, 0, 0);
		regno(r) = SP;
		r = block(PLUS, r, bcon(-8), PTR+LONGLONG, 0, 0);
		r = block(UMUL, r, NIL, LONGLONG, 0, 0);
		q = tempnode(0, LONGLONG, 0, 0);
		tmpnr = regno(q);
		r = buildtree(ASSIGN, q, r);
		ecomp(r);
	} else {
		/* copy directly into temp */
		q = tempnode(0, p->n_type, p->n_df, p->n_ap);
		tmpnr = regno(q);
		r = buildtree(ASSIGN, q, p);
		ecomp(r);
	}

	/* copy from temp to register parameter */
	r = tempnode(tmpnr, LONGLONG, 0, 0);
	q = block(REG, NIL, NIL, LONGLONG, 0, 0);
	regno(q) = R0R1 - R0 + (*regp);
	p = buildtree(ASSIGN, q, r);

	(*regp) += 2;

	return p;
}
예제 #30
0
파일: code.c 프로젝트: JamesLinus/pcc
/*
 * XXX This is a hack.  We cannot have (l)doubles in more than one
 * register class.  So we bounce them in and out of temps to
 * move them in and out of the right registers.
 */
static void
param_double(struct symtab *sym, int *regp, int dotemps)
{
	int reg = *regp;
	NODE *p, *q, *t;
	int navail;
	int tmpnr;

	/* alignment */
	++reg;
	reg &= ~1;

	navail = nargregs - (reg - A0);

	if (navail < 2) {
		/* would have appeared half in registers/half
		 * on the stack, but alignment ensures it
		 * appears on the stack */
		if (dotemps)
			putintemp(sym);
		*regp = reg;
		return;
	}

	t = tempnode(0, LONGLONG, 0, 0);
	tmpnr = regno(t);
	q = block(REG, NIL, NIL, LONGLONG, 0, 0);
	q->n_rval = A0A1 + (reg - A0);
	p = buildtree(ASSIGN, t, q);
	ecomp(p);

	if (dotemps) {
		sym->soffset = tmpnr;
		sym->sflags |= STNODE;
	} else {
		q = tempnode(tmpnr, sym->stype, sym->sdf, sym->sap);
		p = nametree(sym);
		p = buildtree(ASSIGN, p, q);
		ecomp(p);
	}
	*regp = reg + 2;
}