Treat -ffixed-reg as we do for global asm regs. The only slightly complicated part of this patch is that the rs6000 backend itself sets fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] in some cases, which means we can't simply test fixed_regs[] to determine whether a reg appeared as -ffixed-reg.
PR target/69645 * config/rs6000/rs6000.c (fixed_reg_p): New function. (fixed_regs_p): Rename from global_regs_p. Call fixed_reg_p. Update all uses. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 0e570e4..99473bd 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -22996,17 +22996,34 @@ is_altivec_return_reg (rtx reg, void *xyes) } -/* Look for user-defined global regs in the range FIRST to LAST-1. - We should not restore these, and so cannot use lmw or out-of-line - restore functions if there are any. We also can't save them - (well, emit frame notes for them), because frame unwinding during - exception handling will restore saved registers. */ +/* Return whether REG is a global user reg or has been specifed by + -ffixed-REG. */ static bool -global_regs_p (unsigned first, unsigned last) +fixed_reg_p (int reg) +{ + /* Ignore fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] when the + backend sets it, overriding anything the user might have given. */ + if (reg == RS6000_PIC_OFFSET_TABLE_REGNUM + && ((DEFAULT_ABI == ABI_V4 && flag_pic) + || (DEFAULT_ABI == ABI_DARWIN && flag_pic) + || (TARGET_TOC && TARGET_MINIMAL_TOC))) + return false; + + return fixed_regs[reg]; +} + +/* Look for user-defined global regs or -ffixed-<reg> in the range + FIRST to LAST-1. We should not restore these, and so cannot use + lmw or out-of-line restore functions if there are any. We also + can't save them (well, emit frame notes for them), because frame + unwinding during exception handling will restore saved registers. */ + +static bool +fixed_regs_p (unsigned first, unsigned last) { while (first < last) - if (global_regs[first++]) + if (fixed_reg_p (first++)) return true; return false; } @@ -23037,7 +23054,7 @@ rs6000_savres_strategy (rs6000_stack_t *info, && !TARGET_POWERPC64 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used) && info->first_gp_reg_save < 31 - && !global_regs_p (info->first_gp_reg_save, 32)) + && !fixed_regs_p (info->first_gp_reg_save, 32)) strategy |= SAVRES_MULTIPLE; if (crtl->calls_eh_return @@ -23050,16 +23067,16 @@ rs6000_savres_strategy (rs6000_stack_t *info, /* The out-of-line FP routines use double-precision stores; we can't use those routines if we don't have such stores. */ || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT) - || global_regs_p (info->first_fp_reg_save, 64)) + || fixed_regs_p (info->first_fp_reg_save, 64)) strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS; if (info->first_gp_reg_save == 32 || (!(strategy & SAVRES_MULTIPLE) - && global_regs_p (info->first_gp_reg_save, 32))) + && fixed_regs_p (info->first_gp_reg_save, 32))) strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS; if (info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1 - || global_regs_p (info->first_altivec_reg_save, LAST_ALTIVEC_REGNO + 1)) + || fixed_regs_p (info->first_altivec_reg_save, LAST_ALTIVEC_REGNO + 1)) strategy |= SAVE_INLINE_VRS | REST_INLINE_VRS; /* Define cutoff for using out-of-line functions to save registers. */ -- Alan Modra Australia Development Lab, IBM