fixed some bugs concerning am_offs
[libfirm] / ir / be / ia32 / ia32_new_nodes.c
index 9d83667..6d39016 100644 (file)
@@ -190,19 +190,16 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
                case dump_node_mode_txt:
                        mode = get_irn_mode(n);
 
-                       if (mode == mode_BB || mode == mode_ANY || mode == mode_BAD || mode == mode_T) {
-                               mode = NULL;
-                       }
-                       else if (is_ia32_Load(n)) {
-                               mode = get_irn_mode(get_irn_n(n, 0));
-                       }
-                       else if (is_ia32_Store(n)) {
-                               mode = get_irn_mode(get_irn_n(n, 2));
+                       if (is_ia32_Load(n) || is_ia32_Store(n)) {
+                               mode = get_ia32_ls_mode(n);
                        }
 
                        if (mode) {
                                fprintf(F, "[%s]", get_mode_name(mode));
                        }
+                       else {
+                               fprintf(F, "[?NOMODE?]");
+                       }
                        break;
 
                case dump_node_nodeattr_txt:
@@ -219,8 +216,13 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
                                fprintf(F, "[%s%s]", pref, get_ia32_cnst(n));
                        }
 
-                       if (is_ia32_AddrModeS(n) || is_ia32_AddrModeD(n)) {
-                               fprintf(F, "[AM] ");
+                       if (! is_ia32_Lea(n)) {
+                               if (is_ia32_AddrModeS(n)) {
+                                       fprintf(F, "[AM S] ");
+                               }
+                               else if (is_ia32_AddrModeD(n)) {
+                                       fprintf(F, "[AM D] ");
+                               }
                        }
 
                        break;
@@ -273,6 +275,9 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
                                case ia32_AddrModeS:
                                        fprintf(F, "AM Source (Load)");
                                        break;
+                               default:
+                                       fprintf(F, "unknown (%d)", attr->tp);
+                                       break;
                        }
                        fprintf(F, "\n");
 
@@ -292,9 +297,33 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
                                case ia32_am_Full:
                                        fprintf(F, "full");
                                        break;
+                               default:
+                                       fprintf(F, "unknown (%d)", attr->am_support);
+                                       break;
                        }
                        fprintf(F, "\n");
 
+                       /* dump am flavour */
+                       fprintf(F, "AM flavour =");
+                       if (attr->am_flavour == ia32_am_N) {
+                               fprintf(F, " none");
+                       }
+                       else {
+                               if (attr->am_flavour & ia32_O) {
+                                       fprintf(F, " O");
+                               }
+                               if (attr->am_flavour & ia32_B) {
+                                       fprintf(F, " B");
+                               }
+                               if (attr->am_flavour & ia32_I) {
+                                       fprintf(F, " I");
+                               }
+                               if (attr->am_flavour & ia32_S) {
+                                       fprintf(F, " S");
+                               }
+                       }
+                       fprintf(F, " (%d)\n", attr->am_flavour);
+
                        /* dump AM offset */
                        fprintf(F, "AM offset = ");
                        if (attr->am_offs) {
@@ -316,16 +345,21 @@ static int dump_node_ia32(ir_node *n, FILE *F, dump_reason_t reason) {
 
                        /* dump flags */
                        fprintf(F, "flags =");
-                       if (attr->flags & arch_irn_flags_dont_spill) {
-                               fprintf(F, " unspillable");
+                       if (attr->flags == arch_irn_flags_none) {
+                               fprintf(F, " none");
                        }
-                       if (attr->flags & arch_irn_flags_rematerializable) {
-                               fprintf(F, " remat");
-                       }
-                       if (attr->flags & arch_irn_flags_ignore) {
-                               fprintf(F, " ignore");
+                       else {
+                               if (attr->flags & arch_irn_flags_dont_spill) {
+                                       fprintf(F, " unspillable");
+                               }
+                               if (attr->flags & arch_irn_flags_rematerializable) {
+                                       fprintf(F, " remat");
+                               }
+                               if (attr->flags & arch_irn_flags_ignore) {
+                                       fprintf(F, " ignore");
+                               }
                        }
-                       fprintf(F, "\n");
+                       fprintf(F, " (%d)\n", attr->flags);
 
                        fprintf(F, "=== IA32 attr end ===\n");
                        /* end of: case dump_node_info_txt */
@@ -418,7 +452,7 @@ ia32_am_flavour_t get_ia32_am_flavour(const ir_node *node) {
  */
 void set_ia32_am_flavour(ir_node *node, ia32_am_flavour_t am_flavour) {
        ia32_attr_t *attr = get_ia32_attr(node);
-       attr->am_support  = am_flavour;
+       attr->am_flavour  = am_flavour;
 }
 
 /**
@@ -435,11 +469,12 @@ char *get_ia32_am_offs(const ir_node *node) {
 
        size = obstack_object_size(attr->am_offs);
     if (size > 0) {
-               res = xcalloc(1, size + 1);
-               memcpy(res, obstack_base(attr->am_offs), size);
+               res    = xcalloc(1, size + 2);
+               res[0] = attr->offs_sign;
+               memcpy(&res[1], obstack_base(attr->am_offs), size);
     }
 
-       res[size] = '\0';
+       res[size + 1] = '\0';
        return res;
 }
 
@@ -449,15 +484,25 @@ char *get_ia32_am_offs(const ir_node *node) {
 static void extend_ia32_am_offs(ir_node *node, char *offset, char op) {
        ia32_attr_t *attr = get_ia32_attr(node);
 
+       if (! offset)
+               return;
+
+       /* offset could already have an explicit sign */
+       /* -> supersede op if necessary               */
+       if (offset[0] == '-' || offset[0] == '+') {
+               op = offset[0];
+               offset++;
+       }
+
        if (!attr->am_offs) {
                /* obstack is not initialized */
                attr->am_offs = xcalloc(1, sizeof(*(attr->am_offs)));
                obstack_init(attr->am_offs);
+               attr->offs_sign = op;
        }
        else {
-               /* obstack is initialized -> there is already one offset */
-               /* present -> connect the offsets with an add            */
-               obstack_printf(attr->am_offs, " %c ", op);
+               /* If obstack is initialized, connect the new offset with op */
+               obstack_printf(attr->am_offs, "%c", op);
        }
 
        obstack_printf(attr->am_offs, "%s", offset);
@@ -534,11 +579,27 @@ void set_ia32_sc(ir_node *node, char *sc) {
 /**
  * Gets the string representation of the internal const (tv or symconst)
  */
-char *get_ia32_cnst(ir_node *node) {
+char *get_ia32_cnst(const ir_node *node) {
   ia32_attr_t *attr = get_ia32_attr(node);
   return attr->cnst;
 }
 
+/**
+ * Gets the mode of the stored/loaded value (only set for Store/Load)
+ */
+ir_mode *get_ia32_ls_mode(const ir_node *node) {
+  ia32_attr_t *attr = get_ia32_attr(node);
+  return attr->ls_mode;
+}
+
+/**
+ * Sets the mode of the stored/loaded value (only set for Store/Load)
+ */
+void set_ia32_ls_mode(ir_node *node, ir_mode *mode) {
+  ia32_attr_t *attr = get_ia32_attr(node);
+  attr->ls_mode     = mode;
+}
+
 /**
  * Returns the argument register requirements of an ia32 node.
  */