示例#1
0
文件: gcc_compat.c 项目: antoineL/pcc
/*
 * Check if we may have to do a cast to/from TI.
 */
NODE *
gcc_eval_ticast(int op, NODE *p1, NODE *p2)
{
	struct attr *a1, *a2;
	int t;

	a2 = NULL; /* XXX flow analysis */
	if ((a1 = isti(p1)) == NULL && (a2 = isti(p2)) == NULL)
		return NIL;

	if (op == RETURN)
		p1 = p1tcopy(p1);
	if (a1 == NULL) {
		if (a2 == NULL)
			cerror("gcc_eval_ticast error");
		switch (p1->n_type) {
		case LDOUBLE:
			p2 = doacall(floatuntixfsp,
			    nametree(floatuntixfsp), p2);
			tfree(p1);
			break;
		case ULONG:
		case LONG:
			p2 = cast(structref(p2, DOT, loti), p1->n_type, 0);
			tfree(p1);
			break;
		case VOID:
			return NIL;
		default:
			uerror("gcc_eval_ticast: %d", p1->n_type);
		}
		return p2;
	}
	/* p2 can be anything, but we must cast it to p1 */
	t = a1->iarg(1);

	if (p2->n_type == STRTY &&
	    (a2 = attr_find(p2->n_ap, GCC_ATYP_MODE)) &&
	    strcmp(a2->sarg(0), TISTR) == 0) {
		/* Already TI, just add extra mode bits */
		a2 = attr_new(GCC_ATYP_MODE, 3);
		a2->sarg(0) = TISTR;
		a2->iarg(1) = t;
		p2->n_ap = attr_add(p2->n_ap, a2);
	} else  {
		p2 = ticast(p2, t);
	}
	tfree(p1);
	return p2;
}
示例#2
0
/*
 * Ensure that a 128-bit assign succeeds.
 * If left is not TI, make right not TI,
 * else if left _is_ TI, make right TI,
 * else do nothing.
 */
static NODE *
timodeassign(NODE *p1, NODE *p2)
{
	struct attr *a1, *a2;

	a1 = isti(p1);
	a2 = isti(p2);
	if (a1 && a2 == NULL) {
		p2 = ticast(p2, a1->iarg(1));
	} else if (a1 == NULL && a2) {
		if (ISFTY(p1->n_type))
			cerror("cannot TI float convert");
		p2 = structref(p2, DOT, loti);
	}
	return buildtree(ASSIGN, p1, p2);
}
示例#3
0
/*
 * Apply a unary op on a TI value.
 */
NODE *
gcc_eval_tiuni(int op, NODE *p1)
{
	struct attr *a1;
	NODE *p;

	if ((a1 = isti(p1)) == NULL)
		return NULL;

	switch (op) {
	case UMINUS:
		p = ticast(bcon(0), 0);
		p = buildtree(CM, p, p1);
		p = doacall(subvti3sp, nametree(subvti3sp), p);
		break;

	case UMUL:
		p = NULL;
	default:
		uerror("unsupported unary TI mode op %d", op);
		p = NULL;
	}
	return p;
}
示例#4
0
/*
 * Evaluate 128-bit operands.
 */
NODE *
gcc_eval_timode(int op, NODE *p1, NODE *p2)
{
	struct attr *a1, *a2;
	struct symtab *sp;
	NODE *p;
	int isu = 0, gotti, isaop;

	if (op == CM)
		return buildtree(op, p1, p2);

	a1 = isti(p1);
	a2 = isti(p2);

	if (a1 == NULL && a2 == NULL)
		return NULL;

	if (op == ASSIGN)
		return timodeassign(p1, p2);

	gotti = (a1 != NULL);
	gotti += (a2 != NULL);

	if (gotti == 0)
		return NULL;

	if (a1 != NULL)
		isu = a1->iarg(1);
	if (a2 != NULL && !isu)
		isu = a2->iarg(1);

	if (a1 == NULL) {
		p1 = ticast(p1, isu);
		a1 = attr_find(p1->n_ap, GCC_ATYP_MODE);
	}
	if (a2 == NULL && (cdope(op) & SHFFLG) == 0) {
		p2 = ticast(p2, isu);
		a2 = attr_find(p2->n_ap, GCC_ATYP_MODE);
	}

	switch (op) {
	case GT:
	case GE:
	case LT:
	case LE:
	case EQ:
	case NE:
		/* change to call */
		sp = isu ? ucmpti2sp : cmpti2sp;
		p = doacall(sp, nametree(sp), buildtree(CM, p1, p2));
		p = buildtree(op, p, bcon(1));
		break;

	case AND:
	case ER:
	case OR:
		if (!ISPTR(p1->n_type))
			p1 = buildtree(ADDROF, p1, NIL);
		if (!ISPTR(p2->n_type))
			p2 = buildtree(ADDROF, p2, NIL);
		p = gcc_andorer(op, p1, p2);
		break;

	case LSEQ:
	case RSEQ:
	case LS:
	case RS:
		sp = op == LS || op == LSEQ ? ashldi3sp :
		    isu ? lshrdi3sp : ashrdi3sp;
		p2 = cast(p2, INT, 0);
		/* XXX p1 ccopy may have side effects */
		p = doacall(sp, nametree(sp), buildtree(CM, ccopy(p1), p2));
		if (op == LSEQ || op == RSEQ) {
			p = buildtree(ASSIGN, p1, p);
		} else
			tfree(p1);
		break;

	case PLUSEQ:
	case MINUSEQ:
	case MULEQ:
	case DIVEQ:
	case MODEQ:
	case PLUS:
	case MINUS:
	case MUL:
	case DIV:
	case MOD:
		isaop = (cdope(op)&ASGOPFLG);
		if (isaop)
			op = UNASG op;
		sp = op == PLUS ? addvti3sp :
		    op == MINUS ? subvti3sp :
		    op == MUL ? mulvti3sp :
		    op == DIV ? (isu ? udivti3sp : divti3sp) :
		    op == MOD ? (isu ? umodti3sp : modti3sp) : 0;
		/* XXX p1 ccopy may have side effects */
		p = doacall(sp, nametree(sp), buildtree(CM, ccopy(p1), p2));
		if (isaop)
			p = buildtree(ASSIGN, p1, p);
		else
			tfree(p1);
		break;

	default:
		uerror("unsupported TImode op %d", op);
		p = bcon(0);
	}
	return p;
}