* stmt.c (expand_asm_operands): Reload in-out reg-only memory operands.
authorRichard Henderson <rth@cygnus.com>
Sun, 25 Apr 1999 23:06:36 +0000 (16:06 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 25 Apr 1999 23:06:36 +0000 (16:06 -0700)
From-SVN: r26628

gcc/ChangeLog
gcc/stmt.c

index 4601daed8e1579362e464da2742e19823e72bcee..8a4eb262c6816c2c62d65d2fe38aa8d2075c916f 100644 (file)
@@ -1,3 +1,7 @@
+Sun Apr 25 23:03:32 1999  Richard Henderson  <rth@cygnus.com>
+
+       * stmt.c (expand_asm_operands): Reload in-out reg-only memory operands.
+
 Sun Apr 25 13:06:13 1999  Richard Henderson  <rth@cygnus.com>
 
        * function.c (assign_parms/STACK_BYTES): Revert last change,
index f5ae0c3e30b3509d2963e031fe823f14ee3de74a..f3780340cdaf38e1e52f3634d57bfd9c0a73a458 100644 (file)
@@ -1183,6 +1183,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
   /* Vector of RTX's of evaluated output operands.  */
   rtx *output_rtx = (rtx *) alloca (noutputs * sizeof (rtx));
   int *inout_opnum = (int *) alloca (noutputs * sizeof (int));
+  rtx *real_output_rtx = (rtx *) alloca (noutputs * sizeof (rtx));
   enum machine_mode *inout_mode
     = (enum machine_mode *) alloca (noutputs * sizeof (enum machine_mode));
   /* The insn we have emitted.  */
@@ -1360,6 +1361,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
         Make the asm insn write into that, then our caller will copy it to
         the real output operand.  Likewise for promoted variables.  */
 
+      real_output_rtx[i] = NULL_RTX;
       if ((TREE_CODE (val) == INDIRECT_REF
           && allows_mem)
          || (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
@@ -1379,7 +1381,12 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
          if (! allows_reg && GET_CODE (output_rtx[i]) != MEM)
            error ("output number %d not directly addressable", i);
          if (! allows_mem && GET_CODE (output_rtx[i]) == MEM)
-           error ("output number %d not restored to memory", i);
+           {
+             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]);
+           }
        }
       else
        {
@@ -1662,6 +1669,12 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
       insn = emit_insn (body);
     }
 
+  /* For any outputs that needed reloading into registers, spill them
+     back to where they belong.  */
+  for (i = 0; i < noutputs; ++i)
+    if (real_output_rtx[i])
+      emit_move_insn (real_output_rtx[i], output_rtx[i]);
+
   free_temp_slots ();
 }
 \f