From: Michael Meissner Date: Tue, 7 May 2013 17:58:02 +0000 (+0000) Subject: backport: re PR target/57150 (GCC when targeting power7 spills long double using... X-Git-Tag: releases/gcc-4.7.4~678 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=10dac7ca9cf0c7575868569f52c92a0ba28b169a;p=thirdparty%2Fgcc.git backport: re PR target/57150 (GCC when targeting power7 spills long double using VSX instructions.) [gcc] 2013-05-07 Michael Meissner Backport from trunk 2013-05-03 Michael Meissner 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-07 Michael Meissner Backport from trunk 2013-05-03 Michael Meissner PR target/57150 * gcc.target/powerpc/pr57150.c: New file. From-SVN: r198692 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4135a70e09aa..19e3766dd09a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2013-05-07 Michael Meissner + + Backport from trunk + 2013-05-03 Michael Meissner + + 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. + 2013-05-03 Marek Polacek Backport from mainline diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6804731c4de8..526d83917a1f 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2398,8 +2398,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 63cbdc8f382d..ed76345051d4 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1033,12 +1033,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) \ @@ -1046,7 +1051,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 \ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cb16efdf83bd..db60bd739a98 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2013-05-07 Michael Meissner + + Backport from trunk + 2013-05-03 Michael Meissner + + PR target/57150 + * gcc.target/powerpc/pr57150.c: New file. + 2013-05-07 Tobias Burnus Backport from mainline diff --git a/gcc/testsuite/gcc.target/powerpc/pr57150.c b/gcc/testsuite/gcc.target/powerpc/pr57150.c new file mode 100644 index 000000000000..119bc4c52fee --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr57150.c @@ -0,0 +1,23 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-require-effective-target powerpc_vsx_ok } */ +/* { dg-options "-O3 -mcpu=power7 -fcaller-saves" } */ +/* { dg-final { scan-assembler-not "lxvd2x" } } */ +/* { dg-final { scan-assembler-not "lxvw4x" } } */ +/* { dg-final { scan-assembler-not "lvx" } } */ +/* { dg-final { scan-assembler-not "stxvd2x" } } */ +/* { dg-final { scan-assembler-not "stxvw4x" } } */ +/* { dg-final { scan-assembler-not "stvx" } } */ + +/* Insure caller save on long double does not use VSX instructions. */ + +extern long double modify (long double); + +void +sum (long double *ptr, long double value, unsigned long n) +{ + unsigned long i; + + for (i = 0; i < n; i++) + ptr[i] += modify (value); +}