aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2001-11-02 16:53:25 -0500
committerDJ Delorie <dj@gcc.gnu.org>2001-11-02 16:53:25 -0500
commitc9e8cb32e3e00dcb180e6c14f14d5ff4636c86a0 (patch)
treeaa0415c691f7154d235d076579f4f4ea69a7498d
parent720ea9b169cada73072e99439211678c49804836 (diff)
downloadgcc-c9e8cb32e3e00dcb180e6c14f14d5ff4636c86a0.zip
gcc-c9e8cb32e3e00dcb180e6c14f14d5ff4636c86a0.tar.gz
gcc-c9e8cb32e3e00dcb180e6c14f14d5ff4636c86a0.tar.bz2
rs6000.c (rs6000_emit_move): Make sure that using FP registers for DImode mem-mem moves is acceptable.
* config/rs6000/rs6000.c (rs6000_emit_move): Make sure that using FP registers for DImode mem-mem moves is acceptable. From-SVN: r46720
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/rs6000/rs6000.c19
2 files changed, 24 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 95ea422..c2c619f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2001-11-02 DJ Delorie <dj@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_move): Make sure that
+ using FP registers for DImode mem-mem moves is acceptable.
+
2001-11-02 Aldy Hernandez <aldyh@redhat.com>
* builtins.c (apply_args_size): Handle vector arguments.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a87e4ef..f10cef5a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1805,6 +1805,25 @@ rs6000_emit_move (dest, source, mode)
|| (CONST_DOUBLE_HIGH (operands[1]) == -1
&& CONST_DOUBLE_LOW (operands[1]) < 0)))
abort ();
+
+ /* Check if GCC is setting up a block move that will end up using FP
+ registers as temporaries. We must make sure this is acceptable. */
+ if (GET_CODE (operands[0]) == MEM
+ && GET_CODE (operands[1]) == MEM
+ && mode == DImode
+ && ! TARGET_POWERPC64
+ && (SLOW_UNALIGNED_ACCESS(DImode, MEM_ALIGN(operands[0]))
+ || SLOW_UNALIGNED_ACCESS(DImode, MEM_ALIGN(operands[1]))))
+ {
+ rtx reg1, reg2;
+ reg1 = gen_reg_rtx(SImode);
+ reg2 = gen_reg_rtx(SImode);
+ rs6000_emit_move (reg1, simplify_subreg (SImode, operands[1], DImode, 0), SImode);
+ rs6000_emit_move (reg2, simplify_subreg (SImode, operands[1], DImode, 4), SImode);
+ rs6000_emit_move (simplify_subreg (SImode, operands[0], DImode, 0), reg1, SImode);
+ rs6000_emit_move (simplify_subreg (SImode, operands[0], DImode, 4), reg2, SImode);
+ return;
+ }
if (! no_new_pseudos && GET_CODE (operands[0]) != REG)
operands[1] = force_reg (mode, operands[1]);