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 <[email protected]>
* 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).