re PR inline-asm/5099 (m68k-aout/3.0.2/cc1 aborts on asm("movw sr,%0":"=hd"(a));)
authorRichard Henderson <rth@redhat.com>
Thu, 4 Apr 2002 23:13:36 +0000 (15:13 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 4 Apr 2002 23:13:36 +0000 (15:13 -0800)
        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

gcc/ChangeLog
gcc/stmt.c

index d14b04c413f7977067cdeae3714cd569374a45a7..6c4dc907035d3e6a444d9daa178f75526f631ba2 100644 (file)
@@ -1,3 +1,10 @@
+2002-04-04  Richard Henderson  <rth@redhat.com>
+
+       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.
+
 2002-04-04  Richard Henderson  <rth@redhat.com>
 
        PR opt/6165
index 4f0cb179547687ca2bb4971246dc712d8d7b9ae8..c5399bc293f063922900904ace741053eca242b3 100644 (file)
@@ -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))