tarval: shift variants with unsigned right operand
authorMatthias Braun <matthias.braun@kit.edu>
Fri, 24 Aug 2012 15:44:09 +0000 (17:44 +0200)
committerMatthias Braun <matthias.braun@kit.edu>
Fri, 24 Aug 2012 17:11:17 +0000 (19:11 +0200)
include/libfirm/tv.h
ir/lower/lower_dw.c
ir/opt/fp-vrp.c
ir/tv/strcalc.c
ir/tv/strcalc.h
ir/tv/tv.c

index 9e10ec8..f546447 100644 (file)
@@ -566,6 +566,12 @@ FIRM_API ir_tarval *tarval_eor(ir_tarval *a, ir_tarval *b);
  */
 FIRM_API ir_tarval *tarval_shl(ir_tarval *a, ir_tarval *b);
 
+/**
+ * logical left shift (variant with unsigned argument).
+ * @see tarval_shl()
+ */
+FIRM_API ir_tarval *tarval_shl_unsigned(ir_tarval *a, unsigned b);
+
 /**
  * Unsigned (logical) right shift.
  *
@@ -576,6 +582,12 @@ FIRM_API ir_tarval *tarval_shl(ir_tarval *a, ir_tarval *b);
  */
 FIRM_API ir_tarval *tarval_shr(ir_tarval *a, ir_tarval *b);
 
+/**
+ * unsigned (logical) right shift (variant with unsigned argument).
+ * @see tarval_shr()
+ */
+FIRM_API ir_tarval *tarval_shr_unsigned(ir_tarval *a, unsigned b);
+
 /**
  * Signed (arithmetic) right shift.
  *
@@ -586,6 +598,12 @@ FIRM_API ir_tarval *tarval_shr(ir_tarval *a, ir_tarval *b);
  */
 FIRM_API ir_tarval *tarval_shrs(ir_tarval *a, ir_tarval *b);
 
+/**
+ * signed (arithmetic) right shift (variant with unsigned argument).
+ * @see tarval_shrs()
+ */
+FIRM_API ir_tarval *tarval_shrs_unsigned(ir_tarval *a, unsigned b);
+
 /**
  * Rotation to left.
  *
index f0bf63b..4ca1bb5 100644 (file)
@@ -111,7 +111,6 @@ typedef struct lower_dw_env_t {
        ir_graph      *irg;
        struct obstack obst;           /**< an obstack holding the temporary data */
        ir_tarval *tv_mode_bytes;      /**< a tarval containing the number of bytes in the lowered modes */
-       ir_tarval *tv_mode_bits;       /**< a tarval containing the number of bits in the lowered modes */
        pdeq      *waitq;              /**< a wait queue of all nodes that must be handled later */
        ir_node  **lowered_phis;       /**< list of lowered phis */
        ir_mode   *high_signed;        /**< doubleword signed type */
@@ -355,7 +354,7 @@ static void lower_Const(ir_node *node, ir_mode *mode)
        ir_tarval *tv       = get_Const_tarval(node);
        ir_tarval *tv_l     = tarval_convert_to(tv, low_mode);
        ir_node   *res_low  = new_rd_Const(dbg, irg, tv_l);
-       ir_tarval *tv_shrs  = tarval_shrs(tv, env->tv_mode_bits);
+       ir_tarval *tv_shrs  = tarval_shrs_unsigned(tv, get_mode_size_bits(low_mode));
        ir_tarval *tv_h     = tarval_convert_to(tv_shrs, mode);
        ir_node   *res_high = new_rd_Const(dbg, irg, tv_h);
 
@@ -3160,7 +3159,6 @@ void ir_lower_dw_ops(void)
        }
 
        lenv.tv_mode_bytes = new_tarval_from_long(param->doubleword_size/(2*8), lenv.low_unsigned);
-       lenv.tv_mode_bits  = new_tarval_from_long(param->doubleword_size/2, lenv.low_unsigned);
        lenv.waitq         = new_pdeq();
        lenv.first_id      = new_id_from_chars(param->little_endian ? ".l" : ".h", 2);
        lenv.next_id       = new_id_from_chars(param->little_endian ? ".h" : ".l", 2);
