This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

deprecate asm memory inputs that don't refer to memories


As discussed.  


r~


        * expr.h (EXPAND_MEMORY): New.
        * expr.c (expand_expr): Check it.
        * stmt.c (expand_asm_operands): Provide it when the constraint
        requires a memory.  Warn for memory input constraints without
        a memory operand.

        * gcc.dg/20011029-2.c: Fix the array reference.
        * gcc.dg/asm-7.c: New.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.546
diff -c -p -d -u -r1.546 expr.c
--- expr.c	3 Jun 2003 17:13:06 -0000	1.546
+++ expr.c	9 Jun 2003 03:03:09 -0000
@@ -7326,7 +7326,9 @@ expand_expr (exp, target, tmode, modifie
 	   Don't fold if this is for wide characters since it's too
 	   difficult to do correctly and this is a very rare case.  */
 
-	if (modifier != EXPAND_CONST_ADDRESS && modifier != EXPAND_INITIALIZER
+	if (modifier != EXPAND_CONST_ADDRESS
+	    && modifier != EXPAND_INITIALIZER
+	    && modifier != EXPAND_MEMORY
 	    && TREE_CODE (array) == STRING_CST
 	    && TREE_CODE (index) == INTEGER_CST
 	    && compare_tree_int (index, TREE_STRING_LENGTH (array)) < 0
@@ -7340,8 +7342,11 @@ expand_expr (exp, target, tmode, modifie
 	   we have an explicit constructor and when our operand is a variable
 	   that was declared const.  */
 
-	if (modifier != EXPAND_CONST_ADDRESS && modifier != EXPAND_INITIALIZER
-	    && TREE_CODE (array) == CONSTRUCTOR && ! TREE_SIDE_EFFECTS (array)
+	if (modifier != EXPAND_CONST_ADDRESS
+	    && modifier != EXPAND_INITIALIZER
+	    && modifier != EXPAND_MEMORY
+	    && TREE_CODE (array) == CONSTRUCTOR
+	    && ! TREE_SIDE_EFFECTS (array)
 	    && TREE_CODE (index) == INTEGER_CST
 	    && 0 > compare_tree_int (index,
 				     list_length (CONSTRUCTOR_ELTS
@@ -7362,6 +7367,7 @@ expand_expr (exp, target, tmode, modifie
 	else if (optimize >= 1
 		 && modifier != EXPAND_CONST_ADDRESS
 		 && modifier != EXPAND_INITIALIZER
+		 && modifier != EXPAND_MEMORY
 		 && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
 		 && TREE_CODE (array) == VAR_DECL && DECL_INITIAL (array)
 		 && TREE_CODE (DECL_INITIAL (array)) != ERROR_MARK)
Index: expr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.h,v
retrieving revision 1.139
diff -c -p -d -u -r1.139 expr.h
--- expr.h	3 Jun 2003 11:14:04 -0000	1.139
+++ expr.h	9 Jun 2003 03:03:09 -0000
@@ -51,9 +51,12 @@ Software Foundation, 59 Temple Place - S
    EXPAND_INITIALIZER is similar but also record any labels on forced_labels.
    EXPAND_CONST_ADDRESS means it is ok to return a MEM whose address
     is a constant that is not a legitimate address.
-   EXPAND_WRITE means we are only going to write to the resulting rtx.  */
+   EXPAND_WRITE means we are only going to write to the resulting rtx.
+   EXPAND_MEMORY means we are interested in a memory result, even if
+    the memory is constant and we could have propagated a constant value.  */
 enum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM = 2, EXPAND_SUM,
-		      EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER, EXPAND_WRITE};
+		      EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER, EXPAND_WRITE,
+		      EXPAND_MEMORY};
 
 /* Prevent the compiler from deferring stack pops.  See
    inhibit_defer_pop for more information.  */
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.303
diff -c -p -d -u -r1.303 stmt.c
--- stmt.c	6 Jun 2003 17:03:08 -0000	1.303
+++ stmt.c	9 Jun 2003 03:03:11 -0000
@@ -1748,7 +1748,9 @@ expand_asm_operands (string, outputs, in
 
       val = TREE_VALUE (tail);
       type = TREE_TYPE (val);
-      op = expand_expr (val, NULL_RTX, VOIDmode, 0);
+      op = expand_expr (val, NULL_RTX, VOIDmode,
+			(allows_mem && !allows_reg
+			 ? EXPAND_MEMORY : EXPAND_NORMAL));
 
       /* Never pass a CONCAT to an ASM.  */
       if (GET_CODE (op) == CONCAT)
@@ -1763,38 +1765,35 @@ expand_asm_operands (string, outputs, in
 	  else if (!allows_mem)
 	    warning ("asm operand %d probably doesn't match constraints",
 		     i + noutputs);
-	  else if (CONSTANT_P (op))
-	    {
-	      op = force_const_mem (TYPE_MODE (type), op);
-	      op = validize_mem (op);
-	    }
-	  else if (GET_CODE (op) == REG
-		   || GET_CODE (op) == SUBREG
-		   || GET_CODE (op) == ADDRESSOF
-		   || GET_CODE (op) == CONCAT)
-	    {
-	      tree qual_type = build_qualified_type (type,
-						     (TYPE_QUALS (type)
-						      | TYPE_QUAL_CONST));
-	      rtx memloc = assign_temp (qual_type, 1, 1, 1);
-	      memloc = validize_mem (memloc);
-	      emit_move_insn (memloc, op);
-	      op = memloc;
-	    }
-
 	  else if (GET_CODE (op) == MEM && MEM_VOLATILE_P (op))
 	    {
 	      /* We won't recognize volatile memory as available a
 		 memory_operand at this point.  Ignore it.  */
 	    }
-	  else if (queued_subexp_p (op))
-	    ;
 	  else
-	    /* ??? Leave this only until we have experience with what
-	       happens in combine and elsewhere when constraints are
-	       not satisfied.  */
-	    warning ("asm operand %d probably doesn't match constraints",
-		     i + noutputs);
+	    {
+	      warning ("asm operand %d uses deprecated memory input "
+		       "without lvalue", i + noutputs);
+
+	      if (CONSTANT_P (op))
+		{
+		  op = force_const_mem (TYPE_MODE (type), op);
+		  op = validize_mem (op);
+		}
+	      else if (GET_CODE (op) == REG
+		       || GET_CODE (op) == SUBREG
+		       || GET_CODE (op) == ADDRESSOF
+		       || GET_CODE (op) == CONCAT)
+		{
+		  tree qual_type = build_qualified_type (type,
+							 (TYPE_QUALS (type)
+							  | TYPE_QUAL_CONST));
+		  rtx memloc = assign_temp (qual_type, 1, 1, 1);
+		  memloc = validize_mem (memloc);
+		  emit_move_insn (memloc, op);
+		  op = memloc;
+		}
+	    }
 	}
 
       generating_concat_p = old_generating_concat_p;
Index: testsuite/gcc.dg/20011029-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/20011029-2.c,v
retrieving revision 1.2
diff -c -p -d -u -r1.2 20011029-2.c
--- testsuite/gcc.dg/20011029-2.c	6 Feb 2002 20:40:17 -0000	1.2
+++ testsuite/gcc.dg/20011029-2.c	9 Jun 2003 03:03:33 -0000
@@ -16,7 +16,7 @@ int foo (int s)
         continue;
       else if (({ register char r;
 		  __asm__ __volatile__ ("" : "=q" (r)
-					: "r" (0), "m" (a)
+					: "r" (0), "m" (a[0])
 					: "cc"); r; }))
         continue;
     }
Index: testsuite/gcc.dg/asm-7.c
===================================================================
RCS file: testsuite/gcc.dg/asm-7.c
diff -N testsuite/gcc.dg/asm-7.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/asm-7.c	9 Jun 2003 03:03:33 -0000
@@ -0,0 +1,26 @@
+/* Gcc 3.3.1 deprecates memory inputs of non-lvalues.  */
+/* { dg-do compile } */
+
+void test(void)
+{
+  register int r;
+  register int r2;
+  int i;
+  static int m;
+
+  __asm__ ("" : : "m"(r));	/* { dg-warning "address of register" } */
+  __asm__ ("" : : "m"(i));
+  __asm__ ("" : : "m"(m));
+  __asm__ ("" : : "m"(0));	/* { dg-warning "deprecated memory input" } */
+  __asm__ ("" : : "m"(i+1));	/* { dg-warning "deprecated memory input" } */
+
+  __asm__ ("" : : "g"(r));
+  __asm__ ("" : : "g"(i));
+  __asm__ ("" : : "g"(m));
+  __asm__ ("" : : "g"(0));
+  __asm__ ("" : : "g"(i+1));
+
+  __asm__ ("" : "=m"(r2));	/* { dg-warning "address of register" } */
+  __asm__ ("" : "=m"(i));
+  __asm__ ("" : "=m"(m));
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]