aboutsummaryrefslogtreecommitdiff
path: root/gcc/stmt.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1999-04-25 16:06:36 -0700
committerRichard Henderson <rth@gcc.gnu.org>1999-04-25 16:06:36 -0700
commit947255ed5a4ad0beaaf47901c3b0ecc74892359f (patch)
tree51cdda6e19a737cbccb3055ed8f95e56a3b43f51 /gcc/stmt.c
parent7e4e2d26dc7d06fe1de81723049d7abfbe77732d (diff)
downloadgcc-947255ed5a4ad0beaaf47901c3b0ecc74892359f.zip
gcc-947255ed5a4ad0beaaf47901c3b0ecc74892359f.tar.gz
gcc-947255ed5a4ad0beaaf47901c3b0ecc74892359f.tar.bz2
* stmt.c (expand_asm_operands): Reload in-out reg-only memory operands.
From-SVN: r26628
Diffstat (limited to 'gcc/stmt.c')
-rw-r--r--gcc/stmt.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/gcc/stmt.c b/gcc/stmt.c
index f5ae0c3..f378034 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -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 ();
}