Loads do not remove any nodes from the exec after sets. Also fix a 'node leak'.
[libfirm] / ir / tv / strcalc.c
index 039d9be..7850416 100644 (file)
@@ -1,15 +1,29 @@
 /*
- * Project:     libFIRM
- * File name:   ir/tv/strcalc.c
- * Purpose:
- * Author:      Mathias Heil
- * Modified by:
- * Created:
- * CVS-ID:      $Id$
- * Copyright:   (c) 2003 Universität Karlsruhe
- * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
  */
 
+/**
+ * @file
+ * @brief    Provides basic mathematical operations on values represented as strings.
+ * @date     2003
+ * @author   Mathias Heil
+ * @version  $Id$
+ */
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #ifdef HAVE_STDLIB_H
 # include <stdlib.h>
 #endif
-#ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-#endif
-#ifdef HAVE_MALLOC_H
-# include <malloc.h>
-#endif
 #ifdef HAVE_STRING_H
 # include <string.h>  /* memset/memcmp */
 #endif
 #define fail_char(a, b, c, d) _fail_char((a), (b), (c), (d), __FILE__,  __LINE__)
 
 /* shortcut output for debugging */
-#  define sc_print_hex(a) sc_print((a), 0, SC_HEX)
-#  define sc_print_dec(a) sc_print((a), 0, SC_DEC)
-#  define sc_print_oct(a) sc_print((a), 0, SC_OCT)
-#  define sc_print_bin(a) sc_print((a), 0, SC_BIN)
+#  define sc_print_hex(a) sc_print((a), 0, SC_HEX, 0)
+#  define sc_print_dec(a) sc_print((a), 0, SC_DEC, 1)
+#  define sc_print_oct(a) sc_print((a), 0, SC_OCT, 0)
+#  define sc_print_bin(a) sc_print((a), 0, SC_BIN, 0)
 
 #ifdef STRCALC_DEBUG_PRINTCOMP
 #  define DEBUGPRINTF_COMPUTATION(x) printf x
@@ -78,6 +86,7 @@ static int carry_flag;              /**< some computation set the carry_flag:
                                          and often defined in other ways! */
 
 static const char sex_digit[4] = { SC_E, SC_C, SC_8, SC_0 };
+static const char zex_digit[4] = { SC_1, SC_3, SC_7, SC_F };
 static const char max_digit[4] = { SC_0, SC_1, SC_3, SC_7 };
 static const char min_digit[4] = { SC_F, SC_E, SC_C, SC_8 };
 
@@ -959,23 +968,32 @@ int sc_get_buffer_length(void)
 }
 
 /**
- * Do sign extension if the mode is signed, expects all upper bits
- * cleared.
+ * Do sign extension if the mode is signed, otherwise to zero extension.
  */
 void sign_extend(char *calc_buffer, ir_mode *mode) {
-  if (mode_is_signed(mode)) {
-    int bits    = get_mode_size_bits(mode) - 1;
-    int ofs     = bits >> 2;
-    int max     = max_digit[bits & 3];
-    int i;
+  int bits    = get_mode_size_bits(mode) - 1;
+  int nibble  = bits >> 2;
+  int max     = max_digit[bits & 3];
+  int i;
 
-    if (calc_buffer[ofs] > max) {
+  if (mode_is_signed(mode)) {
+    if (calc_buffer[nibble] > max) {
       /* sign bit is set, we need sign expansion */
 
-      for (i = ofs + 1; i < calc_buffer_size; ++i)
+      for (i = nibble + 1; i < calc_buffer_size; ++i)
         calc_buffer[i] = SC_F;
-      calc_buffer[ofs] = or_table[(int) calc_buffer[ofs]][(int) sex_digit[bits & 3]];
+      calc_buffer[nibble] = or_table[(int)calc_buffer[nibble]][(int)sex_digit[bits & 3]];
+    } else {
+      /* set all bits to zero */
+      for (i = nibble + 1; i < calc_buffer_size; ++i)
+        calc_buffer[i] = SC_0;
+      calc_buffer[nibble] = and_table[(int)calc_buffer[nibble]][(int)zex_digit[bits & 3]];
     }
+  } else {
+    /* do zero extension */
+    for (i = nibble + 1; i < calc_buffer_size; ++i)
+      calc_buffer[i] = SC_0;
+    calc_buffer[nibble] = and_table[(int)calc_buffer[nibble]][(int)zex_digit[bits & 3]];
   }
 }
 
@@ -1444,7 +1462,7 @@ unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs)
  * convert to a string
  * FIXME: Doesn't check buffer bounds
  */
-const char *sc_print(const void *value, unsigned bits, enum base_t base)
+const char *sc_print(const void *value, unsigned bits, enum base_t base, int signed_mode)
 {
   static const char big_digits[]   = "0123456789ABCDEF";
   static const char small_digits[] = "0123456789abcdef";
@@ -1462,7 +1480,7 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base)
   base_val = alloca(calc_buffer_size);
   div1_res = alloca(calc_buffer_size);
   div2_res = alloca(calc_buffer_size);
-  rem_res = alloca(calc_buffer_size);
+  rem_res  = alloca(calc_buffer_size);
 
   pos = output_buffer + bit_pattern_size;
   *(--pos) = '\0';
@@ -1539,7 +1557,7 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base)
 
     p    = val;
     sign = 0;
-    if (base == SC_DEC) {
+    if (signed_mode && base == SC_DEC) {
       /* check for negative values */
       if (_bit(val, bits - 1)) {
         _negate(val, div2_res);