diff options
author | David S. Miller <davem@davemloft.net> | 2011-11-21 21:50:58 +0000 |
---|---|---|
committer | David S. Miller <davem@gcc.gnu.org> | 2011-11-21 13:50:58 -0800 |
commit | 98ccb32db43c4f2782ca59cd4e0d9ab1b4d37fab (patch) | |
tree | e83a97dd65882dcecbef6e3ce93db0030de097b3 | |
parent | e57a3447f7117ade80869bbcfeb8f8abc3af346a (diff) | |
download | gcc-98ccb32db43c4f2782ca59cd4e0d9ab1b4d37fab.zip gcc-98ccb32db43c4f2782ca59cd4e0d9ab1b4d37fab.tar.gz gcc-98ccb32db43c4f2782ca59cd4e0d9ab1b4d37fab.tar.bz2 |
Correct sparc's REGMODE_NATURAL_SIZE and MODES_TIEABLE_P wrt. vector modes.
* config/sparc/sparc.c (sparc_regmode_natural_size): New function
implementing REGMODE_NATURAL_SIZE taking into consideration vector
modes.
(sparc_modes_tieable_p): Similarly for MODES_TIEABLE_P.
* config/sparc/sparc-protos.h (sparc_regmode_natural_size,
sparc_modes_tieable_p): Declare.
* gcc/config/sparc/sparc.h (REGMODE_NATURAL_SIZE,
MODES_TIEABLE_P): Use new helper functions.
From-SVN: r181599
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/sparc/sparc-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 65 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 18 |
4 files changed, 78 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 854b00e..d45424f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2011-11-21 David S. Miller <davem@davemloft.net> + * config/sparc/sparc.c (sparc_regmode_natural_size): New function + implementing REGMODE_NATURAL_SIZE taking into consideration vector + modes. + (sparc_modes_tieable_p): Similarly for MODES_TIEABLE_P. + * config/sparc/sparc-protos.h (sparc_regmode_natural_size, + sparc_modes_tieable_p): Declare. + * gcc/config/sparc/sparc.h (REGMODE_NATURAL_SIZE, + MODES_TIEABLE_P): Use new helper functions. + Revert 2011-11-16 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index ccf20b1..10fa5ed 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -109,6 +109,8 @@ extern void sparc_expand_vector_init (rtx, rtx); extern void sparc_expand_vec_perm_bmask(enum machine_mode, rtx); extern bool sparc_expand_conditional_move (enum machine_mode, rtx *); extern void sparc_expand_vcond (enum machine_mode, rtx *, int, int); +unsigned int sparc_regmode_natural_size (enum machine_mode); +bool sparc_modes_tieable_p (enum machine_mode, enum machine_mode); #endif /* RTX_CODE */ #endif /* __SPARC_PROTOS_H__ */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 55759a0..b315698 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -11616,4 +11616,69 @@ sparc_expand_vcond (enum machine_mode mode, rtx *operands, int ccode, int fcode) emit_insn (gen_rtx_SET (VOIDmode, operands[0], bshuf)); } +/* On sparc, any mode which naturally allocates into the float + registers should return 4 here. */ + +unsigned int +sparc_regmode_natural_size (enum machine_mode mode) +{ + int size = UNITS_PER_WORD; + + if (TARGET_ARCH64) + { + enum mode_class mclass = GET_MODE_CLASS (mode); + + if (mclass == MODE_FLOAT || mclass == MODE_VECTOR_INT) + size = 4; + } + + return size; +} + +/* Return TRUE if it is a good idea to tie two pseudo registers + when one has mode MODE1 and one has mode MODE2. + If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, + for any hard reg, then this must be FALSE for correct output. + + For V9 we have to deal with the fact that only the lower 32 floating + point registers are 32-bit addressable. */ + +bool +sparc_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2) +{ + enum mode_class mclass1, mclass2; + unsigned short size1, size2; + + if (mode1 == mode2) + return true; + + mclass1 = GET_MODE_CLASS (mode1); + mclass2 = GET_MODE_CLASS (mode2); + if (mclass1 != mclass2) + return false; + + if (! TARGET_V9) + return true; + + /* Classes are the same and we are V9 so we have to deal with upper + vs. lower floating point registers. If one of the modes is a + 4-byte mode, and the other is not, we have to mark them as not + tieable because only the lower 32 floating point register are + addressable 32-bits at a time. + + We can't just test explicitly for SFmode, otherwise we won't + cover the vector mode cases properly. */ + + if (mclass1 != MODE_FLOAT && mclass1 != MODE_VECTOR_INT) + return true; + + size1 = GET_MODE_SIZE (mode1); + size2 = GET_MODE_SIZE (mode2); + if ((size1 > 4 && size2 == 4) + || (size2 > 4 && size1 == 4)) + return false; + + return true; +} + #include "gt-sparc.h" diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index e8707f5..32f8c10 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -716,8 +716,7 @@ extern enum cmodel sparc_cmodel; /* Due to the ARCH64 discrepancy above we must override this next macro too. */ -#define REGMODE_NATURAL_SIZE(MODE) \ - ((TARGET_ARCH64 && FLOAT_MODE_P (MODE)) ? 4 : UNITS_PER_WORD) +#define REGMODE_NATURAL_SIZE(MODE) sparc_regmode_natural_size (MODE) /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. See sparc.c for how we initialize this. */ @@ -735,20 +734,7 @@ extern int sparc_mode_class[]; register window instruction in the prologue. */ #define HARD_REGNO_RENAME_OK(FROM, TO) ((FROM) != 1) -/* Value is 1 if it is a good idea to tie two pseudo registers - when one has mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. - - For V9: SFmode can't be combined with other float modes, because they can't - be allocated to the %d registers. Also, DFmode won't fit in odd %f - registers, but SFmode will. */ -#define MODES_TIEABLE_P(MODE1, MODE2) \ - ((MODE1) == (MODE2) \ - || (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2) \ - && (! TARGET_V9 \ - || (GET_MODE_CLASS (MODE1) != MODE_FLOAT \ - || (MODE1 != SFmode && MODE2 != SFmode))))) +#define MODES_TIEABLE_P(MODE1, MODE2) sparc_modes_tieable_p (MODE1, MODE2) /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ |