aboutsummaryrefslogtreecommitdiff
path: root/gcc/stmt.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-04-04 15:13:36 -0800
committerRichard Henderson <rth@gcc.gnu.org>2002-04-04 15:13:36 -0800
commitecc114f755ea1b4c3a218e8c936689d1d8f04188 (patch)
treeb53b283a2044bb79d2f7decb3ed952fc266a2091 /gcc/stmt.c
parentc4484b8fe055db414048860502d480c63e7ee6b1 (diff)
downloadgcc-ecc114f755ea1b4c3a218e8c936689d1d8f04188.zip
gcc-ecc114f755ea1b4c3a218e8c936689d1d8f04188.tar.gz
gcc-ecc114f755ea1b4c3a218e8c936689d1d8f04188.tar.bz2
re PR inline-asm/5099 (m68k-aout/3.0.2/cc1 aborts on asm("movw sr,%0":"=hd"(a));)
PR middle-end/5099 * stmt.c (expand_asm_operands): Validate outputs vs asm_operand_ok. Support copies into and out of memory. Don't accept allows_reg and allows_mem as gospel. From-SVN: r51884
Diffstat (limited to 'gcc/stmt.c')
-rw-r--r--gcc/stmt.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 4f0cb17..c5399bc 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -1740,25 +1740,48 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
&& (allows_mem || GET_CODE (DECL_RTL (val)) == REG)
&& ! (GET_CODE (DECL_RTL (val)) == REG
&& GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
- || ! allows_reg
|| is_inout)
{
- output_rtx[i] = expand_expr (val, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ enum { do_not_copy, do_copy_reg, do_copy_mem } do_copy;
+ rtx op;
- if (! allows_reg && GET_CODE (output_rtx[i]) != MEM)
+ op = expand_expr (val, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ output_rtx[i] = op;
+
+ if (! allows_reg && GET_CODE (op) != MEM)
error ("output number %d not directly addressable", i);
- if ((! allows_mem && GET_CODE (output_rtx[i]) == MEM)
- || GET_CODE (output_rtx[i]) == CONCAT)
+
+ do_copy = do_not_copy;
+ if (! allows_mem && GET_CODE (op) == MEM)
+ do_copy = do_copy_reg;
+ else if (GET_CODE (op) == CONCAT)
+ do_copy = do_copy_reg;
+ else if (asm_operand_ok (op, constraints[i]) <= 0)
+ {
+ if (allows_reg && !register_operand (op, VOIDmode))
+ do_copy = do_copy_reg;
+ else if (allows_mem && GET_CODE (op) != MEM)
+ do_copy = do_copy_mem;
+ else
+ warning ("asm operand %d probably doesn't match constraints", i);
+ }
+
+ if (do_copy == do_copy_reg)
+ {
+ real_output_rtx[i] = protect_from_queue (op, 1);
+ output_rtx[i] = gen_reg_rtx (GET_MODE (op));
+ }
+ else if (do_copy == do_copy_mem)
{
- real_output_rtx[i] = protect_from_queue (output_rtx[i], 1);
- output_rtx[i] = gen_reg_rtx (GET_MODE (output_rtx[i]));
- if (is_inout)
- emit_move_insn (output_rtx[i], real_output_rtx[i]);
+ real_output_rtx[i] = op;
+ output_rtx[i] = assign_temp (type, 0, 1, 1);
}
+ if (do_copy && is_inout)
+ emit_move_insn (output_rtx[i], real_output_rtx[i]);
}
else
{
- output_rtx[i] = assign_temp (type, 0, 0, 1);
+ output_rtx[i] = assign_temp (type, 0, !allows_reg, 1);
TREE_VALUE (tail) = make_tree (type, output_rtx[i]);
}
@@ -1812,9 +1835,9 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
if (asm_operand_ok (op, constraint) <= 0)
{
- if (allows_reg)
+ if (allows_reg && !register_operand (op, VOIDmode))
op = force_reg (TYPE_MODE (type), op);
- else if (!allows_mem)
+ else if (!allows_mem || GET_CODE (op) == MEM)
warning ("asm operand %d probably doesn't match constraints",
i + noutputs);
else if (CONSTANT_P (op))