This patch is part of the support needed to properly swap IEEE 128-bit floating
point on little endian systems. Note, you will need the rs6000.md changes for
this to become effective.
I have built the compiler with this patch and the previous subpatches (1-9). I
have bootstrapped the compiler with all 16 subpatches installed, and there were
no regressions. Is it ok to install in the trunk?
2015-10-22 Michael Meissner <[email protected]>
* config/rs6000/rs6000.c (rs6000_gen_le_vsx_permute): On little
endian systems generate a ROTATE insn instead of VEC_SELECT for
IEEE 128-bit floating point types that can go in vector
registers.
(chain_contains_only_swaps): Properly swap IEEE 128-bit floating
point types that can go in vector registers on little endian
PowerPC systems.
(mark_swaps_for_removal): Likewise.
(rs6000_analyze_swaps): Likewise.
--
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: [email protected], phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 229194)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -8467,8 +8467,14 @@ rs6000_const_vec (machine_mode mode)
rtx
rs6000_gen_le_vsx_permute (rtx source, machine_mode mode)
{
- rtx par = gen_rtx_PARALLEL (VOIDmode, rs6000_const_vec (mode));
- return gen_rtx_VEC_SELECT (mode, source, par);
+ /* Use ROTATE instead of VEC_SELECT on IEEE 128-bit floating point. */
+ if (FLOAT128_VECTOR_P (mode))
+ return gen_rtx_ROTATE (mode, source, GEN_INT (64));
+ else
+ {
+ rtx par = gen_rtx_PARALLEL (VOIDmode, rs6000_const_vec (mode));
+ return gen_rtx_VEC_SELECT (mode, source, par);
+ }
}
/* Emit a little-endian load from vector memory location SOURCE to VSX
@@ -35844,7 +35850,7 @@ chain_contains_only_swaps (swap_web_entr
for (; link; link = link->next)
{
- if (!VECTOR_MODE_P (GET_MODE (DF_REF_REG (link->ref))))
+ if (!ALTIVEC_OR_VSX_VECTOR_MODE (GET_MODE (DF_REF_REG (link->ref))))
continue;
if (DF_REF_IS_ARTIFICIAL (link->ref))
@@ -35943,7 +35949,7 @@ mark_swaps_for_removal (swap_web_entry *
{
/* Ignore uses for addressability. */
machine_mode mode = GET_MODE (DF_REF_REG (use));
- if (!VECTOR_MODE_P (mode))
+ if (!ALTIVEC_OR_VSX_VECTOR_MODE (mode))
continue;
struct df_link *link = DF_REF_CHAIN (use);
@@ -36457,10 +36463,11 @@ rs6000_analyze_swaps (function *fun)
mode = V4SImode;
}
- if (VECTOR_MODE_P (mode) || mode == TImode)
+ if (ALTIVEC_OR_VSX_VECTOR_MODE (mode) || mode == TImode)
{
insn_entry[uid].is_relevant = 1;
- if (mode == TImode || mode == V1TImode)
+ if (mode == TImode || mode == V1TImode
+ || FLOAT128_VECTOR_P (mode))
insn_entry[uid].is_128_int = 1;
if (DF_REF_INSN_INFO (mention))
insn_entry[uid].contains_subreg
@@ -36481,13 +36488,14 @@ rs6000_analyze_swaps (function *fun)
isn't sufficient to ensure we union the call into the
web with the parameter setup code. */
if (mode == DImode && GET_CODE (insn) == SET
- && VECTOR_MODE_P (GET_MODE (SET_DEST (insn))))
+ && ALTIVEC_OR_VSX_VECTOR_MODE (GET_MODE (SET_DEST (insn))))
mode = GET_MODE (SET_DEST (insn));
- if (VECTOR_MODE_P (mode) || mode == TImode)
+ if (ALTIVEC_OR_VSX_VECTOR_MODE (mode) || mode == TImode)
{
insn_entry[uid].is_relevant = 1;
- if (mode == TImode || mode == V1TImode)
+ if (mode == TImode || mode == V1TImode
+ || FLOAT128_VECTOR_P (mode))
insn_entry[uid].is_128_int = 1;
if (DF_REF_INSN_INFO (mention))
insn_entry[uid].contains_subreg