Handle left shift (when magnitude > mantissa) when converting float constants to...
authorChristoph Mallon <christoph.mallon@gmx.de>
Tue, 11 Sep 2007 11:53:49 +0000 (11:53 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Tue, 11 Sep 2007 11:53:49 +0000 (11:53 +0000)
[r15744]

ir/tv/fltcalc.c
ir/tv/strcalc.c
ir/tv/strcalc.h

index ca16d7f..bed4dac 100644 (file)
@@ -1651,9 +1651,13 @@ int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode) {
                }
 
                assert(exp_val >= 0 && "floating point value not integral before fc_flt2int() call");
-               shift = a->desc.mantissa_size - exp_val + 2;
+               shift = exp_val - a->desc.mantissa_size - 2;
 
-               sc_shrI(_mant(a), shift, 64, 0, result);
+               if (shift > 0) {
+                       sc_shlI(_mant(a),  shift, 64, 0, result);
+               } else {
+                       sc_shrI(_mant(a), -shift, 64, 0, result);
+               }
 
                /* check for overflow */
                highest = sc_get_highest_set_bit(result);
index 3fb6ab3..dc68796 100644 (file)
@@ -1646,9 +1646,7 @@ void sc_divmod(const void *value1, const void *value2, void *div_buffer, void *m
 }
 
 
-void sc_shl(const void *val1, const void *val2, int radius, int sign, void *buffer) {
-       long offset = sc_val_to_long(val2);
-
+void sc_shlI(const void *val1, long offset, int radius, int sign, void *buffer) {
        carry_flag = 0;
 
        DEBUGPRINTF_COMPUTATION(("%s << %ld ", sc_print_hex(value1), offset));
@@ -1661,6 +1659,12 @@ void sc_shl(const void *val1, const void *val2, int radius, int sign, void *buff
        }
 }
 
+void sc_shl(const void *val1, const void *val2, int radius, int sign, void *buffer) {
+       long offset = sc_val_to_long(val2);
+
+       sc_shlI(val1, offset, radius, sign, buffer);
+}
+
 void sc_shrI(const void *val1, long offset, int radius, int sign, void *buffer) {
        carry_flag = 0;
 
index 1b62619..ec666bc 100644 (file)
@@ -143,6 +143,11 @@ void sc_mod(const void *value1, const void *value2, void *buffer);
  */
 void sc_divmod(const void *value1, const void *value2, void *div_buffer, void *mod_buffer);
 
+/**
+ * buffer = value1 << offset
+ */
+void sc_shlI(const void *val1, long offset, int radius, int sign, void *buffer);
+
 /**
  * buffer = value1 << value2
  */