예제 #1
0
/*
 * Unable to convert to OREG (notoff() returned failure).  Output
 * suitable instructions to replace OREG.
 */
void
myormake(NODE *q)
{
	NODE *p;

	if (x2debug)
		printf("myormake(%p)\n", q);

        p = q->n_left;

	/*
	 * This handles failed OREGs conversions, due to the offset
	 * being too large for an OREG.
	 */
	if ((p->n_op == PLUS || p->n_op == MINUS) && p->n_right->n_op == ICON) {
		if (isreg(p->n_left) == 0)
			(void)geninsn(p->n_left, INAREG);
		if (isreg(p->n_right) == 0)
			(void)geninsn(p->n_right, INAREG);
		(void)geninsn(p, INAREG);
	} else if (p->n_op == REG) {
		q->n_op = OREG;
		q->n_lval = p->n_lval;
		q->n_rval = p->n_rval;
		tfree(p);
	}
}
예제 #2
0
/* setup for assignment operator */
int
setasg(NODE *p, int cookie)
{
	if (x2debug)
		printf("setasg(%p,%s)\n", p, prcook(cookie));

	if (p->n_left->n_op == FLD && !isreg(p->n_left->n_left)) {
		NODE *l, *r;
		int reg;

		geninsn(p->n_left->n_left, INAREG);

		reg = DECRA(p->n_left->n_left->n_reg, 0);
		l = tcopy(p->n_left->n_left);
		p->n_left->n_left->n_op = REG;
		p->n_left->n_left->n_rval = reg;
		p->n_left->n_left->n_lval = 0;
		r = tcopy(p->n_left->n_left);

		geninsn(p->n_left, INAREG);
		l = mkbinode(ASSIGN, l, r, l->n_type);
		geninsn(l, INAREG);
		return (1);
	}

	return (0);
}
예제 #3
0
/*
 * Turn a UMUL-referenced node into OREG.
 * Be careful about register classes, this is a place where classes change.
 */
void
offstar(NODE *p, int shape)
{
	NODE *r;

	if (x2debug)
		printf("offstar(%p)\n", p);

	if (isreg(p))
		return; /* Is already OREG */

	r = p->n_right;
	if( p->n_op == PLUS || p->n_op == MINUS ){
		if( r->n_op == ICON ){
			if (isreg(p->n_left) == 0)
				(void)geninsn(p->n_left, INAREG);
			/* Converted in ormake() */
			return;
		}
		if (r->n_op == LS && r->n_right->n_op == ICON &&
		    getlval(r->n_right) == 2 && p->n_op == PLUS) {
			if (isreg(p->n_left) == 0)
				(void)geninsn(p->n_left, INAREG);
			if (isreg(r->n_left) == 0)
				(void)geninsn(r->n_left, INAREG);
			return;
		}
	}
	(void)geninsn(p, INAREG);
}
예제 #4
0
/*
 * Turn a UMUL-referenced node into OREG.
 * Be careful about register classes, this is a place where classes change.
 */
void
offstar(NODE *p, int shape)
{
	if (x2debug)
		printf("offstar(%p)\n", p);

	if (isreg(p))
		return; /* Is already OREG */

	if (p->n_op == UMUL)
		p = p->n_left; /* double indexed umul */

	if (inctree(p)) /* Do post-inc conversion */
		return;

	if( p->n_op == PLUS || p->n_op == MINUS ){
		if (p->n_right->n_op == ICON) {
			if (isreg(p->n_left) == 0)
				(void)geninsn(p->n_left, INAREG);
			/* Converted in ormake() */
			return;
		}
	}
	(void)geninsn(p, INAREG);
}
예제 #5
0
/*
 * Turn a UMUL-referenced node into OREG.
 */
