diff mbox

[rs6000] Add -maltivec={le,be} options

Message ID 1389128467.18332.10.camel@gnopaine
State New
Headers show

Commit Message

Bill Schmidt Jan. 7, 2014, 9:01 p.m. UTC
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  <wschmidt@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.

Comments

Joseph Myers Jan. 7, 2014, 9:51 p.m. UTC | #1
On Tue, 7 Jan 2014, Bill Schmidt wrote:

> +@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.

I don't understand what "using big-endian element order" or "using 
little-endian element order" means.  Is this about the interpretation of 
element numbers in AltiVec intrinsics?  (In GNU C vector indexing with 
array notation, GENERIC, GIMPLE and RTL, vector element numbers are always 
in memory order like in arrays, so a command-line option like this 
*shouldn't* affect anything other than intrinsics.  Cf. the ARM NEON code 
that deals with flipping element order conventions for big endian so that 
intrinsics can follow the ARM convention while GNU C, GENERIC, GIMPLE and 
RTL follow the convention that the architecture-independent compiler 
expects.)
Bill Schmidt Jan. 7, 2014, 10:06 p.m. UTC | #2
On Tue, 2014-01-07 at 21:51 +0000, Joseph S. Myers wrote:
> On Tue, 7 Jan 2014, Bill Schmidt wrote:
> 
> > +@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.
> 
> I don't understand what "using big-endian element order" or "using 
> little-endian element order" means.  Is this about the interpretation of 
> element numbers in AltiVec intrinsics?  (In GNU C vector indexing with 
> array notation, GENERIC, GIMPLE and RTL, vector element numbers are always 
> in memory order like in arrays, so a command-line option like this 
> *shouldn't* affect anything other than intrinsics.  Cf. the ARM NEON code 
> that deals with flipping element order conventions for big endian so that 
> intrinsics can follow the ARM convention while GNU C, GENERIC, GIMPLE and 
> RTL follow the convention that the architecture-independent compiler 
> expects.)
> 

Yes, sorry for not being more clear.  This is indeed for interpretation
of element numbers in Altivec intrinsics such as vec_splat, vec_extract,
vec_insert, and so forth.  By default these will match array element
order for the target endianness.  But with -maltivec=be for a little
endian target, we will force use of big-endian element order (matching
the behavior of the underlying hardware instructions).

There are certain VSX load and store instructions that assume big-endian
ordering of vector elements in a register regardless of target
endianness.  Applications developed for Power BE that use these
instructions via intrinsics will be easier to port to Power LE with
-maltivec=be.
Joseph Myers Jan. 7, 2014, 10:18 p.m. UTC | #3
On Tue, 7 Jan 2014, Bill Schmidt wrote:

> Yes, sorry for not being more clear.  This is indeed for interpretation
> of element numbers in Altivec intrinsics such as vec_splat, vec_extract,
> vec_insert, and so forth.  By default these will match array element
> order for the target endianness.  But with -maltivec=be for a little
> endian target, we will force use of big-endian element order (matching
> the behavior of the underlying hardware instructions).

Thanks for the explanation.  I think you should make the .texi 
documentation say something more like this.
Bill Schmidt Jan. 7, 2014, 11:59 p.m. UTC | #4
On Tue, 2014-01-07 at 22:18 +0000, Joseph S. Myers wrote:
> On Tue, 7 Jan 2014, Bill Schmidt wrote:
> 
> > Yes, sorry for not being more clear.  This is indeed for interpretation
> > of element numbers in Altivec intrinsics such as vec_splat, vec_extract,
> > vec_insert, and so forth.  By default these will match array element
> > order for the target endianness.  But with -maltivec=be for a little
> > endian target, we will force use of big-endian element order (matching
> > the behavior of the underlying hardware instructions).
> 
> Thanks for the explanation.  I think you should make the .texi 
> documentation say something more like this.
> 

Sure, I can wordsmith something along those lines.  Thanks for the
feedback!

Bill
David Edelsohn Jan. 8, 2014, 9:46 p.m. UTC | #5
On Tue, Jan 7, 2014 at 6:59 PM, Bill Schmidt
<wschmidt@linux.vnet.ibm.com> wrote:
> On Tue, 2014-01-07 at 22:18 +0000, Joseph S. Myers wrote:
>> On Tue, 7 Jan 2014, Bill Schmidt wrote:
>>
>> > Yes, sorry for not being more clear.  This is indeed for interpretation
>> > of element numbers in Altivec intrinsics such as vec_splat, vec_extract,
>> > vec_insert, and so forth.  By default these will match array element
>> > order for the target endianness.  But with -maltivec=be for a little
>> > endian target, we will force use of big-endian element order (matching
>> > the behavior of the underlying hardware instructions).
>>
>> Thanks for the explanation.  I think you should make the .texi
>> documentation say something more like this.
>>
>
> Sure, I can wordsmith something along those lines.  Thanks for the
> feedback!

This patch is okay with the documentation clarification requested by Joseph.

I also would suggest removing "but may be enabled in the future" from
the "le" option and limit the comment to ignored on big-endian
targets.

Also, please add a comment to -maltivec that it defaults to the native
endian order.  And for -maltivec=be, please state that this is the
default for big-endian; for -maltivec=le, please state that this is
the default for little-endian. It's important to be clear and
redundant in this type of documentation.

Thanks, David
Bill Schmidt Jan. 8, 2014, 9:57 p.m. UTC | #6
On Wed, 2014-01-08 at 16:46 -0500, David Edelsohn wrote:
> On Tue, Jan 7, 2014 at 6:59 PM, Bill Schmidt
> <wschmidt@linux.vnet.ibm.com> wrote:
> > On Tue, 2014-01-07 at 22:18 +0000, Joseph S. Myers wrote:
> >> On Tue, 7 Jan 2014, Bill Schmidt wrote:
> >>
> >> > Yes, sorry for not being more clear.  This is indeed for interpretation
> >> > of element numbers in Altivec intrinsics such as vec_splat, vec_extract,
> >> > vec_insert, and so forth.  By default these will match array element
> >> > order for the target endianness.  But with -maltivec=be for a little
> >> > endian target, we will force use of big-endian element order (matching
> >> > the behavior of the underlying hardware instructions).
> >>
> >> Thanks for the explanation.  I think you should make the .texi
> >> documentation say something more like this.
> >>
> >
> > Sure, I can wordsmith something along those lines.  Thanks for the
> > feedback!
> 
> This patch is okay with the documentation clarification requested by Joseph.
> 
> I also would suggest removing "but may be enabled in the future" from
> the "le" option and limit the comment to ignored on big-endian
> targets.
> 
> Also, please add a comment to -maltivec that it defaults to the native
> endian order.  And for -maltivec=be, please state that this is the
> default for big-endian; for -maltivec=le, please state that this is
> the default for little-endian. It's important to be clear and
> redundant in this type of documentation.
> 
> Thanks, David
> 

OK, thanks very much for the review.  I'll clean up the documentation as
requested this evening.

Thanks,
Bill
diff mbox

Patch

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).