Lets zeor/sign extend sc_val_to_long()
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 28 Oct 2004 12:19:40 +0000 (12:19 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 28 Oct 2004 12:19:40 +0000 (12:19 +0000)
[r4228]

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

index bc9d803..18f0bf1 100644 (file)
@@ -458,7 +458,7 @@ static char* _add(const char* a, const char* b, char* result)
    * when exponents are equal is required though.
    * Also special care about the sign is needed when the mantissas are equal
    * (+/- 0 ?) */
-  if (sign && sc_val_to_long(exp_diff) == 0) {
+  if (sign && sc_val_to_long(exp_diff, VALUE_SIZE >> 2, 1) == 0) {
     switch (sc_comp(_mant(a), _mant(b))) {
       case 1:  /* a > b */
         if (_sign(a)) _sign(result) = 1;  /* abs(a) is bigger and a is negative */
@@ -769,7 +769,7 @@ static char* _trunc(const char *a, char *result)
     memcpy(&_desc(result), &_desc(a), sizeof(descriptor_t));
 
   exp_bias = (1<<_desc(a).exponent_size)/2-1;
-  exp_val = sc_val_to_long(_exp(a)) - exp_bias;
+  exp_val = sc_val_to_long(_exp(a), VALUE_SIZE >> 2, 1) - exp_bias;
 
   if (exp_val < 0) {
     sc_val_from_ulong(0, NULL);
@@ -1212,7 +1212,7 @@ LLDBL fc_val_to_float(const void *val)
 
   /* @@@ long double exponent is 15bit, so the use of sc_val_to_long should not
    * lead to wrong results */
-  exponent = sc_val_to_long(_exp(value)) ;
+  exponent = sc_val_to_long(_exp(value), VALUE_SIZE >> 2, 1) ;
 
   sc_val_from_ulong(2, NULL);
   _shift_right(_mant(value), sc_get_buffer(), _mant(value));
index 110d55b..b2ac72e 100644 (file)
@@ -1153,14 +1153,22 @@ void sc_val_from_ulong(unsigned long value, void *buffer)
   }
 }
 
-long sc_val_to_long(const void *val)
+long sc_val_to_long(const void *val, unsigned int bits, unsigned int is_signed)
 {
   int i;
   long l = 0;
 
   for (i = CALC_BUFFER_SIZE - 1; i >= 0; i--)
-  {
     l = (l << 4) + _val(((char *)val)[i]);
+
+  if (bits < (sizeof(long) << 3)) {
+    /* remove unused bits */
+    l &= ~((-1) << bits);
+
+    /* sign extend */
+    if (is_signed)
+      if (l & (1 << (bits-1)))
+        l |= ((-1) << bits);
   }
   return l;
 }
@@ -1279,7 +1287,7 @@ void sc_bitcalc(const void* value1, const void* value2, int radius, int sign, un
   long offset;
 
   carry_flag = 0;
-  offset = sc_val_to_long(val2);
+  offset = sc_val_to_long(val2, radius, sign);
 
   DEBUGPRINTF_COMPUTATION(("%s ", sc_print_hex(value1)));
   switch (op)
index 386e705..4704121 100644 (file)
@@ -121,7 +121,7 @@ const int sc_get_buffer_length(void);
 void sc_val_from_str(const char *str, unsigned int len, void *buffer);
 void sc_val_from_long(long l, void *buffer);
 void sc_val_from_ulong(unsigned long l, void *buffer);
-long sc_val_to_long(const void *val);
+long sc_val_to_long(const void *val, unsigned int bits, unsigned int sign);
 void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer);
 void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer);
 
index 92ab9a2..5bceca6 100644 (file)
@@ -364,7 +364,7 @@ long get_tarval_long(tarval* tv)
   ANNOUNCE();
   assert(tarval_is_long(tv) && "tarval too big to fit in long");
 
-  return sc_val_to_long(tv->value);
+  return sc_val_to_long(tv->value, get_mode_size_bits(tv->mode), mode_is_signed(tv->mode));
 }
 
 tarval *new_tarval_from_double(long double d, ir_mode *mode)