OSDN Git Service

gcc/ChangeLog:
[pf3gnuchains/gcc-fork.git] / gcc / cfgexpand.c
index 0ed6bd5..f4a9f5e 100644 (file)
@@ -2234,6 +2234,38 @@ unwrap_constant (rtx x)
   return ret;
 }
 
+/* Convert X to MODE, that must be Pmode or ptr_mode, without emitting
+   any rtl.  */
+
+static rtx
+convert_debug_memory_address (enum machine_mode mode, rtx x)
+{
+  enum machine_mode xmode = GET_MODE (x);
+
+#ifndef POINTERS_EXTEND_UNSIGNED
+  gcc_assert (mode == Pmode);
+  gcc_assert (xmode == mode || xmode == VOIDmode);
+#else
+  gcc_assert (mode == Pmode || mode == ptr_mode);
+
+  if (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode)
+    return x;
+
+  if (GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (xmode))
+    x = simplify_gen_subreg (mode, x, xmode,
+                            subreg_lowpart_offset
+                            (mode, xmode));
+  else if (POINTERS_EXTEND_UNSIGNED > 0)
+    x = gen_rtx_ZERO_EXTEND (mode, x);
+  else if (!POINTERS_EXTEND_UNSIGNED)
+    x = gen_rtx_SIGN_EXTEND (mode, x);
+  else
+    gcc_unreachable ();
+#endif /* POINTERS_EXTEND_UNSIGNED */
+
+  return x;
+}
+
 /* Return an RTX equivalent to the value of the tree expression
    EXP.  */
 
@@ -2410,6 +2442,7 @@ expand_debug_expr (tree exp)
        return NULL;
 
       gcc_assert (GET_MODE (op0) == Pmode
+                 || GET_MODE (op0) == ptr_mode
                  || GET_CODE (op0) == CONST_INT
                  || GET_CODE (op0) == CONST_DOUBLE);
 
@@ -2436,6 +2469,7 @@ expand_debug_expr (tree exp)
        return NULL;
 
       gcc_assert (GET_MODE (op0) == Pmode
+                 || GET_MODE (op0) == ptr_mode
                  || GET_CODE (op0) == CONST_INT
                  || GET_CODE (op0) == CONST_DOUBLE);
 
@@ -2468,13 +2502,32 @@ expand_debug_expr (tree exp)
 
        if (offset)
          {
+           enum machine_mode addrmode, offmode;
+
            gcc_assert (MEM_P (op0));
 
+           op0 = XEXP (op0, 0);
+           addrmode = GET_MODE (op0);
+           if (addrmode == VOIDmode)
+             addrmode = Pmode;
+
            op1 = expand_debug_expr (offset);
            if (!op1)
              return NULL;
 
-           op0 = gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, XEXP (op0, 0), op1));
+           offmode = GET_MODE (op1);
+           if (offmode == VOIDmode)
+             offmode = TYPE_MODE (TREE_TYPE (offset));
+
+           if (addrmode != offmode)
+             op1 = simplify_gen_subreg (addrmode, op1, offmode,
+                                        subreg_lowpart_offset (addrmode,
+                                                               offmode));
+
+           /* Don't use offset_address here, we don't need a
+              recognizable address, and we don't want to generate
+              code.  */
+           op0 = gen_rtx_MEM (mode, gen_rtx_PLUS (addrmode, op0, op1));
          }
 
        if (MEM_P (op0))
@@ -2785,7 +2838,9 @@ expand_debug_expr (tree exp)
       if (!op0 || !MEM_P (op0))
        return NULL;
 
-      return XEXP (op0, 0);
+      op0 = convert_debug_memory_address (mode, XEXP (op0, 0));
+
+      return op0;
 
     case VECTOR_CST:
       exp = build_constructor_from_list (TREE_TYPE (exp),