Exemplo n.º 1
0
NODE *
getlr(NODE *p, int c)
{
	/* return the pointer to the left or right side of p, or p itself,
	   depending on the optype of p */

	switch (c) {

	case '1':
	case '2':
	case '3':
	case 'D':
		if (c == 'D')
			c = 0;
		else
			c -= '0';
		if (resc[c].n_op == FREE)
			comperr("getlr: free node");
		return &resc[c];

	case 'L':
		return( optype( p->n_op ) == LTYPE ? p : p->n_left );

	case 'R':
		return( optype( p->n_op ) != BITYPE ? p : p->n_right );

	}
	cerror( "bad getlr: %c", c );
	/* NOTREACHED */
	return NULL;
}
Exemplo n.º 2
0
/*
 * Convert a node to REG or OREG.
 * Shape is register class where we want the result.
 * Returns register class if register nodes.
 * If w is: (should be shapes)
 *	- SRREG - result in register, call geninsn().
 *	- SROREG - create OREG; call offstar().
 *	- 0 - clear su, walk down.
 */
static int
swmatch(NODE *p, int shape, int w)
{
	int rv = 0;

	F2DEBUG(("swmatch: p=%p, shape=%s, w=%s\n", p, prcook(shape), srtyp[w]));

	switch (w) {
	case SRREG:
		rv = geninsn(p, shape);
		break;

	case SROREG:
		/* should be here only if op == UMUL */
		if (p->n_op != UMUL && p->n_op != FLD)
			comperr("swmatch %p", p);
		if (p->n_op == FLD) {
			offstar(p->n_left->n_left, shape);
			p->n_left->n_su = 0;
		} else
			offstar(p->n_left, shape);
		p->n_su = 0;
		rv = ffs(shape)-1;
		break;

	case 0:
		if (optype(p->n_op) == BITYPE)
			swmatch(p->n_right, 0, 0);
		if (optype(p->n_op) != LTYPE)
			swmatch(p->n_left, 0, 0);
		p->n_su = 0;
	}
	return rv;

}
Exemplo n.º 3
0
Arquivo: gen.c Projeto: Godzil/osXdk
static void tmpalloc(sNode_t p) 
{
	p->x.optimized=0;
	p->x.name="*******";
	p->x.adrmode='*';
	releasetmp(p->kids[0]); releasetmp(p->kids[1]);
	switch (generic(p->op)) {
	case ARG:
		p->x.argoffset = argoffset;
		argoffset += p->syms[0]->u.c.v.i;
/*
		if (0) {
			Node k=p->kids[0];
			if (k->count==0
			    && generic(k->op)!=INDIR
			    && generic(k->op)!=ADDRF
			    && generic(k->op)!=ADDRG
			    && generic(k->op)!=ADDRL
			    && generic(k->op)!=CNST )
			{
				p->x.optimized=1;
				k->x.optimized=1;
				k->x.name=stringf("(sp),%d",p->x.argoffset);
				k->x.adrmode='I';
			}
		}
*/
		break;
	case CALL:
		p->x.argoffset = argoffset;
		argoffset = 0;
		break;
	case ASGN:
		if (optimizelevel>=3) 
		{	/* kids[1] : expression droite */
			if (optype(p->op)!=B
			    && p==p->kids[1]->x.next
			    &&   ( generic(p->kids[0]->op)==ADDRF
				|| generic(p->kids[0]->op)==ADDRG
				|| generic(p->kids[0]->op)==ADDRL)
			    && generic(p->kids[1]->op)!=INDIR
			    && generic(p->kids[1]->op)!=ADDRF
			    && generic(p->kids[1]->op)!=ADDRG
			    && generic(p->kids[1]->op)!=ADDRL
			    && generic(p->kids[1]->op)!=CNST )
			{
				sNode_t k=p->kids[1];
				p->x.optimized=1;
				k->x.optimized=1;
				k->x.result=p->kids[0]->x.result;
				k->x.name=k->x.result->x.name;
				k->x.adrmode=k->x.result->x.adrmode;
				if (k->x.adrmode=='C') k->x.adrmode='D';
				else k->x.adrmode='I';
			}
		}
		break;
	}
	if (needtmp(p)) gettmp(p);
}
Exemplo n.º 4
0
static void prelabel(Node p) {
	if (p == NULL)
		return;
	prelabel(p->kids[0]);
	prelabel(p->kids[1]);
	if (NeedsReg[opindex(p->op)])
		setreg(p, (*IR->x.rmap)(opkind(p->op)));
	switch (generic(p->op)) {
	case ADDRF: case ADDRL:
		if (p->syms[0]->sclass == REGISTER)
			p->op = VREG+P;
		break;
	case INDIR:
		if (p->kids[0]->op == VREG+P)
			setreg(p, p->kids[0]->syms[0]);
		break;
	case ASGN:
		if (p->kids[0]->op == VREG+P)
			rtarget(p, 1, p->kids[0]->syms[0]);
		break;
	case CVI: case CVU: case CVP:
		if (optype(p->op) != F
		&&  opsize(p->op) <= p->syms[0]->u.c.v.i)
			p->op = LOAD + opkind(p->op);
		break;
	}
	(IR->x.target)(p);
}
Exemplo n.º 5
0
/* XXX should this go away now? */
int
shtemp(NODE *p)
{
	return 0;
#if 0
	int r;

	if (p->n_op == STARG )
		p = p->n_left;

	switch (p->n_op) {
	case REG:
		return (!istreg(p->n_rval));

	case OREG:
		r = p->n_rval;
		if (R2TEST(r)) {
			if (istreg(R2UPK1(r)))
				return(0);
			r = R2UPK2(r);
		}
		return (!istreg(r));

	case UMUL:
		p = p->n_left;
		return (p->n_op != UMUL && shtemp(p));
	}

	if (optype(p->n_op) != LTYPE)
		return(0);
	return(1);
#endif
}
Exemplo n.º 6
0
Arquivo: tree.c Projeto: UraKn0x/gbdk
char *opname(int op) {
	static char *opnames[] = {
	"",
	"CNST",
	"ARG",
	"ASGN",
	"INDIR",
	"CVC",
	"CVD",
	"CVF",
	"CVI",
	"CVP",
	"CVS",
	"CVU",
	"NEG",
	"CALL",
	"*LOAD*",
	"RET",
	"ADDRG",
	"ADDRF",
	"ADDRL",
	"ADD",
	"SUB",
	"LSH",
	"MOD",
	"RSH",
	"BAND",
	"BCOM",
	"BOR",
	"BXOR",
	"DIV",
	"MUL",
	"EQ",
	"GE",
	"GT",
	"LE",
	"LT",
	"NE",
	"JUMP",
	"LABEL",
	"AND",
	"NOT",
	"OR",
	"COND",
	"RIGHT",
	"FIELD"
	}, *suffixes[] = {
		"0", "F", "D", "C", "S", "I", "U", "P", "V", "B",
		"10","11","12","13","14","15"
	};

	if (generic(op) >= AND && generic(op) <= FIELD && opsize(op) == 0)
		return opnames[opindex(op)];
	return stringf("%s%s%s",
		opindex(op) > 0 && opindex(op) < NELEMS(opnames) ?
			opnames[opindex(op)] : stringd(opindex(op)),
		suffixes[optype(op)], opsize(op) > 0 ? stringd(opsize(op)) : "");
}
Exemplo n.º 7
0
Arquivo: gen.c Projeto: Godzil/osXdk
static void gettmp(sNode_t p) 
{
	int t;
/*
	Node q;
	int call_found=0, use_zpage=1;
	for (q=p->x.next; q; q=q->x.next) {
		if (generic(q->op)==CALL) call_found=1;
		if ((q->kids[0]==p || q->kids[1]==p) && call_found)
			use_zpage=0; 
	}
*/
	if ( optype(p->op)!=F && optype(p->op)!=D ) 
	{
		for (t=0;t<24;t++)
			if ((busy&(1<<t))==0) 
			{
				busy|=1<<t;
				p->x.result=temp[t];
				p->x.adrmode='D';
				if (t>=8) 
				{
					temp[t]->type->size=2;
					local(temp[t]);
					p->x.adrmode='I';
				}
				p->x.name=temp[t]->x.name;
				return;
			}
	} 
	else
		for (t=24;t<32;t++)
			if ((busy&(1<<t))==0) 
			{
				busy|=1<<t;
				p->x.result=temp[t];
				p->x.adrmode='I';
				temp[t]->type->size=5;
				local(temp[t]);
				p->x.name=temp[t]->x.name;
				return;
			}
	perror("Too complex expression"); exit(1);
}
Exemplo n.º 8
0
static Symbol rmap(int opk)
{
    switch (optype(opk))
    {
        case B:
        case P:
        case I:
        case U:
        case F:
            return regw;
        default:
            return 0;
    }
}
Exemplo n.º 9
0
static void I(defsymbol)(Symbol p) {
	if (p->scope == CONSTANTS)
		switch (optype(ttob(p->type))) {
		case I: p->x.name = stringf("%D", p->u.c.v.i); break;
		case U: p->x.name = stringf("%U", p->u.c.v.u); break;
		case P: p->x.name = stringf("%U", p->u.c.v.p); break;
		default: assert(0);
		}
	else if (p->scope >= LOCAL && p->sclass == STATIC)
		p->x.name = stringf("$%d", genlabel(1));
	else if (p->scope == LABELS || p->generated)
		p->x.name = stringf("$%s", p->name);
	else
		p->x.name = p->name;
}
Exemplo n.º 10
0
Arquivo: svg.c Projeto: Melab/gvmt
char* getNodeText(Node p) {
    switch (generic(p->op)) {
    case LABEL:
        return stringf("LABEL %s", p->syms[0]->x.name);
    case ADDRL:
        if (isdigit(p->syms[0]->name[0]))
            return stringf("ADDRL t%s", p->syms[0]->name);
        else
            return stringf("ADDRL %s", p->syms[0]->name);
    case ADDRG:
        return stringf("ADDRG %s", p->syms[0]->x.name);
    case ADDRF:
        return stringf("ADDRF %s", p->syms[0]->name);
    case EQ:
        return stringf("BREQ %s", p->syms[0]->x.name);
    case NE:
        return stringf("BRNE %s", p->syms[0]->x.name);
    case LT:
        return stringf("BRLT %s", p->syms[0]->x.name);
    case GT:
        return stringf("BRGT %s", p->syms[0]->x.name);
    case LE:
        return stringf("BRLE %s", p->syms[0]->x.name);
    case GE:
        return stringf("BRGE %s", p->syms[0]->x.name);
    case CNST:
        if (optype(p->op) == I)
            return stringf("CNST %d", p->syms[0]->u.c.v.i);
        else if (optype(p->op) == U)
            return stringf("CNST %u", p->syms[0]->u.c.v.u);
        else
            return opname(p->op);
    default:   
        return opname(p->op);
    }
}
Exemplo n.º 11
0
Arquivo: common.c Projeto: pauley/pcc
/*
 * make a fresh copy of p
 */