index cd3dfca..d7baf94 100644 (file)
@@ -435,9 +435,9 @@ undefined:
                                                ir_tarval* const rzn = tarval_or(rz, tarval_neg(rz));
                                                // Concatenate safe lower zeroes.
                                                if (tarval_cmp(lzn, rzn) == ir_relation_less) {
-                                                       z = tarval_mul(tarval_eor(lzn, tarval_shl(lzn, get_tarval_one(m))), rzn);
+                                                       z = tarval_mul(tarval_eor(lzn, tarval_shl_unsigned(lzn, 1)), rzn);
                                                } else {
-                                                       z = tarval_mul(tarval_eor(rzn, tarval_shl(rzn, get_tarval_one(m))), lzn);
+                                                       z = tarval_mul(tarval_eor(rzn, tarval_shl_unsigned(rzn, 1)), lzn);
                                                }
                                                o = get_tarval_null(m);
                                        }
index c4dd863..6a6e612 100644 (file)
@@ -1566,6 +1566,20 @@ void sc_shr(const void *val1, const void *val2, int bitsize, int sign, void *buf
        sc_shrI(val1, shift_cnt, bitsize, sign, buffer);
 }
 
+void sc_shrsI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
+{
+       carry_flag = 0;
+
+       DEBUGPRINTF_COMPUTATION(("%s >>s %ld ", sc_print_hex(value1), shift_cnt));
+       do_shr((const char*) val1, calc_buffer, shift_cnt, bitsize, sign, 1);
+
+       DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
+
+       if ((buffer != NULL) && (buffer != calc_buffer)) {
+               memmove(buffer, calc_buffer, calc_buffer_size);
+       }
+}
+
 void sc_shrs(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
 {
        long offset = sc_val_to_long(val2);
index a2e9428..8d74b81 100644 (file)
@@ -167,6 +167,11 @@ void sc_shrI(const void *val1, long shift_cnt, int bitsize, int sign, void *buff
  */
 void sc_shr(const void *value1, const void *value2, int bitsize, int sign, void *buffer);
 
+/**
+ * buffer = value1 >>s offset
+ */
+void sc_shrsI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer);
+
 /**
  * buffer = value1 >>s value2
  */
index 60f5722..2100c29 100644 (file)
@@ -1291,6 +1291,17 @@ ir_tarval *tarval_shl(ir_tarval *a, ir_tarval *b)
        return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
 
+ir_tarval *tarval_shl_unsigned(ir_tarval *a, unsigned b)
+{
+       ir_mode *mode   = a->mode;
+       unsigned modulo = get_mode_modulo_shift(mode);
+       if (modulo != 0)
+               b %= modulo;
+       assert((unsigned)(long)b==b);
+       sc_shlI(a->value, (long)b, get_mode_size_bits(mode), mode_is_signed(mode), NULL);
+       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+}
+
 /*
  * bitwise unsigned right shift
  */
@@ -1314,6 +1325,17 @@ ir_tarval *tarval_shr(ir_tarval *a, ir_tarval *b)
        return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
 
+ir_tarval *tarval_shr_unsigned(ir_tarval *a, unsigned b)
+{
+       ir_mode *mode   = a->mode;
+       unsigned modulo = get_mode_modulo_shift(mode);
+       if (modulo != 0)
+               b %= modulo;
+       assert((unsigned)(long)b==b);
+       sc_shrI(a->value, (long)b, get_mode_size_bits(mode), mode_is_signed(mode), NULL);
+       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+}
+
 /*
  * bitwise signed right shift
  */
@@ -1337,6 +1359,17 @@ ir_tarval *tarval_shrs(ir_tarval *a, ir_tarval *b)
        return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
 
+ir_tarval *tarval_shrs_unsigned(ir_tarval *a, unsigned b)
+{
+       ir_mode *mode   = a->mode;
+       unsigned modulo = get_mode_modulo_shift(mode);
+       if (modulo != 0)
+               b %= modulo;
+       assert((unsigned)(long)b==b);
+       sc_shrsI(a->value, (long)b, get_mode_size_bits(mode), mode_is_signed(mode), NULL);
+       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+}
+
 /*
  * bitwise rotation to left
  */