renamed to firm_init_reflect()
[libfirm] / ir / ir / irarch.c
index 36a59c4..e539e20 100644 (file)
 #include "dbginfo_t.h"
 #include "iropt_dbg.h"
 #include "irflag_t.h"
-#include "firmstat.h"
+#include "irhooks.h"
 #include "ircons.h"
 #include "irarch.h"
-#include "firmstat.h"
 
 #undef DEB
 
@@ -88,6 +87,14 @@ void arch_dep_set_opts(arch_dep_opts_t the_opts) {
   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;
@@ -330,7 +337,7 @@ ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn)
   }
 
   if (res != irn)
-    stat_arch_dep_replace_mul_with_shifts(irn);
+    hook_arch_dep_replace_mul_with_shifts(irn);
 
   return res;
 }
@@ -398,11 +405,18 @@ static struct ms magic(tarval *d)
   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));
@@ -451,6 +465,8 @@ static struct ms magic(tarval *d)
   /* 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;
 }
 
@@ -471,12 +487,18 @@ static struct mu magicu(tarval *d)
   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));
@@ -518,6 +540,8 @@ static struct mu magicu(tarval *d)
   magu.M = ADD(q2, ONE(mode));                       /* Magic number */
   magu.s = p - bits;                                 /* and shift amount */
 
+  tarval_set_integer_overflow_mode(rem);
+
   return magu;
 }
 
@@ -675,14 +699,13 @@ ir_node *arch_dep_replace_div_by_const(ir_node *irn)
     }
     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);
     }
   }
 
   if (res != irn)
-    stat_arch_dep_replace_div_by_const(irn);
+    hook_arch_dep_replace_div_by_const(irn);
 
   return res;
 }
@@ -760,8 +783,7 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn)
     }
     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);
@@ -774,7 +796,7 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn)
   }
 
   if (res != irn)
-    stat_arch_dep_replace_mod_by_const(irn);
+    hook_arch_dep_replace_mod_by_const(irn);
 
   return res;
 }
@@ -866,8 +888,7 @@ void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn
     }
     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);
@@ -882,7 +903,7 @@ void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn
   }
 
   if (*div)
-    stat_arch_dep_replace_DivMod_by_const(irn);
+    hook_arch_dep_replace_DivMod_by_const(irn);
 }