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]

allow asm in-out memory operands again


Due to popular demand, and the fact that it's simple enough to
expand ("+m"(x)) -> ("=m"(x) : "m"(x)).

The stmt.c hunk I applied to 3.4.  We already do the right thing
there; the warning was added for presumed tree-ssa changes.


r~


        * stmt.c (parse_output_constraint): Don't warn for read-write
        memory operand.
        * gimplify.c (gimplify_asm_expr): Force in-out memory operands
        to minimal lvalues, then expand to non-matching constraints.

Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.152
diff -c -p -d -r1.1.2.152 gimplify.c
*** gimplify.c	5 May 2004 20:54:20 -0000	1.1.2.152
--- gimplify.c	6 May 2004 23:29:18 -0000
*************** gimplify_asm_expr (tree *expr_p, tree *p
*** 2739,2767 ****
  	(*lang_hooks.mark_addressable) (TREE_VALUE (link));
  
        tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
! 			    is_gimple_lvalue, fb_lvalue | fb_mayfail);
        if (tret == GS_ERROR)
  	{
  	  error ("invalid lvalue in asm output %d", i);
  	  ret = tret;
  	}
  
!       if (is_inout && allows_reg)
  	{
! 	  /* An input/output operand that allows a register.  To give the
! 	     optimizers more flexibility, split it into separate input and
! 	     output operands.  */
  	  tree input;
  	  char buf[10];
  
  	  /* Turn the in/out constraint into an output constraint.  */
  	  char *p = xstrdup (constraint);
  	  p[0] = '=';
! 	  TREE_VALUE (TREE_PURPOSE (link)) = build_string (strlen (p), p);
  
  	  /* And add a matching input constraint.  */
! 	  sprintf (buf, "%d", i);
! 	  input = build_string (strlen (buf), buf);
  	  input = build_tree_list (build_tree_list (NULL_TREE, input),
  				   unshare_expr (TREE_VALUE (link)));
  	  ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
--- 2739,2775 ----
  	(*lang_hooks.mark_addressable) (TREE_VALUE (link));
  
        tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
! 			    is_inout ? is_gimple_min_lval : is_gimple_lvalue,
! 			    fb_lvalue | fb_mayfail);
        if (tret == GS_ERROR)
  	{
  	  error ("invalid lvalue in asm output %d", i);
  	  ret = tret;
  	}
  
!       if (is_inout)
  	{
! 	  /* An input/output operand.  To give the optimizers more
! 	     flexibility, split it into separate input and output
!  	     operands.  */
  	  tree input;
  	  char buf[10];
+ 	  size_t constraint_len = strlen (constraint);
  
  	  /* Turn the in/out constraint into an output constraint.  */
  	  char *p = xstrdup (constraint);
  	  p[0] = '=';
! 	  TREE_VALUE (TREE_PURPOSE (link)) = build_string (constraint_len, p);
! 	  free (p);
  
  	  /* And add a matching input constraint.  */
! 	  if (allows_reg)
! 	    {
! 	      sprintf (buf, "%d", i);
! 	      input = build_string (strlen (buf), buf);
! 	    }
! 	  else
! 	    input = build_string (constraint_len - 1, constraint + 1);
  	  input = build_tree_list (build_tree_list (NULL_TREE, input),
  				   unshare_expr (TREE_VALUE (link)));
  	  ASM_INPUTS (expr) = chainon (ASM_INPUTS (expr), input);
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.267.2.57
diff -c -p -d -r1.267.2.57 stmt.c
*** stmt.c	15 Apr 2004 19:55:17 -0000	1.267.2.57
--- stmt.c	6 May 2004 23:29:18 -0000
*************** parse_output_constraint (const char **co
*** 1172,1180 ****
  	break;
        }
  
-   if (*is_inout && !*allows_reg)
-     warning ("read-write constraint does not allow a register");
- 
    return true;
  }
  
--- 1172,1177 ----


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