diff options
author | Michael Meissner <meissner@linux.vnet.ibm.com> | 2013-05-06 23:33:49 +0000 |
---|---|---|
committer | Michael Meissner <meissner@linux.vnet.ibm.com> | 2013-05-06 23:33:49 +0000 |
commit | ec76faffbf88ce2313c35d58464a94c1f65f95ed (patch) | |
tree | b98b8bc4cfa1bdec955e9347eeab420cb0b0e3b8 /gcc/config | |
parent | 6fee3ea2704390f5a3124fcc928eb30ff0350d09 (diff) |
[gcc]
2013-05-06 Michael Meissner <meissner@linux.vnet.ibm.com>
Backport from trunk
2013-05-03 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/57150
* config/rs6000/rs6000.h (HARD_REGNO_CALLER_SAVE_MODE): Use DFmode
to save TFmode registers and DImode to save TImode registers for
caller save operations.
(HARD_REGNO_CALL_PART_CLOBBERED): TFmode and TDmode do not need to
mark being partially clobbered since they only use the first
double word.
* config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): TFmode
and TDmode only use the upper 64-bits of each VSX register.
[gcc/testsuite]
2013-05-06 Michael Meissner <meissner@linux.vnet.ibm.com>
Backport from trunk
2013-05-03 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/57150
* gcc.target/powerpc/pr57150.c: New file.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_8-branch@198656 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 12 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 14 |
2 files changed, 20 insertions, 6 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index fbf57be44a3..5d384dd67de 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2186,8 +2186,16 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p) reg_size = UNITS_PER_WORD; for (m = 0; m < NUM_MACHINE_MODES; ++m) - rs6000_class_max_nregs[m][c] - = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size; + { + int reg_size2 = reg_size; + + /* TFmode/TDmode always takes 2 registers, even in VSX. */ + if (m == TDmode || m == TFmode) + reg_size2 = UNITS_PER_FP_WORD; + + rs6000_class_max_nregs[m][c] + = (GET_MODE_SIZE (m) + reg_size2 - 1) / reg_size2; + } } if (TARGET_E500_DOUBLE) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index b5c79ea6e95..b42f62ac77e 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1068,12 +1068,17 @@ extern unsigned rs6000_pointer_size; #define HARD_REGNO_NREGS(REGNO, MODE) rs6000_hard_regno_nregs[(MODE)][(REGNO)] /* When setting up caller-save slots (MODE == VOIDmode) ensure we allocate - enough space to account for vectors in FP regs. */ + enough space to account for vectors in FP regs. However, TFmode/TDmode + should not use VSX instructions to do a caller save. */ #define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ (TARGET_VSX \ && ((MODE) == VOIDmode || ALTIVEC_OR_VSX_VECTOR_MODE (MODE)) \ - && FP_REGNO_P (REGNO) \ - ? V2DFmode \ + && FP_REGNO_P (REGNO) \ + ? V2DFmode \ + : ((MODE) == TFmode && FP_REGNO_P (REGNO)) \ + ? DFmode \ + : ((MODE) == TDmode && FP_REGNO_P (REGNO)) \ + ? DImode \ : choose_hard_reg_mode ((REGNO), (NREGS), false)) #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ @@ -1081,7 +1086,8 @@ extern unsigned rs6000_pointer_size; && (GET_MODE_SIZE (MODE) > 4) \ && INT_REGNO_P (REGNO)) ? 1 : 0) \ || (TARGET_VSX && FP_REGNO_P (REGNO) \ - && GET_MODE_SIZE (MODE) > 8)) + && GET_MODE_SIZE (MODE) > 8 && ((MODE) != TDmode) \ + && ((MODE) != TFmode))) #define VSX_VECTOR_MODE(MODE) \ ((MODE) == V4SFmode \ |