NODE *
tcopy(NODE *p)
{
	NODE *q;

	q = talloc();
	*q = *p;

	switch (optype(q->n_op)) {
	case BITYPE:
		q->n_right = tcopy(p->n_right);
	case UTYPE:
		q->n_left = tcopy(p->n_left);
	}

	return(q);
}
Exemplo n.º 12
0
static void spillr(Symbol r, Node here) {
	int i;
	Symbol tmp;
	Node p = r->x.lastuse;
	assert(p);
	while (p->x.prevuse)
		assert(r == p->syms[RX]),
		p = p->x.prevuse;
	assert(p->x.registered && !readsreg(p));
	tmp = newtemp(AUTO, optype(p->op), opsize(p->op));
	genspill(r, p, tmp);
	for (p = here->x.next; p; p = p->x.next)
		for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
			Node k = p->x.kids[i];
			if (k->x.registered && k->syms[RX] == r)
				genreload(p, tmp, i);
		}
	putreg(r);
}
Exemplo n.º 13
0
static void dumptree(Node p) {
	if (p->op == VREG+P && p->syms[0]) {
		fprint(stderr, "VREGP(%s)", p->syms[0]->name);
		return;
	} else if (generic(p->op) == LOAD) {
		fprint(stderr, "LOAD(");
		dumptree(p->kids[0]);
		fprint(stderr, ")");
		return;
	}
	fprint(stderr, "%s(", opname(p->op));
	switch (generic(p->op)) {
	case CNST: case LABEL:
	case ADDRG: case ADDRF: case ADDRL:
		if (p->syms[0])
			fprint(stderr, "%s", p->syms[0]->name);
		break;
	case RET:
		if (p->kids[0])
			dumptree(p->kids[0]);
		break;
	case CVF: case CVI: case CVP: case CVU: case JUMP: 
	case ARG: case BCOM: case NEG: case INDIR:
		dumptree(p->kids[0]);
		break;
	case CALL:
		if (optype(p->op) != B) {
			dumptree(p->kids[0]);
			break;
		}
		/* else fall thru */
	case EQ: case NE: case GT: case GE: case LE: case LT:
	case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH:
	case ADD: case SUB:  case DIV: case MUL: case MOD:
		dumptree(p->kids[0]);
		fprint(stderr, ", ");
		dumptree(p->kids[1]);
		break;
	default: assert(0);
	}
	fprint(stderr, ")");
}
Exemplo n.º 14
0
/*
 * set registers in calling conventions live.
 */
