opts = the_opts;
}
+/* check, wheater a mode allows a Mulh instruction */
+static int allow_Mulh(ir_mode *mode)
+{
+ if (get_mode_size_bits(mode) > params->max_bits_for_mulh)
+ return 0;
+ return (mode_is_signed(mode) && params->allow_mulhs) || (!mode_is_signed(mode) && params->allow_mulhu);
+}
+
ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn)
{
ir_node *res = irn;
tarval *ad, *anc, *delta, *q1, *r1, *q2, *r2, *t; /* unsigned */
pnc_number d_cmp, M_cmp;
+ tarval *bits_minus_1, *two_bits_1;
+
struct ms mag;
+ tarval_int_overflow_mode_t rem = tarval_get_integer_overflow_mode();
+
+ /* we need overflow mode to work correctly */
+ tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP);
+
/* 2^(bits-1) */
- tarval *bits_minus_1 = new_tarval_from_long(bits - 1, u_mode);
- tarval *two_bits_1 = SHL(get_mode_one(u_mode), bits_minus_1);
+ bits_minus_1 = new_tarval_from_long(bits - 1, u_mode);
+ two_bits_1 = SHL(get_mode_one(u_mode), bits_minus_1);
ad = CNV(ABS(d), u_mode);
t = ADD(two_bits_1, SHR(CNV(d, u_mode), bits_minus_1));
/* need a sub if d < 0 && M > 0 */
mag.need_sub = d_cmp & Lt && M_cmp & Gt;
+ tarval_set_integer_overflow_mode(rem);
+
return mag;
}
int bits = get_mode_size_bits(mode);
int p;
tarval *nc, *delta, *q1, *r1, *q2, *r2;
+ tarval *bits_minus_1, *two_bits_1, *seven_ff;
struct mu magu;
- tarval *bits_minus_1 = new_tarval_from_long(bits - 1, mode);
- tarval *two_bits_1 = SHL(get_mode_one(mode), bits_minus_1);
- tarval *seven_ff = SUB(two_bits_1, ONE(mode));
+ tarval_int_overflow_mode_t rem = tarval_get_integer_overflow_mode();
+
+ /* we need overflow mode to work correctly */
+ tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP);
+
+ bits_minus_1 = new_tarval_from_long(bits - 1, mode);
+ two_bits_1 = SHL(get_mode_one(mode), bits_minus_1);
+ seven_ff = SUB(two_bits_1, ONE(mode));
magu.need_add = 0; /* initialize the add indicator */
nc = SUB(NEG(ONE(mode)), MOD(NEG(d), d));
magu.M = ADD(q2, ONE(mode)); /* Magic number */
magu.s = p - bits; /* and shift amount */
+ tarval_set_integer_overflow_mode(rem);
+
return magu;
}
int bits = get_mode_size_bits(mode);
ir_node *q, *t, *c;
+ /* Beware: do not transform bad code */
+ if (is_Bad(n) || is_Bad(block))
+ return div;
+
if (mode_is_signed(mode)) {
struct ms mag = magic(tv);
}
else {
/* other constant */
- if ((mode_is_signed(mode) && params->allow_mulhs) ||
- (!mode_is_signed(mode) && params->allow_mulhu))
+ if (allow_Mulh(mode))
res = replace_div_by_mulh(irn, tv);
}
}
}
else {
/* other constant */
- if ((mode_is_signed(mode) && params->allow_mulhs) ||
- (!mode_is_signed(mode) && params->allow_mulhu)) {
+ if (allow_Mulh(mode)) {
res = replace_div_by_mulh(irn, tv);
res = new_rd_Mul(dbg, current_ir_graph, block, res, c, mode);
}
else {
/* other constant */
- if ((mode_is_signed(mode) && params->allow_mulhs) ||
- (!mode_is_signed(mode) && params->allow_mulhu)) {
+ if (allow_Mulh(mode)) {
ir_node *t;
*div = replace_div_by_mulh(irn, tv);