expr.h (EXPAND_MEMORY): New.
* 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. From-SVN: r67645
This commit is contained in:
parent
f8950e171a
commit
017e1b43f9
|
@ -1,3 +1,11 @@
|
|||
2003-06-08 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2003-06-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* varasm.c: Don't include c-tree.h.
|
||||
|
|
12
gcc/expr.c
12
gcc/expr.c
|
@ -7326,7 +7326,9 @@ expand_expr (exp, target, tmode, modifier)
|
|||
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, modifier)
|
|||
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, modifier)
|
|||
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)
|
||||
|
|
|
@ -51,9 +51,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
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. */
|
||||
|
|
53
gcc/stmt.c
53
gcc/stmt.c
|
@ -1748,7 +1748,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
|||
|
||||
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, inputs, clobbers, vol, filename, line)
|
|||
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;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2003-06-08 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gcc.dg/20011029-2.c: Fix the array reference.
|
||||
* gcc.dg/asm-7.c: New.
|
||||
|
||||
2003-06-08 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* gcc.c-torture/compile/20000804-1.x: Dsiable on h8300 port.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
Loading…
Reference in New Issue