fixed some bugs concerning am_offs
[libfirm] / ir / be / ia32 / ia32_new_nodes.c
index 2f5fd78..6d39016 100644 (file)
@@ -190,16 +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 (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:
@@ -216,11 +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)) {
-                               fprintf(F, "[AM S] ");
-                       }
-                       else if (is_ia32_AddrModeD(n)) {
-                               fprintf(F, "[AM D] ");
+                       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;
@@ -467,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;
 }
 
@@ -481,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);
@@ -566,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.
  */