int *
livecall(NODE *p)
{
	static int r[NTEMPREG+1];
	NODE *q;
	int cr = 0;

	if (optype(p->n_op) != BITYPE)
		return r[0] = -1, r;

	for (q = p->n_right; q->n_op == CM; q = q->n_left) {
		if (q->n_right->n_op == ASSIGN &&
		    q->n_right->n_left->n_op == REG)
			r[cr++] = regno(q->n_right->n_left);
	}
	if (q->n_op == ASSIGN && q->n_left->n_op == REG)
		r[cr++] = regno(q->n_left);
	r[cr++] = -1;
	return r;
}
Exemplo n.º 15
0
static void I(defsymbol)(Symbol p) {
	if (p->scope == CONSTANTS)
		switch (optype(ttob(p->type))) {
		case I: p->x.name = stringf("%D", p->u.c.v.i); break;
		case U: p->x.name = stringf("%U", p->u.c.v.u); break;
		case P: p->x.name = stringf("%U", p->u.c.v.p); break;
		case F:
			{	// JDC: added this to get inline floats
				floatint_t temp;

				temp.f = p->u.c.v.d;
				p->x.name = stringf("%U", temp.ui );
			}
			break;// JDC: added this
		default: assert(0);
		}
	else if (p->scope >= LOCAL && p->sclass == STATIC)
		p->x.name = stringf("$%d", genlabel(1));
	else if (p->scope == LABELS || p->generated)
		p->x.name = stringf("$%s", p->name);
	else
		p->x.name = p->name;
}
Exemplo n.º 16
0
/* getop: get next operator or numeric operand, return type */
int getop(char s[])
{
	int i, c, type;

	i = 0;
	while ( (s[i] = c = getch()) == ' ' || c == '\t')
		;		/* skip white space */
	if (c == '-') {		/* '-' could be operator or negative indicator */
		s[++i] = c = getch();
		if (!isdigit(c)) {
			ungetch(c);
			s[i] = '\0';
			return s[0];
		}
	}
	if (isop(c) || c == '\n') {
	        s[i] = '\0';
		return c;
	} else if (isdigit(c) || c == '.') { /* digit */
		type = NUMBER;
		if (isdigit(c))		/* collect integer part */
			while (isdigit(s[++i] = c = getch()))
				;
		if (c == '.')		/* collect fraction part */
			while (isdigit(s[++i] = c = getch()))
				;
	} else {		/* handles any other input */
		while ( (s[++i] = c = getch()) != ' ' && c != '\t' && c != '\n')
			;
		type = optype(s, i-1);
	}
	s[i] = '\0';
	if (c != EOF)
		ungetch(c);
	return type;
}
Exemplo n.º 17
0
static void dumptree(Node p) {
    switch (specific(p->op)) {
    case ASGN+B:
        assert(p->kids[0]);
        assert(p->kids[1]);
        assert(p->syms[0]);
        dumptree(p->kids[0]);
        dumptree(p->kids[1]);
        print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.u);
        return;
    case RET+V:
        assert(!p->kids[0]);
        assert(!p->kids[1]);
        print("%s\n", opname(p->op));
        return;
    }
    switch (generic(p->op)) {
    case CNST:
    case ADDRG:
    case ADDRF:
    case ADDRL:
    case LABEL:
        assert(!p->kids[0]);
        assert(!p->kids[1]);
        assert(p->syms[0] && p->syms[0]->x.name);
        print("%s %s\n", opname(p->op), p->syms[0]->x.name);
        return;
    case CVF:
    case CVI:
    case CVP:
    case CVU:
        assert(p->kids[0]);
        assert(!p->kids[1]);
        assert(p->syms[0]);
        dumptree(p->kids[0]);
        print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.i);
        return;
    case ARG:
    case BCOM:
    case NEG:
    case INDIR:
    case JUMP:
    case RET:
        assert(p->kids[0]);
        assert(!p->kids[1]);
        dumptree(p->kids[0]);
        print("%s\n", opname(p->op));
        return;
    case CALL:
        assert(p->kids[0]);
        assert(!p->kids[1]);
        assert(optype(p->op) != B);
        dumptree(p->kids[0]);
        print("%s\n", opname(p->op));
        return;
    case ASGN:
    case BOR:
    case BAND:
    case BXOR:
    case RSH:
    case LSH:
    case ADD:
    case SUB:
    case DIV:
    case MUL:
    case MOD:
        assert(p->kids[0]);
        assert(p->kids[1]);
        dumptree(p->kids[0]);
        dumptree(p->kids[1]);
        print("%s\n", opname(p->op));
        return;
    case EQ:
    case NE:
    case GT:
    case GE:
    case LE:
    case LT:
        assert(p->kids[0]);
        assert(p->kids[1]);
        assert(p->syms[0]);
        assert(p->syms[0]->x.name);
        dumptree(p->kids[0]);
        dumptree(p->kids[1]);
        print("%s %s\n", opname(p->op), p->syms[0]->x.name);
        return;
    }
    assert(0);
}
Exemplo n.º 18
0
static Tree root1(Tree p) {
	if (p == NULL)
		return p;
	if (p->type == voidtype)
		warn++;
	switch (generic(p->op)) {
	case COND: {
		Tree q = p->kids[1];
		assert(q && q->op == RIGHT);
		if (p->u.sym && q->kids[0] && generic(q->kids[0]->op) == ASGN)
			q->kids[0] = root1(q->kids[0]->kids[1]);
		else
			q->kids[0] = root1(q->kids[0]);
		if (p->u.sym && q->kids[1] && generic(q->kids[1]->op) == ASGN)
			q->kids[1] = root1(q->kids[1]->kids[1]);
		else
			q->kids[1] = root1(q->kids[1]);
		p->u.sym = 0;
		if (q->kids[0] == 0 && q->kids[1] == 0)
			p = root1(p->kids[0]);
		}
		break;
	case AND: case OR:
		if ((p->kids[1] = root1(p->kids[1])) == 0)
			p = root1(p->kids[0]);
		break;
	case NOT:
		if (warn++ == 0)
			warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case RIGHT:
		if (p->kids[1] == 0)
			return root1(p->kids[0]);
		if (p->kids[0] && p->kids[0]->op == CALL+B
		&&  p->kids[1] && p->kids[1]->op == INDIR+B)
			/* avoid premature release of the CALL+B temporary */
			return p->kids[0];
		if (p->kids[0] && p->kids[0]->op == RIGHT
		&&  p->kids[1] == p->kids[0]->kids[0])
			/* de-construct e++ construction */
			return p->kids[0]->kids[1];
		p = tree(RIGHT, p->type, root1(p->kids[0]), root1(p->kids[1]));
		return p->kids[0] || p->kids[1] ? p : (Tree)0;
	case EQ:  case NE:  case GT:   case GE:  case LE:  case LT:
	case ADD: case SUB: case MUL:  case DIV: case MOD:
	case LSH: case RSH: case BAND: case BOR: case BXOR:
		if (warn++ == 0)
			warning("expression with no effect elided\n");
		p = tree(RIGHT, p->type, root1(p->kids[0]), root1(p->kids[1]));
		return p->kids[0] || p->kids[1] ? p : (Tree)0;
	case INDIR:
		if (p->type->size == 0 && unqual(p->type) != voidtype)
			warning("reference to `%t' elided\n", p->type);
		if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
			warning("reference to `volatile %t' elided\n", p->type);
		/* fall thru */
	case NEG: case BCOM: case FIELD:
		if (warn++ == 0)
			warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case ADDRL: case ADDRG: case ADDRF: case CNST:
		if (needconst)
			return p;
		if (warn++ == 0)
			warning("expression with no effect elided\n");
		return NULL;
	case CVF:
		if (optype(p->op) == I
		|| p->type->size < p->kids[0]->type->size)
			if (warn++ == 0)
				warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case CVI:
		if ((optype(p->op) == U || optype(p->op) == I)
		&& p->type->size < p->kids[0]->type->size
		&& specific(p->kids[0]->op) != CALL+I)
			if (warn++ == 0)
				warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case CVU: case CVP:
		if ((optype(p->op) == U && p->type->size <  p->kids[0]->type->size)
		||  (optype(p->op) == I && p->type->size <= p->kids[0]->type->size))
			if (warn++ == 0)
				warning("expression with no effect elided\n");
		return root1(p->kids[0]);
	case ARG: case ASGN: case CALL: case JUMP: case LABEL:
		break;
	default: assert(0);
	}
	return p;
}
Exemplo n.º 19
0
static rcc_node_ty visit(Node p) {
	Symbol q;
	rcc_node_ty left = NULL, right = NULL;
	int suffix = optype(p->op), size = opsize(p->op);

	assert(p);
	for (q = temps; q; q = q->u.t.next)
		if (q->u.t.cse == p) {
			q->u.t.cse = NULL;
			return rcc_CSE(0, 0, symboluid(q), visit(p));
		}
	if (p->kids[0] != NULL)
		left = visit(p->kids[0]);
	if (p->kids[1] != NULL)
		right = visit(p->kids[1]);
	switch (specific(p->op)) {
	case CNST+F:
		assert(p->syms[0]);
		return rcc_CNSTF(suffix, size, mk_real(size, p->syms[0]->u.c.v));
	case CALL+B:
		assert(p->syms[0]);
		assert(p->syms[0]->type);
		return rcc_CALLB(suffix, size, left, right, typeuid(p->syms[0]->type));
	case RET+V:
		return rcc_RET(suffix, size);
	case LABEL+V:
		assert(p->syms[0]);
		return rcc_LABEL(suffix, size, p->syms[0]->u.l.label);
	}
	switch (generic(p->op)) {
	case CNST:
		assert(p->syms[0]);
		return rcc_CNST(suffix, size, p->syms[0]->u.c.v.i);	/* FIXME */
	case ARG:
		assert(p->syms[0]);
		return rcc_ARG(suffix, size, left, p->syms[0]->u.c.v.i, p->syms[1]->u.c.v.i);
	case ASGN:
		assert(p->syms[0]);
		assert(p->syms[1]);
		return rcc_ASGN(suffix, size, left, right, p->syms[0]->u.c.v.i, p->syms[1]->u.c.v.i);
	case CVF: case CVI: case CVP: case CVU:
		assert(p->syms[0]);
		return rcc_CVT(suffix, size, generic(p->op), left, p->syms[0]->u.c.v.i);
	case CALL:
		assert(p->syms[0]);
		assert(p->syms[0]->type);
		return rcc_CALL(suffix, size, left, typeuid(p->syms[0]->type));
#define xx(op) case op: return rcc_##op(suffix, size, symboluid(p->syms[0]))
	xx(ADDRG);
	xx(ADDRF);
#undef xx
	case ADDRL:
		if (!p->syms[0]->defined)
			(*IR->local)(p->syms[0]);
		p->syms[0]->defined = 1;
		return rcc_ADDRL(suffix, size, symboluid(p->syms[0]));
	case JUMP:
		if (p->syms[0] != NULL)
			return rcc_BRANCH(suffix, size, p->syms[0]->u.l.label);
		return rcc_Unary(suffix, size, generic(p->op), left);
	case INDIR: case RET: case NEG: case BCOM: 
		return rcc_Unary(suffix, size, generic(p->op), left);
	case BOR: case BAND: case BXOR: case RSH: case LSH:
	case ADD: case SUB: case DIV: case MUL: case MOD:
		return rcc_Binary(suffix, size, generic(p->op), left, right);
	case EQ: case NE: case GT: case GE: case LE: case LT:
		assert(p->syms[0]);
		return rcc_Compare(suffix, size, generic(p->op), left, right, p->syms[0]->u.l.label);
	}
	assert(0);
	return NULL;
}
Exemplo n.º 20
0
/*
 * Try to find constructs like "a = a + 1;" and match them together
 * with instructions like "incl a" or "addl $1,a".
 *
 * Level assignment for priority:
 *	left	right	prio
 *	-	-	-
 *	direct	direct	1
 *	direct	REG	2
 *	direct	OREG	3
 *	OREG	direct	4
 *	OREG	REG	5
 *	OREG	OREG	6
 */
