diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
| -rw-r--r-- | gcc/config/rs6000/rs6000.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index bf831ea..db8fdcc 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3430,6 +3430,71 @@ rs6000_hard_regno_nregs (int regno, enum machine_mode mode) return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; } + +/* Change register usage conditional on target flags. */ +void +rs6000_conditional_register_usage (void) +{ + int i; + + /* Set MQ register fixed (already call_used) if not POWER + architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not + be allocated. */ + if (! TARGET_POWER) + fixed_regs[64] = 1; + + /* 64-bit AIX reserves GPR13 for thread-private data. */ + if (TARGET_64BIT) + fixed_regs[13] = call_used_regs[13] + = call_really_used_regs[13] = 1; + + /* Conditionally disable FPRs. */ + if (TARGET_SOFT_FLOAT || !TARGET_FPRS) + for (i = 32; i < 64; i++) + fixed_regs[i] = call_used_regs[i] + = call_really_used_regs[i] = 1; + + if (DEFAULT_ABI == ABI_V4 + && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM + && flag_pic == 2) + fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; + + if (DEFAULT_ABI == ABI_V4 + && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM + && flag_pic == 1) + fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] + = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] + = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; + + if (DEFAULT_ABI == ABI_DARWIN + && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) + global_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] + = fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] + = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] + = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; + + if (TARGET_ALTIVEC) + global_regs[VSCR_REGNO] = 1; + + if (TARGET_SPE) + { + global_regs[SPEFSCR_REGNO] = 1; + fixed_regs[FIXED_SCRATCH] + = call_used_regs[FIXED_SCRATCH] + = call_really_used_regs[FIXED_SCRATCH] = 1; + } + + if (! TARGET_ALTIVEC) + { + for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i) + fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1; + call_really_used_regs[VRSAVE_REGNO] = 1; + } + + if (TARGET_ALTIVEC_ABI) + for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i) + call_used_regs[i] = call_really_used_regs[i] = 1; +} /* Try to output insns to set TARGET equal to the constant C if it can be done in less than N insns. Do all computations in MODE. |
