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
This commit is contained in:
parent
e57a3447f7
commit
98ccb32db4
4 changed files with 78 additions and 16 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Add table
Reference in a new issue