diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2014-08-15 14:16:56 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2014-08-15 14:16:56 +0000 |
commit | 363785f63edd6a56427b6aa3f256ffac9a2d376d (patch) | |
tree | d886728242b3aebd8e545464fab6b08a692d885a /gcc | |
parent | 592f32fa9bda0f9d685e1221ff7576712af1b73b (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 48 |
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]) |