void
offstar(NODE *p, int shape)
{
	if (x2debug)
		printf("offstar(%p)\n", p);

	if (p->n_op == PLUS || p->n_op == MINUS) {
		if (p->n_right->n_op == ICON) {
			if (isreg(p->n_left) == 0)
				(void)geninsn(p->n_left, INAREG);
			/* Converted in ormake() */
			return;
		}
	}
	(void)geninsn(p, INAREG);
}
예제 #6
0
파일: match.c 프로젝트: JamesLinus/pcc
/*
 * 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;

}
예제 #7
0
/*
 * Turn a UMUL-referenced node into OREG.
 * Be careful about register classes, this is a place where classes change.
 *
 * AMD64 (and i386) have a quite powerful addressing scheme:
 * 	:	4(%rax)		4 + %rax
 * 	:	4(%rbx,%rax,8)	4 + %rbx + %rax * 8
 * 	:	4(,%rax)	4 + %rax * 8
 * The 8 above can be 1,2,4 or 8.
 */
void
offstar(NODE *p, int shape)
{
	NODE *l;

	if (x2debug) {
		printf("offstar(%p)\n", p);
		fwalk(p, e2print, 0);
	}

	if (isreg(p))
		return; /* Matched (%rax) */

	if (findls(p, 0))
		return; /* Matched (,%rax,8) */

	if ((p->n_op == PLUS || p->n_op == MINUS) && p->n_left->n_op == ICON) {
		l = p->n_right;
		if (isreg(l))
			return; /* Matched 4(%rax) */
		if (findls(l, 0))
			return; /* Matched 4(,%rax,8) */
		if (l->n_op == PLUS && isreg(l->n_right)) {
			if (findls(l->n_left, 0))
				return; /* Matched 4(%rbx,%rax,8) */
			(void)geninsn(l->n_left, INAREG);
			return; /* Generate 4(%rbx,%rax) */
		}
		(void)geninsn(l, INAREG);
		return; /* Generate 4(%rbx) */
	}

	if (p->n_op == PLUS) {
		if (!isreg(p->n_left)) /* ensure right is REG */
			(void)geninsn(p->n_left, INAREG);
		if (isreg(p->n_right))
			return; /* Matched (%rax,%rbx) */
		if (findls(p->n_right, 0))
			return; /* Matched (%rax,%rbx,4) */
		(void)geninsn(p->n_right, INAREG);
		return; /* Generate (%rbx,%rax) */
	}
		
	(void)geninsn(p, INAREG);
}
예제 #8
0
void
offstar(NODE *p, int shape)
{
	NODE *q;

	if (x2debug)
		printf("offstar(%p)\n", p);

	if( p->n_op == PLUS || p->n_op == MINUS ){
		if( p->n_right->n_op == ICON ){
			q = p->n_left;
			if (q->n_op != REG)
				geninsn(q, INAREG);
			p->n_su = -1;
		}
	}
	geninsn(p, INAREG);
}
예제 #9
0
/*
 * Turn a UMUL-referenced node into OREG.
 * Be careful about register classes, this is a place where classes change.
 */
void
offstar(NODE *p, int shape)
{
	NODE *r;

	if (x2debug)
		printf("offstar(%p)\n", p);

	if (isreg(p))
		return; /* Is already OREG */

	r = p->n_right;
	if( p->n_op == PLUS || p->n_op == MINUS ){
		if( r->n_op == ICON ){
			if (isreg(p->n_left) == 0 ||
			    (p->n_left->n_op == REG &&
			    p->n_left->n_rval != 2 && p->n_left->n_rval != 3))
				(void)geninsn(p->n_left, INBREG);
			/* Converted in ormake() */
			return;
		}
	}
	(void)geninsn(p, INBREG);
}
예제 #10
0
/*
 * Check if LS and try to make it indexable.
 * Ignore SCONV to long.
 * Return 0 if failed.
 */
static int
findls(NODE *p, int check)
{
	CONSZ c;

	if (p->n_op == SCONV && p->n_type == LONG && p->n_left->n_type == INT)
		p = p->n_left; /* Ignore pointless SCONVs here */
	if (p->n_op != LS || p->n_right->n_op != ICON)
		return 0;
	if ((c = p->n_right->n_lval) != 1 && c != 2 && c != 3)
		return 0;
	if (check == 1 && p->n_left->n_op != REG)
		return 0;
	if (!isreg(p->n_left))
		(void)geninsn(p->n_left, INAREG);
	return 1;
}