int
findmops(NODE *p, int cookie)
{
	extern int *qtable[];
	struct optab *q;
	int i, sh, shl, shr, lvl = 10;
	NODE *l, *r;
	int *ixp;
	struct optab *qq = NULL; /* XXX gcc */
	int idx = 0, gol = 0, gor = 0;

	shl = shr = 0;

	F2DEBUG(("findmops tree: %s\n", prcook(cookie)));
	F2WALK(p);

	l = getlr(p, 'L');
	r = getlr(p, 'R');
	/* See if this is a usable tree to work with */
	/* Currently only check for leaves */
	if (optype(r->n_op) != BITYPE || treecmp(l, r->n_left) == 0)
		return FFAIL;

	F2DEBUG(("findmops is useable\n"));

	/* We can try to find a match.  Use right op */
	ixp = qtable[r->n_op];
	l = getlr(r, 'L');
	r = getlr(r, 'R');

	for (i = 0; ixp[i] >= 0; i++) {
		q = &table[ixp[i]];

		F2DEBUG(("findmops: ixp %d\n", ixp[i]));
		if (!acceptable(q))		/* target-dependent filter */
			continue;

		if (ttype(l->n_type, q->ltype) == 0 ||
		    ttype(r->n_type, q->rtype) == 0)
			continue; /* Types must be correct */

		F2DEBUG(("findmops got types\n"));

		switch (cookie) {
		case FOREFF:
			if ((q->visit & FOREFF) == 0)
				continue; /* Not only for side effects */
			break;
		case FORCC:
			if ((q->visit & FORCC) == 0)
				continue; /* Not only for side effects */
			break;
		default:
			if ((cookie & q->visit) == 0)
				continue; /* Won't match requested shape */
			if (((cookie & INREGS & q->lshape) == 0) || !isreg(l))
				continue; /* Bad return register */
			break;
		}
		F2DEBUG(("findmops cookie\n"));

		/*
		 * left shape must match left node.
		 */
		if ((shl = tshape(l, q->lshape)) != SRDIR && (shl != SROREG))
			continue;

		F2DEBUG(("findmops lshape %s\n", srtyp[shl]));
		F2WALK(l);

		if ((shr = chcheck(r, q->rshape, 0)) == SRNOPE)
			continue;

		F2DEBUG(("findmops rshape %s\n", srtyp[shr]));

		/*
		 * Only allow RLEFT. XXX
		 */
		if ((q->rewrite & (RLEFT|RRIGHT)) != RLEFT)
			continue;

		F2DEBUG(("rewrite OK\n"));

		F2WALK(r);
		if (q->needs & REWRITE)
			break;	/* Done here */

		if (lvl <= (shl + shr))
			continue;

		lvl = shl + shr;
		qq = q;
		idx = ixp[i];
		gol = shl;
		gor = shr;
	}

	if (lvl == 10)
		return FFAIL;
	F2DEBUG(("findmops entry %d(%s,%s)\n", idx, srtyp[gol], srtyp[gor]));

	/*
	 * Now we're here and have a match. left is semi-direct and 
	 * right may be anything.
	 */

	sh = -1;
	sh = shswitch(sh, p->n_left, qq->lshape, cookie,
	    qq->rewrite & RLEFT, gol);
	sh = shswitch(sh, r, qq->rshape, cookie, 0, gor);

	if (sh == -1) {
		if (cookie & (FOREFF|FORCC))
			sh = 0;
		else
			sh = ffs(cookie & qq->visit & INREGS)-1;
	}
	F2DEBUG(("findmops done: node %p class %d\n", p, sh));

	/* Trickery:  Set table index on assign to op instead */
	/* gencode() will remove useless nodes */
	p->n_su = MKIDX(idx, 0);
	p->n_su |= ISMOPS; /* XXX tell gencode to reduce the right tree */
	SCLASS(p->n_su, sh);

	return sh;
}
Exemplo n.º 21
0
//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
Exemplo n.º 22
0
Arquivo: gen.c Projeto: Godzil/osXdk
static int needtmp(sNode_t p) 
{
	switch (generic(p->op)) 
	{
		case ADDRF: 
		case ADDRG: 
		case ADDRL:
		case CNST:
			assert(optimizelevel==0);
			return 1;
		case INDIR:
			if (optimizelevel>=3) 
			{
				if (optype(p->op)==B) 
				{ /* fix frontend bug: remove all INDIRB nodes */
					p->x.optimized=1;
					p->x.result=p->kids[0]->x.result;
					p->x.name=p->x.result->x.name;
					p->x.adrmode=p->kids[0]->x.adrmode;
					return 0;
				} 
				else 
				if (p->x.next
				     &&	( p->kids[0]->count==0
					|| p->count==1
					  && ( p->x.next->kids[0]==p
					    || p->x.next->kids[1]==p)
					)
				     && ( generic(p->kids[0]->op)==ADDRF
					|| generic(p->kids[0]->op)==ADDRG
					|| generic(p->kids[0]->op)==ADDRL
					|| generic(p->kids[0]->op)==CNST ))
				{
					p->x.optimized=1;
					p->x.result=p->kids[0]->x.result;
					p->x.name=p->x.result->x.name;
					if (p->x.result->x.adrmode=='C')
						p->x.adrmode='D';
					else p->x.adrmode='I';
					return 0;
				}
			}
			return 1;
		case ASGN:
		case ARG:
		case EQ: 
		case GE: 
		case GT: 
		case LE: 
		case LT: 
		case NE:
		case RET:
		case JUMP: 
		case LABEL:
			return 0;
		case CALL: 
			if (optype(p->op)==B) return 0;
			if (p->count==0) p->op=CALLV;
			if (optype(p->op)==V) return 0;
			else return 1;
		default:
			return 1;
	}
}