diff options
author | Alan Modra <amodra@gmail.com> | 2017-08-16 10:36:35 +0930 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2017-08-16 10:36:35 +0930 |
commit | 973d3f1905307988ba17a4f93d9a95518b91fe42 (patch) | |
tree | 3f24168bf8319d40504517c3fa40d6e640f7e7bb /gcc | |
parent | 9171123bfcd64715f85ed0e75085c3d0d31422a2 (diff) | |
download | gcc-973d3f1905307988ba17a4f93d9a95518b91fe42.zip gcc-973d3f1905307988ba17a4f93d9a95518b91fe42.tar.gz gcc-973d3f1905307988ba17a4f93d9a95518b91fe42.tar.bz2 |
[RS6000] Don't restore fixed regs
* config/rs6000/rs6000.c (rs6000_savres_strategy): Don't restore
fixed regs.
From-SVN: r251114
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 79 |
2 files changed, 53 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 14fc3db..4e6720f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2017-08-16 Alan Modra <amodra@gmail.com> + + * config/rs6000/rs6000.c (rs6000_savres_strategy): Don't restore + fixed regs. + 2017-08-15 Joseph Myers <joseph@codesourcery.com> PR target/78460 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 1360c15..5510306 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -24406,36 +24406,47 @@ rs6000_savres_strategy (rs6000_stack_t *info, | SAVE_INLINE_GPRS | SAVE_INLINE_VRS); + /* Don't ever restore fixed regs. That means we can't use the + out-of-line register restore functions if a fixed reg is in the + range of regs restored. */ + if (!(strategy & REST_INLINE_FPRS)) + for (int i = info->first_fp_reg_save; i < 64; i++) + if (fixed_regs[i]) + { + strategy |= REST_INLINE_FPRS; + break; + } + /* We can only use the out-of-line routines to restore fprs if we've saved all the registers from first_fp_reg_save in the prologue. Otherwise, we risk loading garbage. Of course, if we have saved out-of-line then we know we haven't skipped any fprs. */ if ((strategy & SAVE_INLINE_FPRS) && !(strategy & REST_INLINE_FPRS)) - { - int i; - - for (i = info->first_fp_reg_save; i < 64; i++) - if (fixed_regs[i] || !save_reg_p (i)) - { - strategy |= REST_INLINE_FPRS; - break; - } - } + for (int i = info->first_fp_reg_save; i < 64; i++) + if (!save_reg_p (i)) + { + strategy |= REST_INLINE_FPRS; + break; + } /* Similarly, for altivec regs. */ + if (!(strategy & REST_INLINE_VRS)) + for (int i = info->first_altivec_reg_save; i < LAST_ALTIVEC_REGNO + 1; i++) + if (fixed_regs[i]) + { + strategy |= REST_INLINE_VRS; + break; + } + if ((strategy & SAVE_INLINE_VRS) && !(strategy & REST_INLINE_VRS)) - { - int i; - - for (i = info->first_altivec_reg_save; i < LAST_ALTIVEC_REGNO + 1; i++) - if (fixed_regs[i] || !save_reg_p (i)) - { - strategy |= REST_INLINE_VRS; - break; - } - } + for (int i = info->first_altivec_reg_save; i < LAST_ALTIVEC_REGNO + 1; i++) + if (!save_reg_p (i)) + { + strategy |= REST_INLINE_VRS; + break; + } /* info->lr_save_p isn't yet set if the only reason lr needs to be saved is an out-of-line save or restore. Set up the value for @@ -24490,6 +24501,16 @@ rs6000_savres_strategy (rs6000_stack_t *info, } } + /* Don't ever restore fixed regs. */ + if ((strategy & (REST_INLINE_GPRS | REST_MULTIPLE)) != REST_INLINE_GPRS) + for (int i = info->first_gp_reg_save; i < 32; i++) + if (fixed_reg_p (i)) + { + strategy |= REST_INLINE_GPRS; + strategy &= ~REST_MULTIPLE; + break; + } + /* We can only use load multiple or the out-of-line routines to restore gprs if we've saved all the registers from first_gp_reg_save. Otherwise, we risk loading garbage. @@ -24497,17 +24518,13 @@ rs6000_savres_strategy (rs6000_stack_t *info, we haven't skipped any gprs. */ if ((strategy & (SAVE_INLINE_GPRS | SAVE_MULTIPLE)) == SAVE_INLINE_GPRS && (strategy & (REST_INLINE_GPRS | REST_MULTIPLE)) != REST_INLINE_GPRS) - { - int i; - - for (i = info->first_gp_reg_save; i < 32; i++) - if (fixed_reg_p (i) || !save_reg_p (i)) - { - strategy |= REST_INLINE_GPRS; - strategy &= ~REST_MULTIPLE; - break; - } - } + for (int i = info->first_gp_reg_save; i < 32; i++) + if (!save_reg_p (i)) + { + strategy |= REST_INLINE_GPRS; + strategy &= ~REST_MULTIPLE; + break; + } if (TARGET_ELF && TARGET_64BIT) { |