Esempio n. 1
0
/**
 * lower 64bit minus operation
 */
static void ia32_lower_minus64(ir_node *node, ir_mode *mode)
{
	dbg_info *dbg     = get_irn_dbg_info(node);
	ir_node  *block   = get_nodes_block(node);
	ir_node  *op      = get_Minus_op(node);
	ir_node  *op_low  = get_lowered_low(op);
	ir_node  *op_high = get_lowered_high(op);
	ir_node  *minus   = new_bd_ia32_l_Minus64(dbg, block, op_low, op_high);
	ir_node  *l_res   = new_r_Proj(minus, ia32_mode_gp, pn_ia32_Minus64_res_low);
	ir_node  *h_res   = new_r_Proj(minus, mode, pn_ia32_Minus64_res_high);
	ir_set_dw_lowered(node, l_res, h_res);
}
Esempio n. 2
0
static void lower64_minus(ir_node *node, ir_mode *mode)
{
	dbg_info *dbgi         = get_irn_dbg_info(node);
	ir_graph *irg          = get_irn_irg(node);
	ir_node  *block        = get_nodes_block(node);
	ir_node  *op           = get_Minus_op(node);
	ir_node  *right_low    = get_lowered_low(op);
	ir_node  *right_high   = get_lowered_high(op);
	ir_mode  *low_unsigned = get_irn_mode(right_low);
	ir_node  *left_low     = new_r_Const_null(irg, low_unsigned);
	ir_node  *left_high    = new_r_Const_null(irg, mode);
	ir_node  *subs         = new_bd_arm_SubS_t(dbgi, block, left_low,
	                                           right_low);
	ir_node  *res_low      = new_r_Proj(subs, low_unsigned, pn_arm_SubS_t_res);
	ir_node  *res_flags    = new_r_Proj(subs, mode_ANY, pn_arm_SubS_t_flags);
	ir_node  *sbc          = new_bd_arm_SbC_t(dbgi, block, left_high,
	                                          right_high, res_flags, mode);
	ir_set_dw_lowered(node, res_low, sbc);
}
Esempio n. 3
0
/*
 * Check, if the value of a node is != 0.
 *
 * This is a often needed case, so we handle here Confirm
 * nodes too.
 */
int value_not_zero(const ir_node *n, const ir_node **confirm)
{
#define RET_ON(x)  if (x) { *confirm = n; return 1; } break

	ir_tarval *tv;
	ir_mode *mode = get_irn_mode(n);
	ir_relation relation;

	*confirm = NULL;

	/* there might be several Confirms one after other that form an interval */
	for (;;) {
		if (is_Minus(n)) {
			/* we can safely skip Minus when checking for != 0 */
			n = get_Minus_op(n);
			continue;
		}
		if (! is_Confirm(n))
			break;

		/*
		 * Note: A Confirm is never after a Const. So,
		 * we simply can check the bound for being a Const
		 * without the fear that is might be hidden by a further Confirm.
		 */
		tv = value_of(get_Confirm_bound(n));
		if (tv == tarval_bad) {
			n = get_Confirm_value(n);
			continue;
		}

		relation = tarval_cmp(tv, get_mode_null(mode));

		/*
		 * Beware: C might by a NaN. It is not clear, what we should do
		 * than. Of course a NaN is != 0, but we might use this function
		 * to remove up Exceptions, and NaN's might generate Exception.
		 * So, we do NOT handle NaNs here for safety.
		 *
		 * Note that only the C != 0 case need additional checking.
		 */
		switch (get_Confirm_relation(n)) {
		case ir_relation_equal: /* n == C /\ C != 0 ==> n != 0 */
			RET_ON(relation != ir_relation_equal && relation != ir_relation_unordered);
		case ir_relation_less_greater: /* n != C /\ C == 0 ==> n != 0 */
			RET_ON(relation == ir_relation_equal);
		case ir_relation_less: /* n <  C /\ C <= 0 ==> n != 0 */
			RET_ON(relation == ir_relation_less || relation == ir_relation_equal);
		case ir_relation_less_equal: /* n <= C /\ C <  0 ==> n != 0 */
			RET_ON(relation == ir_relation_less);
		case ir_relation_greater_equal: /* n >= C /\ C >  0 ==> n != 0 */
			RET_ON(relation == ir_relation_greater);
		case ir_relation_greater: /* n >  C /\ C >= 0 ==> n != 0 */
			RET_ON(relation == ir_relation_greater || relation == ir_relation_equal);
		default:
			break;
		}
		n = get_Confirm_value(n);
	}
	/* global entities are never NULL */
	if (is_SymConst_addr_ent(n))
		return true;

	tv = value_of(n);
	if (tv == tarval_bad)
		return false;

	relation = tarval_cmp(tv, get_mode_null(mode));

	/* again, need check for NaN */
	return (relation != ir_relation_equal) && (relation != ir_relation_unordered);

#undef RET_ON
}
Esempio n. 4
0
/*
 * Check, if the value of a node can be confirmed >= 0 or <= 0,
 * If the mode of the value did not honor signed zeros, else
 * check for >= 0 or < 0.
 */
