diff options
author | Richard Henderson <rth@redhat.com> | 2002-04-04 15:13:36 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-04-04 15:13:36 -0800 |
commit | ecc114f755ea1b4c3a218e8c936689d1d8f04188 (patch) | |
tree | b53b283a2044bb79d2f7decb3ed952fc266a2091 /gcc/stmt.c | |
parent | c4484b8fe055db414048860502d480c63e7ee6b1 (diff) | |
download | gcc-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.c | 47 |
1 files changed, 35 insertions, 12 deletions
@@ -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)) |