summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2014-08-15 14:16:56 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2014-08-15 14:16:56 +0000
commit363785f63edd6a56427b6aa3f256ffac9a2d376d (patch)
treed886728242b3aebd8e545464fab6b08a692d885a /gcc
parent592f32fa9bda0f9d685e1221ff7576712af1b73b (diff)
downloadgcc-363785f63edd6a56427b6aa3f256ffac9a2d376d.tar.gz
rs6000.c (rs6000_emit_move): Use SDmode for load/store from/to non-floating class pseudo.
2014-08-15 Vladimir Makarov <vmakarov@redhat.com> * config/rs6000/rs6000.c (rs6000_emit_move): Use SDmode for load/store from/to non-floating class pseudo. From-SVN: r214023
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/rs6000/rs6000.c48
2 files changed, 53 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 736783ef4ec..2b68ebb4b9a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-08-15 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_move): Use SDmode for
+ load/store from/to non-floating class pseudo.
+
2014-08-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
* input.c (diagnostic_file_cache_fini): Fix typo in comment.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d90afcc8e5f..897bb922d2d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -8308,6 +8308,30 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
+ /* Transform (p0:DD, (SUBREG:DD p1:SD)) to ((SUBREG:SD p0:DD),
+ p1:SD) if p1 is not of floating point class and p0 is spilled as
+ we can have no analogous movsd_store for this. */
+ if (lra_in_progress && mode == DDmode
+ && REG_P (operands[0]) && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER
+ && reg_preferred_class (REGNO (operands[0])) == NO_REGS
+ && GET_CODE (operands[1]) == SUBREG && REG_P (SUBREG_REG (operands[1]))
+ && GET_MODE (SUBREG_REG (operands[1])) == SDmode)
+ {
+ enum reg_class cl;
+ int regno = REGNO (SUBREG_REG (operands[1]));
+
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ cl = reg_preferred_class (regno);
+ regno = cl == NO_REGS ? -1 : ira_class_hard_regs[cl][1];
+ }
+ if (regno >= 0 && ! FP_REGNO_P (regno))
+ {
+ mode = SDmode;
+ operands[0] = gen_lowpart_SUBREG (SDmode, operands[0]);
+ operands[1] = SUBREG_REG (operands[1]);
+ }
+ }
if (lra_in_progress
&& mode == SDmode
&& REG_P (operands[0]) && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER
@@ -8338,6 +8362,30 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
gcc_unreachable();
return;
}
+ /* Transform ((SUBREG:DD p0:SD), p1:DD) to (p0:SD, (SUBREG:SD
+ p:DD)) if p0 is not of floating point class and p1 is spilled as
+ we can have no analogous movsd_load for this. */
+ if (lra_in_progress && mode == DDmode
+ && GET_CODE (operands[0]) == SUBREG && REG_P (SUBREG_REG (operands[0]))
+ && GET_MODE (SUBREG_REG (operands[0])) == SDmode
+ && REG_P (operands[1]) && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER
+ && reg_preferred_class (REGNO (operands[1])) == NO_REGS)
+ {
+ enum reg_class cl;
+ int regno = REGNO (SUBREG_REG (operands[0]));
+
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ cl = reg_preferred_class (regno);
+ regno = cl == NO_REGS ? -1 : ira_class_hard_regs[cl][0];
+ }
+ if (regno >= 0 && ! FP_REGNO_P (regno))
+ {
+ mode = SDmode;
+ operands[0] = SUBREG_REG (operands[0]);
+ operands[1] = gen_lowpart_SUBREG (SDmode, operands[1]);
+ }
+ }
if (lra_in_progress
&& mode == SDmode
&& (REG_P (operands[0])