ir_value_classify_sign classify_value_sign(ir_node *n)
{
	ir_tarval *tv, *c;
	ir_mode *mode;
	ir_relation cmp, ncmp;
	int negate = 1;

	for (;;) {
		unsigned code = get_irn_opcode(n);

		switch (code) {
		case iro_Minus:
			negate *= -1;
			n = get_Minus_op(n);
			continue;
		case iro_Confirm:
			break;
		default:
			return value_classified_unknown;
		}
		break;
	}
	if (!is_Confirm(n))
		return value_classified_unknown;

	tv  = value_of(get_Confirm_bound(n));
	if (tv == tarval_bad)
		return value_classified_unknown;

	mode = get_irn_mode(n);

	/*
	 * We can handle only >=, >, <, <= cases.
	 * We could handle == too, but this will be optimized into
	 * a constant either.
	 *
	 * Note that for integer modes we have a slightly better
	 * optimization possibilities, so we handle this
	 * different.
	 */
	cmp = get_Confirm_relation(n);

	switch (cmp) {
	case ir_relation_less:
		/*
		 * must be x < c <= 1 to be useful if integer mode and -0 = 0
		 *         x < c <= 0 to be useful else
		 */
	case ir_relation_less_equal:
		/*
		 * must be x <= c < 1 to be useful if integer mode and -0 = 0
		 *         x <= c < 0 to be useful else
		 */
		c = mode_is_int(mode) && mode_honor_signed_zeros(mode) ?
			get_mode_one(mode) : get_mode_null(mode);

		ncmp = tarval_cmp(tv, c);
		if (ncmp == ir_relation_equal)
			ncmp = ir_relation_less_equal;

		if (cmp != (ncmp ^ ir_relation_equal))
			return value_classified_unknown;

		/* yep, negative */
		return value_classified_negative * negate;

	case ir_relation_greater_equal:
		/*
		 * must be x >= c > -1 to be useful if integer mode
		 *         x >= c >= 0 to be useful else
		 */
	case ir_relation_greater:
		/*
		 * must be x > c >= -1 to be useful if integer mode
		 *         x > c >= 0 to be useful else
		 */
		if (mode_is_int(mode)) {
			c = get_mode_minus_one(mode);

			ncmp = tarval_cmp(tv, c);
			if (ncmp == ir_relation_equal)
				ncmp = ir_relation_greater_equal;

			if (cmp != (ncmp ^ ir_relation_equal))
				return value_classified_unknown;
		} else {
			c = get_mode_minus_one(mode);

			ncmp = tarval_cmp(tv, c);

			if (ncmp != ir_relation_equal && ncmp != ir_relation_greater)
				return value_classified_unknown;
		}

		/* yep, positive */
		return value_classified_positive * negate;

	default:
		return value_classified_unknown;
	}
}
Esempio n. 5
0
ir_node *copy_const_value(dbg_info *dbg, ir_node *n, ir_node *block)
{
	ir_graph *irg = get_irn_irg(block);

	/* @@@ GL I think we should implement this using the routines from irgopt
	 * for dead node elimination/inlineing. */
	ir_mode *m = get_irn_mode(n);
	ir_node *nn;
	switch (get_irn_opcode(n)) {
	case iro_Const:
		nn = new_rd_Const(dbg, irg, get_Const_tarval(n));
		break;
	case iro_SymConst:
		nn = new_rd_SymConst(dbg, irg, get_irn_mode(n), get_SymConst_symbol(n), get_SymConst_kind(n));
		break;
	case iro_Add:
		nn = new_rd_Add(dbg, block,
		                copy_const_value(dbg, get_Add_left(n), block),
		                copy_const_value(dbg, get_Add_right(n), block), m);
		break;
	case iro_Sub:
		nn = new_rd_Sub(dbg, block,
		                copy_const_value(dbg, get_Sub_left(n), block),
		                copy_const_value(dbg, get_Sub_right(n), block), m);
		break;
	case iro_Mul:
		nn = new_rd_Mul(dbg, block,
		                copy_const_value(dbg, get_Mul_left(n), block),
		                copy_const_value(dbg, get_Mul_right(n), block), m);
		break;
	case iro_And:
		nn = new_rd_And(dbg, block,
		                copy_const_value(dbg, get_And_left(n), block),
		                copy_const_value(dbg, get_And_right(n), block), m);
		break;
	case iro_Or:
		nn = new_rd_Or(dbg, block,
		               copy_const_value(dbg, get_Or_left(n), block),
		               copy_const_value(dbg, get_Or_right(n), block), m);
		break;
	case iro_Eor:
		nn = new_rd_Eor(dbg, block,
		                copy_const_value(dbg, get_Eor_left(n), block),
		                copy_const_value(dbg, get_Eor_right(n), block), m);
		break;
	case iro_Conv:
		nn = new_rd_Conv(dbg, block,
		                 copy_const_value(dbg, get_Conv_op(n), block), m);
		break;
	case iro_Minus:
		nn = new_rd_Minus(dbg, block,
		                  copy_const_value(dbg, get_Minus_op(n), block), m);
		break;
	case iro_Not:
		nn = new_rd_Not(dbg, block,
		                copy_const_value(dbg, get_Not_op(n), block), m);
		break;
	case iro_Unknown:
		nn = new_r_Unknown(irg, m);
		break;
	default:
		panic("opcode invalid or not implemented %+F", n);
	}
	return nn;
}