コード例 #1
0
ファイル: code.c プロジェクト: paploo/pcc
NODE *
funarg(NODE *p, int *n)
{
	NODE *r;
	int sz;

	if (p->n_op == CM) {
		p->n_left = funarg(p->n_left, n);
		p->n_right = funarg(p->n_right, n);
		return p;
	}

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

	if (*n >= 4) {
		*n += sz;
		r = block(OREG, NIL, NIL, p->n_type|PTR, 0, 0);
		r->n_rval = SP;
		r->n_lval = -(32 + *n * 4);
	} else {
		r = block(REG, NIL, NIL, p->n_type, 0, 0);
		r->n_lval = 0;
		r->n_rval = argreg(p->n_type, n);
	}
	p = block(ASSIGN, r, p, p->n_type, 0, 0);
	clocal(p);

	return p;
}
コード例 #2
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);
			}
		}
	}
}
コード例 #3
0
ファイル: function.c プロジェクト: bill2009/lcc1802
//function(..) module saved jan 1 2013 as part of prep for scrt integration
static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
    int i, saved, sizefsave, sizeisave, varargs;
    Symbol r, argregs[NUM_ARG_REGS];

    usedmask[0] = usedmask[1] = 0;
    freemask[0] = freemask[1] = ~(unsigned)0;
    offset = maxoffset = maxargoffset = 0;
    for (i = 0; callee[i]; i++) //find last argument
        ;
    varargs = variadic(f->type) //see if variable arguments by type or by name of final argument
              || i > 0 && strcmp(callee[i-1]->name, "va_alist") == 0;
    for (i = 0; callee[i]; i++) {  //for each argument
        Symbol p = callee[i];
        Symbol q = caller[i];
        assert(q);
        offset = roundup(offset, q->type->align); //calculate the offset from the caller's sp
        p->x.offset = q->x.offset = offset;
        p->x.name = q->x.name = stringd(offset);
        r = argreg(i, offset, optype(ttob(q->type)), q->type->size, optype(ttob(caller[0]->type)));
        if (i < NUM_ARG_REGS)
            argregs[i] = r;
        offset = roundup(offset + q->type->size, 2); //i dunno
        if (varargs)
            p->sclass = AUTO;  //variable args are always auto?
        else if (r && ncalls == 0 &&  //I dunno
                 !isstruct(q->type) && !p->addressed &&
                 !(isfloat(q->type) && r->x.regnode->set == IREG)) {
            p->sclass = q->sclass = REGISTER;
            askregvar(p, r);
            assert(p->x.regnode && p->x.regnode->vbl == p);
            q->x = p->x;
            q->type = p->type;
        }
        else if (askregvar(p, rmap(ttob(p->type)))
                 && r != NULL
                 && (isint(p->type) || p->type == q->type)) {
            assert(q->sclass != REGISTER);
            p->sclass = q->sclass = REGISTER;
            q->type = p->type;
        }
    }
    assert(!caller[i]);  //done with arguments, their individual offsets and maxargoffset have been set
    offset = 0;
    gencode(caller, callee);
    if (ncalls) //prepare to save return address if necessary(i.e. we do calls of our own)
        usedmask[IREG] |= ((unsigned)1)<<REG_RETADDR;
    usedmask[IREG] &= INT_CALLEE_SAVE;  //limit saving to those we're responsible for
    usedmask[FREG] &= 0xfff00000;
    maxargoffset = roundup(maxargoffset, usedmask[FREG] ? 8 : 2);
    if (ncalls && maxargoffset < NUM_ARG_REGS*2)
        maxargoffset = NUM_ARG_REGS*2;
    sizefsave = 4*bitcount(usedmask[FREG]); //space needed to save the float regs
    sizeisave = 2*bitcount(usedmask[IREG]);  //space needed to save the int regs
    framesize = roundup(maxargoffset + sizefsave //space for outgoing arguments, space for saving floats,
                        + sizeisave + maxoffset, 2);  //space for saving ints, space for locals
    //segment(CODE);
    //printf("\talign 16\n");
    printf("%s:\n", f->x.name);
    i = maxargoffset + sizefsave - framesize;  //I dunno but it's -v and it's never used!
    if (framesize > 0)
        print("\talu2I sp,sp,%d,smi,smbi\n", framesize);
    saved = maxargoffset;
    /space needed for outgoing arguments