Hi,

This patch adds flavors of the -maltivec option that allow explicit
specification of vector element order.  This is independent of the
target endianness in effect.  The primary use of this is to allow
specifying big-endian vector element order when targeting a
little-endian processor, which aids porting of certain Power BE
applications to Power LE.

The -maltivec=be and -maltivec=le options are intended to match the
behavior of -qaltivec=be and -qaltivec=le that are being introduced for
the IBM XL compilers.  In discussions with the IBM XL designers, we've
agreed that -maltivec=le for big-endian processors need not be supported
at this time, as this is not known to be helpful to anyone.  This patch
ignores that combination while displaying a warning message.

It also makes sense for -maltivec=be and -maltivec=le to imply
-maltivec, as implemented here.

This patch only enables and documents the new options.  Future patches
will make use of the new macro VECTOR_ELT_ORDER_BIG to implement related
changes to vector builtins.

Bootstrapped and tested on powerpc64{,le}-unknown-linux-gnu with no
regressions.  I've also verified the options are now available for both
targets, and that they work as designed (and -maltivec and -mno-altivec
also still work as designed).  Is this ok for trunk?

Thanks,
Bill


2014-01-08  Bill Schmidt  <wschm...@linux.vnet.ibm.com>

        * doc/invoke.texi: Add -maltivec={be,le} options.
        * config/rs6000/rs6000.opt: Likewise.
        * config/rs6000/rs6000.c (rs6000_option_override_internal): Ensure
        that -maltivec={le,be} implies -maltivec; disallow -maltivec=le
        when targeting big endian, at least for now.
        * config/rs6000/rs6000.h: Add #define of VECTOR_ELT_ORDER_BIG.


Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi (revision 206375)
+++ gcc/doc/invoke.texi (working copy)
@@ -17285,6 +17285,18 @@ the AltiVec instruction set.  You may also need to
 @option{-mabi=altivec} to adjust the current ABI with AltiVec ABI
 enhancements.
 
+@item -maltivec=be
+@opindex maltivec=be
+Generate Altivec instructions using big-endian element order,
+regardless of whether the target is big- or little-endian.
+
+@item -maltivec=le
+@opindex maltivec=le
+Generate Altivec instructions using little-endian element order,
+regardless of whether the target is big- or little-endian.  This
+option is currently ignored for big-endian targets, but may be enabled
+in the future.
+
 @item -mvrsave
 @itemx -mno-vrsave
 @opindex mvrsave
Index: gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc/config/rs6000/rs6000.opt        (revision 206375)
+++ gcc/config/rs6000/rs6000.opt        (working copy)
@@ -137,6 +137,14 @@ maltivec
 Target Report Mask(ALTIVEC) Var(rs6000_isa_flags)
 Use AltiVec instructions
 
+maltivec=le
+Target Report RejectNegative Var(rs6000_altivec_element_order, 1) Save
+Generate Altivec instructions using little-endian element order
+
+maltivec=be
+Target Report RejectNegative Var(rs6000_altivec_element_order, 2)
+Generate Altivec instructions using big-endian element order
+
 mhard-dfp
 Target Report Mask(DFP) Var(rs6000_isa_flags)
 Use decimal floating point instructions
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 206375)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -3212,6 +3212,18 @@ rs6000_option_override_internal (bool global_init_
       && !(processor_target_table[tune_index].target_enable & OPTION_MASK_HTM))
     rs6000_isa_flags |= ~rs6000_isa_flags_explicit & OPTION_MASK_STRICT_ALIGN;
 
+  /* -maltivec={le,be} implies -maltivec.  */
+  if (rs6000_altivec_element_order != 0)
+    rs6000_isa_flags |= OPTION_MASK_ALTIVEC;
+
+  /* Disallow -maltivec=le in big endian mode for now.  This is not
+     known to be useful for anyone.  */
+  if (BYTES_BIG_ENDIAN && rs6000_altivec_element_order == 1)
+    {
+      warning (0, N_("-maltivec=le not allowed for big-endian targets"));
+      rs6000_altivec_element_order = 0;
+    }
+
   /* Add some warnings for VSX.  */
   if (TARGET_VSX)
     {
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h  (revision 206375)
+++ gcc/config/rs6000/rs6000.h  (working copy)
@@ -468,6 +468,15 @@ extern int rs6000_vector_align[];
    ? rs6000_vector_align[(MODE)]                                       \
    : (int)GET_MODE_BITSIZE ((MODE)))
 
+/* Determine the element order to use for vector instructions.  By
+   default we use big-endian element order when targeting big-endian,
+   and little-endian element order when targeting little-endian.  For
+   programs being ported from BE Power to LE Power, it can sometimes
+   be useful to use big-endian element order when targeting little-endian.
+   This is set via -maltivec=be, for example.  */
+#define VECTOR_ELT_ORDER_BIG                                  \
+  (BYTES_BIG_ENDIAN || (rs6000_altivec_element_order == 2))
+
 /* Alignment options for fields in structures for sub-targets following
    AIX-like ABI.
    ALIGN_POWER word-aligns FP doubles (default AIX ABI).


Reply via email to