This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
allow asm in-out memory operands again
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 6 May 2004 15:38:26 -0700
- Subject: 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 ----