[PATCH] libstdc++: Implement LWG 3555 changes to transform/elements_view

2021-06-17 Thread Patrick Palka via Gcc-patches
libstdc++-v3/ChangeLog:

* include/std/ranges (transform_view::_Iterator::_S_iter_concept):
Consider _Base instead of _Vp as per LWG 3555.
(elements_view::_Iterator::_S_iter_concept): Likewise.
---
 libstdc++-v3/include/std/ranges | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index f93a880ff8a..bf85b1629f0 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1613,11 +1613,11 @@ namespace views::__adaptor
  static auto
  _S_iter_concept()
  {
-   if constexpr (random_access_range<_Vp>)
+   if constexpr (random_access_range<_Base>)
  return random_access_iterator_tag{};
-   else if constexpr (bidirectional_range<_Vp>)
+   else if constexpr (bidirectional_range<_Base>)
  return bidirectional_iterator_tag{};
-   else if constexpr (forward_range<_Vp>)
+   else if constexpr (forward_range<_Base>)
  return forward_iterator_tag{};
else
  return input_iterator_tag{};
@@ -3659,11 +3659,11 @@ namespace views::__adaptor
  static auto
  _S_iter_concept()
  {
-   if constexpr (random_access_range<_Vp>)
+   if constexpr (random_access_range<_Base>)
  return random_access_iterator_tag{};
-   else if constexpr (bidirectional_range<_Vp>)
+   else if constexpr (bidirectional_range<_Base>)
  return bidirectional_iterator_tag{};
-   else if constexpr (forward_range<_Vp>)
+   else if constexpr (forward_range<_Base>)
  return forward_iterator_tag{};
else
  return input_iterator_tag{};
-- 
2.32.0.93.g670b81a890



[PATCH] libstdc++: Implement LWG 3553 change to split_view

2021-06-17 Thread Patrick Palka via Gcc-patches
libstdc++-v3/ChangeLog:

* include/std/ranges (split_view::_OuterIter::value_type::begin):
Remove the non-const overload, and remove the copyable constraint
on the const overload as per LWG 3553.
---
 libstdc++-v3/include/std/ranges | 6 --
 1 file changed, 6 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index bf85b1629f0..49babe81437 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -2932,14 +2932,8 @@ namespace views::__adaptor
 
constexpr _InnerIter<_Const>
begin() const
- requires copyable<_OuterIter>
{ return _InnerIter<_Const>{_M_i}; }
 
-   constexpr _InnerIter<_Const>
-   begin()
- requires (!copyable<_OuterIter>)
-   { return _InnerIter<_Const>{std::move(_M_i)}; }
-
constexpr default_sentinel_t
end() const
{ return default_sentinel; }
-- 
2.32.0.93.g670b81a890



[PATCH] libstdc++: Implement LWG 3546 changes to common_iterator

2021-06-17 Thread Patrick Palka via Gcc-patches
libstdc++-v3/ChangeLog:

* include/bits/stl_iterator.h
(__detail::__common_iter_use_postfix_proxy): Add
move_constructible constraint as LWG 3546.
(common_iterator::__postfix_proxy): Adjust initializer of
_M_keep as per LWG 3546.
---
 libstdc++-v3/include/bits/stl_iterator.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index 6ec046b597b..7fe727d8093 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1672,7 +1672,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 template
   concept __common_iter_use_postfix_proxy
= (!requires (_It& __i) { { *__i++ } -> __can_reference; })
- && constructible_from, iter_reference_t<_It>>;
+ && constructible_from, iter_reference_t<_It>>
+ && move_constructible>;
   } // namespace __detail
 
   /// An iterator/sentinel adaptor for representing a non-common range.
@@ -1715,7 +1716,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   iter_value_t<_It> _M_keep;
 
   __postfix_proxy(iter_reference_t<_It>&& __x)
-  : _M_keep(std::move(__x)) { }
+  : _M_keep(std::forward>(__x)) { }
 
   friend class common_iterator;
 
-- 
2.32.0.93.g670b81a890



[PATCH v2] [MIPS]: add .module mipsREV to all output asm file

2021-06-17 Thread YunQiang Su
Currently, the asm output file for MIPS has no rev info.
It can make some trouble, for example:
  assembler is mips1 by default,
  gcc is fpxx by default.
To assemble the output of gcc -S, we have to pass -mips2
to assembler.

gcc/ChangeLog:

* gcc/config/mips/mips.c (mips_module_isa_name): New.
mips_file_start: add .module mipsREV to all asm output
---
 gcc/config/mips/mips.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 1f1475cf400..51cc70e6ceb 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -9877,6 +9877,40 @@ mips_mdebug_abi_name (void)
 }
 }
 
+static const char *
+mips_module_isa_name()
+{
+  if (ISA_MIPS1)
+return "mips1";
+  else if (ISA_MIPS2)
+return "mips2";
+  else if (ISA_MIPS3)
+return "mips3";
+  else if (ISA_MIPS4)
+return "mips4";
+  else if (ISA_MIPS32)
+return "mips32";
+  else if (ISA_MIPS32R2)
+return "mips32r2";
+  else if (ISA_MIPS32R3)
+return "mips32r3";
+  else if (ISA_MIPS32R5)
+return "mips32r5";
+  else if (ISA_MIPS32R6)
+return "mips32r6";
+  else if (ISA_MIPS64)
+return "mips64";
+  else if (ISA_MIPS64R2)
+return "mips64r2";
+  else if (ISA_MIPS64R3)
+return "mips64r3";
+  else if (ISA_MIPS64R5)
+return "mips64r5";
+  else if (ISA_MIPS64R6)
+return "mips64r6";
+  gcc_unreachable ();
+}
+
 /* Implement TARGET_ASM_FILE_START.  */
 
 static void
@@ -9908,6 +9942,9 @@ mips_file_start (void)
 fprintf (asm_out_file, "\t.nan\t%s\n",
 mips_nan == MIPS_IEEE_754_2008 ? "2008" : "legacy");
 
+  fprintf (asm_out_file, "\t.module\t%s\n",
+  mips_module_isa_name ());
+
 #ifdef HAVE_AS_DOT_MODULE
   /* Record the FP ABI.  See below for comments.  */
   if (TARGET_NO_FLOAT)
-- 
2.30.2



Re: [Patch] Add 'default' to -foffload=; document that flag [PR67300]

2021-06-17 Thread Tobias Burnus

On 17.06.21 23:57, Sandra Loosemore wrote:


On 6/17/21 1:40 PM, Jakub Jelinek wrote:

Could we introduce a different option which wouldn't imply enabling that
target:
-foffload-options==option


I think that works – in particular, if we do not document all
the legacy stuff but just how it should be used.

That includes not mentioning that disable and default can
be used in a list and that those can also take arguments.


I don't feel qualified to comment on the details of the behavior, but
separating the options and making them more orthogonal to one another
would certainly make things easier to document.  :-)


I fully concur.

Probably not fully polished, but I have attached a version for discussion.


One other thing I'd like to see in the docs is how to ask GCC what
offload targets it is configured to support by default.  This could be
put in a paragraph that also includes the language about how you need
to have the compilers for those offload targets installed too.


"gcc -v 2>&1 |grep OFFLOAD_TARGET_NAMES"  shows them.

Note that with the flags under discussion, you can modify
the output, e.g.
* "gcc -v -foffload=disable" removes it
* "gcc -v -foffload=nvptx-none" either gives an error (not supported) or
  just shows that single target.

 * * *

Installing:
Building oneself: "make install" – and everything is there

With a distributions, you need to find the name of the .rpm/.deb
package for the target your are interested in and then run
apt-get / yum / zypper / ...

Hence, when you normally build GCC as a user, for all configured offload
targets, their lto1 should be there - and if lto-wrapper cannot find it,
it aborts with a fatal error.
For distribution compilers, it usually just means that the optional
package is not installed – the missing lto1 should/is then just ignored,
That's the reason why GCC's configure script now has a flag
--enable-offload-defaulted to toggle between supporting optional packages
(distro use) and always errors (normal use).

If you want to know how to build it, have a lot of fun with incomplete
documentation and a look at https://gcc.gnu.org/wiki/Offloading or
at the SUSE/Debian/Red Hat build scripts or g-t-s – and expect that
you won't finish soon ...

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
Add 'default' to -foffload=; document that flag [PR67300]

As -foffload={options,targets,targets=options} is very convoluted,
it has been split into -foffload=targets (supporting the old syntax
for backward compatibilty) and -foffload-options={options,target=options}.

Only the new syntax is documented.

Additionally, -foffload=default is supported, which can reset the
devices after -foffload=disable / -foffload=targets to the default,
if needed.

 gcc/common.opt |  10 ++-
 gcc/doc/invoke.texi|  41 +
 gcc/gcc.c  | 100 +
 gcc/lto-opts.c |   3 +-
 gcc/lto-wrapper.c  |  10 +--
 gcc/opts.c |   2 +-
 .../testsuite/libgomp.c-c++-common/reduction-16.c  |   2 +-
 .../testsuite/libgomp.c-c++-common/reduction-5.c   |   2 +-
 .../testsuite/libgomp.c-c++-common/reduction-6.c   |   2 +-
 libgomp/testsuite/libgomp.c/target-44.c|   2 +-
 10 files changed, 140 insertions(+), 34 deletions(-)

diff --git a/gcc/common.opt b/gcc/common.opt
index a1353e06bdc..a695a8c5964 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2095,9 +2095,15 @@ fnon-call-exceptions
 Common Var(flag_non_call_exceptions) Optimization
 Support synchronous non-call exceptions.
 
+; -foffload= is documented
+; -foffload== is supported for backward compatibility
 foffload=
-Common Driver Joined MissingArgError(options or targets missing after %qs)
--foffload==	Specify offloading targets and options for them.
+Driver Joined MissingArgError(targets missing after %qs)
+-foffload=	Specify offloading targets
+
+foffload-options=
+Common Driver Joined MissingArgError(options or targets=options missing after %qs)
+-foffload==	Specify options for the offloading targets
 
 foffload-abi=
 Common Joined RejectNegative Enum(offload_abi) Var(flag_offload_abi) Init(OFFLOAD_ABI_UNSET)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index af2ce189fae..82993fa2c1d 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -204,6 +204,7 @@ in the following sections.
 -fhosted  -ffreestanding @gol
 -fopenacc  -fopenacc-dim=@var{geom} @gol
 -fopenmp  -fopenmp-simd @gol
+-foffload=@var{arg} -foffload-options=@var{arg} @gol
 -fms-extensions  -fplan9-extensions  -fsso-struct=@var{endianness} @gol
 -fallow-single-precision  -fcond-mismatch  -flax-vector-conversions @gol
 -fsigned-bitfields  -fsigned-char @gol
@@ -2639,6 +2640,46 @@ Enable handling of 

[PATCH 2/3 V2] Fix IEEE 128-bit min/max test.

2021-06-17 Thread Michael Meissner via Gcc-patches
Here is a replacement patch.  Can I check this into the master branch, and
eventually backport it to GCC 11?

[PATCH] Fix IEEE 128-bit min/max test.

This patch fixes the float128-minmax.c test so that it can accommodate the
generation of xsmincqp and xsmaxcqp instructions on power10.  I changed
the effective target from 'float128' to 'ppc_float128_hw', since this
needs the IEEE 128-bit float hardware support.  Changing to use
'ppc_float128_hw' allows the 'lp64' test to be dropped.  The 'lp64' test
was needed because big endian 32-bit code cannot enable the IEEE 128-bit
floating point instructions.

gcc/testsuite/
2021-06-17  Michael Meissner  

* gcc.target/powerpc/float128-minmax.c: Adjust expected code for
power10.
* lib/target-supports.exp (check_effective_target_has_arch_pwr10):
New target support.
---
 gcc/testsuite/gcc.target/powerpc/float128-minmax.c | 10 ++
 gcc/testsuite/lib/target-supports.exp  | 10 ++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c 
b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
index fe397518f2f..b0e6bd39873 100644
--- a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
+++ b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
@@ -1,6 +1,5 @@
-/* { dg-do compile { target lp64 } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-require-effective-target float128 } */
+/* { dg-require-effective-target ppc_float128_hw } */
 /* { dg-options "-mpower9-vector -O2 -ffast-math" } */
 
 #ifndef TYPE
@@ -12,5 +11,8 @@
 TYPE f128_min (TYPE a, TYPE b) { return __builtin_fminf128 (a, b); }
 TYPE f128_max (TYPE a, TYPE b) { return __builtin_fmaxf128 (a, b); }
 
-/* { dg-final { scan-assembler {\mxscmpuqp\M} } } */
-/* { dg-final { scan-assembler-not {\mbl\M}   } } */
+/* Adjust code power10 which has native min/max instructions.  */
+/* { dg-final { scan-assembler-times {\mxscmpuqp\M} 2 { target { ! 
has_arch_pwr10 } } } } */
+/* { dg-final { scan-assembler-times {\mxsmincqp\M} 1 { target has_arch_pwr10 
} } } */
+/* { dg-final { scan-assembler-times {\mxsmaxcqp\M} 1 { target has_arch_pwr10 
} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index 7f78c5593ac..789723fb287 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -6127,6 +6127,16 @@ proc check_effective_target_has_arch_pwr9 { } {
}]
 }
 
+proc check_effective_target_has_arch_pwr10 { } {
+   return [check_no_compiler_messages arch_pwr10 assembly {
+   #ifndef _ARCH_PWR10
+   #error does not have power10 support.
+   #else
+   /* "has power10 support" */
+   #endif
+   }]
+}
+
 # Return 1 if this is a PowerPC target supporting -mcpu=power10.
 # Limit this to 64-bit linux systems for now until other targets support
 # power10.
-- 
2.31.1


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


[PATCH] Modula-2 into the GCC tree on master

2021-06-17 Thread Gaius Mulley via Gcc-patches



Hello Richard, David, Matthias and GCC Steering Committee,

here are a set of patches which merge the gm2 front end into the
GCC tree.  The patches have been bootstrapped under aarch64 GNU/Linux
Debian Stretch using make -j 4, x86_64 GNU/Linux Debian Stretch built
using make -j 24 and also under x86_64 GNU/Linux Debian Buster using
make -j 4.

Tested on Debian Stretch x86_64
===

built GCC bootstrap 3 times:

1.  built vanilla GCC (enabling bootstrap) enabling front ends:
c,c++,go,d,fortran and ran the regression tests.  (make -j 4).

2.  the patches below were applied and associated tarball untarred.
The same front ends c,c++,go,d,fortran (again building from
bootstrap) were enabled (no m2) and ran the regression tests.
There were no changes to the regression test results between 1 and
2.

3.  Then it was rebuilt (from bootstrap) enabling the front ends
c,c++,go,d,fortran,m2 and ran the
regression tests and again no extra failures were seen.

4.  It has been built in source tree (./configure --enable-languages=m2)
and out of source tree with make -j 24.

Built on Debian Buster x86_64
=

1.  built vanilla GCC (enabling bootstrap) enabling front ends:
c,c++,go,d,fortran and ran the regression tests.

2.  the patches below were applied and associated tarball untarred.
The same front ends c,c++,go,d,fortran (again building from
bootstrap) were enabled (no m2) and ran the regression tests.
There were no changes to the regression test results between 1 and
2.

3.  Then it was rebuilt (from bootstrap) enabling the front ends
c,c++,go,d,fortran,m2 and ran the
regression tests and again no extra failures were seen.

Built a patched tree enabling bootstrap make -j 4 for front ends
c,c++,m2 all compiled and bootstrapped.

How to merge


1.  apply patches below to the master GCC tree.

2.  cd gcc-git-top

wget http://floppsie.comp.glam.ac.uk/download/c/gm2-front-end-20210617-tar.gz

tar zxf gm2-front-end-20210617-tar.gz
rm gm2-front-end-20210617-tar.gz
# new directories gm2tools, libgm2, gcc/m2, gcc/testsuite/gm2 are created
# and populated.  Documentation in gcc/doc and testsuite/lib contains some
# Modula-2 dejagnu scripts.

3.  cd gcc-git-top
autogen Makefile.def
autoconf
cd libgm2
/bin/sh ./autogen.sh
cd ../gm2tools
/bin/sh ./autogen.sh

Thank you Richard for the extensive feedback from the last time the
patches were posted.  I've gone though your points and addressed them
(I think).

> It looks like libgm2 is built independently on whether m2 is enabled
> or not?  I'd like to see a while-listing of supported targets like
> done for example for libgomp via configure.tgt or for libgo (see
> toplevel configure).

I've added a test in libgm2/configure.ac to restict the building of
libgm2 - or to restrict it to building libm2min which is a near zero
runtime library.  It restricts on host and target and can easily be
changed.

> The driver changes have been posted and reviewed previously but I
> didn't see any real OK there but motivational questions - they never
> were posted together with the m2 driver portion (I guess that would
> be gcc/m2/gm2spec.c in the tarball).

yes gcc/m2/gm2spec.c.

> I've not seen reviews or postings (besides as tarball) of the
> frontend or the library (but I don't remember seeing extensive
> reviews of other languages frontends or runtime portions at the
> point of their inclusion - still the glueing to the middle-end
> should get the chance to be reviewed).

the glue code is in m2/gm2-gcc/*.[ch].  The filenames adopt a similar
naming scheme to other front ends: m2/gm2-gcc/m2decl.c for
declarations, m2/gm2-gcc/m2expr.c for expressions etc.  The exported
names are prefixed by the module name so that the code can be linked
against the Modula-2 version with an appropriate definition module
(for example m2/gm2-gcc/m2expr.def).

> I've tried to find my way through gcc/m2 but am quite lost in the
> number of subdirectories.

I've added a README in each directory giving an overview of the
contents.

> I do see in gm2-lang.c and elsewhere inclusion of system headers
> outside of system.h which is going to be a portability problem.

I've changed nearly all headers to use "config.h", "system.h" and
friends and modified the bootstrap tool to automatically generate
these gcc header includes.

> From the parse_file langhook we eventually dispatch to
> init_PerCompilationInit which looks like a Modula-2 scaffolding
> file?

yes indeed.

> Is the compiler written in Modula-2?  It's not clear what
> parts make up the interface to the GCC middle-end.

yes most of the compiler and libraries are written in Modula-2 there
is some interface code written in C/C++.  In particular, for the
compiler, the directory m2/gm2-gcc contains all the tree cr

Re: [Patch] Add 'default' to -foffload=; document that flag [PR67300]

2021-06-17 Thread Sandra Loosemore

On 6/17/21 1:40 PM, Jakub Jelinek wrote:

On Thu, Jun 17, 2021 at 09:28:00PM +0200, Tobias Burnus wrote:

I am not sure whether I fully agree with this or not. However:

Let's propose something radical, which probably won't break any real-world
code, avoids the need to add a new -foffload= keyword and is
also intuitive to the user:

* -foffload==-option

Suggestion: This no longer affects the list of enabled targets. As by default
all targets are enabled, this one will (kept) be(en) enabled (but might
silently fail if the target lto1 is not installed).

* -foffload=disable  and -foffload=

This is the only way to modify the list of supported offload devices to those
specified. By adding a triplet explicitly, it will give an error via lto1.

That will solve all issues, possibly except for
   -foffload=-lm -foffload=nxpt-none=-latomic -foffload=amdgcn-amdhsa
some might find it surprising that nvptx offloading will be disabled,
but others might find it natural.


Could we introduce a different option which wouldn't imply enabling that
target:
-foffload-options==option
and make
-foffload==option
imply (expand in the driver)
-foffload-options==option -foffload=
?
That would be mostly backwards compatible, but would allow users to specify 
options
separately from the enabled target list.
The  in the above cases couldn't include disable or
default, but the -foffload= case could, and disable
(either in the list or separately) would simply disable all targets (even
those enabled earlier), while default would reset the list to the default
(basically cancel all previous non-options -foffload= options).
And the -foffload-options= would accumulate in the order given on the
command line.


I don't feel qualified to comment on the details of the behavior, but 
separating the options and making them more orthogonal to one another 
would certainly make things easier to document.  :-)


One other thing I'd like to see in the docs is how to ask GCC what 
offload targets it is configured to support by default.  This could be 
put in a paragraph that also includes the language about how you need to 
have the compilers for those offload targets installed too.


-Sandra


[committed] libstdc++: Simplify constexpr checks in std::char_traits [PR 91488]

2021-06-17 Thread Jonathan Wakely via Gcc-patches
This removes the helper functions added by r8-1294 to detect whether the
char_traits member functions can be evaluated at compile time. Instead,
we can just use __builtin_constant_evaluated directly, which is well
supported by non-GCC compilers by now.

As a result, there is a chance that those members will no longer be
usable in constant expressions when using old versions of non-GCC
compilers. Make the relevant feature test macros depend on the
availability of __builtin_constant_evaluated, so they are defined only
when the feature is actualyl available.

The new testcase from the PR is added to the libitm testsuite, because
that's where we can be sure it's OK to use the -fgnu-tm option.

Signed-off-by: Jonathan Wakely 

PR libstdc++/91488

libstdc++-v3/ChangeLog:

* include/bits/basic_string.h (__cpp_lib_constexpr_string): Only
define when is_constant_evaluated is available.
* include/bits/char_traits.h (__cpp_lib_constexpr_char_traits):
Likewise.
(__constant_string_p, __constant_array_p): Remove.
(char_traits): Use is_constant_evaluated directly.
* include/std/version (__cpp_lib_constexpr_char_traits)
(__cpp_lib_constexpr_string): Only define when
is_constant_evaluated is available.

libitm/ChangeLog:

* testsuite/libitm.c++/libstdc++-pr91488.C: New test.

Tested powerpc64le-linux. Committed to trunk.

commit b376b1ef38971b84975ad1540bf5d2ae0b924e76
Author: Jonathan Wakely 
Date:   Thu Jun 17 14:11:22 2021

libstdc++: Simplify constexpr checks in std::char_traits [PR 91488]

This removes the helper functions added by r8-1294 to detect whether the
char_traits member functions can be evaluated at compile time. Instead,
we can just use __builtin_constant_evaluated directly, which is well
supported by non-GCC compilers by now.

As a result, there is a chance that those members will no longer be
usable in constant expressions when using old versions of non-GCC
compilers. Make the relevant feature test macros depend on the
availability of __builtin_constant_evaluated, so they are defined only
when the feature is actualyl available.

The new testcase from the PR is added to the libitm testsuite, because
that's where we can be sure it's OK to use the -fgnu-tm option.

Signed-off-by: Jonathan Wakely 

PR libstdc++/91488

libstdc++-v3/ChangeLog:

* include/bits/basic_string.h (__cpp_lib_constexpr_string): Only
define when is_constant_evaluated is available.
* include/bits/char_traits.h (__cpp_lib_constexpr_char_traits):
Likewise.
(__constant_string_p, __constant_array_p): Remove.
(char_traits): Use is_constant_evaluated directly.
* include/std/version (__cpp_lib_constexpr_char_traits)
(__cpp_lib_constexpr_string): Only define when
is_constant_evaluated is available.

libitm/ChangeLog:

* testsuite/libitm.c++/libstdc++-pr91488.C: New test.

diff --git a/libitm/testsuite/libitm.c++/libstdc++-pr91488.C 
b/libitm/testsuite/libitm.c++/libstdc++-pr91488.C
new file mode 100644
index 000..e9e82bd1ce2
--- /dev/null
+++ b/libitm/testsuite/libitm.c++/libstdc++-pr91488.C
@@ -0,0 +1,9 @@
+// PR libstdc++/91488 "inlining failed in call to always_inline"
+// { dg-do run }
+// { dg-additional-options "-O1" }
+
+#include 
+
+int main() {
+return std::char_traits::length("");
+}
diff --git a/libstdc++-v3/include/bits/basic_string.h 
b/libstdc++-v3/include/bits/basic_string.h
index 84356adc7ae..9911d4deb72 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -52,12 +52,13 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if __cplusplus == 201703L
+#ifdef __cpp_lib_is_constant_evaluated
+// Support P1032R1 in C++20 (but not P0980R1 yet).
+# define __cpp_lib_constexpr_string 201811L
+#elif __cplusplus >= 201703L && _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
 // Support P0426R1 changes to char_traits in C++17.
 # define __cpp_lib_constexpr_string 201611L
 #elif __cplusplus > 201703L
-// Also support P1032R1 in C++20 (but not P0980R1 yet).
-# define __cpp_lib_constexpr_string 201811L
 #endif
 
 #if _GLIBCXX_USE_CXX11_ABI
diff --git a/libstdc++-v3/include/bits/char_traits.h 
b/libstdc++-v3/include/bits/char_traits.h
index 95fb7c1ee89..3da6e28a513 100644
--- a/libstdc++-v3/include/bits/char_traits.h
+++ b/libstdc++-v3/include/bits/char_traits.h
@@ -235,62 +235,12 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if __cplusplus >= 201703L
-
-#if __cplusplus == 201703L
-// Unofficial macro indicating P0426R1 support
-# define __cpp_lib_constexpr_char_traits 201611L
-#else
-// Also support P1032R1 in C++20
+#ifdef __cpp_lib_is_constant_evaluated
+// Unofficial macro indicating P1032R1 support 

Re: [PATCH] gcc/configure.ac: fix register issue for global_load assembler functions

2021-06-17 Thread Joseph Myers
On Thu, 17 Jun 2021, Marcel Vollweiler wrote:

> Thank you for your proposals. I adapted configure.ac and gcn.c
> accordingly (similar to the GATHER_STATISTICS example).

Thanks, the configure changes in this version are OK.

-- 
Joseph S. Myers
jos...@codesourcery.com


[pushed] c++: deleted after first declaration [PR101106]

2021-06-17 Thread Jason Merrill via Gcc-patches
An explicitly deleted function must be deleted on its first declaration.  We
were diagnosing this error only with -Wpedantic, but always giving the
"previous declaration" note.  This patch removes the -Wpedantic dependency
and also makes the note depend on the previous diagnostic.

Tested x86_64-pc-linux-gnu, applying to trunk.

PR c++/101106

gcc/cp/ChangeLog:

* decl.c (duplicate_decls): Make 'deleted after first declaration'
pedwarn on by default.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/deleted15.C: New test.
---
 gcc/cp/decl.c  | 9 -
 gcc/testsuite/g++.dg/cpp0x/deleted15.C | 6 ++
 2 files changed, 10 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/deleted15.C

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 02772e94763..66bcc4be84d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2170,11 +2170,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool 
hiding, bool was_hidden)
  if (DECL_DELETED_FN (newdecl))
{
  auto_diagnostic_group d;
- pedwarn (newdecl_loc, OPT_Wpedantic,
-  "deleted definition of %qD is not first declaration",
-  newdecl);
- inform (olddecl_loc,
- "previous declaration of %qD", olddecl);
+ if (pedwarn (newdecl_loc, 0, "deleted definition of %qD "
+  "is not first declaration", newdecl))
+   inform (olddecl_loc,
+   "previous declaration of %qD", olddecl);
}
  DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/deleted15.C 
b/gcc/testsuite/g++.dg/cpp0x/deleted15.C
new file mode 100644
index 000..06d2171d6d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/deleted15.C
@@ -0,0 +1,6 @@
+// PR c++/101106
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+int f();
+int f() = delete;  // { dg-message "not first declaration" }

base-commit: 58e3b17f4c42d050a1768b025712e6d18bcb76ae
-- 
2.27.0



Re: [PATCH 2/3] Fix IEEE 128-bit min/max test.

2021-06-17 Thread Michael Meissner via Gcc-patches
On Thu, Jun 17, 2021 at 01:11:58PM -0500, Segher Boessenkool wrote:
> On Tue, Jun 08, 2021 at 08:22:40PM -0400, Michael Meissner wrote:
> > 
> > * gcc.target/powerpc/float128-minmax.c: Adjust expected code for
> > power10.
> > * lib/target-supports.exp (check_effective_target_has_arch_pwr10):
> > New target support.
> > ---
> >  gcc/testsuite/gcc.target/powerpc/float128-minmax.c |  8 +---
> >  gcc/testsuite/lib/target-supports.exp  | 10 ++
> >  2 files changed, 15 insertions(+), 3 deletions(-)
> > 
> > diff --git a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c 
> > b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
> > index fe397518f2f..a7d3a3a0b3e 100644
> > --- a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
> > +++ b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
> > @@ -1,6 +1,5 @@
> > -/* { dg-do compile { target lp64 } } */
> 
> Does that work?  Why was it there before?

The lp64 eliminates 32-bit, which does not support hardware IEEE 128-bit due to
the lack of TImode.  The test was written before the ppc_float128_hw test.  Now
that we have ppc_float128_hw, we don't need an explicit lp64.
 
> >  /* { dg-require-effective-target powerpc_p9vector_ok } */
> > -/* { dg-require-effective-target float128 } */
> > +/* { dg-require-effective-target ppc_float128_hw } */
> 
> Why is it okay to no longer run this test where it ran before?

The ppc_float128_hw test is a more precise test than just float128 and power9.
For 64-bit, it doesn't matter, but it allows us to drop the lp64 test.
 
> > -/* { dg-final { scan-assembler {\mxscmpuqp\M} } } */
> > +/* Adjust code power10 which has native min/max instructions.  */
> > +/* { dg-final { scan-assembler {\mxscmpuqp\M} { target { ! 
> > has_arch_pwr10 } } } } */
> 
> You need scan-assembler-times here?  (Not that it had that before this
> patch, of course).
> 
> > +/* { dg-final { scan-assembler {\mxsmincqp\M} { target {   
> > has_arch_pwr10 } } } } */
> > +/* { dg-final { scan-assembler {\mxsmaxcqp\M} { target {   
> > has_arch_pwr10 } } } } */
> 
> You can write just  { target has_arch_pwr10 }  here, I think?  Please do
> so (if that works, I haven't actually tested it :-) )
> 
> 
> Segher

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


Re: [Patch] Add 'default' to -foffload=; document that flag [PR67300]

2021-06-17 Thread Jakub Jelinek via Gcc-patches
On Thu, Jun 17, 2021 at 09:28:00PM +0200, Tobias Burnus wrote:
> I am not sure whether I fully agree with this or not. However:
> 
> Let's propose something radical, which probably won't break any real-world
> code, avoids the need to add a new -foffload= keyword and is
> also intuitive to the user:
> 
> * -foffload==-option
> 
> Suggestion: This no longer affects the list of enabled targets. As by default
> all targets are enabled, this one will (kept) be(en) enabled (but might
> silently fail if the target lto1 is not installed).
> 
> * -foffload=disable  and -foffload=
> 
> This is the only way to modify the list of supported offload devices to those
> specified. By adding a triplet explicitly, it will give an error via lto1.
> 
> That will solve all issues, possibly except for
>   -foffload=-lm -foffload=nxpt-none=-latomic -foffload=amdgcn-amdhsa
> some might find it surprising that nvptx offloading will be disabled,
> but others might find it natural.

Could we introduce a different option which wouldn't imply enabling that
target:
-foffload-options==option
and make
-foffload==option
imply (expand in the driver)
-foffload-options==option -foffload=
?
That would be mostly backwards compatible, but would allow users to specify 
options
separately from the enabled target list.
The  in the above cases couldn't include disable or
default, but the -foffload= case could, and disable
(either in the list or separately) would simply disable all targets (even
those enabled earlier), while default would reset the list to the default
(basically cancel all previous non-options -foffload= options).
And the -foffload-options= would accumulate in the order given on the
command line.

Jakub



[Patch, fortran V3] PR fortran/100683 - Array initialization refuses valid

2021-06-17 Thread José Rui Faustino de Sousa via Gcc-patches

Hi all!

Update to a proposed patch to:

PR100683 - Array initialization refuses valid

due to more errors being found...

Patch tested only on x86_64-pc-linux-gnu.

Add call to simplify expression before parsing *and* check 
*appropriately* if the expression is still an array after simplification.


Add two more situations (already present in the original PR) to 
pr87993.f90 to catch the kind of error I was making.


Thank you very much.

Best regards,
José Rui

Fortran: Fix bogus error

gcc/fortran/ChangeLog:

PR fortran/100683
* resolve.c (gfc_resolve_expr): Add call to gfc_simplify_expr.

gcc/testsuite/ChangeLog:

PR fortran/100683
* gfortran.dg/pr87993.f90: increased test coverage.
* gfortran.dg/PR100683.f90: New test.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 45c3ad3..01a2977 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -7137,7 +7137,12 @@ gfc_resolve_expr (gfc_expr *e)
   /* Also try to expand a constructor.  */
   if (t)
 	{
+	  t = gfc_simplify_expr (e, 1);
+	  if (!t)
+	break;
 	  gfc_expression_rank (e);
+	  if (e->expr_type != EXPR_ARRAY)
+	break;
 	  if (gfc_is_constant_expr (e) || gfc_is_expandable_expr (e))
 	gfc_expand_constructor (e, false);
 	}
diff --git a/gcc/testsuite/gfortran.dg/PR100683.f90 b/gcc/testsuite/gfortran.dg/PR100683.f90
new file mode 100644
index 000..6929bb5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/PR100683.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+!
+! Test the fix for PR100683
+! 
+
+program main_p
+
+  implicit none
+
+  integer:: i
+  integer, parameter :: n = 11
+  integer, parameter :: u(*) = [(i, i=1,n)]
+
+  type :: foo_t
+integer :: i
+  end type foo_t
+
+  type, extends(foo_t) :: bar_t
+integer :: a(n)
+  end type bar_t
+  
+  type(bar_t), parameter :: a(*) = [(bar_t(i, u), i=1,n)]
+  type(bar_t):: b(n) = [(bar_t(i, u), i=1,n)]
+
+  if(any(a(:)%i/=u))   stop 1
+  do i = 1, n
+if(any(a(i)%a/=u)) stop 2
+  end do
+  if(any(b(:)%i/=u))   stop 3
+  do i = 1, n
+if(any(b(i)%a/=u)) stop 4
+  end do
+  stop
+
+end program main_p
+
diff --git a/gcc/testsuite/gfortran.dg/pr87993.f90 b/gcc/testsuite/gfortran.dg/pr87993.f90
index 96d353d..abc6d0d 100644
--- a/gcc/testsuite/gfortran.dg/pr87993.f90
+++ b/gcc/testsuite/gfortran.dg/pr87993.f90
@@ -2,7 +2,15 @@
 ! Code contributed by Gerhard Steinmetz 
 program p
integer, parameter :: a(2) = 1
-   integer, parameter :: b = a%kind
+   character, parameter :: b(2) = "X"
+   integer, parameter :: i = a%kind
+   integer, parameter :: j = a(2)%kind
+   integer, parameter :: k = b%kind
+   integer, parameter :: l = b(2)%kind
if (any(a /= 1)) stop 1
-   if (b /= kind(a)) stop 2
+   if (any(b /= "X")) stop 2
+   if (i /= kind(a)) stop 3
+   if (j /= kind(a)) stop 4
+   if (k /= kind(b)) stop 5
+   if (l /= kind(b)) stop 6
 end


Re: [Patch] Add 'default' to -foffload=; document that flag [PR67300]

2021-06-17 Thread Tobias Burnus

On 17.06.21 19:50, Jakub Jelinek wrote:


On Thu, Jun 17, 2021 at 11:41:39AM -0600, Sandra Loosemore wrote:

I think it would useful to add an example with a target list and
multiple options since I think the syntax looks pretty hairy.


I fully concur that -foffload= is a mess trying to achieve too many
things at the same time. [Hence, I kept rephrasing the description
without reaching a good wording.]

In terms of real-world usage, I think something like the following
covers all real-world needs:

-foffload=disable
-foffload=-latomic -foffload=-lm
-foffload="-lgfortran -lm" -foffload=nvptx-none=-latomic
-foffload=-lm -foffload=nvptx-none=-latomic 
-foffload=amdgcn-amdhsa=-march=gfx906
-foffload=-fdump-tree-all

Possibly with -foffload=default added to item 3 + 4, but cf. below.


Hmmm, I had started to put together some comments on
grammar/punctuation/markup on the first version before the second iteration
showed up in my mailbox, but more critically I could not figure out whether
-foffload=default is supposed to be exactly identical to the default
behavior; if it isn't, it should be, or -foffload=default ought to be
renamed.  So let's get that sorted out first.  I suggest reorganizing the

Yeah.  If we want for --enable-offload-default also all configured targets,
we could add another keyword for it (all), but I'm not sure it would be
useful, because whenever it would be different from default it would mean
the linking would fail because one or more offloading targets that were
configured isn't supported (installed).


I am not sure whether I fully agree with this or not. However:

Let's propose something radical, which probably won't break any real-world
code, avoids the need to add a new -foffload= keyword and is
also intuitive to the user:

* -foffload==-option

Suggestion: This no longer affects the list of enabled targets. As by default
all targets are enabled, this one will (kept) be(en) enabled (but might
silently fail if the target lto1 is not installed).

* -foffload=disable  and -foffload=

This is the only way to modify the list of supported offload devices to those
specified. By adding a triplet explicitly, it will give an error via lto1.

That will solve all issues, possibly except for
  -foffload=-lm -foffload=nxpt-none=-latomic -foffload=amdgcn-amdhsa
some might find it surprising that nvptx offloading will be disabled,
but others might find it natural.


Hence: Do you think this change makes sense? It looks somewhat consistent,
avoids a new -foffload= flag etc.?
It also would solve the testsuite issue without needing to add
a new flag and a comment explaining why the flag is needed.


What do you think? It breaks backward compatibility, but I am not
sure anyone way relying on the current behavior.

  * * *

Compared to the current version, I would also give an error if
 -foffload=
contains 'disable' and any other target entry (including 'disable')
and for '-foffload=disable= – as both does not make any sense.

This does not really change the semantic but avoids odd code.


-foffload= will then restrict it to certain
targets & by specifying them explicitly, lto1 will still give
an error when not available.


And similarly figure out what happens with the optional flags, if they are
gathered from all the -foffload= options that refer to a particular target,
or taken from the last -foffload option that mentions that target, something
else.


Currently,
  -foffload=-lm -foffload=nvptx-none=-latomic -foffload=-lgfortran
works, taking the arguments "-lm -lgfortran" for all but nvptx-none
and "-lm -latomic -lgfortran" for nvptx-none. I think this really needs
to continue to work.

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf


Re: [PATCH 2/3] Fix IEEE 128-bit min/max test.

2021-06-17 Thread Michael Meissner via Gcc-patches
On Thu, Jun 17, 2021 at 01:11:58PM -0500, Segher Boessenkool wrote:
> On Tue, Jun 08, 2021 at 08:22:40PM -0400, Michael Meissner wrote:
> > 
> > * gcc.target/powerpc/float128-minmax.c: Adjust expected code for
> > power10.
> > * lib/target-supports.exp (check_effective_target_has_arch_pwr10):
> > New target support.
> > ---
> >  gcc/testsuite/gcc.target/powerpc/float128-minmax.c |  8 +---
> >  gcc/testsuite/lib/target-supports.exp  | 10 ++
> >  2 files changed, 15 insertions(+), 3 deletions(-)
> > 
> > diff --git a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c 
> > b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
> > index fe397518f2f..a7d3a3a0b3e 100644
> > --- a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
> > +++ b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
> > @@ -1,6 +1,5 @@
> > -/* { dg-do compile { target lp64 } } */
> 
> Does that work?  Why was it there before?
> 
> >  /* { dg-require-effective-target powerpc_p9vector_ok } */
> > -/* { dg-require-effective-target float128 } */
> > +/* { dg-require-effective-target ppc_float128_hw } */
> 
> Why is it okay to no longer run this test where it ran before?

I was just being more precise.

> > -/* { dg-final { scan-assembler {\mxscmpuqp\M} } } */
> > +/* Adjust code power10 which has native min/max instructions.  */
> > +/* { dg-final { scan-assembler {\mxscmpuqp\M} { target { ! 
> > has_arch_pwr10 } } } } */
> 
> You need scan-assembler-times here?  (Not that it had that before this
> patch, of course).

I can change it to scan-assembler-times.

> > +/* { dg-final { scan-assembler {\mxsmincqp\M} { target {   
> > has_arch_pwr10 } } } } */
> > +/* { dg-final { scan-assembler {\mxsmaxcqp\M} { target {   
> > has_arch_pwr10 } } } } */
> 
> You can write just  { target has_arch_pwr10 }  here, I think?  Please do
> so (if that works, I haven't actually tested it :-) )

I thought so originally, but it didn't like it, so I added the extra {}'s.  But
I can try it again.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


Re: [PATCH 1/3] Add IEEE 128-bit min/max support on PowerPC.

2021-06-17 Thread Michael Meissner via Gcc-patches
On Thu, Jun 17, 2021 at 12:39:04PM -0500, Segher Boessenkool wrote:
> On Tue, Jun 08, 2021 at 08:21:25PM -0400, Michael Meissner wrote:
> > GCC will not convert ternary operations into using min/max instructions
> > provided in this patch unless the user uses -Ofast or similar switches due 
> > to
> > issues with NaNs.
> 
> It will not do it because it is *incorrect* to do :-)
> 
> (The RTL operators smin/smax are undefined for any NaN inputs (unless
> both are the same bit pattern), and for different sign zeroes; it isn't
> only NaNs even).
> 
> > gcc/
> > 2021-06-08  Michael Meissner  
> > 
> > * config/rs6000/rs6000.c (rs6000_emit_minmax): Add support for ISA
> > 3.1 IEEE 128-bit floating point xsmaxcqp and xsmincqp
> > instructions.
> 
> Please don't randomly break lines.
> 
> > --- a/gcc/config/rs6000/rs6000.c
> > +++ b/gcc/config/rs6000/rs6000.c
> > @@ -16103,7 +16103,8 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, 
> > rtx op0, rtx op1)
> >/* VSX/altivec have direct min/max insns.  */
> >if ((code == SMAX || code == SMIN)
> >&& (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
> > - || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode
> > + || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))
> > + || (TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode
> 
> The actual insns only check TARGET_POWER10 (so no TARGET_FLOAT128_HW).
> Which is right, this or that?

It should include TARGET_FLOAT128_HW.  The problem area is a power10 running in
big endian mode and running 32-bit code.  Because we don't have TImode, we
can't enable the IEEE 128-bit hardware instructions.  And because we don't have
GLIBC support, we don't enable the FLOAT128 stuff by default on big endian.

> > +/* { dg-require-effective-target ppc_float128_hw } */
> > +/* { dg-require-effective-target power10_ok } */
> > +/* { dg-options "-mdejagnu-cpu=power10 -O2 -ffast-math" } */
> 
> In testcases we can assume that float128_hw is set whenever we have a
> p10; we don't manually disable it to make live hard for ourselves ;-)

Again, I put it in case somebody builds a BE power10 compiler.

> We could disallow disabling QP float separately from all other float.
> We will still need to test if float is enabled at all so it won't help
> all that much immediately, alas.
> 
> With that TARGET_POWER10 condition fixed: okay for trunk, and for 11
> once it is tested for trunk on all systems.  Thanks!

Thanks.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


Re: [PATCH 3/6] return auto_vec from get_loop_hot_path

2021-06-17 Thread Christophe Lyon via Gcc-patches
On Thu, Jun 17, 2021 at 4:53 PM Trevor Saunders 
wrote:

> On Thu, Jun 17, 2021 at 03:48:28PM +0200, Christophe Lyon wrote:
> > On Tue, 15 Jun 2021 at 08:47, Richard Biener via Gcc-patches
> >  wrote:
> > >
> > > On Tue, Jun 15, 2021 at 8:01 AM Trevor Saunders 
> wrote:
> > > >
> > > > This ensures callers take ownership of the returned vector.
> > > >
> > > > Signed-off-by: Trevor Saunders 
> > > >
> > > > bootstrapped and regtested on x86_64-linux-gnu, ok?
> > >
> > > OK.
> >
> > Since this was committed, I've noticed build errors (for
> cross-compilers):
> >
> /tmp/9562118_6.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cfgloopanal.c:
> > In function 'auto_vec get_loop_hot_path(const
> > loop*)':
> >
> /tmp/9562118_6.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cfgloopanal.c:528:10:
> > error: could not convert 'path' from 'vec' to
> > 'auto_vec'
> >return path;
> >   ^
> >
> /tmp/9562118_6.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cfgloopanal.c:529:1:
> > warning: control reaches end of non-void function [-Wreturn-type]
> >  }
> >  ^
> >
> > I'm using gcc-4.8.5 as host compiler
>
> Ah, interesting, I believe the following patch corrects the oversight
> here.  Its interesting that newer compilers use the auto_vec(vec &&)
> constructor to fix this up but 4.8.5 refuses.
>
> diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
> index fdd8d3f43fe..2db46c81036 100644
> --- a/gcc/cfgloopanal.c
> +++ b/gcc/cfgloopanal.c
> @@ -504,7 +504,7 @@ auto_vec
>  get_loop_hot_path (const class loop *loop)
>   {
>  basic_block bb = loop->header;
>  -  vec path = vNULL;
>  +  auto_vec path;
> bitmap visited = BITMAP_ALLOC (NULL);
>
>while (true)
>
>Sorry about the trouble, will commit the above as obvious if
>it bootstraps.
>
>
Thanks, I confirm the builds complete again.

Christophe


>Trev
>
> >
> > Christophe
> >
> > >
> > > > gcc/ChangeLog:
> > > >
> > > > * cfgloop.h (get_loop_hot_path): Return
> auto_vec.
> > > > * cfgloopanal.c (get_loop_hot_path): Likewise.
> > > > * tree-ssa-loop-ivcanon.c (tree_estimate_loop_size):
> Likewise.
> > > > ---
> > > >  gcc/cfgloop.h   | 2 +-
> > > >  gcc/cfgloopanal.c   | 2 +-
> > > >  gcc/tree-ssa-loop-ivcanon.c | 5 ++---
> > > >  3 files changed, 4 insertions(+), 5 deletions(-)
> > > >
> > > > diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
> > > > index 113241da130..5e699276c88 100644
> > > > --- a/gcc/cfgloop.h
> > > > +++ b/gcc/cfgloop.h
> > > > @@ -840,7 +840,7 @@ enum
> > > >
> > > >  extern void doloop_optimize_loops (void);
> > > >  extern void move_loop_invariants (void);
> > > > -extern vec get_loop_hot_path (const class loop *loop);
> > > > +extern auto_vec get_loop_hot_path (const class loop
> *loop);
> > > >
> > > >  /* Returns the outermost loop of the loop nest that contains LOOP.*/
> > > >  static inline class loop *
> > > > diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
> > > > index d0eade3dd34..e7b7ae2163e 100644
> > > > --- a/gcc/cfgloopanal.c
> > > > +++ b/gcc/cfgloopanal.c
> > > > @@ -500,7 +500,7 @@ single_likely_exit (class loop *loop, vec
> exits)
> > > > order against direction of edges from latch.  Specially, if
> > > > header != latch, latch is the 1-st block.  */
> > > >
> > > > -vec
> > > > +auto_vec
> > > >  get_loop_hot_path (const class loop *loop)
> > > >  {
> > > >basic_block bb = loop->header;
> > > > diff --git a/gcc/tree-ssa-loop-ivcanon.c
> b/gcc/tree-ssa-loop-ivcanon.c
> > > > index 3f9e9d0869f..b1971f83544 100644
> > > > --- a/gcc/tree-ssa-loop-ivcanon.c
> > > > +++ b/gcc/tree-ssa-loop-ivcanon.c
> > > > @@ -218,7 +218,7 @@ tree_estimate_loop_size (class loop *loop, edge
> exit, edge edge_to_cancel,
> > > >gimple_stmt_iterator gsi;
> > > >unsigned int i;
> > > >bool after_exit;
> > > > -  vec path = get_loop_hot_path (loop);
> > > > +  auto_vec path = get_loop_hot_path (loop);
> > > >
> > > >size->overall = 0;
> > > >size->eliminated_by_peeling = 0;
> > > > @@ -342,7 +342,6 @@ tree_estimate_loop_size (class loop *loop, edge
> exit, edge edge_to_cancel,
> > > >   - size->last_iteration_eliminated_by_peeling) >
> upper_bound)
> > > > {
> > > >free (body);
> > > > - path.release ();
> > > >   return true;
> > > > }
> > > > }
> > > > @@ -379,7 +378,7 @@ tree_estimate_loop_size (class loop *loop, edge
> exit, edge edge_to_cancel,
> > > > size->num_branches_on_hot_path++;
> > > > }
> > > >  }
> > > > -  path.release ();
> > > > +
> > > >if (dump_file && (dump_flags & TDF_DETAILS))
> > > >  fprintf (dump_file, "size: %i-%i, last_iteration: %i-%i\n",
> size->overall,
> > > >  size->eliminated_by_peeling, size->last_iteration,
> > > > --
> > > > 2.20.1
> > > >
>


Re: [PATCH 1/5] libstdc++: Implement P2325 changes to default-constructibilty of views

2021-06-17 Thread Jonathan Wakely via Gcc-patches
On Thu, 17 Jun 2021, 19:19 Jonathan Wakely,  wrote:

>
>
> On Thu, 17 Jun 2021, 16:50 Patrick Palka via Libstdc++, <
> libstd...@gcc.gnu.org> wrote:
>
>> This implements the wording changes of P2325R3 "Views should not be
>> required to be default constructible".  Changes are relatively
>> straightforward, besides perhaps those to __box (which now stands
>> for copyable-box instead of semiregular-box) and __non_propagating_cache.
>>
>> For __box, this patch implements the recommended practice to also avoid
>> std::optional when the boxed type is nothrow_move/copy_constructible.
>>
>> For __non_propagating_cache, now that it's used by split_view::_M_current,
>> we need to add assignment from a value of the underlying type to the
>> subset of the std::optional API implemented for the cache (needed by
>> split_view::begin()).  Hence the new __non_propagating_cache::operator=
>> overload.
>>
>> While we're changing __box, this fixes the undesirable list-init in
>> the constuctors of the partial specialization as reported in PR100475
>> comment #7.
>
>
>
> As I said on IRC, I'm not sure why the defaulted default constructors need
> to be constrained (rather than just letting them get deleted) but the patch
> is OK.
>

Because the default member initializers are in the immediate context, so
the constructor would look valid to is_default_constructible, and only get
deleted when instantiated. (Thanks to Barry for reminding me of that.)

>


Re: [PATCH 1/5] libstdc++: Implement P2325 changes to default-constructibilty of views

2021-06-17 Thread Jonathan Wakely via Gcc-patches
On Thu, 17 Jun 2021, 16:50 Patrick Palka via Libstdc++, <
libstd...@gcc.gnu.org> wrote:

> This implements the wording changes of P2325R3 "Views should not be
> required to be default constructible".  Changes are relatively
> straightforward, besides perhaps those to __box (which now stands
> for copyable-box instead of semiregular-box) and __non_propagating_cache.
>
> For __box, this patch implements the recommended practice to also avoid
> std::optional when the boxed type is nothrow_move/copy_constructible.
>
> For __non_propagating_cache, now that it's used by split_view::_M_current,
> we need to add assignment from a value of the underlying type to the
> subset of the std::optional API implemented for the cache (needed by
> split_view::begin()).  Hence the new __non_propagating_cache::operator=
> overload.
>
> While we're changing __box, this fixes the undesirable list-init in
> the constuctors of the partial specialization as reported in PR100475
> comment #7.



As I said on IRC, I'm not sure why the defaulted default constructors need
to be constrained (rather than just letting them get deleted) but the patch
is OK.


Re: [PATCH 2/5] libstdc++: Move ranges algos used by into ranges_util.h

2021-06-17 Thread Jonathan Wakely via Gcc-patches
On Thu, 17 Jun 2021, 16:47 Patrick Palka via Libstdc++, <
libstd...@gcc.gnu.org> wrote:

> The  header defines simplified copies of some ranges algorithms
> in order to avoid including the entirety of ranges_algo.h.  A subsequent
> patch is going to want to use ranges::search in  as well, but
> that algorithm is more complicated compared to the other copied ones.
>
> So rather than additionally copying ranges::search into , this
> patch splits out all the ranges algos used by  (including
> ranges::search) from ranges_algo.h to ranges_util.h, and deletes the
> simplified copies in .  This seems like the best place for
> these algorithms, as ranges_util.h is included only from  and
> ranges_algo.h.
>


OK, thanks.


Re: [PATCH 2/3] Fix IEEE 128-bit min/max test.

2021-06-17 Thread Segher Boessenkool
On Tue, Jun 08, 2021 at 08:22:40PM -0400, Michael Meissner wrote:
> 
>   * gcc.target/powerpc/float128-minmax.c: Adjust expected code for
>   power10.
>   * lib/target-supports.exp (check_effective_target_has_arch_pwr10):
>   New target support.
> ---
>  gcc/testsuite/gcc.target/powerpc/float128-minmax.c |  8 +---
>  gcc/testsuite/lib/target-supports.exp  | 10 ++
>  2 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c 
> b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
> index fe397518f2f..a7d3a3a0b3e 100644
> --- a/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
> +++ b/gcc/testsuite/gcc.target/powerpc/float128-minmax.c
> @@ -1,6 +1,5 @@
> -/* { dg-do compile { target lp64 } } */

Does that work?  Why was it there before?

>  /* { dg-require-effective-target powerpc_p9vector_ok } */
> -/* { dg-require-effective-target float128 } */
> +/* { dg-require-effective-target ppc_float128_hw } */

Why is it okay to no longer run this test where it ran before?

> -/* { dg-final { scan-assembler {\mxscmpuqp\M} } } */
> +/* Adjust code power10 which has native min/max instructions.  */
> +/* { dg-final { scan-assembler {\mxscmpuqp\M} { target { ! 
> has_arch_pwr10 } } } } */

You need scan-assembler-times here?  (Not that it had that before this
patch, of course).

> +/* { dg-final { scan-assembler {\mxsmincqp\M} { target {   
> has_arch_pwr10 } } } } */
> +/* { dg-final { scan-assembler {\mxsmaxcqp\M} { target {   
> has_arch_pwr10 } } } } */

You can write just  { target has_arch_pwr10 }  here, I think?  Please do
so (if that works, I haven't actually tested it :-) )


Segher


Re: [Patch] Add 'default' to -foffload=; document that flag [PR67300]

2021-06-17 Thread Jakub Jelinek via Gcc-patches
On Thu, Jun 17, 2021 at 11:41:39AM -0600, Sandra Loosemore wrote:
> On 6/17/21 10:03 AM, Tobias Burnus wrote:
> 
> > Updated version – only lightly tested.  I think it is
> > consistent like that and the documentation should now be
> > comprehensive.  (I will have to do some additional testing.)
> > 
> > Further comments and thoughts?
> 
> Hmmm, I had started to put together some comments on
> grammar/punctuation/markup on the first version before the second iteration
> showed up in my mailbox, but more critically I could not figure out whether
> -foffload=default is supposed to be exactly identical to the default
> behavior; if it isn't, it should be, or -foffload=default ought to be
> renamed.  So let's get that sorted out first.  I suggest reorganizing the

Yeah.  If we want for --enable-offload-default also all configured targets,
we could add another keyword for it (all), but I'm not sure it would be
useful, because whenever it would be different from default it would mean
the linking would fail because one or more offloading targets that were
configured isn't supported (installed).

We need to figure out what it means -foffload=nvptx-none -foffload=default,
if the latter overrides the former (as if it wasn't specified), or if it
adds all the remaining offload targets that are default in addition to it.
And similarly figure out what happens with the optional flags, if they are
gathered from all the -foffload= options that refer to a particular target,
or taken from the last -foffload option that mentions that target, something
else.

Jakub



Re: [Patch] Add 'default' to -foffload=; document that flag [PR67300]

2021-06-17 Thread Sandra Loosemore

On 6/17/21 10:03 AM, Tobias Burnus wrote:


Updated version – only lightly tested.  I think it is
consistent like that and the documentation should now be
comprehensive.  (I will have to do some additional testing.)

Further comments and thoughts?


Hmmm, I had started to put together some comments on 
grammar/punctuation/markup on the first version before the second 
iteration showed up in my mailbox, but more critically I could not 
figure out whether -foffload=default is supposed to be exactly identical 
to the default behavior; if it isn't, it should be, or -foffload=default 
ought to be renamed.  So let's get that sorted out first.  I suggest 
reorganizing the documentation to first have a paragraph discussing the 
default behavior, and then move on to how to modify it, with separate 
paragraphs for enabling offload targets explicitly and on adding options 
for offload compilation on all/some targets.


I think it would useful to add an example with a target list and 
multiple options since I think the syntax looks pretty hairy.


-Sandra


Re: [PATCH 1/3] Add IEEE 128-bit min/max support on PowerPC.

2021-06-17 Thread Segher Boessenkool
On Tue, Jun 08, 2021 at 08:21:25PM -0400, Michael Meissner wrote:
> GCC will not convert ternary operations into using min/max instructions
> provided in this patch unless the user uses -Ofast or similar switches due to
> issues with NaNs.

It will not do it because it is *incorrect* to do :-)

(The RTL operators smin/smax are undefined for any NaN inputs (unless
both are the same bit pattern), and for different sign zeroes; it isn't
only NaNs even).

> gcc/
> 2021-06-08  Michael Meissner  
> 
>   * config/rs6000/rs6000.c (rs6000_emit_minmax): Add support for ISA
>   3.1 IEEE 128-bit floating point xsmaxcqp and xsmincqp
>   instructions.

Please don't randomly break lines.

> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -16103,7 +16103,8 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx 
> op0, rtx op1)
>/* VSX/altivec have direct min/max insns.  */
>if ((code == SMAX || code == SMIN)
>&& (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
> -   || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode
> +   || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))
> +   || (TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode

The actual insns only check TARGET_POWER10 (so no TARGET_FLOAT128_HW).
Which is right, this or that?

> +/* { dg-require-effective-target ppc_float128_hw } */
> +/* { dg-require-effective-target power10_ok } */
> +/* { dg-options "-mdejagnu-cpu=power10 -O2 -ffast-math" } */

In testcases we can assume that float128_hw is set whenever we have a
p10; we don't manually disable it to make live hard for ourselves ;-)

We could disallow disabling QP float separately from all other float.
We will still need to test if float is enabled at all so it won't help
all that much immediately, alas.

With that TARGET_POWER10 condition fixed: okay for trunk, and for 11
once it is tested for trunk on all systems.  Thanks!


Segher


Re: [PATCH RFC] mklog: add subject line skeleton

2021-06-17 Thread Jason Merrill via Gcc-patches

On 6/17/21 5:17 AM, Martin Liška wrote:

On 6/17/21 5:42 AM, Jason Merrill wrote:

|Does this seem like an improvement?|


Yes, I support the patch.

I've made some adjustments to the patch in order to make flake8 happy.


Pushed with those changes, thanks.

Jason



Re: [PATCH] libstdc++: Fix for deadlock in std::counting_semaphore [PR100806]

2021-06-17 Thread Jonathan Wakely via Gcc-patches
On Wed, 16 Jun 2021 at 20:53, Thomas Rodgers  wrote:
>
> Same as previous version except removing the copyright notice from the
> test.
>
> libstdc++-v3/ChangeLog:
> libstdc++/PR100806
> * include/bits/semaphore_base.h (__atomic_semaphore::_M_release():
> Force _M_release() to wake all waiting threads.
> * testsuite/30_threads/semaphore/100806.cc: New test.

OK for trunk and 11, thanks.


> ---
>  libstdc++-v3/include/bits/semaphore_base.h|  4 +-
>  .../testsuite/30_threads/semaphore/100806.cc  | 60 +++
>  2 files changed, 63 insertions(+), 1 deletion(-)
>  create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
>
> diff --git a/libstdc++-v3/include/bits/semaphore_base.h 
> b/libstdc++-v3/include/bits/semaphore_base.h
> index 9a55978068f..c4565d7e560 100644
> --- a/libstdc++-v3/include/bits/semaphore_base.h
> +++ b/libstdc++-v3/include/bits/semaphore_base.h
> @@ -256,7 +256,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>if (__update > 1)
> __atomic_notify_address_bare(&_M_counter, true);
>else
> -   __atomic_notify_address_bare(&_M_counter, false);
> +   __atomic_notify_address_bare(&_M_counter, true);
> +// FIXME - Figure out why this does not wake a waiting thread
> +// __atomic_notify_address_bare(&_M_counter, false);
>  }
>
>private:
> diff --git a/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc 
> b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
> new file mode 100644
> index 000..938c2793be1
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/30_threads/semaphore/100806.cc
> @@ -0,0 +1,60 @@
> +// { dg-options "-std=gnu++2a -pthread" }
> +// { dg-do run { target c++2a } }
> +// { dg-require-effective-target pthread }
> +// { dg-require-gthreads "" }
> +// { dg-add-options libatomic }
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +std::counting_semaphore<4> semaphore{6};
> +
> +std::mutex mtx;
> +std::vector results;
> +
> +void thread_main(size_t x)
> +{
> +  semaphore.acquire();
> +  std::this_thread::sleep_for(std::chrono::milliseconds(100));
> +  semaphore.release();
> +  {
> +std::ostringstream stm;
> +stm << "Thread " << x << " finished.";
> +std::lock_guard g{ mtx };
> +results.push_back(stm.str());
> +  }
> +}
> +
> +int main()
> +{
> +
> +constexpr auto nthreads = 10;
> +
> +std::vector threads(nthreads);
> +
> +
> +size_t counter{0};
> +for(auto& t : threads)
> +{
> +t = std::thread(thread_main, counter++);
> +}
> +
> +for(auto& t : threads)
> +  {
> +t.join();
> +{
> +  std::lock_guard g{ mtx };
> +  for (auto&& r : results)
> +std::cout << r << '\n';
> +  std::cout.flush();
> +  results.clear();
> +}
> +  }
> +}
> --
> 2.26.2
>


RE: [EXTERNAL] [PATCH] gcov: Use system IO buffering

2021-06-17 Thread Eugene Rozenfeld via Gcc-patches
Thank you for your reply Martin!

AUTO_PROFILE_VERSION should also be changed. Then create_gcov can be updated to 
support both the old format and the new format.

Eugene

-Original Message-
From: Martin Liška  
Sent: Thursday, June 17, 2021 2:38 AM
To: Eugene Rozenfeld ; gcc-patches@gcc.gnu.org
Subject: Re: [EXTERNAL] [PATCH] gcov: Use system IO buffering

On 6/17/21 3:59 AM, Eugene Rozenfeld wrote:
> |The commit from this patch 
> (https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fgit%2F%3Fp%3Dgcc.git%3Ba%3Dcommit%3Bh%3D23eb66d1d46a34cb28c4acbdf8a1deb80a7c5a05data=04%7C01%7CEugene.Rozenfeld%40microsoft.com%7C508d63026ea84be211cc08d9317395bb%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637595194782996821%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=UG%2B41tXMZ94%2Ff80qCnmq%2BtZsFkLXc9NrdWF8KXwPjnk%3Dreserved=0)
>  changed the semantics of gcov_read_string and gcov_write_string. Before this 
> change the string storage was as described in gcov-io.h: "Strings are padded 
> with 1 to 4 NUL bytes, to bring the length up to a multiple of 4. The number 
> of 4 bytes is stored, followed by the padded string." After this change the 
> number before the string indicates the number of bytes (not words) and there 
> is no padding. Was this file format change intentional?

Hello.

Thanks for heads up!

Yes, the change was intentional and I'm going to update documentation entry in 
gcov-io.h.

> It breaks AutoFDO because create_gcov produces strings in the format 
> specified in gcov-io.h. Thanks, Eugene

Sure, that needs to be adjusted.

Martin



Re: [Patch] Add 'default' to -foffload=; document that flag [PR67300]

2021-06-17 Thread Tobias Burnus

On 17.06.21 14:27, Jakub Jelinek via Gcc-patches wrote:

How does this interact with --enable-offload-defaulted ?


Well, it requires all configured offload targets, making the
installation mandatory.

I think that's fine and consistent and is as documented.


Won't -fopenmp=default=-lm force in all configured targets even when say
nvptx-none mkoffload/offloading compiler is missing?


Yes – but you could use -foffload=-lm instead if you don't want to have this.

I have to admit that I missed that for -foffload==,
 can be a list of targets.
Thus, '-foffload=default=-lm' probably should be supported.

I think -foffload=disable=-... does not make sense & is now rejected,
likewise for: -foffload=disable,default,disable,nvptx-none=-lm.

For consistency, I now accept -foffload=default=-lm.

And for consistency between
  -foffload=hsa,disable,nvptx-none
and
  -foffload=hsa -foffload=disable -foffload=nvptx-none
the first one no longer disables all offload devices but now
acts like the second one and enables nvptx-none, only.

I hope that everything is now consistent but I find -foffload=
syntax wise overengineered.  :-(

 * * *

Updated version – only lightly tested.  I think it is
consistent like that and the documentation should now be
comprehensive.  (I will have to do some additional testing.)

Further comments and thoughts?

Tobias

-
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
Add 'default' to -foffload=; document that flag [PR67300]

It is long overdue to add documentation for -foffload; while in the past
the need for the user to know the flag was limited, it is now needed
rather often by users.

Additionally, as soon as only some devices need specific flags such
as -latomic, all non-specified offload targets get disabled, unless
explicitly specified. To make that easier, the new flag -foffload=default
has been added. That issue came up at
https://gcc.gnu.org/pipermail/gcc-patches/2021-May/570627.html

	PR other/67300

gcc/ChangeLog:

	* doc/invoke.texi (-foffload=): Finally add documentation for it.
	* gcc.c (handle_foffload_option): Support -foffload=default; reject
	-foffload=disable=options.
	* lto-wrapper.c (append_offload_options): Accept -foffload=default=options
	by all targets.

libgomp/ChangeLog:

	* testsuite/libgomp.c-c++-common/reduction-16.c: Use -foffload=default.
	* testsuite/libgomp.c-c++-common/reduction-5.c: Likewise.
	* testsuite/libgomp.c-c++-common/reduction-6.c: Likewise.
	* testsuite/libgomp.c/target-44.c: Likewise.


 gcc/doc/invoke.texi| 47 +-
 gcc/gcc.c  | 30 --
 gcc/lto-wrapper.c  |  6 ++-
 .../testsuite/libgomp.c-c++-common/reduction-16.c  |  6 ++-
 .../testsuite/libgomp.c-c++-common/reduction-5.c   |  7 +++-
 .../testsuite/libgomp.c-c++-common/reduction-6.c   |  7 +++-
 libgomp/testsuite/libgomp.c/target-44.c|  6 ++-
 7 files changed, 98 insertions(+), 11 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index fe812cbd512..a97c8dee12b 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -203,7 +203,7 @@ in the following sections.
 -fno-asm  -fno-builtin  -fno-builtin-@var{function}  -fgimple@gol
 -fhosted  -ffreestanding @gol
 -fopenacc  -fopenacc-dim=@var{geom} @gol
--fopenmp  -fopenmp-simd @gol
+-fopenmp  -fopenmp-simd -foffload=@var{arg} @gol
 -fms-extensions  -fplan9-extensions  -fsso-struct=@var{endianness} @gol
 -fallow-single-precision  -fcond-mismatch  -flax-vector-conversions @gol
 -fsigned-bitfields  -fsigned-char @gol
@@ -2639,6 +2639,51 @@ Enable handling of OpenMP's SIMD directives with @code{#pragma omp}
 in C/C++ and @code{!$omp} in Fortran. Other OpenMP directives
 are ignored.
 
+@item -foffload=@var{options}
+@itemx -foffload=@var{target-list=options}
+@itemx -foffload=@var{target-list}
+@opindex foffload
+@cindex Offloading
+@cindex OpenACC
+@cindex OpenMP
+Specifies for which offload/non-host/accelerator devices code should
+be generated when using OpenACC (@option{-fopenacc}) -- or OpenMP
+(@option{-fopenmp}) with target regions.  It additionally permits to
+pass arguments to the offload-target compiler.  Note that code compiled
+for one or more offload-target devices can still be executable when some
+or all offload device are unavailable at runtime, in line with and as
+specified by the OpenACC and OpenMP specifications.
+
+The options specified with @option{-foffload=}@var{options} are passed
+to the all enabled offloading compilers.  This can be used to link
+libraries required for the offloaded code such as @code{-lm},
+@code{-latomic}, or @code{-lgfortran}.  In order to apply an option
+to only one or more specific offload targets,
+@option{-foffload=}@var{target-list=options} can be used.
+
+By default, all configured offloading compilers are 

[PATCH 55/55] rs6000: Enable the new builtin support

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-05  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (write_init_file):
Initialize new_builtins_are_live to 1.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index acb213ca606..658c4e042f1 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2755,7 +2755,7 @@ write_init_file (void)
   fprintf (init_file, "#include \"rs6000-builtins.h\"\n");
   fprintf (init_file, "\n");
 
-  fprintf (init_file, "int new_builtins_are_live = 0;\n\n");
+  fprintf (init_file, "int new_builtins_are_live = 1;\n\n");
 
   fprintf (init_file, "tree rs6000_builtin_decls_x[RS6000_OVLD_MAX];\n\n");
 
-- 
2.27.0



[PATCH 54/55] rs6000: Test case adjustments

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-15  Bill Schmidt  

gcc/testsuite/
* gcc.target/powerpc/bfp/scalar-extract-exp-2.c: Adjust.
* gcc.target/powerpc/bfp/scalar-extract-sig-2.c: Adjust.
* gcc.target/powerpc/bfp/scalar-insert-exp-2.c: Adjust.
* gcc.target/powerpc/bfp/scalar-insert-exp-5.c: Adjust.
* gcc.target/powerpc/bfp/scalar-insert-exp-8.c: Adjust.
* gcc.target/powerpc/bfp/scalar-test-neg-2.c: Adjust.
* gcc.target/powerpc/bfp/scalar-test-neg-3.c: Adjust.
* gcc.target/powerpc/bfp/scalar-test-neg-5.c: Adjust.
* gcc.target/powerpc/byte-in-set-2.c: Adjust.
* gcc.target/powerpc/cmpb-2.c: Adjust.
* gcc.target/powerpc/cmpb32-2.c: Adjust.
* gcc.target/powerpc/crypto-builtin-2.c: Adjust.
* gcc.target/powerpc/fold-vec-splat-floatdouble.c: Adjust.
* gcc.target/powerpc/fold-vec-splat-longlong.c: Adjust.
* gcc.target/powerpc/fold-vec-splat-misc-invalid.c: Adjust.
* gcc.target/powerpc/int_128bit-runnable.c: Adjust.
* gcc.target/powerpc/p8vector-builtin-8.c: Adjust.
* gcc.target/powerpc/pr80315-1.c: Adjust.
* gcc.target/powerpc/pr80315-2.c: Adjust.
* gcc.target/powerpc/pr80315-3.c: Adjust.
* gcc.target/powerpc/pr80315-4.c: Adjust.
* gcc.target/powerpc/pr88100.c: Adjust.
* gcc.target/powerpc/pragma_misc9.c: Adjust.
* gcc.target/powerpc/pragma_power8.c: Adjust.
* gcc.target/powerpc/pragma_power9.c: Adjust.
* gcc.target/powerpc/test_fpscr_drn_builtin_error.c: Adjust.
* gcc.target/powerpc/test_fpscr_rn_builtin_error.c: Adjust.
* gcc.target/powerpc/test_mffsl.c: Adjust.
* gcc.target/powerpc/vec-gnb-2.c: Adjust.
* gcc.target/powerpc/vsu/vec-all-nez-7.c: Adjust.
* gcc.target/powerpc/vsu/vec-any-eqz-7.c: Adjust.
* gcc.target/powerpc/vsu/vec-cmpnez-7.c: Adjust.
* gcc.target/powerpc/vsu/vec-cntlz-lsbb-2.c: Adjust.
* gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c: Adjust.
* gcc.target/powerpc/vsu/vec-xst-len-12.c: Adjust.
* gcc.target/powerpc/vsu/vec-xst-len-13.c: Adjust.
---
 .../gcc.target/powerpc/bfp/scalar-extract-exp-2.c  |  2 +-
 .../gcc.target/powerpc/bfp/scalar-extract-sig-2.c  |  2 +-
 .../gcc.target/powerpc/bfp/scalar-insert-exp-2.c   |  2 +-
 .../gcc.target/powerpc/bfp/scalar-insert-exp-5.c   |  2 +-
 .../gcc.target/powerpc/bfp/scalar-insert-exp-8.c   |  2 +-
 .../gcc.target/powerpc/bfp/scalar-test-neg-2.c |  2 +-
 .../gcc.target/powerpc/bfp/scalar-test-neg-3.c |  2 +-
 .../gcc.target/powerpc/bfp/scalar-test-neg-5.c |  2 +-
 gcc/testsuite/gcc.target/powerpc/byte-in-set-2.c   |  2 +-
 gcc/testsuite/gcc.target/powerpc/cmpb-2.c  |  2 +-
 gcc/testsuite/gcc.target/powerpc/cmpb32-2.c|  2 +-
 .../gcc.target/powerpc/crypto-builtin-2.c  | 14 +++---
 .../powerpc/fold-vec-splat-floatdouble.c   |  4 ++--
 .../gcc.target/powerpc/fold-vec-splat-longlong.c   | 10 +++---
 .../powerpc/fold-vec-splat-misc-invalid.c  |  8 
 .../gcc.target/powerpc/int_128bit-runnable.c   |  6 +++---
 .../gcc.target/powerpc/p8vector-builtin-8.c|  1 +
 gcc/testsuite/gcc.target/powerpc/pr80315-1.c   |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-2.c   |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-3.c   |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-4.c   |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr88100.c | 12 ++--
 gcc/testsuite/gcc.target/powerpc/pragma_misc9.c|  2 +-
 gcc/testsuite/gcc.target/powerpc/pragma_power8.c   |  2 ++
 gcc/testsuite/gcc.target/powerpc/pragma_power9.c   |  3 +++
 .../powerpc/test_fpscr_drn_builtin_error.c |  4 ++--
 .../powerpc/test_fpscr_rn_builtin_error.c  | 12 ++--
 gcc/testsuite/gcc.target/powerpc/test_mffsl.c  |  3 ++-
 gcc/testsuite/gcc.target/powerpc/vec-gnb-2.c   |  2 +-
 .../gcc.target/powerpc/vsu/vec-all-nez-7.c |  2 +-
 .../gcc.target/powerpc/vsu/vec-any-eqz-7.c |  2 +-
 .../gcc.target/powerpc/vsu/vec-cmpnez-7.c  |  2 +-
 .../gcc.target/powerpc/vsu/vec-cntlz-lsbb-2.c  |  2 +-
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c  |  2 +-
 .../gcc.target/powerpc/vsu/vec-xl-len-13.c |  2 +-
 .../gcc.target/powerpc/vsu/vec-xst-len-12.c|  2 +-
 36 files changed, 65 insertions(+), 62 deletions(-)

diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c 
b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c
index 922180675fc..53b67c95cf9 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c
@@ -14,7 +14,7 @@ get_exponent (double *p)
 {
   double source = *p;
 
-  return scalar_extract_exp (source);  /* { dg-error 
"'__builtin_vec_scalar_extract_exp' is not supported in this compiler 
configuration" } */
+  return scalar_extract_exp (source);  /* { dg-error 

[PATCH 53/55] rs6000: Update altivec.h for automated interfaces

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-10  Bill Schmidt  

gcc/
* config/rs6000/altivec.h: Delete a number of #defines that are
now superfluous; include rs6000-vecdefines.h; include some
synonyms.
---
 gcc/config/rs6000/altivec.h | 522 +++-
 1 file changed, 41 insertions(+), 481 deletions(-)

diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index 5b631c7ebaf..8daf933e53e 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -55,32 +55,36 @@
 #define __CR6_LT   2
 #define __CR6_LT_REV   3
 
-/* Synonyms.  */
+#include "rs6000-vecdefines.h"
+
+/* Deprecated interfaces.  */
+#define vec_lvx vec_ld
+#define vec_lvxl vec_ldl
+#define vec_stvx vec_st
+#define vec_stvxl vec_stl
 #define vec_vaddcuw vec_addc
 #define vec_vand vec_and
 #define vec_vandc vec_andc
-#define vec_vrfip vec_ceil
 #define vec_vcmpbfp vec_cmpb
 #define vec_vcmpgefp vec_cmpge
 #define vec_vctsxs vec_cts
 #define vec_vctuxs vec_ctu
 #define vec_vexptefp vec_expte
-#define vec_vrfim vec_floor
-#define vec_lvx vec_ld
-#define vec_lvxl vec_ldl
 #define vec_vlogefp vec_loge
 #define vec_vmaddfp vec_madd
 #define vec_vmhaddshs vec_madds
-#define vec_vmladduhm vec_mladd
 #define vec_vmhraddshs vec_mradds
+#define vec_vmladduhm vec_mladd
 #define vec_vnmsubfp vec_nmsub
 #define vec_vnor vec_nor
 #define vec_vor vec_or
-#define vec_vpkpx vec_packpx
 #define vec_vperm vec_perm
-#define vec_permxor __builtin_vec_vpermxor
+#define vec_vpkpx vec_packpx
 #define vec_vrefp vec_re
+#define vec_vrfim vec_floor
 #define vec_vrfin vec_round
+#define vec_vrfip vec_ceil
+#define vec_vrfiz vec_trunc
 #define vec_vrsqrtefp vec_rsqrte
 #define vec_vsel vec_sel
 #define vec_vsldoi vec_sld
@@ -91,440 +95,56 @@
 #define vec_vspltisw vec_splat_s32
 #define vec_vsr vec_srl
 #define vec_vsro vec_sro
-#define vec_stvx vec_st
-#define vec_stvxl vec_stl
 #define vec_vsubcuw vec_subc
 #define vec_vsum2sws vec_sum2s
 #define vec_vsumsws vec_sums
-#define vec_vrfiz vec_trunc
 #define vec_vxor vec_xor
 
+#ifdef _ARCH_PWR8
+#define vec_vclz vec_cntlz
+#define vec_vgbbd vec_gb
+#define vec_vmrgew vec_mergee
+#define vec_vmrgow vec_mergeo
+#define vec_vpopcntu vec_popcnt
+#define vec_vrld vec_rl
+#define vec_vsld vec_sl
+#define vec_vsrd vec_sr
+#define vec_vsrad vec_sra
+#endif
+
+#ifdef _ARCH_PWR9
+#define vec_extract_fp_from_shorth vec_extract_fp32_from_shorth
+#define vec_extract_fp_from_shortl vec_extract_fp32_from_shortl
+#define vec_vctz vec_cnttz
+#endif
+
+/* Synonyms.  */
 /* Functions that are resolved by the backend to one of the
typed builtins.  */
-#define vec_vaddfp __builtin_vec_vaddfp
-#define vec_addc __builtin_vec_addc
-#define vec_adde __builtin_vec_adde
-#define vec_addec __builtin_vec_addec
-#define vec_vaddsws __builtin_vec_vaddsws
-#define vec_vaddshs __builtin_vec_vaddshs
-#define vec_vaddsbs __builtin_vec_vaddsbs
-#define vec_vavgsw __builtin_vec_vavgsw
-#define vec_vavguw __builtin_vec_vavguw
-#define vec_vavgsh __builtin_vec_vavgsh
-#define vec_vavguh __builtin_vec_vavguh
-#define vec_vavgsb __builtin_vec_vavgsb
-#define vec_vavgub __builtin_vec_vavgub
-#define vec_ceil __builtin_vec_ceil
-#define vec_cmpb __builtin_vec_cmpb
-#define vec_vcmpeqfp __builtin_vec_vcmpeqfp
-#define vec_cmpge __builtin_vec_cmpge
-#define vec_vcmpgtfp __builtin_vec_vcmpgtfp
-#define vec_vcmpgtsw __builtin_vec_vcmpgtsw
-#define vec_vcmpgtuw __builtin_vec_vcmpgtuw
-#define vec_vcmpgtsh __builtin_vec_vcmpgtsh
-#define vec_vcmpgtuh __builtin_vec_vcmpgtuh
-#define vec_vcmpgtsb __builtin_vec_vcmpgtsb
-#define vec_vcmpgtub __builtin_vec_vcmpgtub
-#define vec_vcfsx __builtin_vec_vcfsx
-#define vec_vcfux __builtin_vec_vcfux
-#define vec_cts __builtin_vec_cts
-#define vec_ctu __builtin_vec_ctu
-#define vec_cpsgn __builtin_vec_copysign
-#define vec_double __builtin_vec_double
-#define vec_doublee __builtin_vec_doublee
-#define vec_doubleo __builtin_vec_doubleo
-#define vec_doublel __builtin_vec_doublel
-#define vec_doubleh __builtin_vec_doubleh
-#define vec_expte __builtin_vec_expte
-#define vec_float __builtin_vec_float
-#define vec_float2 __builtin_vec_float2
-#define vec_floate __builtin_vec_floate
-#define vec_floato __builtin_vec_floato
-#define vec_floor __builtin_vec_floor
-#define vec_loge __builtin_vec_loge
-#define vec_madd __builtin_vec_madd
-#define vec_madds __builtin_vec_madds
-#define vec_mtvscr __builtin_vec_mtvscr
-#define vec_reve __builtin_vec_vreve
-#define vec_vmaxfp __builtin_vec_vmaxfp
-#define vec_vmaxsw __builtin_vec_vmaxsw
-#define vec_vmaxsh __builtin_vec_vmaxsh
-#define vec_vmaxsb __builtin_vec_vmaxsb
-#define vec_vminfp __builtin_vec_vminfp
-#define vec_vminsw __builtin_vec_vminsw
-#define vec_vminsh __builtin_vec_vminsh
-#define vec_vminsb __builtin_vec_vminsb
-#define vec_mradds __builtin_vec_mradds
-#define vec_vmsumshm __builtin_vec_vmsumshm
-#define vec_vmsumuhm __builtin_vec_vmsumuhm
-#define vec_vmsummbm __builtin_vec_vmsummbm
-#define vec_vmsumubm 

[PATCH 52/55] rs6000: Debug support

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-04-01  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (rs6000_debug_type): New function.
(def_builtin): Change debug formatting for easier parsing and
include more information.
(rs6000_init_builtins): Add dump of autogenerated builtins.
(altivec_init_builtins): Dump __builtin_altivec_mask_for_load for
completeness.
---
 gcc/config/rs6000/rs6000-call.c | 193 +++-
 1 file changed, 189 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 54cf014ed23..d28bb14b0bb 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -8880,6 +8880,106 @@ rs6000_gimplify_va_arg (tree valist, tree type, 
gimple_seq *pre_p,
 
 /* Builtins.  */
 
+/* Debug utility to translate a type node to a single token.  */
+static
+const char *rs6000_debug_type (tree type)
+{
+  if (type == void_type_node)
+return "void";
+  else if (type == long_integer_type_node)
+return "long";
+  else if (type == long_unsigned_type_node)
+return "ulong";
+  else if (type == long_long_integer_type_node)
+return "longlong";
+  else if (type == long_long_unsigned_type_node)
+return "ulonglong";
+  else if (type == bool_V16QI_type_node)
+return "vbc";
+  else if (type == bool_V2DI_type_node)
+return "vbll";
+  else if (type == bool_V4SI_type_node)
+return "vbi";
+  else if (type == bool_V8HI_type_node)
+return "vbs";
+  else if (type == bool_int_type_node)
+return "bool";
+  else if (type == dfloat64_type_node)
+return "_Decimal64";
+  else if (type == double_type_node)
+return "double";
+  else if (type == intDI_type_node)
+return "sll";
+  else if (type == intHI_type_node)
+return "ss";
+  else if (type == ibm128_float_type_node)
+return "__ibm128";
+  else if (type == opaque_V4SI_type_node)
+return "opaque";
+  else if (POINTER_TYPE_P (type))
+return "void*";
+  else if (type == intQI_type_node || type == char_type_node)
+return "sc";
+  else if (type == dfloat32_type_node)
+return "_Decimal32";
+  else if (type == float_type_node)
+return "float";
+  else if (type == intSI_type_node || type == integer_type_node)
+return "si";
+  else if (type == dfloat128_type_node)
+return "_Decimal128";
+  else if (type == long_double_type_node)
+return "longdouble";
+  else if (type == intTI_type_node)
+return "sq";
+  else if (type == unsigned_intDI_type_node)
+return "ull";
+  else if (type == unsigned_intHI_type_node)
+return "us";
+  else if (type == unsigned_intQI_type_node)
+return "uc";
+  else if (type == unsigned_intSI_type_node)
+return "ui";
+  else if (type == unsigned_intTI_type_node)
+return "uq";
+  else if (type == unsigned_V16QI_type_node)
+return "vuc";
+  else if (type == unsigned_V1TI_type_node)
+return "vuq";
+  else if (type == unsigned_V2DI_type_node)
+return "vull";
+  else if (type == unsigned_V4SI_type_node)
+return "vui";
+  else if (type == unsigned_V8HI_type_node)
+return "vus";
+  else if (type == V16QI_type_node)
+return "vsc";
+  else if (type == V1TI_type_node)
+return "vsq";
+  else if (type == V2DF_type_node)
+return "vd";
+  else if (type == V2DI_type_node)
+return "vsll";
+  else if (type == V4SF_type_node)
+return "vf";
+  else if (type == V4SI_type_node)
+return "vsi";
+  else if (type == V8HI_type_node)
+return "vss";
+  else if (type == pixel_V8HI_type_node)
+return "vp";
+  else if (type == pcvoid_type_node)
+return "voidc*";
+  else if (type == float128_type_node)
+return "_Float128";
+  else if (type == vector_pair_type_node)
+return "__vector_pair";
+  else if (type == vector_quad_type_node)
+return "__vector_quad";
+  else
+return "unknown";
+}
+
 static void
 def_builtin (const char *name, tree type, enum rs6000_builtins code)
 {
@@ -8908,7 +9008,7 @@ def_builtin (const char *name, tree type, enum 
rs6000_builtins code)
   /* const function, function only depends on the inputs.  */
   TREE_READONLY (t) = 1;
   TREE_NOTHROW (t) = 1;
-  attr_string = ", const";
+  attr_string = "= const";
 }
   else if ((classify & RS6000_BTC_PURE) != 0)
 {
@@ -8916,7 +9016,7 @@ def_builtin (const char *name, tree type, enum 
rs6000_builtins code)
 external state.  */
   DECL_PURE_P (t) = 1;
   TREE_NOTHROW (t) = 1;
-  attr_string = ", pure";
+  attr_string = "= pure";
 }
   else if ((classify & RS6000_BTC_FP) != 0)
 {
@@ -8930,12 +9030,12 @@ def_builtin (const char *name, tree type, enum 
rs6000_builtins code)
{
  DECL_PURE_P (t) = 1;
  DECL_IS_NOVOPS (t) = 1;
- attr_string = ", fp, pure";
+ attr_string = "= fp, pure";
}
   else
{
  TREE_READONLY (t) = 1;
- attr_string = ", fp, const";
+ attr_string = "= fp, const";
}
 }
   

[PATCH 51/55] rs6000: Miscellaneous uses of rs6000_builtin_decls_x

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-05  Bill Schmidt  

gcc/
* config/rs6000/rs6000.c (rs6000_builtin_reciprocal): Use
rs6000_builtin_decls_x when appropriate.
(add_condition_to_bb): Likewise.
(rs6000_atomic_assign_expand_fenv): Likewise.
---
 gcc/config/rs6000/rs6000.c | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 70a2be90787..7f6c1f8036e 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -22767,12 +22767,16 @@ rs6000_builtin_reciprocal (tree fndecl)
   if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
return NULL_TREE;
 
+  if (new_builtins_are_live)
+   return rs6000_builtin_decls_x[RS6000_BIF_RSQRT_2DF];
   return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_2DF];
 
 case VSX_BUILTIN_XVSQRTSP:
   if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
return NULL_TREE;
 
+  if (new_builtins_are_live)
+   return rs6000_builtin_decls_x[RS6000_BIF_RSQRT_4SF];
   return rs6000_builtin_decls[VSX_BUILTIN_RSQRT_4SF];
 
 default:
@@ -25361,7 +25365,10 @@ add_condition_to_bb (tree function_decl, tree 
version_decl,
 
   tree bool_zero = build_int_cst (bool_int_type_node, 0);
   tree cond_var = create_tmp_var (bool_int_type_node);
-  tree predicate_decl = rs6000_builtin_decls [(int) 
RS6000_BUILTIN_CPU_SUPPORTS];
+  tree predicate_decl
+= (new_builtins_are_live
+   ? rs6000_builtin_decls_x[(int) RS6000_BIF_CPU_SUPPORTS]
+   : rs6000_builtin_decls [(int) RS6000_BUILTIN_CPU_SUPPORTS]);
   const char *arg_str = rs6000_clone_map[clone_isa].name;
   tree predicate_arg = build_string_literal (strlen (arg_str) + 1, arg_str);
   gimple *call_cond_stmt = gimple_build_call (predicate_decl, 1, 
predicate_arg);
@@ -27586,8 +27593,14 @@ rs6000_atomic_assign_expand_fenv (tree *hold, tree 
*clear, tree *update)
   return;
 }
 
-  tree mffs = rs6000_builtin_decls[RS6000_BUILTIN_MFFS];
-  tree mtfsf = rs6000_builtin_decls[RS6000_BUILTIN_MTFSF];
+  tree mffs
+= (new_builtins_are_live
+   ? rs6000_builtin_decls_x[RS6000_BIF_MFFS]
+   : rs6000_builtin_decls[RS6000_BUILTIN_MFFS]);
+  tree mtfsf
+= (new_builtins_are_live
+   ? rs6000_builtin_decls_x[RS6000_BIF_MTFSF]
+   : rs6000_builtin_decls[RS6000_BUILTIN_MTFSF]);
   tree call_mffs = build_call_expr (mffs, 0);
 
   /* Generates the equivalent of feholdexcept (_var)
-- 
2.27.0



[PATCH 50/55] rs6000: Update rs6000_builtin_decl

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-05  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (rs6000_new_builtin_decl): New
function.
(rs6000_builtin_decl): Call it.
---
 gcc/config/rs6000/rs6000-call.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 6b60f0852ef..54cf014ed23 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -16258,11 +16258,31 @@ rs6000_init_builtins (void)
 }
 }
 
+static tree
+rs6000_new_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
+{
+  rs6000_gen_builtins fcode = (rs6000_gen_builtins) code;
+
+  if (fcode >= RS6000_OVLD_MAX)
+return error_mark_node;
+
+  if (!rs6000_new_builtin_is_supported_p (fcode))
+{
+  rs6000_invalid_new_builtin (fcode);
+  return error_mark_node;
+}
+
+  return rs6000_builtin_decls_x[code];
+}
+
 /* Returns the rs6000 builtin decl for CODE.  */
 
 tree
 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
 {
+  if (new_builtins_are_live)
+return rs6000_new_builtin_decl (code, initialize_p);
+
   HOST_WIDE_INT fnmask;
 
   if (code >= RS6000_BUILTIN_COUNT)
-- 
2.27.0



[PATCH 49/55] rs6000: Builtin expansion, part 6

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-24  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (new_htm_spr_num): New function.
(new_htm_expand_builtin): Implement.
(rs6000_expand_new_builtin): Handle 32-bit and endian cases.
---
 gcc/config/rs6000/rs6000-call.c | 202 
 1 file changed, 202 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index e1b685fb874..6b60f0852ef 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -15068,11 +15068,171 @@ new_mma_expand_builtin (tree exp, rtx target, 
insn_code icode,
   return target;
 }
 
+/* Return the appropriate SPR number associated with the given builtin.  */
+static inline HOST_WIDE_INT
+new_htm_spr_num (enum rs6000_gen_builtins code)
+{
+  if (code == RS6000_BIF_GET_TFHAR
+  || code == RS6000_BIF_SET_TFHAR)
+return TFHAR_SPR;
+  else if (code == RS6000_BIF_GET_TFIAR
+  || code == RS6000_BIF_SET_TFIAR)
+return TFIAR_SPR;
+  else if (code == RS6000_BIF_GET_TEXASR
+  || code == RS6000_BIF_SET_TEXASR)
+return TEXASR_SPR;
+  gcc_assert (code == RS6000_BIF_GET_TEXASRU
+ || code == RS6000_BIF_SET_TEXASRU);
+  return TEXASRU_SPR;
+}
+
 /* Expand the HTM builtin in EXP and store the result in TARGET.  */
 static rtx
 new_htm_expand_builtin (bifdata *bifaddr, rs6000_gen_builtins fcode,
tree exp, rtx target)
 {
+  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+  bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
+
+  if (!TARGET_POWERPC64
+  && (fcode == RS6000_BIF_TABORTDC
+ || fcode == RS6000_BIF_TABORTDCI))
+{
+  error ("builtin %qs is only valid in 64-bit mode", bifaddr->bifname);
+  return const0_rtx;
+}
+
+  rtx op[MAX_HTM_OPERANDS], pat;
+  int nopnds = 0;
+  tree arg;
+  call_expr_arg_iterator iter;
+  insn_code icode = bifaddr->icode;
+  bool uses_spr = bif_is_htmspr (*bifaddr);
+  rtx cr = NULL_RTX;
+
+  if (uses_spr)
+icode = rs6000_htm_spr_icode (nonvoid);
+  const insn_operand_data *insn_op = _data[icode].operand[0];
+
+  if (nonvoid)
+{
+  machine_mode tmode = (uses_spr) ? insn_op->mode : E_SImode;
+  if (!target
+ || GET_MODE (target) != tmode
+ || (uses_spr && !(*insn_op->predicate) (target, tmode)))
+   target = gen_reg_rtx (tmode);
+  if (uses_spr)
+   op[nopnds++] = target;
+}
+
+  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+{
+  if (arg == error_mark_node || nopnds >= MAX_HTM_OPERANDS)
+   return const0_rtx;
+
+  insn_op = _data[icode].operand[nopnds];
+  op[nopnds] = expand_normal (arg);
+
+  if (!(*insn_op->predicate) (op[nopnds], insn_op->mode))
+   {
+ if (!strcmp (insn_op->constraint, "n"))
+   {
+ int arg_num = (nonvoid) ? nopnds : nopnds + 1;
+ if (!CONST_INT_P (op[nopnds]))
+   error ("argument %d must be an unsigned literal", arg_num);
+ else
+   error ("argument %d is an unsigned literal that is "
+  "out of range", arg_num);
+ return const0_rtx;
+   }
+ op[nopnds] = copy_to_mode_reg (insn_op->mode, op[nopnds]);
+   }
+
+  nopnds++;
+}
+
+  /* Handle the builtins for extended mnemonics.  These accept
+ no arguments, but map to builtins that take arguments.  */
+  switch (fcode)
+{
+case RS6000_BIF_TENDALL:  /* Alias for: tend. 1  */
+case RS6000_BIF_TRESUME:  /* Alias for: tsr. 1  */
+  op[nopnds++] = GEN_INT (1);
+  break;
+case RS6000_BIF_TSUSPEND: /* Alias for: tsr. 0  */
+  op[nopnds++] = GEN_INT (0);
+  break;
+default:
+  break;
+}
+
+  /* If this builtin accesses SPRs, then pass in the appropriate
+ SPR number and SPR regno as the last two operands.  */
+  if (uses_spr)
+{
+  machine_mode mode = (TARGET_POWERPC64) ? DImode : SImode;
+  op[nopnds++] = gen_rtx_CONST_INT (mode, new_htm_spr_num (fcode));
+}
+  /* If this builtin accesses a CR, then pass in a scratch
+ CR as the last operand.  */
+  else if (bif_is_htmcr (*bifaddr))
+{
+  cr = gen_reg_rtx (CCmode);
+  op[nopnds++] = cr;
+}
+
+  switch (nopnds)
+{
+case 1:
+  pat = GEN_FCN (icode) (op[0]);
+  break;
+case 2:
+  pat = GEN_FCN (icode) (op[0], op[1]);
+  break;
+case 3:
+  pat = GEN_FCN (icode) (op[0], op[1], op[2]);
+  break;
+case 4:
+  pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
+  break;
+default:
+  gcc_unreachable ();
+}
+  if (!pat)
+return NULL_RTX;
+  emit_insn (pat);
+
+  if (bif_is_htmcr (*bifaddr))
+{
+  if (fcode == RS6000_BIF_TBEGIN)
+   {
+ /* Emit code to set TARGET to true or false depending on
+whether the tbegin. instruction successfully or failed
+to start a transaction.  We do this by placing the 1's
+complement of CR's 

[PATCH 48/55] rs6000: Builtin expansion, part 5

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-17  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (new_mma_expand_builtin):
Implement.
---
 gcc/config/rs6000/rs6000-call.c | 103 
 1 file changed, 103 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 981eabc1187..e1b685fb874 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14962,6 +14962,109 @@ static rtx
 new_mma_expand_builtin (tree exp, rtx target, insn_code icode,
rs6000_gen_builtins fcode)
 {
+  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+  tree arg;
+  call_expr_arg_iterator iter;
+  const struct insn_operand_data *insn_op;
+  rtx op[MAX_MMA_OPERANDS];
+  unsigned nopnds = 0;
+  bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
+  machine_mode tmode = VOIDmode;
+
+  if (!void_func)
+{
+  tmode = insn_data[icode].operand[0].mode;
+  if (!target
+ || GET_MODE (target) != tmode
+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
+   target = gen_reg_rtx (tmode);
+  op[nopnds++] = target;
+}
+  else
+target = const0_rtx;
+
+  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+{
+  if (arg == error_mark_node)
+   return const0_rtx;
+
+  rtx opnd;
+  insn_op = _data[icode].operand[nopnds];
+  if (TREE_CODE (arg) == ADDR_EXPR
+ && MEM_P (DECL_RTL (TREE_OPERAND (arg, 0
+   opnd = DECL_RTL (TREE_OPERAND (arg, 0));
+  else
+   opnd = expand_normal (arg);
+
+  if (!(*insn_op->predicate) (opnd, insn_op->mode))
+   {
+ if (!strcmp (insn_op->constraint, "n"))
+   {
+ if (!CONST_INT_P (opnd))
+   error ("argument %d must be an unsigned literal", nopnds);
+ else
+   error ("argument %d is an unsigned literal that is "
+  "out of range", nopnds);
+ return const0_rtx;
+   }
+ opnd = copy_to_mode_reg (insn_op->mode, opnd);
+   }
+
+  /* Some MMA instructions have INOUT accumulator operands, so force
+their target register to be the same as their input register.  */
+  if (!void_func
+ && nopnds == 1
+ && !strcmp (insn_op->constraint, "0")
+ && insn_op->mode == tmode
+ && REG_P (opnd)
+ && (*insn_data[icode].operand[0].predicate) (opnd, tmode))
+   target = op[0] = opnd;
+
+  op[nopnds++] = opnd;
+}
+
+  rtx pat;
+  switch (nopnds)
+{
+case 1:
+  pat = GEN_FCN (icode) (op[0]);
+  break;
+case 2:
+  pat = GEN_FCN (icode) (op[0], op[1]);
+  break;
+case 3:
+  /* The ASSEMBLE builtin source operands are reversed in little-endian
+mode, so reorder them.  */
+  if (fcode == RS6000_BIF_ASSEMBLE_PAIR_V_INTERNAL && !WORDS_BIG_ENDIAN)
+   std::swap (op[1], op[2]);
+  pat = GEN_FCN (icode) (op[0], op[1], op[2]);
+  break;
+case 4:
+  pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
+  break;
+case 5:
+  /* The ASSEMBLE builtin source operands are reversed in little-endian
+mode, so reorder them.  */
+  if (fcode == RS6000_BIF_ASSEMBLE_ACC_INTERNAL && !WORDS_BIG_ENDIAN)
+   {
+ std::swap (op[1], op[4]);
+ std::swap (op[2], op[3]);
+   }
+  pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
+  break;
+case 6:
+  pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
+  break;
+case 7:
+  pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6]);
+  break;
+default:
+  gcc_unreachable ();
+}
+  if (!pat)
+return NULL_RTX;
+  emit_insn (pat);
+
   return target;
 }
 
-- 
2.27.0



[PATCH 47/55] rs6000: Builtin expansion, part 4

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-05  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (elemrev_icode): Implement.
(ldv_expand_builtin): Likewise.
(lxvrse_expand_builtin): Likewise.
(lxvrze_expand_builtin): Likewise.
(stv_expand_builtin): Likewise.
---
 gcc/config/rs6000/rs6000-call.c | 217 
 1 file changed, 217 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index ad3e6a4bbe5..981eabc1187 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14710,12 +14710,114 @@ new_cpu_expand_builtin (enum rs6000_gen_builtins 
fcode,
 static insn_code
 elemrev_icode (rs6000_gen_builtins fcode)
 {
+  switch (fcode)
+{
+default:
+  gcc_unreachable ();
+case RS6000_BIF_ST_ELEMREV_V1TI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+ : CODE_FOR_vsx_st_elemrev_v1ti);
+case RS6000_BIF_ST_ELEMREV_V2DF:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+ : CODE_FOR_vsx_st_elemrev_v2df);
+case RS6000_BIF_ST_ELEMREV_V2DI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+ : CODE_FOR_vsx_st_elemrev_v2di);
+case RS6000_BIF_ST_ELEMREV_V4SF:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+ : CODE_FOR_vsx_st_elemrev_v4sf);
+case RS6000_BIF_ST_ELEMREV_V4SI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+ : CODE_FOR_vsx_st_elemrev_v4si);
+case RS6000_BIF_ST_ELEMREV_V8HI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+ : CODE_FOR_vsx_st_elemrev_v8hi);
+case RS6000_BIF_ST_ELEMREV_V16QI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+ : CODE_FOR_vsx_st_elemrev_v16qi);
+case RS6000_BIF_LD_ELEMREV_V2DF:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+ : CODE_FOR_vsx_ld_elemrev_v2df);
+case RS6000_BIF_LD_ELEMREV_V1TI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+ : CODE_FOR_vsx_ld_elemrev_v1ti);
+case RS6000_BIF_LD_ELEMREV_V2DI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+ : CODE_FOR_vsx_ld_elemrev_v2di);
+case RS6000_BIF_LD_ELEMREV_V4SF:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+ : CODE_FOR_vsx_ld_elemrev_v4sf);
+case RS6000_BIF_LD_ELEMREV_V4SI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+ : CODE_FOR_vsx_ld_elemrev_v4si);
+case RS6000_BIF_LD_ELEMREV_V8HI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+ : CODE_FOR_vsx_ld_elemrev_v8hi);
+case RS6000_BIF_LD_ELEMREV_V16QI:
+  return (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+ : CODE_FOR_vsx_ld_elemrev_v16qi);
+}
+  gcc_unreachable ();
   return (insn_code) 0;
 }
 
 static rtx
 ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
 {
+  rtx pat, addr;
+  bool blk = (icode == CODE_FOR_altivec_lvlx
+ || icode == CODE_FOR_altivec_lvlxl
+ || icode == CODE_FOR_altivec_lvrx
+ || icode == CODE_FOR_altivec_lvrxl);
+
+  if (target == 0
+  || GET_MODE (target) != tmode
+  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+target = gen_reg_rtx (tmode);
+
+  op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+  /* For LVX, express the RTL accurately by ANDing the address with -16.
+ LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine.  */
+  if (icode == CODE_FOR_altivec_lvx_v1ti
+  || icode == CODE_FOR_altivec_lvx_v2df
+  || icode == CODE_FOR_altivec_lvx_v2di
+  || icode == CODE_FOR_altivec_lvx_v4sf
+  || icode == CODE_FOR_altivec_lvx_v4si
+  || icode == CODE_FOR_altivec_lvx_v8hi
+  || icode == CODE_FOR_altivec_lvx_v16qi)
+{
+  rtx rawaddr;
+  if (op[0] == const0_rtx)
+   rawaddr = op[1];
+  else
+   {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
+   }
+  addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+  addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+  emit_insn (gen_rtx_SET (target, addr));
+}
+  else
+{
+  if (op[0] == const0_rtx)
+   addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
+  else
+   {
+ op[0] = copy_to_mode_reg (Pmode, op[0]);
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+ gen_rtx_PLUS (Pmode, op[1], op[0]));
+   }
+
+  pat = GEN_FCN (icode) (target, addr);
+  if (! pat)
+   return 0;
+  emit_insn (pat);
+}
+
   return target;
 }
 
@@ -14723,6 +14825,42 @@ static rtx
 lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
   machine_mode tmode, machine_mode smode)
 {
+  rtx pat, addr;
+  op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+  if (op[0] == const0_rtx)
+addr = 

[PATCH 46/55] rs6000: Builtin expansion, part 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-05  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (new_cpu_expand_builtin):
Implement.
---
 gcc/config/rs6000/rs6000-call.c | 100 
 1 file changed, 100 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 754cd46b1c1..ad3e6a4bbe5 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14604,6 +14604,106 @@ static rtx
 new_cpu_expand_builtin (enum rs6000_gen_builtins fcode,
tree exp ATTRIBUTE_UNUSED, rtx target)
 {
+  /* __builtin_cpu_init () is a nop, so expand to nothing.  */
+  if (fcode == RS6000_BIF_CPU_INIT)
+return const0_rtx;
+
+  if (target == 0 || GET_MODE (target) != SImode)
+target = gen_reg_rtx (SImode);
+
+#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
+  tree arg = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
+  /* Target clones creates an ARRAY_REF instead of STRING_CST, convert it back
+ to a STRING_CST.  */
+  if (TREE_CODE (arg) == ARRAY_REF
+  && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST
+  && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST
+  && compare_tree_int (TREE_OPERAND (arg, 1), 0) == 0)
+arg = TREE_OPERAND (arg, 0);
+
+  if (TREE_CODE (arg) != STRING_CST)
+{
+  error ("builtin %qs only accepts a string argument",
+rs6000_builtin_info_x[(size_t) fcode].bifname);
+  return const0_rtx;
+}
+
+  if (fcode == RS6000_BIF_CPU_IS)
+{
+  const char *cpu = TREE_STRING_POINTER (arg);
+  rtx cpuid = NULL_RTX;
+  for (size_t i = 0; i < ARRAY_SIZE (cpu_is_info); i++)
+   if (strcmp (cpu, cpu_is_info[i].cpu) == 0)
+ {
+   /* The CPUID value in the TCB is offset by _DL_FIRST_PLATFORM.  */
+   cpuid = GEN_INT (cpu_is_info[i].cpuid + _DL_FIRST_PLATFORM);
+   break;
+ }
+  if (cpuid == NULL_RTX)
+   {
+ /* Invalid CPU argument.  */
+ error ("cpu %qs is an invalid argument to builtin %qs",
+cpu, rs6000_builtin_info_x[(size_t) fcode].bifname);
+ return const0_rtx;
+   }
+
+  rtx platform = gen_reg_rtx (SImode);
+  rtx tcbmem = gen_const_mem (SImode,
+ gen_rtx_PLUS (Pmode,
+   gen_rtx_REG (Pmode, TLS_REGNUM),
+   GEN_INT (TCB_PLATFORM_OFFSET)));
+  emit_move_insn (platform, tcbmem);
+  emit_insn (gen_eqsi3 (target, platform, cpuid));
+}
+  else if (fcode == RS6000_BIF_CPU_SUPPORTS)
+{
+  const char *hwcap = TREE_STRING_POINTER (arg);
+  rtx mask = NULL_RTX;
+  int hwcap_offset;
+  for (size_t i = 0; i < ARRAY_SIZE (cpu_supports_info); i++)
+   if (strcmp (hwcap, cpu_supports_info[i].hwcap) == 0)
+ {
+   mask = GEN_INT (cpu_supports_info[i].mask);
+   hwcap_offset = TCB_HWCAP_OFFSET (cpu_supports_info[i].id);
+   break;
+ }
+  if (mask == NULL_RTX)
+   {
+ /* Invalid HWCAP argument.  */
+ error ("%s %qs is an invalid argument to builtin %qs",
+"hwcap", hwcap,
+rs6000_builtin_info_x[(size_t) fcode].bifname);
+ return const0_rtx;
+   }
+
+  rtx tcb_hwcap = gen_reg_rtx (SImode);
+  rtx tcbmem = gen_const_mem (SImode,
+ gen_rtx_PLUS (Pmode,
+   gen_rtx_REG (Pmode, TLS_REGNUM),
+   GEN_INT (hwcap_offset)));
+  emit_move_insn (tcb_hwcap, tcbmem);
+  rtx scratch1 = gen_reg_rtx (SImode);
+  emit_insn (gen_rtx_SET (scratch1, gen_rtx_AND (SImode, tcb_hwcap, 
mask)));
+  rtx scratch2 = gen_reg_rtx (SImode);
+  emit_insn (gen_eqsi3 (scratch2, scratch1, const0_rtx));
+  emit_insn (gen_rtx_SET (target, gen_rtx_XOR (SImode, scratch2, 
const1_rtx)));
+}
+  else
+gcc_unreachable ();
+
+  /* Record that we have expanded a CPU builtin, so that we can later
+ emit a reference to the special symbol exported by LIBC to ensure we
+ do not link against an old LIBC that doesn't support this feature.  */
+  cpu_builtin_p = true;
+
+#else
+  warning (0, "builtin %qs needs GLIBC (2.23 and newer) that exports hardware "
+  "capability bits", rs6000_builtin_info_x[(size_t) fcode].bifname);
+
+  /* For old LIBCs, always return FALSE.  */
+  emit_move_insn (target, GEN_INT (0));
+#endif /* TARGET_LIBC_PROVIDES_HWCAP_IN_TCB */
+
   return target;
 }
 
-- 
2.27.0



[PATCH 45/55] rs6000: Builtin expansion, part 2

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-05  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (rs6000_invalid_new_builtin):
Implement.
(rs6000_expand_ldst_mask): Likewise.
(rs6000_init_builtins): Initialize altivec_builtin_mask_for_load.
---
 gcc/config/rs6000/rs6000-call.c | 101 +++-
 1 file changed, 100 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 8693836cd5a..754cd46b1c1 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -11671,6 +11671,75 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
 static void
 rs6000_invalid_new_builtin (enum rs6000_gen_builtins fncode)
 {
+  size_t uns_fncode = (size_t) fncode;
+  const char *name = rs6000_builtin_info_x[uns_fncode].bifname;
+
+  switch (rs6000_builtin_info_x[uns_fncode].enable)
+{
+case ENB_P5:
+  error ("%qs requires the %qs option", name, "-mcpu=power5");
+  break;
+case ENB_P6:
+  error ("%qs requires the %qs option", name, "-mcpu=power6");
+  break;
+case ENB_ALTIVEC:
+  error ("%qs requires the %qs option", name, "-maltivec");
+  break;
+case ENB_CELL:
+  error ("%qs is only valid for the cell processor", name);
+  break;
+case ENB_VSX:
+  error ("%qs requires the %qs option", name, "-mvsx");
+  break;
+case ENB_P7:
+  error ("%qs requires the %qs option", name, "-mcpu=power7");
+  break;
+case ENB_P7_64:
+  error ("%qs requires the %qs option and either the %qs or %qs option",
+name, "-mcpu=power7", "-m64", "-mpowerpc64");
+  break;
+case ENB_P8:
+  error ("%qs requires the %qs option", name, "-mcpu=power8");
+  break;
+case ENB_P8V:
+  error ("%qs requires the %qs option", name, "-mpower8-vector");
+  break;
+case ENB_P9:
+  error ("%qs requires the %qs option", name, "-mcpu=power9");
+  break;
+case ENB_P9_64:
+  error ("%qs requires the %qs option and either the %qs or %qs option",
+name, "-mcpu=power9", "-m64", "-mpowerpc64");
+  break;
+case ENB_P9V:
+  error ("%qs requires the %qs option", name, "-mpower9-vector");
+  break;
+case ENB_IEEE128_HW:
+  error ("%qs requires ISA 3.0 IEEE 128-bit floating point", name);
+  break;
+case ENB_DFP:
+  error ("%qs requires the %qs option", name, "-mhard-dfp");
+  break;
+case ENB_CRYPTO:
+  error ("%qs requires the %qs option", name, "-mcrypto");
+  break;
+case ENB_HTM:
+  error ("%qs requires the %qs option", name, "-mhtm");
+  break;
+case ENB_P10:
+  error ("%qs requires the %qs option", name, "-mcpu=power10");
+  break;
+case ENB_P10_64:
+  error ("%qs requires the %qs option and either the %qs or %qs option",
+name, "-mcpu=power10", "-m64", "-mpowerpc64");
+  break;
+case ENB_MMA:
+  error ("%qs requires the %qs option", name, "-mmma");
+  break;
+default:
+case ENB_ALWAYS:
+  gcc_unreachable ();
+};
 }
 
 /* Target hook for early folding of built-ins, shamelessly stolen
@@ -14501,7 +14570,33 @@ rs6000_expand_builtin (tree exp, rtx target, rtx 
subtarget ATTRIBUTE_UNUSED,
 rtx
 rs6000_expand_ldst_mask (rtx target, tree arg0)
  {
-  return target;
+  int icode2 = (BYTES_BIG_ENDIAN ? (int) CODE_FOR_altivec_lvsr_direct
+   : (int) CODE_FOR_altivec_lvsl_direct);
+  machine_mode tmode = insn_data[icode2].operand[0].mode;
+  machine_mode mode = insn_data[icode2].operand[1].mode;
+  rtx op, addr, pat;
+
+  gcc_assert (TARGET_ALTIVEC);
+
+  gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg0)));
+  op = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
+  addr = memory_address (mode, op);
+  /* We need to negate the address.  */
+  op = gen_reg_rtx (GET_MODE (addr));
+  emit_insn (gen_rtx_SET (op, gen_rtx_NEG (GET_MODE (addr), addr)));
+  op = gen_rtx_MEM (mode, op);
+
+  if (target == 0
+  || GET_MODE (target) != tmode
+  || ! (*insn_data[icode2].operand[0].predicate) (target, tmode))
+target = gen_reg_rtx (tmode);
+
+  pat = GEN_FCN (icode2) (target, op);
+  if (!pat)
+return 0;
+  emit_insn (pat);
+
+   return target;
  }
 
 /* Expand the CPU builtin in FCODE and store the result in TARGET.  */
@@ -15401,6 +15496,10 @@ rs6000_init_builtins (void)
   /* Execute the autogenerated initialization code for builtins.  */
   rs6000_autoinit_builtins ();
 
+  if (new_builtins_are_live)
+altivec_builtin_mask_for_load
+  = rs6000_builtin_decls_x[RS6000_BIF_MASK_FOR_LOAD];
+
   if (new_builtins_are_live)
 {
 #ifdef SUBTARGET_INIT_BUILTINS
-- 
2.27.0



[PATCH 44/55] rs6000: Builtin expansion, part 1

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-17  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (rs6000_expand_new_builtin): New
forward decl.
(rs6000_invalid_new_builtin): New stub function.
(rs6000_expand_builtin): Call rs6000_expand_new_builtin.
(rs6000_expand_ldst_mask): New stub function.
(new_cpu_expand_builtin): Likewise.
(elemrev_icode): Likewise.
(ldv_expand_builtin): Likewise.
(lxvrse_expand_builtin): Likewise.
(lxvrze_expand_builtin): Likewise.
(stv_expand_builtin): Likewise.
(new_mma_expand_builtin): Likewise.
(new_htm_expand_builtin): Likewise.
(rs6000_expand_new_builtin): New function.
---
 gcc/config/rs6000/rs6000-call.c | 526 
 1 file changed, 526 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 52df3d165e1..8693836cd5a 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -190,6 +190,7 @@ static tree builtin_function_type (machine_mode, 
machine_mode,
 static void rs6000_common_init_builtins (void);
 static void htm_init_builtins (void);
 static void mma_init_builtins (void);
+static rtx rs6000_expand_new_builtin (tree, rtx, rtx, machine_mode, int);
 static bool rs6000_gimple_fold_new_builtin (gimple_stmt_iterator *gsi);
 
 
@@ -11664,6 +11665,14 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
 error ("%qs is not supported with the current options", name);
 }
 
+/* Raise an error message for a builtin function that is called without the
+   appropriate target options being set.  */
+
+static void
+rs6000_invalid_new_builtin (enum rs6000_gen_builtins fncode)
+{
+}
+
 /* Target hook for early folding of built-ins, shamelessly stolen
from ia64.c.  */
 
@@ -14193,6 +14202,9 @@ rs6000_expand_builtin (tree exp, rtx target, rtx 
subtarget ATTRIBUTE_UNUSED,
   machine_mode mode ATTRIBUTE_UNUSED,
   int ignore ATTRIBUTE_UNUSED)
 {
+  if (new_builtins_are_live)
+return rs6000_expand_new_builtin (exp, target, subtarget, mode, ignore);
+
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   enum rs6000_builtins fcode
 = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
@@ -14485,6 +14497,520 @@ rs6000_expand_builtin (tree exp, rtx target, rtx 
subtarget ATTRIBUTE_UNUSED,
   gcc_unreachable ();
 }
 
+/* Expand ALTIVEC_BUILTIN_MASK_FOR_LOAD.  */
+rtx
+rs6000_expand_ldst_mask (rtx target, tree arg0)
+ {
+  return target;
+ }
+
+/* Expand the CPU builtin in FCODE and store the result in TARGET.  */
+static rtx
+new_cpu_expand_builtin (enum rs6000_gen_builtins fcode,
+   tree exp ATTRIBUTE_UNUSED, rtx target)
+{
+  return target;
+}
+
+static insn_code
+elemrev_icode (rs6000_gen_builtins fcode)
+{
+  return (insn_code) 0;
+}
+
+static rtx
+ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
+{
+  return target;
+}
+
+static rtx
+lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
+  machine_mode tmode, machine_mode smode)
+{
+  return target;
+}
+
+static rtx
+lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
+  machine_mode tmode, machine_mode smode)
+{
+  return target;
+}
+
+static rtx
+stv_expand_builtin (insn_code icode, rtx *op,
+   machine_mode tmode, machine_mode smode)
+{
+  return NULL_RTX;
+}
+
+/* Expand the MMA built-in in EXP.  */
+static rtx
+new_mma_expand_builtin (tree exp, rtx target, insn_code icode,
+   rs6000_gen_builtins fcode)
+{
+  return target;
+}
+
+/* Expand the HTM builtin in EXP and store the result in TARGET.  */
+static rtx
+new_htm_expand_builtin (bifdata *bifaddr, rs6000_gen_builtins fcode,
+   tree exp, rtx target)
+{
+  return const0_rtx;
+}
+
+/* Expand an expression EXP that calls a built-in function,
+   with result going to TARGET if that's convenient
+   (and in mode MODE if that's convenient).
+   SUBTARGET may be used as the target for computing one of EXP's operands.
+   IGNORE is nonzero if the value is to be ignored.
+   Use the new builtin infrastructure.  */
+static rtx
+rs6000_expand_new_builtin (tree exp, rtx target,
+  rtx subtarget ATTRIBUTE_UNUSED,
+  machine_mode ignore_mode ATTRIBUTE_UNUSED,
+  int ignore ATTRIBUTE_UNUSED)
+{
+  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+  enum rs6000_gen_builtins fcode
+= (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
+  size_t uns_fcode = (size_t)fcode;
+  enum insn_code icode = rs6000_builtin_info_x[uns_fcode].icode;
+
+  /* We have two different modes (KFmode, TFmode) that are the IEEE 128-bit
+ floating point type, depending on whether long double is the IBM extended
+ double (KFmode) or long double is IEEE 128-bit (TFmode).  It is simpler if
+ we only define one variant of the 

[PATCH 43/55] rs6000: Support for vectorizing built-in functions

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-05  Bill Schmidt  

gcc/
* config/rs6000/rs6000.c (rs6000-builtins.h): New include.
(rs6000_new_builtin_vectorized_function): New function.
(rs6000_new_builtin_md_vectorized_function): Likewise.
(rs6000_builtin_vectorized_function): Call
rs6000_new_builtin_vectorized_function.
(rs6000_builtin_md_vectorized_function): Call
rs6000_new_builtin_md_vectorized_function.
---
 gcc/config/rs6000/rs6000.c | 200 +
 1 file changed, 200 insertions(+)

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 38f928134f3..70a2be90787 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -77,6 +77,7 @@
 #include "case-cfn-macros.h"
 #include "ppc-auxv.h"
 #include "rs6000-internal.h"
+#include "rs6000-builtins.h"
 #include "opts.h"
 
 /* This file should be included last.  */
@@ -5488,6 +5489,198 @@ rs6000_loop_unroll_adjust (unsigned nunroll, struct 
loop *loop)
   return nunroll;
 }
 
+/* Returns a function decl for a vectorized version of the builtin function
+   with builtin function code FN and the result vector type TYPE, or NULL_TREE
+   if it is not available.  */
+
+static tree
+rs6000_new_builtin_vectorized_function (unsigned int fn, tree type_out,
+   tree type_in)
+{
+  machine_mode in_mode, out_mode;
+  int in_n, out_n;
+
+  if (TARGET_DEBUG_BUILTIN)
+fprintf (stderr, "rs6000_new_builtin_vectorized_function (%s, %s, %s)\n",
+combined_fn_name (combined_fn (fn)),
+GET_MODE_NAME (TYPE_MODE (type_out)),
+GET_MODE_NAME (TYPE_MODE (type_in)));
+
+  if (TREE_CODE (type_out) != VECTOR_TYPE
+  || TREE_CODE (type_in) != VECTOR_TYPE)
+return NULL_TREE;
+
+  out_mode = TYPE_MODE (TREE_TYPE (type_out));
+  out_n = TYPE_VECTOR_SUBPARTS (type_out);
+  in_mode = TYPE_MODE (TREE_TYPE (type_in));
+  in_n = TYPE_VECTOR_SUBPARTS (type_in);
+
+  switch (fn)
+{
+CASE_CFN_COPYSIGN:
+  if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+   return rs6000_builtin_decls_x[RS6000_BIF_CPSGNDP];
+  if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return rs6000_builtin_decls_x[RS6000_BIF_CPSGNSP];
+  if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return rs6000_builtin_decls_x[RS6000_BIF_COPYSIGN_V4SF];
+  break;
+CASE_CFN_CEIL:
+  if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+   return rs6000_builtin_decls_x[RS6000_BIF_XVRDPIP];
+  if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return rs6000_builtin_decls_x[RS6000_BIF_XVRSPIP];
+  if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return rs6000_builtin_decls_x[RS6000_BIF_VRFIP];
+  break;
+CASE_CFN_FLOOR:
+  if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+   return rs6000_builtin_decls_x[RS6000_BIF_XVRDPIM];
+  if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return rs6000_builtin_decls_x[RS6000_BIF_XVRSPIM];
+  if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return rs6000_builtin_decls_x[RS6000_BIF_VRFIM];
+  break;
+CASE_CFN_FMA:
+  if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+   return rs6000_builtin_decls_x[RS6000_BIF_XVMADDDP];
+  if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return rs6000_builtin_decls_x[RS6000_BIF_XVMADDSP];
+  if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return rs6000_builtin_decls_x[RS6000_BIF_VMADDFP];
+  break;
+CASE_CFN_TRUNC:
+  if (VECTOR_UNIT_VSX_P (V2DFmode)
+ && out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+   return rs6000_builtin_decls_x[RS6000_BIF_XVRDPIZ];
+  if (VECTOR_UNIT_VSX_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return rs6000_builtin_decls_x[RS6000_BIF_XVRSPIZ];
+  if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
+ && out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+   return 

[PATCH 42/55] rs6000: Handle gimple folding of target built-ins

2021-06-17 Thread Bill Schmidt via Gcc-patches
This is another patch that looks bigger than it really is.  Because we
have a new namespace for the builtins, allowing us to have both the old
and new builtin infrastructure supported at once, we need versions of
these functions that use the new builtin namespace.  Otherwise the code is
unchanged.

2021-06-17  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (rs6000_gimple_fold_new_builtin):
New forward decl.
(rs6000_gimple_fold_builtin): Call rs6000_gimple_fold_new_builtin.
(rs6000_new_builtin_valid_without_lhs): New function.
(rs6000_gimple_fold_new_mma_builtin): Likewise.
(rs6000_gimple_fold_new_builtin): Likewise.
---
 gcc/config/rs6000/rs6000-call.c | 1152 +++
 1 file changed, 1152 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 269fddcdc7e..52df3d165e1 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -190,6 +190,7 @@ static tree builtin_function_type (machine_mode, 
machine_mode,
 static void rs6000_common_init_builtins (void);
 static void htm_init_builtins (void);
 static void mma_init_builtins (void);
+static bool rs6000_gimple_fold_new_builtin (gimple_stmt_iterator *gsi);
 
 
 /* Hash table to keep track of the argument types for builtin functions.  */
@@ -11992,6 +11993,9 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator 
*gsi)
 bool
 rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
 {
+  if (new_builtins_are_live)
+return rs6000_gimple_fold_new_builtin (gsi);
+
   gimple *stmt = gsi_stmt (*gsi);
   tree fndecl = gimple_call_fndecl (stmt);
   gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
@@ -12939,6 +12943,35 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
   return false;
 }
 
+/*  Helper function to sort out which built-ins may be valid without having
+a LHS.  */
+static bool
+rs6000_new_builtin_valid_without_lhs (enum rs6000_gen_builtins fn_code,
+ tree fndecl)
+{
+  if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node)
+return true;
+
+  switch (fn_code)
+{
+case RS6000_BIF_STVX_V16QI:
+case RS6000_BIF_STVX_V8HI:
+case RS6000_BIF_STVX_V4SI:
+case RS6000_BIF_STVX_V4SF:
+case RS6000_BIF_STVX_V2DI:
+case RS6000_BIF_STVX_V2DF:
+case RS6000_BIF_STXVW4X_V16QI:
+case RS6000_BIF_STXVW4X_V8HI:
+case RS6000_BIF_STXVW4X_V4SF:
+case RS6000_BIF_STXVW4X_V4SI:
+case RS6000_BIF_STXVD2X_V2DF:
+case RS6000_BIF_STXVD2X_V2DI:
+  return true;
+default:
+  return false;
+}
+}
+
 /* Check whether a builtin function is supported in this target
configuration.  */
 bool
@@ -13030,6 +13063,1125 @@ rs6000_new_builtin_is_supported_p (enum 
rs6000_gen_builtins fncode)
   return true;
 }
 
+/* Expand the MMA built-ins early, so that we can convert the pass-by-reference
+   __vector_quad arguments into pass-by-value arguments, leading to more
+   efficient code generation.  */
+static bool
+rs6000_gimple_fold_new_mma_builtin (gimple_stmt_iterator *gsi,
+   rs6000_gen_builtins fn_code)
+{
+  gimple *stmt = gsi_stmt (*gsi);
+  size_t fncode = (size_t) fn_code;
+
+  if (!bif_is_mma (rs6000_builtin_info_x[fncode]))
+return false;
+
+  /* Each call that can be gimple-expanded has an associated built-in
+ function that it will expand into.  If this one doesn't, we have
+ already expanded it!  */
+  if (rs6000_builtin_info_x[fncode].assoc_bif == RS6000_BIF_NONE)
+return false;
+
+  bifdata *bd = _builtin_info_x[fncode];
+  unsigned nopnds = bd->nargs;
+  gimple_seq new_seq = NULL;
+  gimple *new_call;
+  tree new_decl;
+
+  /* Compatibility built-ins; we used to call these
+ __builtin_mma_{dis,}assemble_pair, but now we call them
+ __builtin_vsx_{dis,}assemble_pair.  Handle the old verions.  */
+  if (fncode == RS6000_BIF_ASSEMBLE_PAIR)
+fncode = RS6000_BIF_ASSEMBLE_PAIR_V;
+  else if (fncode == RS6000_BIF_DISASSEMBLE_PAIR)
+fncode = RS6000_BIF_DISASSEMBLE_PAIR_V;
+
+  if (fncode == RS6000_BIF_DISASSEMBLE_ACC
+  || fncode == RS6000_BIF_DISASSEMBLE_PAIR_V)
+{
+  /* This is an MMA disassemble built-in function.  */
+  push_gimplify_context (true);
+  unsigned nvec = (fncode == RS6000_BIF_DISASSEMBLE_ACC) ? 4 : 2;
+  tree dst_ptr = gimple_call_arg (stmt, 0);
+  tree src_ptr = gimple_call_arg (stmt, 1);
+  tree src_type = TREE_TYPE (src_ptr);
+  tree src = create_tmp_reg_or_ssa_name (TREE_TYPE (src_type));
+  gimplify_assign (src, build_simple_mem_ref (src_ptr), _seq);
+
+  /* If we are not disassembling an accumulator/pair or our destination is
+another accumulator/pair, then just copy the entire thing as is.  */
+  if ((fncode == RS6000_BIF_DISASSEMBLE_ACC
+  && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_quad_type_node)
+ || (fncode == RS6000_BIF_DISASSEMBLE_PAIR_V

[PATCH 41/55] rs6000: Handle overloads during program parsing

2021-06-17 Thread Bill Schmidt via Gcc-patches
Although this patch looks quite large, the changes are fairly minimal.
Most of it is duplicating the large function that does the overload
resolution using the automatically generated data structures instead of
the old hand-generated ones.  This doesn't make the patch terribly easy to
review, unfortunately.  Just be aware that generally we aren't changing
the logic and functionality of overload handling.

2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-c.c (rs6000-builtins.h): New include.
(altivec_resolve_new_overloaded_builtin): New forward decl.
(rs6000_new_builtin_type_compatible): New function.
(altivec_resolve_overloaded_builtin): Call
altivec_resolve_new_overloaded_builtin.
(altivec_build_new_resolved_builtin): New function.
(altivec_resolve_new_overloaded_builtin): Likewise.
* config/rs6000/rs6000-call.c (rs6000_new_builtin_is_supported_p):
Likewise.
---
 gcc/config/rs6000/rs6000-c.c| 1083 +++
 gcc/config/rs6000/rs6000-call.c |   91 +++
 2 files changed, 1174 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index afcb5bb6e39..a986e57fe7d 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -35,6 +35,10 @@
 #include "langhooks.h"
 #include "c/c-tree.h"
 
+#include "rs6000-builtins.h"
+
+static tree
+altivec_resolve_new_overloaded_builtin (location_t, tree, void *);
 
 
 /* Handle the machine specific pragma longcall.  Its syntax is
@@ -811,6 +815,30 @@ is_float128_p (tree t)
  && t == long_double_type_node));
 }
   
+static bool
+rs6000_new_builtin_type_compatible (tree t, tree u)
+{
+  if (t == error_mark_node)
+return false;
+
+  if (INTEGRAL_TYPE_P (t) && INTEGRAL_TYPE_P (u))
+return true;
+
+  if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
+  && is_float128_p (t) && is_float128_p (u))
+return true;
+
+  if (POINTER_TYPE_P (t) && POINTER_TYPE_P (u))
+{
+  t = TREE_TYPE (t);
+  u = TREE_TYPE (u);
+  if (TYPE_READONLY (u))
+   t = build_qualified_type (t, TYPE_QUAL_CONST);
+}
+
+  return lang_hooks.types_compatible_p (t, u);
+}
+
 static inline bool
 rs6000_builtin_type_compatible (tree t, int id)
 {
@@ -927,6 +955,10 @@ tree
 altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
void *passed_arglist)
 {
+  if (new_builtins_are_live)
+return altivec_resolve_new_overloaded_builtin (loc, fndecl,
+  passed_arglist);
+
   vec *arglist = static_cast *> (passed_arglist);
   unsigned int nargs = vec_safe_length (arglist);
   enum rs6000_builtins fcode
@@ -1930,3 +1962,1054 @@ altivec_resolve_overloaded_builtin (location_t loc, 
tree fndecl,
 return error_mark_node;
   }
 }
+
+/* Build a tree for a function call to an Altivec non-overloaded builtin.
+   The overloaded builtin that matched the types and args is described
+   by DESC.  The N arguments are given in ARGS, respectively.
+
+   Actually the only thing it does is calling fold_convert on ARGS, with
+   a small exception for vec_{all,any}_{ge,le} predicates. */
+
+static tree
+altivec_build_new_resolved_builtin (tree *args, int n, tree fntype,
+   tree ret_type,
+   rs6000_gen_builtins bif_id,
+   rs6000_gen_builtins ovld_id)
+{
+  tree argtypes = TYPE_ARG_TYPES (fntype);
+  tree arg_type[MAX_OVLD_ARGS];
+  tree fndecl = rs6000_builtin_decls_x[bif_id];
+  tree call;
+
+  for (int i = 0; i < n; i++)
+arg_type[i] = TREE_VALUE (argtypes), argtypes = TREE_CHAIN (argtypes);
+
+  /* The AltiVec overloading implementation is overall gross, but this
+ is particularly disgusting.  The vec_{all,any}_{ge,le} builtins
+ are completely different for floating-point vs. integer vector
+ types, because the former has vcmpgefp, but the latter should use
+ vcmpgtXX.
+
+ In practice, the second and third arguments are swapped, and the
+ condition (LT vs. EQ, which is recognizable by bit 1 of the first
+ argument) is reversed.  Patch the arguments here before building
+ the resolved CALL_EXPR.  */
+  if (n == 3
+  && ovld_id == RS6000_OVLD_VEC_CMPGE_P
+  && bif_id != RS6000_BIF_VCMPGEFP_P
+  && bif_id != RS6000_BIF_XVCMPGEDP_P)
+{
+  std::swap (args[1], args[2]);
+  std::swap (arg_type[1], arg_type[2]);
+
+  args[0] = fold_build2 (BIT_XOR_EXPR, TREE_TYPE (args[0]), args[0],
+build_int_cst (NULL_TREE, 2));
+}
+
+  /* If the number of arguments to an overloaded function increases,
+ we must expand this switch.  */
+  gcc_assert (MAX_OVLD_ARGS <= 4);
+
+  switch (n)
+{
+case 0:
+  call = build_call_expr (fndecl, 0);
+  break;
+case 1:
+  call = build_call_expr (fndecl, 1,
+ fully_fold_convert 

[PATCH 40/55] rs6000: Always initialize vector_pair and vector_quad nodes

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-24  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (rs6000_init_builtins): Remove
TARGET_EXTRA_BUILTINS guard.
---
 gcc/config/rs6000/rs6000-call.c | 51 -
 1 file changed, 24 insertions(+), 27 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index bf832b81a16..731eed4b04b 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -13516,34 +13516,31 @@ rs6000_init_builtins (void)
 ieee128_float_type_node = ibm128_float_type_node = long_double_type_node;
 
   /* Vector pair and vector quad support.  */
-  if (TARGET_EXTRA_BUILTINS)
-{
-  vector_pair_type_node = make_node (OPAQUE_TYPE);
-  SET_TYPE_MODE (vector_pair_type_node, OOmode);
-  TYPE_SIZE (vector_pair_type_node) = bitsize_int (GET_MODE_BITSIZE 
(OOmode));
-  TYPE_PRECISION (vector_pair_type_node) = GET_MODE_BITSIZE (OOmode);
-  TYPE_SIZE_UNIT (vector_pair_type_node) = size_int (GET_MODE_SIZE 
(OOmode));
-  SET_TYPE_ALIGN (vector_pair_type_node, 256);
-  TYPE_USER_ALIGN (vector_pair_type_node) = 0;
-  lang_hooks.types.register_builtin_type (vector_pair_type_node,
- "__vector_pair");
-  ptr_vector_pair_type_node
-   = build_pointer_type (build_qualified_type (vector_pair_type_node,
-   TYPE_QUAL_CONST));
+  vector_pair_type_node = make_node (OPAQUE_TYPE);
+  SET_TYPE_MODE (vector_pair_type_node, OOmode);
+  TYPE_SIZE (vector_pair_type_node) = bitsize_int (GET_MODE_BITSIZE (OOmode));
+  TYPE_PRECISION (vector_pair_type_node) = GET_MODE_BITSIZE (OOmode);
+  TYPE_SIZE_UNIT (vector_pair_type_node) = size_int (GET_MODE_SIZE (OOmode));
+  SET_TYPE_ALIGN (vector_pair_type_node, 256);
+  TYPE_USER_ALIGN (vector_pair_type_node) = 0;
+  lang_hooks.types.register_builtin_type (vector_pair_type_node,
+ "__vector_pair");
+  ptr_vector_pair_type_node
+= build_pointer_type (build_qualified_type (vector_pair_type_node,
+   TYPE_QUAL_CONST));
 
-  vector_quad_type_node = make_node (OPAQUE_TYPE);
-  SET_TYPE_MODE (vector_quad_type_node, XOmode);
-  TYPE_SIZE (vector_quad_type_node) = bitsize_int (GET_MODE_BITSIZE 
(XOmode));
-  TYPE_PRECISION (vector_quad_type_node) = GET_MODE_BITSIZE (XOmode);
-  TYPE_SIZE_UNIT (vector_quad_type_node) = size_int (GET_MODE_SIZE 
(XOmode));
-  SET_TYPE_ALIGN (vector_quad_type_node, 512);
-  TYPE_USER_ALIGN (vector_quad_type_node) = 0;
-  lang_hooks.types.register_builtin_type (vector_quad_type_node,
- "__vector_quad");
-  ptr_vector_quad_type_node
-   = build_pointer_type (build_qualified_type (vector_quad_type_node,
-   TYPE_QUAL_CONST));
-}
+  vector_quad_type_node = make_node (OPAQUE_TYPE);
+  SET_TYPE_MODE (vector_quad_type_node, XOmode);
+  TYPE_SIZE (vector_quad_type_node) = bitsize_int (GET_MODE_BITSIZE (XOmode));
+  TYPE_PRECISION (vector_quad_type_node) = GET_MODE_BITSIZE (XOmode);
+  TYPE_SIZE_UNIT (vector_quad_type_node) = size_int (GET_MODE_SIZE (XOmode));
+  SET_TYPE_ALIGN (vector_quad_type_node, 512);
+  TYPE_USER_ALIGN (vector_quad_type_node) = 0;
+  lang_hooks.types.register_builtin_type (vector_quad_type_node,
+ "__vector_quad");
+  ptr_vector_quad_type_node
+= build_pointer_type (build_qualified_type (vector_quad_type_node,
+   TYPE_QUAL_CONST));
 
   /* Initialize the modes for builtin_function_type, mapping a machine mode to
  tree type node.  */
-- 
2.27.0



[PATCH 39/55] rs6000: Add sanity to V2DI_type_node definitions

2021-06-17 Thread Bill Schmidt via Gcc-patches
It seems quite strange for these to be "vector long" for 64-bit and
"vector long long" for 32-bit, when "vector long long" will do for both.

2021-03-04  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (rs6000_init_builtins): Change
initialization of V2DI_type_node and unsigned_V2DI_type_node.
---
 gcc/config/rs6000/rs6000-call.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 14c257cfddf..bf832b81a16 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -13270,9 +13270,13 @@ rs6000_init_builtins (void)
 (TARGET_ALTIVEC)  ? ", altivec" : "",
 (TARGET_VSX)  ? ", vsx" : "");
 
-  V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 ? "__vector long"
-  : "__vector long long",
-  long_long_integer_type_node, 2);
+  if (new_builtins_are_live)
+V2DI_type_node = rs6000_vector_type ("__vector long long",
+long_long_integer_type_node, 2);
+  else
+V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 ? "__vector long"
+: "__vector long long",
+long_long_integer_type_node, 2);
   ptr_V2DI_type_node
 = build_pointer_type (build_qualified_type (V2DI_type_node,
TYPE_QUAL_CONST));
@@ -13323,7 +13327,12 @@ rs6000_init_builtins (void)
 = build_pointer_type (build_qualified_type (unsigned_V4SI_type_node,
TYPE_QUAL_CONST));
 
-  unsigned_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
+  if (new_builtins_are_live)
+unsigned_V2DI_type_node
+  = rs6000_vector_type ("__vector unsigned long long",
+   long_long_unsigned_type_node, 2);
+  else
+unsigned_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
   ? "__vector unsigned long"
   : "__vector unsigned long long",
   long_long_unsigned_type_node, 2);
-- 
2.27.0



[PATCH 38/55] rs6000: Darwin builtin support

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-04  Bill Schmidt  

gcc/
* config/rs6000/darwin.h (SUBTARGET_INIT_BUILTINS): Use the new
decl when new_builtins_are_live.
* config/rs6000/rs6000-builtin-new.def (__builtin_cfstring): New
built-in.
---
 gcc/config/rs6000/darwin.h   | 8 ++--
 gcc/config/rs6000/rs6000-builtin-new.def | 6 ++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h
index 42f39e60305..6abf8e84f54 100644
--- a/gcc/config/rs6000/darwin.h
+++ b/gcc/config/rs6000/darwin.h
@@ -504,8 +504,12 @@
 #define SUBTARGET_INIT_BUILTINS
\
 do {   \
   darwin_patch_builtins ();\
-  rs6000_builtin_decls[(unsigned) (RS6000_BUILTIN_CFSTRING)]   \
-= darwin_init_cfstring_builtins ((unsigned) (RS6000_BUILTIN_CFSTRING)); \
+  if (new_builtins_are_live)   \
+rs6000_builtin_decls_x[(unsigned) (RS6000_BIF_CFSTRING)]   \
+  = darwin_init_cfstring_builtins ((unsigned) (RS6000_BIF_CFSTRING)); \
+  else \
+rs6000_builtin_decls[(unsigned) (RS6000_BUILTIN_CFSTRING)] \
+  = darwin_init_cfstring_builtins ((unsigned) (RS6000_BUILTIN_CFSTRING)); \
 } while(0)
 
 /* So far, there is no rs6000_fold_builtin, if one is introduced, then
diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 4b640cac654..b7e92b05baa 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -187,6 +187,12 @@
 ; Builtins that have been around since time immemorial or are just
 ; considered available everywhere.
 [always]
+; __builtin_cfstring is for Darwin, which will replace the decl we
+; create here with another one during subtarget processing.  We just
+; need to ensure it has a slot in the builtin enumeration.
+  void __builtin_cfstring ();
+CFSTRING nothing {}
+
   void __builtin_cpu_init ();
 CPU_INIT nothing {cpu}
 
-- 
2.27.0



[PATCH 37/55] rs6000: Execute the automatic built-in initialization code

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-03-04  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (rs6000-builtins.h): New #include.
(rs6000_init_builtins): Call rs6000_autoinit_builtins; skip the old
initialization logic when new builtins are enabled.
---
 gcc/config/rs6000/rs6000-call.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index d9be017ee61..14c257cfddf 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -69,6 +69,7 @@
 #include "opts.h"
 
 #include "rs6000-internal.h"
+#include "rs6000-builtins.h"
 
 #if TARGET_MACHO
 #include "gstab.h"  /* for N_SLINE */
@@ -13622,6 +13623,17 @@ rs6000_init_builtins (void)
 = build_pointer_type (build_qualified_type (void_type_node,
TYPE_QUAL_CONST));
 
+  /* Execute the autogenerated initialization code for builtins.  */
+  rs6000_autoinit_builtins ();
+
+  if (new_builtins_are_live)
+{
+#ifdef SUBTARGET_INIT_BUILTINS
+  SUBTARGET_INIT_BUILTINS;
+#endif
+  return;
+}
+
   /* Create Altivec, VSX and MMA builtins on machines with at least the
  general purpose extensions (970 and newer) to allow the use of
  the target attribute.  */
-- 
2.27.0



[PATCH 35/55] rs6000: Add Cell builtins

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Add cell stanza.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 27 
 1 file changed, 27 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index b6f4b604383..4b640cac654 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -1102,6 +1102,33 @@
 VEC_SET_V8HI nothing {set}
 
 
+; Cell builtins.
+[cell]
+  pure vsc __builtin_altivec_lvlx (signed long, const void *);
+LVLX altivec_lvlx {ldvec}
+
+  pure vsc __builtin_altivec_lvlxl (signed long, const void *);
+LVLXL altivec_lvlxl {ldvec}
+
+  pure vsc __builtin_altivec_lvrx (signed long, const void *);
+LVRX altivec_lvrx {ldvec}
+
+  pure vsc __builtin_altivec_lvrxl (signed long, const void *);
+LVRXL altivec_lvrxl {ldvec}
+
+  void __builtin_altivec_stvlx (vsc, signed long, void *);
+STVLX altivec_stvlx {stvec}
+
+  void __builtin_altivec_stvlxl (vsc, signed long, void *);
+STVLXL altivec_stvlxl {stvec}
+
+  void __builtin_altivec_stvrx (vsc, signed long, void *);
+STVRX altivec_stvrx {stvec}
+
+  void __builtin_altivec_stvrxl (vsc, signed long, void *);
+STVRXL altivec_stvrxl {stvec}
+
+
 ; VSX builtins.
 [vsx]
   pure vd __builtin_altivec_lvx_v2df (signed long, const void *);
-- 
2.27.0



[PATCH 34/55] rs6000: Add miscellaneous builtins

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-15  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Add ieee128-hw, dfp,
crypto, and htm stanzas.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 215 +++
 1 file changed, 215 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index f3e1c8bbd82..b6f4b604383 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -2811,6 +2811,221 @@
 XL_LEN_R xl_len_r {}
 
 
+; Builtins requiring hardware support for IEEE-128 floating-point.
+[ieee128-hw]
+  fpmath _Float128 __builtin_addf128_round_to_odd (_Float128, _Float128);
+ADDF128_ODD addkf3_odd {}
+
+  fpmath _Float128 __builtin_divf128_round_to_odd (_Float128, _Float128);
+DIVF128_ODD divkf3_odd {}
+
+  fpmath _Float128 __builtin_fmaf128_round_to_odd (_Float128, _Float128, 
_Float128);
+FMAF128_ODD fmakf4_odd {}
+
+  fpmath _Float128 __builtin_mulf128_round_to_odd (_Float128, _Float128);
+MULF128_ODD mulkf3_odd {}
+
+  const signed int __builtin_vsx_scalar_cmp_exp_qp_eq (_Float128, _Float128);
+VSCEQPEQ xscmpexpqp_eq_kf {}
+
+  const signed int __builtin_vsx_scalar_cmp_exp_qp_gt (_Float128, _Float128);
+VSCEQPGT xscmpexpqp_gt_kf {}
+
+  const signed int __builtin_vsx_scalar_cmp_exp_qp_lt (_Float128, _Float128);
+VSCEQPLT xscmpexpqp_lt_kf {}
+
+  const signed int __builtin_vsx_scalar_cmp_exp_qp_unordered (_Float128, 
_Float128);
+VSCEQPUO xscmpexpqp_unordered_kf {}
+
+  fpmath _Float128 __builtin_sqrtf128_round_to_odd (_Float128);
+SQRTF128_ODD sqrtkf2_odd {}
+
+  fpmath _Float128 __builtin_subf128_round_to_odd (_Float128, _Float128);
+SUBF128_ODD subkf3_odd {}
+
+  fpmath double __builtin_truncf128_round_to_odd (_Float128);
+TRUNCF128_ODD trunckfdf2_odd {}
+
+  const signed long long __builtin_vsx_scalar_extract_expq (_Float128);
+VSEEQP xsxexpqp_kf {}
+
+  const signed __int128 __builtin_vsx_scalar_extract_sigq (_Float128);
+VSESQP xsxsigqp_kf {}
+
+  const _Float128 __builtin_vsx_scalar_insert_exp_q (unsigned __int128, 
unsigned long long);
+VSIEQP xsiexpqp_kf {}
+
+  const _Float128 __builtin_vsx_scalar_insert_exp_qp (_Float128, unsigned long 
long);
+VSIEQPF xsiexpqpf_kf {}
+
+  const signed int __builtin_vsx_scalar_test_data_class_qp (_Float128, const 
int<7>);
+VSTDCQP xststdcqp_kf {}
+
+  const signed int __builtin_vsx_scalar_test_neg_qp (_Float128);
+VSTDCNQP xststdcnegqp_kf {}
+
+
+
+; Decimal floating-point builtins.
+[dfp]
+  const _Decimal64 __builtin_ddedpd (const int<2>, _Decimal64);
+DDEDPD dfp_ddedpd_dd {}
+
+  const _Decimal128 __builtin_ddedpdq (const int<2>, _Decimal128);
+DDEDPDQ dfp_ddedpd_td {}
+
+  const _Decimal64 __builtin_denbcd (const int<1>, _Decimal64);
+DENBCD dfp_denbcd_dd {}
+
+  const _Decimal128 __builtin_denbcdq (const int<1>, _Decimal128);
+DENBCDQ dfp_denbcd_td {}
+
+  const _Decimal128 __builtin_denb2dfp_v16qi (vsc);
+DENB2DFP_V16QI dfp_denbcd_v16qi {}
+
+  const _Decimal64 __builtin_diex (signed long long, _Decimal64);
+DIEX dfp_diex_dd {}
+
+  const _Decimal128 __builtin_diexq (signed long long, _Decimal128);
+DIEXQ dfp_diex_td {}
+
+  const _Decimal64 __builtin_dscli (_Decimal64, const int<6>);
+DSCLI dfp_dscli_dd {}
+
+  const _Decimal128 __builtin_dscliq (_Decimal128, const int<6>);
+DSCLIQ dfp_dscli_td {}
+
+  const _Decimal64 __builtin_dscri (_Decimal64, const int<6>);
+DSCRI dfp_dscri_dd {}
+
+  const _Decimal128 __builtin_dscriq (_Decimal128, const int<6>);
+DSCRIQ dfp_dscri_td {}
+
+  const signed long long __builtin_dxex (_Decimal64);
+DXEX dfp_dxex_dd {}
+
+  const signed long long __builtin_dxexq (_Decimal128);
+DXEXQ dfp_dxex_td {}
+
+  const _Decimal128 __builtin_pack_dec128 (unsigned long long, unsigned long 
long);
+PACK_TD packtd {}
+
+  void __builtin_set_fpscr_drn (const int[0,7]);
+SET_FPSCR_DRN rs6000_set_fpscr_drn {}
+
+  const unsigned long __builtin_unpack_dec128 (_Decimal128, const int<1>);
+UNPACK_TD unpacktd {}
+
+
+[crypto]
+  const vull __builtin_crypto_vcipher (vull, vull);
+VCIPHER crypto_vcipher_v2di {}
+
+  const vuc __builtin_crypto_vcipher_be (vuc, vuc);
+VCIPHER_BE crypto_vcipher_v16qi {}
+
+  const vull __builtin_crypto_vcipherlast (vull, vull);
+VCIPHERLAST crypto_vcipherlast_v2di {}
+
+  const vuc __builtin_crypto_vcipherlast_be (vuc, vuc);
+VCIPHERLAST_BE crypto_vcipherlast_v16qi {}
+
+  const vull __builtin_crypto_vncipher (vull, vull);
+VNCIPHER crypto_vncipher_v2di {}
+
+  const vuc __builtin_crypto_vncipher_be (vuc, vuc);
+VNCIPHER_BE crypto_vncipher_v16qi {}
+
+  const vull __builtin_crypto_vncipherlast (vull, vull);
+VNCIPHERLAST crypto_vncipherlast_v2di {}
+
+  const vuc __builtin_crypto_vncipherlast_be (vuc, vuc);
+VNCIPHERLAST_BE crypto_vncipherlast_v16qi {}
+
+  const vull __builtin_crypto_vsbox (vull);
+VSBOX crypto_vsbox_v2di {}
+
+  const 

[PATCH 33/55] rs6000: Add MMA builtins

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-16  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Add mma stanza.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 416 +++
 1 file changed, 416 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index b0e12a0ed9b..f3e1c8bbd82 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -3332,3 +3332,419 @@
 
   const unsigned long long __builtin_pextd (unsigned long long, unsigned long 
long);
 PEXTD pextd {}
+
+
+[mma]
+  void __builtin_mma_assemble_acc (v512 *, vuc, vuc, vuc, vuc);
+ASSEMBLE_ACC nothing {mma}
+
+  v512 __builtin_mma_assemble_acc_internal (vuc, vuc, vuc, vuc);
+ASSEMBLE_ACC_INTERNAL mma_assemble_acc {mma}
+
+  void __builtin_mma_assemble_pair (v256 *, vuc, vuc);
+ASSEMBLE_PAIR nothing {mma}
+
+  v256 __builtin_mma_assemble_pair_internal (vuc, vuc);
+ASSEMBLE_PAIR_INTERNAL vsx_assemble_pair {mma}
+
+  void __builtin_mma_build_acc (v512 *, vuc, vuc, vuc, vuc);
+BUILD_ACC nothing {mma}
+
+  v512 __builtin_mma_build_acc_internal (vuc, vuc, vuc, vuc);
+BUILD_ACC_INTERNAL mma_assemble_acc {mma}
+
+  void __builtin_mma_disassemble_acc (void *, v512 *);
+DISASSEMBLE_ACC nothing {mma,quad}
+
+  vuc __builtin_mma_disassemble_acc_internal (v512, const int<2>);
+DISASSEMBLE_ACC_INTERNAL mma_disassemble_acc {mma}
+
+  void __builtin_mma_disassemble_pair (void *, v256 *);
+DISASSEMBLE_PAIR nothing {mma,pair}
+
+  vuc __builtin_mma_disassemble_pair_internal (v256, const int<2>);
+DISASSEMBLE_PAIR_INTERNAL vsx_disassemble_pair {mma}
+
+  void __builtin_mma_pmxvbf16ger2 (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVBF16GER2 nothing {mma}
+
+  v512 __builtin_mma_pmxvbf16ger2_internal (vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVBF16GER2_INTERNAL mma_pmxvbf16ger2 {mma}
+
+  void __builtin_mma_pmxvbf16ger2nn (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVBF16GER2NN nothing {mma,quad}
+
+  v512 __builtin_mma_pmxvbf16ger2nn_internal (v512, vuc, vuc, const int<4>, 
const int<4>, const int<2>);
+PMXVBF16GER2NN_INTERNAL mma_pmxvbf16ger2nn {mma,quad}
+
+  void __builtin_mma_pmxvbf16ger2np (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVBF16GER2NP nothing {mma,quad}
+
+  v512 __builtin_mma_pmxvbf16ger2np_internal (v512, vuc, vuc, const int<4>, 
const int<4>, const int<2>);
+PMXVBF16GER2NP_INTERNAL mma_pmxvbf16ger2np {mma,quad}
+
+  void __builtin_mma_pmxvbf16ger2pn (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVBF16GER2PN nothing {mma,quad}
+
+  v512 __builtin_mma_pmxvbf16ger2pn_internal (v512, vuc, vuc, const int<4>, 
const int<4>, const int<2>);
+PMXVBF16GER2PN_INTERNAL mma_pmxvbf16ger2pn {mma,quad}
+
+  void __builtin_mma_pmxvbf16ger2pp (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVBF16GER2PP nothing {mma,quad}
+
+  v512 __builtin_mma_pmxvbf16ger2pp_internal (v512, vuc, vuc, const int<4>, 
const int<4>, const int<2>);
+PMXVBF16GER2PP_INTERNAL mma_pmxvbf16ger2pp {mma,quad}
+
+  void __builtin_mma_pmxvf16ger2 (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVF16GER2 nothing {mma}
+
+  v512 __builtin_mma_pmxvf16ger2_internal (vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVF16GER2_INTERNAL mma_pmxvf16ger2 {mma}
+
+  void __builtin_mma_pmxvf16ger2nn (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVF16GER2NN nothing {mma,quad}
+
+  v512 __builtin_mma_pmxvf16ger2nn_internal (v512, vuc, vuc, const int<4>, 
const int<4>, const int<2>);
+PMXVF16GER2NN_INTERNAL mma_pmxvf16ger2nn {mma,quad}
+
+  void __builtin_mma_pmxvf16ger2np (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVF16GER2NP nothing {mma,quad}
+
+  v512 __builtin_mma_pmxvf16ger2np_internal (v512, vuc, vuc, const int<4>, 
const int<4>, const int<2>);
+PMXVF16GER2NP_INTERNAL mma_pmxvf16ger2np {mma,quad}
+
+  void __builtin_mma_pmxvf16ger2pn (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVF16GER2PN nothing {mma,quad}
+
+  v512 __builtin_mma_pmxvf16ger2pn_internal (v512, vuc, vuc, const int<4>, 
const int<4>, const int<2>);
+PMXVF16GER2PN_INTERNAL mma_pmxvf16ger2pn {mma,quad}
+
+  void __builtin_mma_pmxvf16ger2pp (v512 *, vuc, vuc, const int<4>, const 
int<4>, const int<2>);
+PMXVF16GER2PP nothing {mma,quad}
+
+  v512 __builtin_mma_pmxvf16ger2pp_internal (v512, vuc, vuc, const int<4>, 
const int<4>, const int<2>);
+PMXVF16GER2PP_INTERNAL mma_pmxvf16ger2pp {mma,quad}
+
+  void __builtin_mma_pmxvf32ger (v512 *, vuc, vuc, const int<4>, const int<4>);
+PMXVF32GER nothing {mma}
+
+  v512 __builtin_mma_pmxvf32ger_internal (vuc, vuc, const int<4>, const 
int<4>);
+PMXVF32GER_INTERNAL mma_pmxvf32ger {mma}
+
+  void __builtin_mma_pmxvf32gernn (v512 *, vuc, vuc, const int<4>, const 

[PATCH 32/55] rs6000: Add Power10 builtins

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-15  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Add power10 and power10-64
stanzas.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 523 +++
 1 file changed, 523 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 8885df089a6..b0e12a0ed9b 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -2809,3 +2809,526 @@
 
   pure vsc __builtin_vsx_xl_len_r (void *, signed long);
 XL_LEN_R xl_len_r {}
+
+
+[power10]
+  const vbq __builtin_altivec_cmpge_1ti (vsq, vsq);
+CMPGE_1TI vector_nltv1ti {}
+
+  const vbq __builtin_altivec_cmpge_u1ti (vuq, vuq);
+CMPGE_U1TI vector_nltuv1ti {}
+
+  const vbq __builtin_altivec_cmple_1ti (vsq, vsq);
+CMPLE_1TI vector_ngtv1ti {}
+
+  const vbq __builtin_altivec_cmple_u1ti (vuq, vuq);
+CMPLE_U1TI vector_ngtuv1ti {}
+
+  const unsigned long long __builtin_altivec_cntmbb (vuc, const int<1>);
+VCNTMBB vec_cntmb_v16qi {}
+
+  const unsigned long long __builtin_altivec_cntmbd (vull, const int<1>);
+VCNTMBD vec_cntmb_v2di {}
+
+  const unsigned long long __builtin_altivec_cntmbh (vus, const int<1>);
+VCNTMBH vec_cntmb_v8hi {}
+
+  const unsigned long long __builtin_altivec_cntmbw (vui, const int<1>);
+VCNTMBW vec_cntmb_v4si {}
+
+  const vsq __builtin_altivec_div_v1ti (vsq, vsq);
+DIV_V1TI vsx_div_v1ti {}
+
+  const vsq __builtin_altivec_dives (vsq, vsq);
+DIVES_V1TI vsx_dives_v1ti {}
+
+  const vuq __builtin_altivec_diveu (vuq, vuq);
+DIVEU_V1TI vsx_diveu_v1ti {}
+
+  const vsq __builtin_altivec_mods (vsq, vsq);
+MODS_V1TI vsx_mods_v1ti {}
+
+  const vuq __builtin_altivec_modu (vuq, vuq);
+MODU_V1TI vsx_modu_v1ti {}
+
+  const vuc __builtin_altivec_mtvsrbm (unsigned long long);
+MTVSRBM vec_mtvsr_v16qi {}
+
+  const vull __builtin_altivec_mtvsrdm (unsigned long long);
+MTVSRDM vec_mtvsr_v2di {}
+
+  const vus __builtin_altivec_mtvsrhm (unsigned long long);
+MTVSRHM vec_mtvsr_v8hi {}
+
+  const vuq __builtin_altivec_mtvsrqm (unsigned long long);
+MTVSRQM vec_mtvsr_v1ti {}
+
+  const vui __builtin_altivec_mtvsrwm (unsigned long long);
+MTVSRWM vec_mtvsr_v4si {}
+
+  pure signed __int128 __builtin_altivec_se_lxvrbx (signed long, const signed 
char *);
+SE_LXVRBX vsx_lxvrbx {lxvrse}
+
+  pure signed __int128 __builtin_altivec_se_lxvrhx (signed long, const signed 
short *);
+SE_LXVRHX vsx_lxvrhx {lxvrse}
+
+  pure signed __int128 __builtin_altivec_se_lxvrwx (signed long, const signed 
int *);
+SE_LXVRWX vsx_lxvrwx {lxvrse}
+
+  pure signed __int128 __builtin_altivec_se_lxvrdx (signed long, const signed 
long long *);
+SE_LXVRDX vsx_lxvrdx {lxvrse}
+
+  void __builtin_altivec_tr_stxvrbx (vsq, signed long, signed char *);
+TR_STXVRBX vsx_stxvrbx {stvec}
+
+  void __builtin_altivec_tr_stxvrhx (vsq, signed long, signed int *);
+TR_STXVRHX vsx_stxvrhx {stvec}
+
+  void __builtin_altivec_tr_stxvrwx (vsq, signed long, signed short *);
+TR_STXVRWX vsx_stxvrwx {stvec}
+
+  void __builtin_altivec_tr_stxvrdx (vsq, signed long, signed long long *);
+TR_STXVRDX vsx_stxvrdx {stvec}
+
+  const vuq __builtin_altivec_udiv_v1ti (vuq, vuq);
+UDIV_V1TI vsx_udiv_v1ti {}
+
+  const vull __builtin_altivec_vcfuged (vull, vull);
+VCFUGED vcfuged {}
+
+  const vsc __builtin_altivec_vclrlb (vsc, signed int);
+VCLRLB vclrlb {}
+
+  const vsc __builtin_altivec_vclrrb (vsc, signed int);
+VCLRRB vclrrb {}
+
+  const signed int __builtin_altivec_vcmpaet_p (vsq, vsq);
+VCMPAET_P vector_ae_v1ti_p {}
+
+  const vbq __builtin_altivec_vcmpequt (vsq, vsq);
+VCMPEQUT vector_eqv1ti {}
+
+  const signed int __builtin_altivec_vcmpequt_p (signed int, vsq, vsq);
+VCMPEQUT_P vector_eq_v1ti_p {pred}
+
+  const vbq __builtin_altivec_vcmpgtst (vsq, vsq);
+VCMPGTST vector_gtv1ti {}
+
+  const signed int __builtin_altivec_vcmpgtst_p (signed int, vsq, vsq);
+VCMPGTST_P vector_gt_v1ti_p {pred}
+
+  const vbq __builtin_altivec_vcmpgtut (vuq, vuq);
+VCMPGTUT vector_gtuv1ti {}
+
+  const signed int __builtin_altivec_vcmpgtut_p (signed int, vuq, vuq);
+VCMPGTUT_P vector_gtu_v1ti_p {pred}
+
+  const vbq __builtin_altivec_vcmpnet (vsq, vsq);
+VCMPNET vcmpnet {}
+
+  const signed int __builtin_altivec_vcmpnet_p (vsq, vsq);
+VCMPNET_P vector_ne_v1ti_p {}
+
+  const vull __builtin_altivec_vclzdm (vull, vull);
+VCLZDM vclzdm {}
+
+  const vull __builtin_altivec_vctzdm (vull, vull);
+VCTZDM vctzdm {}
+
+  const vsll __builtin_altivec_vdivesd (vsll, vsll);
+VDIVESD dives_v2di {}
+
+  const vsi __builtin_altivec_vdivesw (vsi, vsi);
+VDIVESW dives_v4si {}
+
+  const vull __builtin_altivec_vdiveud (vull, vull);
+VDIVEUD diveu_v2di {}
+
+  const vui __builtin_altivec_vdiveuw (vui, vui);
+VDIVEUW diveu_v4si {}
+
+  const vsll __builtin_altivec_vdivsd (vsll, vsll);
+VDIVSD divv2di3 {}
+
+  const vsi 

[PATCH 31/55] rs6000: Add more type nodes to support builtin processing

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-10  Bill Schmidt  

gcc/
* config/rs6000/rs6000-call.c (rs6000_init_builtins): Initialize
various pointer type nodes.
* config/rs6000/rs6000.h (rs6000_builtin_type_index): Add enum
values for various pointer types.
(ptr_V16QI_type_node): New macro.
(ptr_V1TI_type_node): New macro.
(ptr_V2DI_type_node): New macro.
(ptr_V2DF_type_node): New macro.
(ptr_V4SI_type_node): New macro.
(ptr_V4SF_type_node): New macro.
(ptr_V8HI_type_node): New macro.
(ptr_unsigned_V16QI_type_node): New macro.
(ptr_unsigned_V1TI_type_node): New macro.
(ptr_unsigned_V8HI_type_node): New macro.
(ptr_unsigned_V4SI_type_node): New macro.
(ptr_unsigned_V2DI_type_node): New macro.
(ptr_bool_V16QI_type_node): New macro.
(ptr_bool_V8HI_type_node): New macro.
(ptr_bool_V4SI_type_node): New macro.
(ptr_bool_V2DI_type_node): New macro.
(ptr_bool_V1TI_type_node): New macro.
(ptr_pixel_type_node): New macro.
(ptr_intQI_type_node): New macro.
(ptr_uintQI_type_node): New macro.
(ptr_intHI_type_node): New macro.
(ptr_uintHI_type_node): New macro.
(ptr_intSI_type_node): New macro.
(ptr_uintSI_type_node): New macro.
(ptr_intDI_type_node): New macro.
(ptr_uintDI_type_node): New macro.
(ptr_intTI_type_node): New macro.
(ptr_uintTI_type_node): New macro.
(ptr_long_integer_type_node): New macro.
(ptr_long_unsigned_type_node): New macro.
(ptr_float_type_node): New macro.
(ptr_double_type_node): New macro.
(ptr_long_double_type_node): New macro.
(ptr_dfloat64_type_node): New macro.
(ptr_dfloat128_type_node): New macro.
(ptr_ieee128_type_node): New macro.
(ptr_ibm128_type_node): New macro.
(ptr_vector_pair_type_node): New macro.
(ptr_vector_quad_type_node): New macro.
(ptr_long_long_integer_type_node): New macro.
(ptr_long_long_unsigned_type_node): New macro.
---
 gcc/config/rs6000/rs6000-call.c | 151 
 gcc/config/rs6000/rs6000.h  |  82 +
 2 files changed, 233 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 4651345adde..d9be017ee61 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -13272,25 +13272,63 @@ rs6000_init_builtins (void)
   V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 ? "__vector long"
   : "__vector long long",
   long_long_integer_type_node, 2);
+  ptr_V2DI_type_node
+= build_pointer_type (build_qualified_type (V2DI_type_node,
+   TYPE_QUAL_CONST));
+
   V2DF_type_node = rs6000_vector_type ("__vector double", double_type_node, 2);
+  ptr_V2DF_type_node
+= build_pointer_type (build_qualified_type (V2DF_type_node,
+   TYPE_QUAL_CONST));
+
   V4SI_type_node = rs6000_vector_type ("__vector signed int",
   intSI_type_node, 4);
+  ptr_V4SI_type_node
+= build_pointer_type (build_qualified_type (V4SI_type_node,
+   TYPE_QUAL_CONST));
+
   V4SF_type_node = rs6000_vector_type ("__vector float", float_type_node, 4);
+  ptr_V4SF_type_node
+= build_pointer_type (build_qualified_type (V4SF_type_node,
+   TYPE_QUAL_CONST));
+
   V8HI_type_node = rs6000_vector_type ("__vector signed short",
   intHI_type_node, 8);
+  ptr_V8HI_type_node
+= build_pointer_type (build_qualified_type (V8HI_type_node,
+   TYPE_QUAL_CONST));
+
   V16QI_type_node = rs6000_vector_type ("__vector signed char",
intQI_type_node, 16);
+  ptr_V16QI_type_node
+= build_pointer_type (build_qualified_type (V16QI_type_node,
+   TYPE_QUAL_CONST));
 
   unsigned_V16QI_type_node = rs6000_vector_type ("__vector unsigned char",
unsigned_intQI_type_node, 16);
+  ptr_unsigned_V16QI_type_node
+= build_pointer_type (build_qualified_type (unsigned_V16QI_type_node,
+   TYPE_QUAL_CONST));
+
   unsigned_V8HI_type_node = rs6000_vector_type ("__vector unsigned short",
   unsigned_intHI_type_node, 8);
+  ptr_unsigned_V8HI_type_node
+= build_pointer_type (build_qualified_type (unsigned_V8HI_type_node,
+   TYPE_QUAL_CONST));
+
   unsigned_V4SI_type_node = rs6000_vector_type ("__vector unsigned int",
   unsigned_intSI_type_node, 4);
+  

[PATCH 30/55] rs6000: Add Power9 builtins

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-15  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Add power9-vector, power9,
and power9-64 stanzas.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 375 +++
 1 file changed, 375 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index f13fb13b0ad..8885df089a6 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -2434,3 +2434,378 @@
 
   const double __builtin_vsx_xscvspdpn (vf);
 XSCVSPDPN vsx_xscvspdpn {}
+
+
+; Power9 vector builtins.
+[power9-vector]
+  const vss __builtin_altivec_convert_4f32_8f16 (vf, vf);
+CONVERT_4F32_8F16 convert_4f32_8f16 {}
+
+  const vss __builtin_altivec_convert_4f32_8i16 (vf, vf);
+CONVERT_4F32_8I16 convert_4f32_8i16 {}
+
+  const signed int __builtin_altivec_first_match_index_v16qi (vsc, vsc);
+VFIRSTMATCHINDEX_V16QI first_match_index_v16qi {}
+
+  const signed int __builtin_altivec_first_match_index_v8hi (vss, vss);
+VFIRSTMATCHINDEX_V8HI first_match_index_v8hi {}
+
+  const signed int __builtin_altivec_first_match_index_v4si (vsi, vsi);
+VFIRSTMATCHINDEX_V4SI first_match_index_v4si {}
+
+  const signed int __builtin_altivec_first_match_or_eos_index_v16qi (vsc, vsc);
+VFIRSTMATCHOREOSINDEX_V16QI first_match_or_eos_index_v16qi {}
+
+  const signed int __builtin_altivec_first_match_or_eos_index_v8hi (vss, vss);
+VFIRSTMATCHOREOSINDEX_V8HI first_match_or_eos_index_v8hi {}
+
+  const signed int __builtin_altivec_first_match_or_eos_index_v4si (vsi, vsi);
+VFIRSTMATCHOREOSINDEX_V4SI first_match_or_eos_index_v4si {}
+
+  const signed int __builtin_altivec_first_mismatch_index_v16qi (vsc, vsc);
+VFIRSTMISMATCHINDEX_V16QI first_mismatch_index_v16qi {}
+
+  const signed int __builtin_altivec_first_mismatch_index_v8hi (vss, vss);
+VFIRSTMISMATCHINDEX_V8HI first_mismatch_index_v8hi {}
+
+  const signed int __builtin_altivec_first_mismatch_index_v4si (vsi, vsi);
+VFIRSTMISMATCHINDEX_V4SI first_mismatch_index_v4si {}
+
+  const signed int __builtin_altivec_first_mismatch_or_eos_index_v16qi (vsc, 
vsc);
+VFIRSTMISMATCHOREOSINDEX_V16QI first_mismatch_or_eos_index_v16qi {}
+
+  const signed int __builtin_altivec_first_mismatch_or_eos_index_v8hi (vss, 
vss);
+VFIRSTMISMATCHOREOSINDEX_V8HI first_mismatch_or_eos_index_v8hi {}
+
+  const signed int __builtin_altivec_first_mismatch_or_eos_index_v4si (vsi, 
vsi);
+VFIRSTMISMATCHOREOSINDEX_V4SI first_mismatch_or_eos_index_v4si {}
+
+  const vsc __builtin_altivec_vadub (vsc, vsc);
+VADUB vaduv16qi3 {}
+
+  const vss __builtin_altivec_vaduh (vss, vss);
+VADUH vaduv8hi3 {}
+
+  const vsi __builtin_altivec_vaduw (vsi, vsi);
+VADUW vaduv4si3 {}
+
+  const vsll __builtin_altivec_vbpermd (vsll, vsc);
+VBPERMD altivec_vbpermd {}
+
+  const signed int __builtin_altivec_vclzlsbb_v16qi (vsc);
+VCLZLSBB_V16QI vclzlsbb_v16qi {}
+
+  const signed int __builtin_altivec_vclzlsbb_v4si (vsi);
+VCLZLSBB_V4SI vclzlsbb_v4si {}
+
+  const signed int __builtin_altivec_vclzlsbb_v8hi (vss);
+VCLZLSBB_V8HI vclzlsbb_v8hi {}
+
+  const vsc __builtin_altivec_vctzb (vsc);
+VCTZB ctzv16qi2 {}
+
+  const vsll __builtin_altivec_vctzd (vsll);
+VCTZD ctzv2di2 {}
+
+  const vss __builtin_altivec_vctzh (vss);
+VCTZH ctzv8hi2 {}
+
+  const vsi __builtin_altivec_vctzw (vsi);
+VCTZW ctzv4si2 {}
+
+  const signed int __builtin_altivec_vctzlsbb_v16qi (vsc);
+VCTZLSBB_V16QI vctzlsbb_v16qi {}
+
+  const signed int __builtin_altivec_vctzlsbb_v4si (vsi);
+VCTZLSBB_V4SI vctzlsbb_v4si {}
+
+  const signed int __builtin_altivec_vctzlsbb_v8hi (vss);
+VCTZLSBB_V8HI vctzlsbb_v8hi {}
+
+  const signed int __builtin_altivec_vcmpaeb_p (vsc, vsc);
+VCMPAEB_P vector_ae_v16qi_p {}
+
+  const signed int __builtin_altivec_vcmpaed_p (vsll, vsll);
+VCMPAED_P vector_ae_v2di_p {}
+
+  const signed int __builtin_altivec_vcmpaedp_p (vd, vd);
+VCMPAEDP_P vector_ae_v2df_p {}
+
+  const signed int __builtin_altivec_vcmpaefp_p (vf, vf);
+VCMPAEFP_P vector_ae_v4sf_p {}
+
+  const signed int __builtin_altivec_vcmpaeh_p (vss, vss);
+VCMPAEH_P vector_ae_v8hi_p {}
+
+  const signed int __builtin_altivec_vcmpaew_p (vsi, vsi);
+VCMPAEW_P vector_ae_v4si_p {}
+
+  const vsc __builtin_altivec_vcmpneb (vsc, vsc);
+VCMPNEB vcmpneb {}
+
+  const signed int __builtin_altivec_vcmpneb_p (vsc, vsc);
+VCMPNEB_P vector_ne_v16qi_p {}
+
+  const signed int __builtin_altivec_vcmpned_p (vsll, vsll);
+VCMPNED_P vector_ne_v2di_p {}
+
+  const signed int __builtin_altivec_vcmpnedp_p (vd, vd);
+VCMPNEDP_P vector_ne_v2df_p {}
+
+  const signed int __builtin_altivec_vcmpnefp_p (vf, vf);
+VCMPNEFP_P vector_ne_v4sf_p {}
+
+  const vss __builtin_altivec_vcmpneh (vss, vss);
+VCMPNEH vcmpneh {}
+
+  const signed int __builtin_altivec_vcmpneh_p (vss, vss);
+VCMPNEH_P vector_ne_v8hi_p {}
+
+  const vsi 

[PATCH 29/55] rs6000: Add power8-vector builtins

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-04-01  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Add power8-vector stanza.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 438 +++
 1 file changed, 438 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index bffce52ee47..f13fb13b0ad 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -1996,3 +1996,441 @@
 
   const unsigned long long __builtin_divdeu (unsigned long long, unsigned long 
long);
 DIVDEU diveu_di {}
+
+
+; Power8 vector built-ins.
+[power8-vector]
+  const vsll __builtin_altivec_abs_v2di (vsll);
+ABS_V2DI absv2di2 {}
+
+  const vsc __builtin_altivec_bcddiv10_v16qi (vsc);
+BCDDIV10_V16QI bcddiv10_v16qi {}
+
+  const vsc __builtin_altivec_bcdmul10_v16qi (vsc);
+BCDMUL10_V16QI bcdmul10_v16qi {}
+
+  const vsc __builtin_altivec_eqv_v16qi (vsc, vsc);
+EQV_V16QI eqvv16qi3 {}
+
+  const vuc __builtin_altivec_eqv_v16qi_uns (vuc, vuc);
+EQV_V16QI_UNS eqvv16qi3 {}
+
+  const vsq __builtin_altivec_eqv_v1ti (vsq, vsq);
+EQV_V1TI eqvv1ti3 {}
+
+  const vuq __builtin_altivec_eqv_v1ti_uns (vuq, vuq);
+EQV_V1TI_UNS eqvv1ti3 {}
+
+  const vd __builtin_altivec_eqv_v2df (vd, vd);
+EQV_V2DF eqvv2df3 {}
+
+  const vsll __builtin_altivec_eqv_v2di (vsll, vsll);
+EQV_V2DI eqvv2di3 {}
+
+  const vull __builtin_altivec_eqv_v2di_uns (vull, vull);
+EQV_V2DI_UNS eqvv2di3 {}
+
+  const vf __builtin_altivec_eqv_v4sf (vf, vf);
+EQV_V4SF eqvv4sf3 {}
+
+  const vsi __builtin_altivec_eqv_v4si (vsi, vsi);
+EQV_V4SI eqvv4si3 {}
+
+  const vui __builtin_altivec_eqv_v4si_uns (vui, vui);
+EQV_V4SI_UNS eqvv4si3 {}
+
+  const vss __builtin_altivec_eqv_v8hi (vss, vss);
+EQV_V8HI eqvv8hi3 {}
+
+  const vus __builtin_altivec_eqv_v8hi_uns (vus, vus);
+EQV_V8HI_UNS eqvv8hi3 {}
+
+  const vsc __builtin_altivec_nand_v16qi (vsc, vsc);
+NAND_V16QI nandv16qi3 {}
+
+  const vuc __builtin_altivec_nand_v16qi_uns (vuc, vuc);
+NAND_V16QI_UNS nandv16qi3 {}
+
+  const vsq __builtin_altivec_nand_v1ti (vsq, vsq);
+NAND_V1TI nandv1ti3 {}
+
+  const vuq __builtin_altivec_nand_v1ti_uns (vuq, vuq);
+NAND_V1TI_UNS nandv1ti3 {}
+
+  const vd __builtin_altivec_nand_v2df (vd, vd);
+NAND_V2DF nandv2df3 {}
+
+  const vsll __builtin_altivec_nand_v2di (vsll, vsll);
+NAND_V2DI nandv2di3 {}
+
+  const vull __builtin_altivec_nand_v2di_uns (vull, vull);
+NAND_V2DI_UNS nandv2di3 {}
+
+  const vf __builtin_altivec_nand_v4sf (vf, vf);
+NAND_V4SF nandv4sf3 {}
+
+  const vsi __builtin_altivec_nand_v4si (vsi, vsi);
+NAND_V4SI nandv4si3 {}
+
+  const vui __builtin_altivec_nand_v4si_uns (vui, vui);
+NAND_V4SI_UNS nandv4si3 {}
+
+  const vss __builtin_altivec_nand_v8hi (vss, vss);
+NAND_V8HI nandv8hi3 {}
+
+  const vus __builtin_altivec_nand_v8hi_uns (vus, vus);
+NAND_V8HI_UNS nandv8hi3 {}
+
+  const vsc __builtin_altivec_neg_v16qi (vsc);
+NEG_V16QI negv16qi2 {}
+
+  const vd __builtin_altivec_neg_v2df (vd);
+NEG_V2DF negv2df2 {}
+
+  const vsll __builtin_altivec_neg_v2di (vsll);
+NEG_V2DI negv2di2 {}
+
+  const vf __builtin_altivec_neg_v4sf (vf);
+NEG_V4SF negv4sf2 {}
+
+  const vsi __builtin_altivec_neg_v4si (vsi);
+NEG_V4SI negv4si2 {}
+
+  const vss __builtin_altivec_neg_v8hi (vss);
+NEG_V8HI negv8hi2 {}
+
+  const vsc __builtin_altivec_orc_v16qi (vsc, vsc);
+ORC_V16QI orcv16qi3 {}
+
+  const vuc __builtin_altivec_orc_v16qi_uns (vuc, vuc);
+ORC_V16QI_UNS orcv16qi3 {}
+
+  const vsq __builtin_altivec_orc_v1ti (vsq, vsq);
+ORC_V1TI orcv1ti3 {}
+
+  const vuq __builtin_altivec_orc_v1ti_uns (vuq, vuq);
+ORC_V1TI_UNS orcv1ti3 {}
+
+  const vd __builtin_altivec_orc_v2df (vd, vd);
+ORC_V2DF orcv2df3 {}
+
+  const vsll __builtin_altivec_orc_v2di (vsll, vsll);
+ORC_V2DI orcv2di3 {}
+
+  const vull __builtin_altivec_orc_v2di_uns (vull, vull);
+ORC_V2DI_UNS orcv2di3 {}
+
+  const vf __builtin_altivec_orc_v4sf (vf, vf);
+ORC_V4SF orcv4sf3 {}
+
+  const vsi __builtin_altivec_orc_v4si (vsi, vsi);
+ORC_V4SI orcv4si3 {}
+
+  const vui __builtin_altivec_orc_v4si_uns (vui, vui);
+ORC_V4SI_UNS orcv4si3 {}
+
+  const vss __builtin_altivec_orc_v8hi (vss, vss);
+ORC_V8HI orcv8hi3 {}
+
+  const vus __builtin_altivec_orc_v8hi_uns (vus, vus);
+ORC_V8HI_UNS orcv8hi3 {}
+
+  const vsc __builtin_altivec_vclzb (vsc);
+VCLZB clzv16qi2 {}
+
+  const vsll __builtin_altivec_vclzd (vsll);
+VCLZD clzv2di2 {}
+
+  const vss __builtin_altivec_vclzh (vss);
+VCLZH clzv8hi2 {}
+
+  const vsi __builtin_altivec_vclzw (vsi);
+VCLZW clzv4si2 {}
+
+  const vuc __builtin_altivec_vgbbd (vuc);
+VGBBD p8v_vgbbd {}
+
+  const vsq __builtin_altivec_vaddcuq (vsq, vsq);
+VADDCUQ altivec_vaddcuq {}
+
+  const vsq __builtin_altivec_vaddecuq (vsq, vsq, vsq);
+VADDECUQ altivec_vaddecuq {}
+
+  const vsq __builtin_altivec_vaddeuqm (vsq, vsq, vsq);
+

[PATCH 28/55] rs6000: Add power7 and power7-64 builtins

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-04-02  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Add power7 and power7-64
stanzas.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 39 
 1 file changed, 39 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index ca694be1ac3..bffce52ee47 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -1957,3 +1957,42 @@
 
   const vsll __builtin_vsx_xxspltd_2di (vsll, const int<1>);
 XXSPLTD_V2DI vsx_xxspltd_v2di {}
+
+
+; Power7 builtins (ISA 2.06).
+[power7]
+  const unsigned int __builtin_addg6s (unsigned int, unsigned int);
+ADDG6S addg6s {}
+
+  const signed long __builtin_bpermd (signed long, signed long);
+BPERMD bpermd_di {}
+
+  const unsigned int __builtin_cbcdtd (unsigned int);
+CBCDTD cbcdtd {}
+
+  const unsigned int __builtin_cdtbcd (unsigned int);
+CDTBCD cdtbcd {}
+
+  const signed int __builtin_divwe (signed int, signed int);
+DIVWE dive_si {}
+
+  const unsigned int __builtin_divweu (unsigned int, unsigned int);
+DIVWEU diveu_si {}
+
+  const vsq __builtin_pack_vector_int128 (unsigned long long, unsigned long 
long);
+PACK_V1TI packv1ti {}
+
+  void __builtin_ppc_speculation_barrier ();
+SPECBARR speculation_barrier {}
+
+  const unsigned long __builtin_unpack_vector_int128 (vsq, const int<1>);
+UNPACK_V1TI unpackv1ti {}
+
+
+; Power7 builtins requiring 64-bit GPRs (even with 32-bit addressing).
+[power7-64]
+  const signed long long __builtin_divde (signed long long, signed long long);
+DIVDE dive_di {}
+
+  const unsigned long long __builtin_divdeu (unsigned long long, unsigned long 
long);
+DIVDEU diveu_di {}
-- 
2.27.0



[PATCH 27/55] rs6000: Add available-everywhere and ancient builtins

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Add always, power5, and
power6 stanzas.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 72 
 1 file changed, 72 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 974cdc8c37c..ca694be1ac3 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -184,6 +184,78 @@
 
 
 
+; Builtins that have been around since time immemorial or are just
+; considered available everywhere.
+[always]
+  void __builtin_cpu_init ();
+CPU_INIT nothing {cpu}
+
+  bool __builtin_cpu_is (string);
+CPU_IS nothing {cpu}
+
+  bool __builtin_cpu_supports (string);
+CPU_SUPPORTS nothing {cpu}
+
+  unsigned long long __builtin_ppc_get_timebase ();
+GET_TB rs6000_get_timebase {}
+
+  double __builtin_mffs ();
+MFFS rs6000_mffs {}
+
+; This will break for long double == _Float128.  libgcc history.
+  const long double __builtin_pack_longdouble (double, double);
+PACK_TF packtf {}
+
+  unsigned long __builtin_ppc_mftb ();
+MFTB rs6000_mftb_di {32bit}
+
+  void __builtin_mtfsb0 (const int<5>);
+MTFSB0 rs6000_mtfsb0 {}
+
+  void __builtin_mtfsb1 (const int<5>);
+MTFSB1 rs6000_mtfsb1 {}
+
+  void __builtin_mtfsf (const int<8>, double);
+MTFSF rs6000_mtfsf {}
+
+  const __ibm128 __builtin_pack_ibm128 (double, double);
+PACK_IF packif {}
+
+  void __builtin_set_fpscr_rn (const int[0,3]);
+SET_FPSCR_RN rs6000_set_fpscr_rn {}
+
+  const double __builtin_unpack_ibm128 (__ibm128, const int<1>);
+UNPACK_IF unpackif {}
+
+; This will break for long double == _Float128.  libgcc history.
+  const double __builtin_unpack_longdouble (long double, const int<1>);
+UNPACK_TF unpacktf {}
+
+
+; Builtins that have been around just about forever, but not quite.
+[power5]
+  fpmath double __builtin_recipdiv (double, double);
+RECIP recipdf3 {}
+
+  fpmath float __builtin_recipdivf (float, float);
+RECIPF recipsf3 {}
+
+  fpmath double __builtin_rsqrt (double);
+RSQRT rsqrtdf2 {}
+
+  fpmath float __builtin_rsqrtf (float);
+RSQRTF rsqrtsf2 {}
+
+
+; Power6 builtins.
+[power6]
+  const signed long __builtin_p6_cmpb (signed long, signed long);
+CMPB cmpbdi3 {}
+
+  const signed int __builtin_p6_cmpb_32 (signed int, signed int);
+CMPB_32 cmpbsi3 {}
+
+
 ; AltiVec builtins.
 [altivec]
   const vsc __builtin_altivec_abs_v16qi (vsc);
-- 
2.27.0



[PATCH 3/5] libstdc++: Rename views::split to views::lazy_split as per P2210

2021-06-17 Thread Patrick Palka via Gcc-patches
This mostly mechanical patch performs the renaming part of P2210R3
"Superior string splitting".  It also defines _InnerIter::base()
overloads.

libstdc++-v3/ChangeLog:

* include/std/ranges: Rename views::split to views::lazy_split,
split_view to lazy_split_view, etc. throughout.
(lazy_split_view::_InnerIter::base): Define as per P2210.
* testsuite/std/ranges/*: Likewise.
---
 libstdc++-v3/include/std/ranges   | 68 +++
 .../testsuite/std/ranges/adaptors/100479.cc   |  2 +-
 .../testsuite/std/ranges/adaptors/100577.cc   | 20 +++---
 .../testsuite/std/ranges/adaptors/join.cc |  2 +-
 .../adaptors/{split.cc => lazy_split.cc}  | 54 +++
 .../{split_neg.cc => lazy_split_neg.cc}   |  6 +-
 .../testsuite/std/ranges/adaptors/p2281.cc| 18 ++---
 .../testsuite/std/ranges/adaptors/sizeof.cc   |  2 +-
 libstdc++-v3/testsuite/std/ranges/p2259.cc|  6 +-
 libstdc++-v3/testsuite/std/ranges/p2325.cc| 10 +--
 libstdc++-v3/testsuite/std/ranges/p2367.cc|  4 +-
 11 files changed, 100 insertions(+), 92 deletions(-)
 rename libstdc++-v3/testsuite/std/ranges/adaptors/{split.cc => lazy_split.cc} 
(76%)
 rename libstdc++-v3/testsuite/std/ranges/adaptors/{split_neg.cc => 
lazy_split_neg.cc} (79%)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index f93a880ff8a..cc1ef112ff1 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -2826,19 +2826,19 @@ namespace views::__adaptor
&& (remove_reference_t<_Range>::size() <= 1);
 
 template
-  struct __split_view_outer_iter_cat
+  struct __lazy_split_view_outer_iter_cat
   { };
 
 template
-  struct __split_view_outer_iter_cat<_Base>
+  struct __lazy_split_view_outer_iter_cat<_Base>
   { using iterator_category = input_iterator_tag; };
 
 template
-  struct __split_view_inner_iter_cat
+  struct __lazy_split_view_inner_iter_cat
   { };
 
 template
-  struct __split_view_inner_iter_cat<_Base>
+  struct __lazy_split_view_inner_iter_cat<_Base>
   {
   private:
static constexpr auto
@@ -2860,7 +2860,7 @@ namespace views::__adaptor
   && indirectly_comparable, iterator_t<_Pattern>,
   ranges::equal_to>
   && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
-class split_view : public view_interface>
+class lazy_split_view : public view_interface>
 {
 private:
   template
@@ -2871,17 +2871,17 @@ namespace views::__adaptor
 
   template
struct _OuterIter
- : __detail::__split_view_outer_iter_cat<_Base<_Const>>
+ : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
{
private:
- using _Parent = __detail::__maybe_const_t<_Const, split_view>;
- using _Base = split_view::_Base<_Const>;
+ using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
+ using _Base = lazy_split_view::_Base<_Const>;
 
  constexpr bool
  __at_end() const
  { return __current() == ranges::end(_M_parent->_M_base); }
 
- // [range.split.outer] p1
+ // [range.lazy.split.outer] p1
  //  Many of the following specifications refer to the notional member
  //  current of outer-iterator.  current is equivalent to current_ if
  //  V models forward_range, and parent_->current_ otherwise.
@@ -2914,7 +2914,7 @@ namespace views::__adaptor
  using iterator_concept = conditional_t,
 forward_iterator_tag,
 input_iterator_tag>;
- // iterator_category defined in __split_view_outer_iter_cat
+ // iterator_category defined in __lazy_split_view_outer_iter_cat
  using difference_type = range_difference_t<_Base>;
 
  struct value_type : view_interface
@@ -2974,7 +2974,7 @@ namespace views::__adaptor
  operator++()
  {
// _GLIBCXX_RESOLVE_LIB_DEFECTS
-   // 3505. split_view::outer-iterator::operator++ misspecified
+   // 3505. lazy_split_view::outer-iterator::operator++ misspecified
const auto __end = ranges::end(_M_parent->_M_base);
if (__current() == __end)
  return *this;
@@ -3030,10 +3030,10 @@ namespace views::__adaptor
 
   template
struct _InnerIter
- : __detail::__split_view_inner_iter_cat<_Base<_Const>>
+ : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
{
private:
- using _Base = split_view::_Base<_Const>;
+ using _Base = lazy_split_view::_Base<_Const>;
 
  constexpr bool
  __at_end() const
@@ -3081,7 +3081,7 @@ namespace views::__adaptor
public:
  using iterator_concept
= typename _OuterIter<_Const>::iterator_concept;
- // iterator_category defined in 

[PATCH 26/55] rs6000: Add VSX builtins

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Add vsx stanza.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 857 +++
 1 file changed, 857 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index f1aa5529cdd..974cdc8c37c 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -1028,3 +1028,860 @@
 
   const vss __builtin_vec_set_v8hi (vss, signed short, const int<3>);
 VEC_SET_V8HI nothing {set}
+
+
+; VSX builtins.
+[vsx]
+  pure vd __builtin_altivec_lvx_v2df (signed long, const void *);
+LVX_V2DF altivec_lvx_v2df {ldvec}
+
+  pure vsll __builtin_altivec_lvx_v2di (signed long, const void *);
+LVX_V2DI altivec_lvx_v2di {ldvec}
+
+  pure vd __builtin_altivec_lvxl_v2df (signed long, const void *);
+LVXL_V2DF altivec_lvxl_v2df {ldvec}
+
+  pure vsll __builtin_altivec_lvxl_v2di (signed long, const void *);
+LVXL_V2DI altivec_lvxl_v2di {ldvec}
+
+  const vd __builtin_altivec_nabs_v2df (vd);
+NABS_V2DF vsx_nabsv2df2 {}
+
+  const vsll __builtin_altivec_nabs_v2di (vsll);
+NABS_V2DI nabsv2di2 {}
+
+  void __builtin_altivec_stvx_v2df (vd, signed long, void *);
+STVX_V2DF altivec_stvx_v2df {stvec}
+
+  void __builtin_altivec_stvx_v2di (vsll, signed long, void *);
+STVX_V2DI altivec_stvx_v2di {stvec}
+
+  void __builtin_altivec_stvxl_v2df (vd, signed long, void *);
+STVXL_V2DF altivec_stvxl_v2df {stvec}
+
+  void __builtin_altivec_stvxl_v2di (vsll, signed long, void *);
+STVXL_V2DI altivec_stvxl_v2di {stvec}
+
+  const vd __builtin_altivec_vand_v2df (vd, vd);
+VAND_V2DF andv2df3 {}
+
+  const vsll __builtin_altivec_vand_v2di (vsll, vsll);
+VAND_V2DI andv2di3 {}
+
+  const vull __builtin_altivec_vand_v2di_uns (vull, vull);
+VAND_V2DI_UNS andv2di3 {}
+
+  const vd __builtin_altivec_vandc_v2df (vd, vd);
+VANDC_V2DF andcv2df3 {}
+
+  const vsll __builtin_altivec_vandc_v2di (vsll, vsll);
+VANDC_V2DI andcv2di3 {}
+
+  const vull __builtin_altivec_vandc_v2di_uns (vull, vull);
+VANDC_V2DI_UNS andcv2di3 {}
+
+  const vsll __builtin_altivec_vcmpequd (vull, vull);
+VCMPEQUD vector_eqv2di {}
+
+  const int __builtin_altivec_vcmpequd_p (int, vsll, vsll);
+VCMPEQUD_P vector_eq_v2di_p {pred}
+
+  const vsll __builtin_altivec_vcmpgtsd (vsll, vsll);
+VCMPGTSD vector_gtv2di {}
+
+  const int __builtin_altivec_vcmpgtsd_p (int, vsll, vsll);
+VCMPGTSD_P vector_gt_v2di_p {pred}
+
+  const vsll __builtin_altivec_vcmpgtud (vull, vull);
+VCMPGTUD vector_gtuv2di {}
+
+  const int __builtin_altivec_vcmpgtud_p (int, vsll, vsll);
+VCMPGTUD_P vector_gtu_v2di_p {pred}
+
+  const vd __builtin_altivec_vnor_v2df (vd, vd);
+VNOR_V2DF norv2df3 {}
+
+  const vsll __builtin_altivec_vnor_v2di (vsll, vsll);
+VNOR_V2DI norv2di3 {}
+
+  const vull __builtin_altivec_vnor_v2di_uns (vull, vull);
+VNOR_V2DI_UNS norv2di3 {}
+
+  const vd __builtin_altivec_vor_v2df (vd, vd);
+VOR_V2DF iorv2df3 {}
+
+  const vsll __builtin_altivec_vor_v2di (vsll, vsll);
+VOR_V2DI iorv2di3 {}
+
+  const vull __builtin_altivec_vor_v2di_uns (vull, vull);
+VOR_V2DI_UNS iorv2di3 {}
+
+  const vd __builtin_altivec_vperm_2df (vd, vd, vuc);
+VPERM_2DF altivec_vperm_v2df {}
+
+  const vsll __builtin_altivec_vperm_2di (vsll, vsll, vuc);
+VPERM_2DI altivec_vperm_v2di {}
+
+  const vull __builtin_altivec_vperm_2di_uns (vull, vull, vuc);
+VPERM_2DI_UNS altivec_vperm_v2di_uns {}
+
+  const vd __builtin_altivec_vreve_v2df (vd);
+VREVE_V2DF altivec_vrevev2df2 {}
+
+  const vsll __builtin_altivec_vreve_v2di (vsll);
+VREVE_V2DI altivec_vrevev2di2 {}
+
+  const vd __builtin_altivec_vsel_2df (vd, vd, vd);
+VSEL_2DF vector_select_v2df {}
+
+  const vsll __builtin_altivec_vsel_2di (vsll, vsll, vsll);
+VSEL_2DI_B vector_select_v2di {}
+
+  const vull __builtin_altivec_vsel_2di_uns (vull, vull, vull);
+VSEL_2DI_UNS vector_select_v2di_uns {}
+
+  const vd __builtin_altivec_vsldoi_2df (vd, vd, const int<4>);
+VSLDOI_2DF altivec_vsldoi_v2df {}
+
+  const vsll __builtin_altivec_vsldoi_2di (vsll, vsll, const int<4>);
+VSLDOI_2DI altivec_vsldoi_v2di {}
+
+  const vd __builtin_altivec_vxor_v2df (vd, vd);
+VXOR_V2DF xorv2df3 {}
+
+  const vsll __builtin_altivec_vxor_v2di (vsll, vsll);
+VXOR_V2DI xorv2di3 {}
+
+  const vull __builtin_altivec_vxor_v2di_uns (vull, vull);
+VXOR_V2DI_UNS xorv2di3 {}
+
+  const signed __int128 __builtin_vec_ext_v1ti (vsq, signed int);
+VEC_EXT_V1TI nothing {extract}
+
+  const double __builtin_vec_ext_v2df (vd, signed int);
+VEC_EXT_V2DF nothing {extract}
+
+  const signed long long __builtin_vec_ext_v2di (vsll, signed int);
+VEC_EXT_V2DI nothing {extract}
+
+  const vsq __builtin_vec_init_v1ti (signed __int128);
+VEC_INIT_V1TI nothing {init}
+
+  const vd __builtin_vec_init_v2df (double, double);
+VEC_INIT_V2DF nothing {init}
+
+  const 

[PATCH 25/55] rs6000: Add the rest of the [altivec] stanza to the builtins file

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-10  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: Finish altivec stanza.
* config/rs6000/rs6000-call.c (rs6000_init_builtins): Move
initialization of pcvoid_type_node here...
(altivec_init_builtins): ...from here.
* config/rs6000/rs6000.h (rs6000_builtin_type_index): Add
RS6000_BTI_const_ptr_void.
(pcvoid_type_node): New macro.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 831 +++
 gcc/config/rs6000/rs6000-call.c  |   7 +-
 gcc/config/rs6000/rs6000.h   |   2 +
 3 files changed, 836 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index a84a3def2d5..f1aa5529cdd 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -197,3 +197,834 @@
 
   const vss __builtin_altivec_abs_v8hi (vss);
 ABS_V8HI absv8hi2 {}
+
+  const vsc __builtin_altivec_abss_v16qi (vsc);
+ABSS_V16QI altivec_abss_v16qi {}
+
+  const vsi __builtin_altivec_abss_v4si (vsi);
+ABSS_V4SI altivec_abss_v4si {}
+
+  const vss __builtin_altivec_abss_v8hi (vss);
+ABSS_V8HI altivec_abss_v8hi {}
+
+  const vf __builtin_altivec_copysignfp (vf, vf);
+COPYSIGN_V4SF vector_copysignv4sf3 {}
+
+  void __builtin_altivec_dss (const int<2>);
+DSS altivec_dss {}
+
+  void __builtin_altivec_dssall ();
+DSSALL altivec_dssall {}
+
+  void __builtin_altivec_dst (void *, const int, const int<2>);
+DST altivec_dst {}
+
+  void __builtin_altivec_dstst (void *, const int, const int<2>);
+DSTST altivec_dstst {}
+
+  void __builtin_altivec_dststt (void *, const int, const int<2>);
+DSTSTT altivec_dststt {}
+
+  void __builtin_altivec_dstt (void *, const int, const int<2>);
+DSTT altivec_dstt {}
+
+  fpmath vsi __builtin_altivec_fix_sfsi (vf);
+FIX_V4SF_V4SI fix_truncv4sfv4si2 {}
+
+  fpmath vui __builtin_altivec_fixuns_sfsi (vf);
+FIXUNS_V4SF_V4SI fixuns_truncv4sfv4si2 {}
+
+  fpmath vf __builtin_altivec_float_sisf (vsi);
+FLOAT_V4SI_V4SF floatv4siv4sf2 {}
+
+  pure vsc __builtin_altivec_lvebx (signed long, const void *);
+LVEBX altivec_lvebx {ldvec}
+
+  pure vss __builtin_altivec_lvehx (signed long, const void *);
+LVEHX altivec_lvehx {ldvec}
+
+  pure vsi __builtin_altivec_lvewx (signed long, const void *);
+LVEWX altivec_lvewx {ldvec}
+
+  pure vuc __builtin_altivec_lvsl (signed long, const void *);
+LVSL altivec_lvsl {ldvec}
+
+  pure vuc __builtin_altivec_lvsr (signed long, const void *);
+LVSR altivec_lvsr {ldvec}
+
+  pure vsi __builtin_altivec_lvx (signed long, const void *);
+LVX altivec_lvx_v4si {ldvec}
+
+  pure vsq __builtin_altivec_lvx_v1ti (signed long, const void *);
+LVX_V1TI altivec_lvx_v1ti {ldvec}
+
+  pure vsc __builtin_altivec_lvx_v16qi (signed long, const void *);
+LVX_V16QI altivec_lvx_v16qi {ldvec}
+
+  pure vf __builtin_altivec_lvx_v4sf (signed long, const void *);
+LVX_V4SF altivec_lvx_v4sf {ldvec}
+
+  pure vsi __builtin_altivec_lvx_v4si (signed long, const void *);
+LVX_V4SI altivec_lvx_v4si {ldvec}
+
+  pure vss __builtin_altivec_lvx_v8hi (signed long, const void *);
+LVX_V8HI altivec_lvx_v8hi {ldvec}
+
+  pure vsi __builtin_altivec_lvxl (signed long, const void *);
+LVXL altivec_lvxl_v4si {ldvec}
+
+  pure vsc __builtin_altivec_lvxl_v16qi (signed long, const void *);
+LVXL_V16QI altivec_lvxl_v16qi {ldvec}
+
+  pure vf __builtin_altivec_lvxl_v4sf (signed long, const void *);
+LVXL_V4SF altivec_lvxl_v4sf {ldvec}
+
+  pure vsi __builtin_altivec_lvxl_v4si (signed long, const void *);
+LVXL_V4SI altivec_lvxl_v4si {ldvec}
+
+  pure vss __builtin_altivec_lvxl_v8hi (signed long, const void *);
+LVXL_V8HI altivec_lvxl_v8hi {ldvec}
+
+  const vsc __builtin_altivec_mask_for_load (const void *);
+MASK_FOR_LOAD altivec_lvsr_direct {ldstmask}
+
+  vss __builtin_altivec_mfvscr ();
+MFVSCR altivec_mfvscr {}
+
+  void __builtin_altivec_mtvscr (vsi);
+MTVSCR altivec_mtvscr {}
+
+  const vsll __builtin_altivec_vmulesw (vsi, vsi);
+VMULESW vec_widen_smult_even_v4si {}
+
+  const vull __builtin_altivec_vmuleuw (vui, vui);
+VMULEUW vec_widen_umult_even_v4si {}
+
+  const vsll __builtin_altivec_vmulosw (vsi, vsi);
+VMULOSW vec_widen_smult_odd_v4si {}
+
+  const vull __builtin_altivec_vmulouw (vui, vui);
+VMULOUW vec_widen_umult_odd_v4si {}
+
+  const vsc __builtin_altivec_nabs_v16qi (vsc);
+NABS_V16QI nabsv16qi2 {}
+
+  const vf __builtin_altivec_nabs_v4sf (vf);
+NABS_V4SF vsx_nabsv4sf2 {}
+
+  const vsi __builtin_altivec_nabs_v4si (vsi);
+NABS_V4SI nabsv4si2 {}
+
+  const vss __builtin_altivec_nabs_v8hi (vss);
+NABS_V8HI nabsv8hi2 {}
+
+  void __builtin_altivec_stvebx (vsc, signed long, void *);
+STVEBX altivec_stvebx {stvec}
+
+  void __builtin_altivec_stvehx (vss, signed long, void *);
+STVEHX altivec_stvehx {stvec}
+
+  void 

[PATCH 5/5] libstdc++: Implement new views::split as per P2210

2021-06-17 Thread Patrick Palka via Gcc-patches
This implements the new views::split as specified by P2210R2 "Superior
string splitting".

libstdc++-v3/ChangeLog:

* include/std/ranges (__non_propagating_cache::operator bool):
Define.
(split_view): Define as per P2210.
(views::__detail::__can_split_view): Define.
(views::_Split, views::Split): Define.
* testsuite/std/ranges/adaptors/100577.cc (test01, test02):
Test views::split.
* testsuite/std/ranges/adaptors/split.cc: New test.
* testsuite/std/ranges/p2325.cc (test08a): New test.
* testsuite/std/ranges/p2367.cc (test01): Test views::split.
---
 libstdc++-v3/include/std/ranges   | 205 ++
 .../testsuite/std/ranges/adaptors/100577.cc   |  16 +-
 .../testsuite/std/ranges/adaptors/split.cc| 196 +
 libstdc++-v3/testsuite/std/ranges/p2325.cc|  14 ++
 libstdc++-v3/testsuite/std/ranges/p2367.cc|   1 +
 5 files changed, 430 insertions(+), 2 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/std/ranges/adaptors/split.cc

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 78562924bee..42278f128b8 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1195,6 +1195,10 @@ namespace views::__adaptor
  return *this;
}
 
+   constexpr explicit
+   operator bool() const noexcept
+   { return this->_M_is_engaged(); }
+
constexpr _Tp&
operator*() noexcept
{ return this->_M_get(); }
@@ -3278,6 +3282,207 @@ namespace views::__adaptor
 inline constexpr _LazySplit lazy_split;
   } // namespace views
 
+  template
+requires view<_Vp> && view<_Pattern>
+  && indirectly_comparable, iterator_t<_Pattern>,
+  ranges::equal_to>
+  class split_view : public view_interface>
+  {
+  private:
+_Pattern _M_pattern = _Pattern();
+__detail::__non_propagating_cache>> 
_M_cached_begin;
+_Vp _M_base = _Vp();
+
+struct _Iterator;
+struct _Sentinel;
+
+  public:
+split_view() requires (default_initializable<_Vp>
+  && default_initializable<_Pattern>)
+  = default;
+
+constexpr
+split_view(_Vp __base, _Pattern __pattern)
+  : _M_pattern(std::move(__pattern)),
+   _M_base(std::move(__base))
+{ }
+
+template
+  requires constructible_from<_Vp, views::all_t<_Range>>
+   && constructible_from<_Pattern, single_view>>
+constexpr
+split_view(_Range&& __r, range_value_t<_Range> __e)
+  : _M_pattern(views::single(__e)),
+   _M_base(views::all(std::forward<_Range>(__r)))
+{ }
+
+constexpr _Vp
+base() const& requires copyable<_Vp>
+{ return _M_base; }
+
+constexpr _Vp
+base() &&
+{ return std::move(_M_base); }
+
+constexpr _Iterator
+begin()
+{
+  if (!_M_cached_begin)
+   _M_cached_begin = _M_find_next(ranges::begin(_M_base));
+  return {this, ranges::begin(_M_base), *_M_cached_begin};
+}
+
+constexpr auto
+end()
+{
+  if constexpr (common_range<_Vp>)
+   return _Iterator{this, ranges::end(_M_base), {}};
+  else
+   return _Sentinel{this};
+}
+
+constexpr subrange>
+_M_find_next(iterator_t<_Vp> __it)
+{
+  auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), 
_M_pattern);
+  if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
+   {
+ ++__b;
+ ++__e;
+   }
+  return {__b, __e};
+}
+
+  private:
+struct _Iterator
+{
+private:
+  split_view* _M_parent = nullptr;
+  iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
+  subrange> _M_next = subrange>();
+  bool _M_trailing_empty = false;
+
+public:
+  using iterator_concept = forward_iterator_tag;
+  using iterator_category = input_iterator_tag;
+  using value_type = subrange>;
+  using difference_type = range_difference_t<_Vp>;
+
+  _Iterator() requires default_initializable> = default;
+
+  constexpr
+  _Iterator(split_view* __parent,
+   iterator_t<_Vp> __current,
+   subrange> __next)
+   : _M_parent(__parent),
+ _M_cur(std::move(__current)),
+ _M_next(std::move(__next))
+  { }
+
+  constexpr iterator_t<_Vp>
+  base() const
+  { return _M_cur; }
+
+  constexpr value_type
+  operator*() const
+  { return {_M_cur, _M_next.begin()}; }
+
+  constexpr _Iterator&
+  operator++()
+  {
+   _M_cur = _M_next.begin();
+   if (_M_cur != ranges::end(_M_parent->_M_base))
+ {
+   _M_cur = _M_next.end();
+   if (_M_cur == ranges::end(_M_parent->_M_base))
+ {
+   _M_trailing_empty = true;
+   _M_next = {_M_cur, _M_cur};
+ }
+   else
+ _M_next = _M_parent->_M_find_next(_M_cur);
+ }
+   else
+ _M_trailing_empty = 

[PATCH 4/5] libstdc++: Implement resolution of LWG 3478 as per P2210

2021-06-17 Thread Patrick Palka via Gcc-patches
This implements the part of P2210R2 "Superior String Splitting" that
resolves LWG 3478 for split_view (now named lazy_split_view).

libstdc++-v3/ChangeLog:

* include/std/ranges (lazy_split_view::_OuterIter::__at_end):
Check _M_trailing_empty.
(lazy_split_view::_OuterIter::_M_trailing_empty): Define this
data member.
(lazy_split_view::_OuterIter::operator++): Set _M_trailing_empty
appropriately.
(lazy_split_view::_OuterIter::operator==): Compare
_M_trailing_empty.
* testsuite/std/ranges/adaptors/100479.cc (test03): Expect two
split parts instead of one.
* testsuite/std/ranges/adaptors/lazy_split.cc (test11): New test.
---
 libstdc++-v3/include/std/ranges   | 21 +++
 .../testsuite/std/ranges/adaptors/100479.cc   |  6 +++---
 .../std/ranges/adaptors/lazy_split.cc | 15 +
 3 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index cc1ef112ff1..78562924bee 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -2879,7 +2879,7 @@ namespace views::__adaptor
 
  constexpr bool
  __at_end() const
- { return __current() == ranges::end(_M_parent->_M_base); }
+ { return __current() == ranges::end(_M_parent->_M_base) && 
!_M_trailing_empty; }
 
  // [range.lazy.split.outer] p1
  //  Many of the following specifications refer to the notional member
@@ -2909,6 +2909,7 @@ namespace views::__adaptor
  [[no_unique_address]]
__detail::__maybe_present_t,
iterator_t<_Base>> _M_current;
+ bool _M_trailing_empty = false;
 
public:
  using iterator_concept = conditional_t,
@@ -2977,7 +2978,10 @@ namespace views::__adaptor
// 3505. lazy_split_view::outer-iterator::operator++ misspecified
const auto __end = ranges::end(_M_parent->_M_base);
if (__current() == __end)
- return *this;
+ {
+   _M_trailing_empty = false;
+   return *this;
+ }
const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
if (__pbegin == __pend)
  ++__current();
@@ -2986,7 +2990,11 @@ namespace views::__adaptor
__current() = ranges::find(std::move(__current()), __end,
   *__pbegin);
if (__current() != __end)
- ++__current();
+ {
+   ++__current();
+   if (__current() == __end)
+ _M_trailing_empty = true;
+ }
  }
else
  do
@@ -2996,6 +3004,8 @@ namespace views::__adaptor
  if (__p == __pend)
{
  __current() = __b;
+ if (__current() == __end)
+   _M_trailing_empty = true;
  break;
}
} while (++__current() != __end);
@@ -3018,7 +3028,10 @@ namespace views::__adaptor
  friend constexpr bool
  operator==(const _OuterIter& __x, const _OuterIter& __y)
requires forward_range<_Base>
- { return __x._M_current == __y._M_current; }
+ {
+   return __x._M_current == __y._M_current
+ && __x._M_trailing_empty == __y._M_trailing_empty;
+ }
 
  friend constexpr bool
  operator==(const _OuterIter& __x, default_sentinel_t)
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/100479.cc 
b/libstdc++-v3/testsuite/std/ranges/adaptors/100479.cc
index 9899ff92c0b..b8c1e6f4f57 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/100479.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/100479.cc
@@ -95,11 +95,11 @@ test03()
 | views::drop_while([](auto) { return false; })
 | views::filter([](auto) { return true; });
   static_assert(ranges::forward_range);
-  VERIFY( ranges::next(v.begin()) == v.end() );
+  VERIFY( ranges::distance(v) == 2 );
   auto w = v;
-  VERIFY( ranges::next(w.begin()) == w.end() );
+  VERIFY( ranges::distance(v) == 2 );
   auto z = std::move(w);
-  VERIFY( ranges::next(z.begin()) == z.end() );
+  VERIFY( ranges::distance(v) == 2 );
   return true;
 }
 
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split.cc 
b/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split.cc
index 12844525d86..133e9a7025b 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/lazy_split.cc
@@ -193,6 +193,20 @@ test10()
   VERIFY( ranges::equal(v, (std::string_view[]){"x", "x"}) );
 }
 
+void
+test11()
+{
+  // LWG 3478
+  static_assert(ranges::distance(views::lazy_split("text"sv, "text"sv)) == 2);
+  static_assert(ranges::distance(views::lazy_split(" 

[PATCH 1/5] libstdc++: Implement P2325 changes to default-constructibilty of views

2021-06-17 Thread Patrick Palka via Gcc-patches
This implements the wording changes of P2325R3 "Views should not be
required to be default constructible".  Changes are relatively
straightforward, besides perhaps those to __box (which now stands
for copyable-box instead of semiregular-box) and __non_propagating_cache.

For __box, this patch implements the recommended practice to also avoid
std::optional when the boxed type is nothrow_move/copy_constructible.

For __non_propagating_cache, now that it's used by split_view::_M_current,
we need to add assignment from a value of the underlying type to the
subset of the std::optional API implemented for the cache (needed by
split_view::begin()).  Hence the new __non_propagating_cache::operator=
overload.

While we're changing __box, this fixes the undesirable list-init in
the constuctors of the partial specialization as reported in PR100475
comment #7.

libstdc++-v3/ChangeLog:

* include/bits/iterator_concepts.h (weakly_incrementable): Remove
default_initializable requirement.
* include/bits/ranges_base.h (ranges::view): Likewise.
* include/bits/ranges_util.h (subrange): Constrain the default
ctor.
* include/bits/stl_iterator.h (back_insert_iterator): Remove the
default ctor.
(front_insert_iterator): Likewise.
(insert_iterator): Likewise.  Remove NSDMIs.
(common_iterator): Constrain the default ctor.
(counted_iterator): Likewise.
* include/bits/stream_iterator.h (ostream_iterator): Remove the
default ctor.
* include/std/ranges (__detail::__box::operator=): Handle
self-assignment in the primary template.
(__detail::__box): In the partial specialization: adjust
constraints as per P2325.  Add specialized operator= for the
case when the wrapped type is not copyable.  Constrain the
default ctor.  Avoid list-initialization.
(single_view): Constraint the default ctor.
(iota_view): Relax semiregular constraint to copyable.
Constrain the default ctor.
(iota_view::_Iterator): Constraint the default ctor.
(basic_istream_view): Remove the default ctor.  Remove NSDMIs.
Remove redundant checks for empty _M_stream.
(basic_istream_view::_Iterator): Likewise.
(ref_view): Remove the default ctor.  Remove NSDMIs.
(ref_view::_Iterator): Constrain the default ctor.
(__detail::__non_propagating_cache::operator=): Define overload
for assigning from a value of the underlying type.
(filter_view): Likewise.
(filter_view::_Iterator): Likewise.
(transform_view): Likewise.
(transform_view::_Iterator): Likewise.
(take_view): Likewise.
(take_view::_Iterator): Likewise.
(take_while_view): Likewise.
(take_while_view::_Iterator): Likewise.
(drop_while_view): Likewise.
(drop_while_view::_Iterator): Likewise.
(join_view): Likewise.
(split_view::_OuterIter::__current): Adjust after changing the
type of _M_current.
(split_view::_M_current): Wrap it in a __non_propagating_cache.
(split_view::split_view): Constrain the default ctor.
(common_view): Constrain the default ctor.
(reverse_view): Likewise.
(elements_view): Likewise.
* include/std/span (enable_view>):
Define this partial specialization to true unconditionally.
* include/std/version (__cpp_lib_ranges): Adjust value.
* testsuite/24_iterators/back_insert_iterator/constexpr.cc:
Don't attempt to default construct a back_insert_iterator.
* testsuite/24_iterators/front_insert_iterator/constexpr.cc:
Don't attempt to default construct a front_insert_iterator.
* testsuite/24_iterators/insert_iterator/constexpr.cc:
Don't attempt to default construct an insert_iterator.
* testsuite/24_iterators/ostream_iterator/requirements/constexpr.cc:
Remove this test for default constructibility of ostream_iterator.
* testsuite/std/ranges/97600.cc: Don't attempt to default
construct a basic_istream_view.
* testsuite/std/ranges/adaptors/detail/semiregular_box.cc:
Rename to ...
* testsuite/std/ranges/adaptors/detail/copyable_box.cc: ... this.
(test02): Adjust now that __box is copyable-box not
semiregular-box.
(test03): New test.
* testsuite/std/ranges/p2325.cc: New test.
* testsuite/std/ranges/single_view.cc (test06): New test.
* testsuite/std/ranges/view.cc: Adjust now that view doesn't
require default_initializable.
---
 libstdc++-v3/include/bits/iterator_concepts.h |   3 +-
 libstdc++-v3/include/bits/ranges_base.h   |   3 +-
 libstdc++-v3/include/bits/ranges_util.h   |   2 +-
 libstdc++-v3/include/bits/stl_iterator.h  |  16 +-
 libstdc++-v3/include/bits/stream_iterator.h   |   5 -
 libstdc++-v3/include/std/ranges   | 160 

[PATCH 24/55] rs6000: Add gengtype handling to the build machinery

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config.gcc (target_gtfiles): Add ./rs6000-builtins.h.
* config/rs6000/t-rs6000 (EXTRA_GTYPE_DEPS): Set.
---
 gcc/config.gcc | 1 +
 gcc/config/rs6000/t-rs6000 | 1 +
 2 files changed, 2 insertions(+)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 9ef4f7ffc12..a7a1a26074c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -491,6 +491,7 @@ powerpc*-*-*)
extra_options="${extra_options} g.opt fused-madd.opt 
rs6000/rs6000-tables.opt"
target_gtfiles="$target_gtfiles \$(srcdir)/config/rs6000/rs6000-logue.c 
\$(srcdir)/config/rs6000/rs6000-call.c"
target_gtfiles="$target_gtfiles 
\$(srcdir)/config/rs6000/rs6000-pcrel-opt.c"
+   target_gtfiles="$target_gtfiles ./rs6000-builtins.h"
;;
 pru-*-*)
cpu_type=pru
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index f8acc4ad90f..7a829951b94 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -22,6 +22,7 @@ TM_H += $(srcdir)/config/rs6000/rs6000-builtin.def
 TM_H += $(srcdir)/config/rs6000/rs6000-cpus.def
 TM_H += $(srcdir)/config/rs6000/rs6000-modes.h
 PASSES_EXTRA += $(srcdir)/config/rs6000/rs6000-passes.def
+EXTRA_GTYPE_DEPS += $(srcdir)/config/rs6000/rs6000-builtin-new.def
 
 rs6000-pcrel-opt.o: $(srcdir)/config/rs6000/rs6000-pcrel-opt.c
$(COMPILE) $<
-- 
2.27.0



[PATCH 2/5] libstdc++: Move ranges algos used by into ranges_util.h

2021-06-17 Thread Patrick Palka via Gcc-patches
The  header defines simplified copies of some ranges algorithms
in order to avoid including the entirety of ranges_algo.h.  A subsequent
patch is going to want to use ranges::search in  as well, but
that algorithm is more complicated compared to the other copied ones.

So rather than additionally copying ranges::search into , this
patch splits out all the ranges algos used by  (including
ranges::search) from ranges_algo.h to ranges_util.h, and deletes the
simplified copies in .  This seems like the best place for
these algorithms, as ranges_util.h is included only from  and
ranges_algo.h.

libstdc++-v3/ChangeLog:

* include/bits/ranges_algo.h (__find_fn, find, __find_if_fn)
(find_if, __find_if_not_fn, find_if_not, _in_in_result)
(__mismatch_fn, mismatch, __search_fn, search): Move to ...
* include/bits/ranges_util.h: ... here.
* include/std/ranges (__detail::find, __detail::find_if)
(__detail::find_if_not, __detail::mismatch): Remove.
(filter_view): Use ranges::find_if instead.
(drop_while_view): Use ranges::find_if_not instead.
(split_view): Use ranges::find and ranges::mismatch instead.
---
 libstdc++-v3/include/bits/ranges_algo.h | 215 +--
 libstdc++-v3/include/bits/ranges_util.h | 219 
 libstdc++-v3/include/std/ranges |  72 ++--
 3 files changed, 233 insertions(+), 273 deletions(-)

diff --git a/libstdc++-v3/include/bits/ranges_algo.h 
b/libstdc++-v3/include/bits/ranges_algo.h
index ecf1378742d..9eeebff6525 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -234,91 +234,7 @@ namespace ranges
 
   inline constexpr __for_each_n_fn for_each_n{};
 
-  struct __find_fn
-  {
-template _Sent, typename _Tp,
-typename _Proj = identity>
-  requires indirect_binary_predicate, const _Tp*>
-  constexpr _Iter
-  operator()(_Iter __first, _Sent __last,
-const _Tp& __value, _Proj __proj = {}) const
-  {
-   while (__first != __last
-   && !(std::__invoke(__proj, *__first) == __value))
- ++__first;
-   return __first;
-  }
-
-template
-  requires indirect_binary_predicate, _Proj>,
-const _Tp*>
-  constexpr borrowed_iterator_t<_Range>
-  operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
-  {
-   return (*this)(ranges::begin(__r), ranges::end(__r),
-  __value, std::move(__proj));
-  }
-  };
-
-  inline constexpr __find_fn find{};
-
-  struct __find_if_fn
-  {
-template _Sent,
-typename _Proj = identity,
-indirect_unary_predicate> _Pred>
-  constexpr _Iter
-  operator()(_Iter __first, _Sent __last,
-_Pred __pred, _Proj __proj = {}) const
-  {
-   while (__first != __last
-   && !(bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
- ++__first;
-   return __first;
-  }
-
-template, _Proj>>
-  _Pred>
-  constexpr borrowed_iterator_t<_Range>
-  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
-  {
-   return (*this)(ranges::begin(__r), ranges::end(__r),
-  std::move(__pred), std::move(__proj));
-  }
-  };
-
-  inline constexpr __find_if_fn find_if{};
-
-  struct __find_if_not_fn
-  {
-template _Sent,
-typename _Proj = identity,
-indirect_unary_predicate> _Pred>
-  constexpr _Iter
-  operator()(_Iter __first, _Sent __last,
-_Pred __pred, _Proj __proj = {}) const
-  {
-   while (__first != __last
-   && (bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
- ++__first;
-   return __first;
-  }
-
-template, _Proj>>
-  _Pred>
-  constexpr borrowed_iterator_t<_Range>
-  operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
-  {
-   return (*this)(ranges::begin(__r), ranges::end(__r),
-  std::move(__pred), std::move(__proj));
-  }
-  };
-
-  inline constexpr __find_if_not_fn find_if_not{};
+  // find, find_if and find_if_not are defined in .
 
   struct __find_first_of_fn
   {
@@ -421,134 +337,7 @@ namespace ranges
 
   inline constexpr __count_if_fn count_if{};
 
-  template
-struct in_in_result
-{
-  [[no_unique_address]] _Iter1 in1;
-  [[no_unique_address]] _Iter2 in2;
-
-  template
-   requires convertible_to
- && convertible_to
-   constexpr
-   operator in_in_result<_IIter1, _IIter2>() const &
-   { return {in1, in2}; }
-
-  template
-   requires convertible_to<_Iter1, _IIter1>
- && convertible_to<_Iter2, _IIter2>
-   constexpr
-   operator in_in_result<_IIter1, _IIter2>() &&
-   { return {std::move(in1), std::move(in2)}; }
-};
-
-  template
-using mismatch_result = 

[PATCH 23/55] rs6000: Incorporate new builtins code into the build machinery

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config.gcc (extra_objs): Include rs6000-builtins.o and
rs6000-c.o.
* config/rs6000/t-rs6000 (rs6000-gen-builtins.o): New target.
(rbtree.o): Likewise.
(rs6000-gen-builtins): Likewise.
(rs6000-builtins.c): Likewise.
(rs6000-builtins.h): Likewise.
(rs6000.o): Add dependency.
(EXTRA_HEADERS): Add rs6000-vecdefines.h.
(rs6000-vecdefines.h): New target.
(rs6000-builtins.o): Likewise.
(rs6000-call.o): Add rs6000-builtins.h as a dependency.
(rs6000-c.o): Likewise.
---
 gcc/config.gcc |  1 +
 gcc/config/rs6000/t-rs6000 | 44 +-
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 1be8d96f5e5..9ef4f7ffc12 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -475,6 +475,7 @@ powerpc*-*-*)
cpu_type=rs6000
extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o"
extra_objs="${extra_objs} rs6000-call.o rs6000-pcrel-opt.o"
+   extra_objs="${extra_objs} rs6000-builtins.o rs6000-c.o"
extra_headers="ppc-asm.h altivec.h htmintrin.h htmxlintrin.h"
extra_headers="${extra_headers} bmi2intrin.h bmiintrin.h"
extra_headers="${extra_headers} xmmintrin.h mm_malloc.h emmintrin.h"
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index 44f7ffb35fe..f8acc4ad90f 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -27,10 +27,6 @@ rs6000-pcrel-opt.o: 
$(srcdir)/config/rs6000/rs6000-pcrel-opt.c
$(COMPILE) $<
$(POSTCOMPILE)
 
-rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c
-   $(COMPILE) $<
-   $(POSTCOMPILE)
-
 rs6000-string.o: $(srcdir)/config/rs6000/rs6000-string.c
$(COMPILE) $<
$(POSTCOMPILE)
@@ -47,7 +43,45 @@ rs6000-logue.o: $(srcdir)/config/rs6000/rs6000-logue.c
$(COMPILE) $<
$(POSTCOMPILE)
 
-rs6000-call.o: $(srcdir)/config/rs6000/rs6000-call.c
+rs6000-gen-builtins.o: $(srcdir)/config/rs6000/rs6000-gen-builtins.c
+   $(COMPILE) $(CXXFLAGS) $<
+   $(POSTCOMPILE)
+
+rbtree.o: $(srcdir)/config/rs6000/rbtree.c
+   $(COMPILE) $<
+   $(POSTCOMPILE)
+
+rs6000-gen-builtins: rs6000-gen-builtins.o rbtree.o
+   $(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) -o $@ \
+   $(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS)
+
+# TODO: Whenever GNU make 4.3 is the minimum required, we should use
+# grouped targets on this:
+#rs6000-builtins.c rs6000-builtins.h rs6000-vecdefines.h &: 
+#   
+rs6000-builtins.c: rs6000-gen-builtins \
+  $(srcdir)/config/rs6000/rs6000-builtin-new.def \
+  $(srcdir)/config/rs6000/rs6000-overload.def
+   ./rs6000-gen-builtins $(srcdir)/config/rs6000/rs6000-builtin-new.def \
+   $(srcdir)/config/rs6000/rs6000-overload.def rs6000-builtins.h \
+   rs6000-builtins.c rs6000-vecdefines.h
+
+rs6000-builtins.h: rs6000-builtins.c
+
+rs6000.o: rs6000-builtins.h
+
+EXTRA_HEADERS += rs6000-vecdefines.h
+rs6000-vecdefines.h : rs6000-builtins.c
+
+rs6000-builtins.o: rs6000-builtins.c
+   $(COMPILE) $<
+   $(POSTCOMPILE)
+
+rs6000-call.o: $(srcdir)/config/rs6000/rs6000-call.c rs6000-builtins.h
+   $(COMPILE) $<
+   $(POSTCOMPILE)
+
+rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c rs6000-builtins.h
$(COMPILE) $<
$(POSTCOMPILE)
 
-- 
2.27.0



[PATCH 22/55] rs6000: Write static initializations for overload tables

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (write_ovld_static_init): New
function.
(write_init_file): Call write_ovld_static_init.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 53 +
 1 file changed, 53 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 819c580b35e..acb213ca606 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2520,6 +2520,58 @@ write_bif_static_init (void)
   fprintf (init_file, "  };\n\n");
 }
 
+/* Write the decls and initializers for rs6000_overload_info[] and
+   rs6000_instance_info[].  */
+static void
+write_ovld_static_init (void)
+{
+  fprintf (init_file,
+  "ovldrecord rs6000_overload_info[RS6000_OVLD_MAX "
+  "- RS6000_OVLD_NONE] =\n");
+  fprintf (init_file, "  {\n");
+  fprintf (init_file, "{ /* RS6000_OVLD_NONE: */\n");
+  fprintf (init_file, "  \"\", NULL\n");
+  fprintf (init_file, "},\n");
+  for (int i = 0; i <= curr_ovld_stanza; i++)
+{
+  fprintf (init_file, "{ /* RS6000_OVLD_%s: */\n",
+  ovld_stanzas[i].stanza_id);
+  fprintf (init_file, "  /* ovld_name */\t\"%s\",\n",
+  ovld_stanzas[i].intern_name);
+  /* First-instance must currently be instantiated at run time.  */
+  fprintf (init_file, "  /* first_instance */\tNULL\n");
+  fprintf (init_file, "},\n");
+}
+  fprintf (init_file, "  };\n\n");
+
+  fprintf (init_file, "ovlddata rs6000_instance_info[RS6000_INST_MAX] =\n");
+  fprintf (init_file, "  {\n");
+  fprintf (init_file, "{ /* RS6000_INST_NONE: */\n");
+  fprintf (init_file, "  \"\", RS6000_BIF_NONE, NULL_TREE, NULL\n");
+  fprintf (init_file, "},\n");
+  for (int i = 0; i <= curr_ovld; i++)
+{
+  fprintf (init_file, "{ /* RS6000_INST_%s: */\n",
+  ovlds[i].ovld_id_name);
+  fprintf (init_file, "  /* bifname */\t\"%s\",\n",
+  ovlds[i].proto.bifname);
+  fprintf (init_file, "  /* bifid */\tRS6000_BIF_%s,\n",
+  ovlds[i].bif_id_name);
+  /* Type must be instantiated at run time.  */
+  fprintf (init_file, "  /* fntype */\t0,\n");
+  fprintf (init_file, "  /* next */\t");
+  if (i < curr_ovld
+ && !strcmp (ovlds[i+1].proto.bifname, ovlds[i].proto.bifname))
+   fprintf (init_file,
+"_instance_info[RS6000_INST_%s]\n",
+ovlds[i+1].ovld_id_name);
+  else
+   fprintf (init_file, "NULL\n");
+  fprintf (init_file, "},\n");
+}
+  fprintf (init_file, "  };\n\n");
+}
+
 /* Write code to initialize the built-in function table.  */
 static void
 write_init_bif_table (void)
@@ -2708,6 +2760,7 @@ write_init_file (void)
   fprintf (init_file, "tree rs6000_builtin_decls_x[RS6000_OVLD_MAX];\n\n");
 
   write_bif_static_init ();
+  write_ovld_static_init ();
 
   rbt_inorder_callback (_rbt, fntype_rbt.rbt_root, write_fntype);
   fprintf (init_file, "\n");
-- 
2.27.0



[PATCH 21/55] rs6000: Write static initializations for built-in table

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (write_bif_static_init): New
function.
(write_init_file): Call write_bif_static_init.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 106 
 1 file changed, 106 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 06040cf6778..819c580b35e 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2416,6 +2416,110 @@ write_header_file (void)
   return 1;
 }
 
+/* Write the decl and initializer for rs6000_builtin_info_x[].  */
+static void
+write_bif_static_init (void)
+{
+  const char *res[3];
+  fprintf (init_file, "bifdata rs6000_builtin_info_x[RS6000_BIF_MAX] =\n");
+  fprintf (init_file, "  {\n");
+  fprintf (init_file, "{ /* RS6000_BIF_NONE: */\n");
+  fprintf (init_file, "  \"\", ENB_ALWAYS, 0, CODE_FOR_nothing, 0,\n");
+  fprintf (init_file, "  0, {0, 0, 0}, {RES_NONE, RES_NONE, RES_NONE},\n");
+  fprintf (init_file, "  {0, 0, 0}, {0, 0, 0}, \"\", RS6000_BIF_NONE\n");
+  fprintf (init_file, "},\n");
+  for (int i = 0; i <= curr_bif; i++)
+{
+  bifdata *bifp = [bif_order[i]];
+  fprintf (init_file, "{ /* RS6000_BIF_%s: */\n", bifp->idname);
+  fprintf (init_file, "  /* bifname */\t\"%s\",\n",
+  bifp->proto.bifname);
+  fprintf (init_file, "  /* enable*/\t%s,\n",
+  enable_string[bifp->stanza]);
+  /* Type must be instantiated at run time.  */
+  fprintf (init_file, "  /* fntype */\t0,\n");
+  fprintf (init_file, "  /* icode */\tCODE_FOR_%s,\n",
+  bifp->patname);
+  fprintf (init_file, "  /* nargs */\t%d,\n",
+  bifp->proto.nargs);
+  fprintf (init_file, "  /* bifattrs */\t0");
+  if (bifp->attrs.isinit)
+   fprintf (init_file, " | bif_init_bit");
+  if (bifp->attrs.isset)
+   fprintf (init_file, " | bif_set_bit");
+  if (bifp->attrs.isextract)
+   fprintf (init_file, " | bif_extract_bit");
+  if (bifp->attrs.isnosoft)
+   fprintf (init_file, " | bif_nosoft_bit");
+  if (bifp->attrs.isldvec)
+   fprintf (init_file, " | bif_ldvec_bit");
+  if (bifp->attrs.isstvec)
+   fprintf (init_file, " | bif_stvec_bit");
+  if (bifp->attrs.isreve)
+   fprintf (init_file, " | bif_reve_bit");
+  if (bifp->attrs.ispred)
+   fprintf (init_file, " | bif_pred_bit");
+  if (bifp->attrs.ishtm)
+   fprintf (init_file, " | bif_htm_bit");
+  if (bifp->attrs.ishtmspr)
+   fprintf (init_file, " | bif_htmspr_bit");
+  if (bifp->attrs.ishtmcr)
+   fprintf (init_file, " | bif_htmcr_bit");
+  if (bifp->attrs.ismma)
+   fprintf (init_file, " | bif_mma_bit");
+  if (bifp->attrs.isquad)
+   fprintf (init_file, " | bif_quad_bit");
+  if (bifp->attrs.ispair)
+   fprintf (init_file, " | bif_pair_bit");
+  if (bifp->attrs.isno32bit)
+   fprintf (init_file, " | bif_no32bit_bit");
+  if (bifp->attrs.is32bit)
+   fprintf (init_file, " | bif_32bit_bit");
+  if (bifp->attrs.iscpu)
+   fprintf (init_file, " | bif_cpu_bit");
+  if (bifp->attrs.isldstmask)
+   fprintf (init_file, " | bif_ldstmask_bit");
+  if (bifp->attrs.islxvrse)
+   fprintf (init_file, " | bif_lxvrse_bit");
+  if (bifp->attrs.islxvrze)
+   fprintf (init_file, " | bif_lxvrze_bit");
+  if (bifp->attrs.isendian)
+   fprintf (init_file, " | bif_endian_bit");
+  fprintf (init_file, ",\n");
+  fprintf (init_file, "  /* restr_opnd */\t{%d, %d, %d},\n",
+  bifp->proto.restr_opnd[0], bifp->proto.restr_opnd[1],
+  bifp->proto.restr_opnd[2]);
+  for (int j = 0; j < 3; j++)
+   res[j] = (bifp->proto.restr_opnd[j] == 0 ? "RES_NONE"
+ : (bifp->proto.restr[j] == RES_BITS ? "RES_BITS"
+: (bifp->proto.restr[j] == RES_RANGE ? "RES_RANGE"
+   : (bifp->proto.restr[j] == RES_VALUES ? "RES_VALUES"
+  : (bifp->proto.restr[j] == RES_VAR_RANGE
+ ? "RES_VAR_RANGE" : "ERROR");
+  fprintf (init_file, "  /* restr */\t{%s, %s, %s},\n",
+  res[0], res[1], res[2]);
+  fprintf (init_file, "  /* restr_val1 */\t{%s, %s, %s},\n",
+  bifp->proto.restr_val1[0] ? bifp->proto.restr_val1[0] : "0",
+  bifp->proto.restr_val1[1] ? bifp->proto.restr_val1[1] : "0",
+  bifp->proto.restr_val1[2] ? bifp->proto.restr_val1[2] : "0");
+  fprintf (init_file, "  /* restr_val2 */\t{%s, %s, %s},\n",
+  bifp->proto.restr_val2[0] ? bifp->proto.restr_val2[0] : "0",
+  bifp->proto.restr_val2[1] ? bifp->proto.restr_val2[1] : "0",
+  bifp->proto.restr_val2[2] ? bifp->proto.restr_val2[2] : "0");
+  fprintf (init_file, "  /* attr_string */\t\"%s\",\n",

[PATCH 20/55] rs6000: Write output to the builtins init file, part 3 of 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-15  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (typemap): New struct.
(TYPE_MAP_SIZE): New macro.
(type_map): New initialized variable.
(map_token_to_type_node): New function.
(write_type_node): Likewise.
(write_fntype_init): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 182 
 1 file changed, 182 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index a261da88097..06040cf6778 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -460,6 +460,108 @@ static rbt_strings fntype_rbt;
identifiers to the order in which they were encountered.  */
 static rbt_strings bifo_rbt;
 
+/* Mapping from type tokens to type node names.  */
+struct typemap
+{
+  const char *key;
+  const char *value;
+};
+
+/* This table must be kept in alphabetical order, as we use binary
+   search for table lookups in map_token_to_type_node.  The table
+   maps tokens from a fntype string to a tree type.  For example,
+   in "si_ftype_hi" we would map "si" to "intSI_type_node" and
+   map "hi" to "intHI_type_node".  */
+#define TYPE_MAP_SIZE 86
+static typemap type_map[TYPE_MAP_SIZE] =
+  {
+{ "bi","bool_int" },
+{ "bv16qi","bool_V16QI" },
+{ "bv1ti", "bool_V1TI" },
+{ "bv2di", "bool_V2DI" },
+{ "bv4si", "bool_V4SI" },
+{ "bv8hi", "bool_V8HI" },
+{ "ci","integer" },
+{ "dd","dfloat64" },
+{ "df","double" },
+{ "di","long_long_integer" },
+{ "hi","intHI" },
+{ "if","ibm128_float" },
+{ "ld","long_double" },
+{ "lg","long_integer" },
+{ "pbv16qi",   "ptr_bool_V16QI" },
+{ "pbv1ti","ptr_bool_V1TI" },
+{ "pbv2di","ptr_bool_V2DI" },
+{ "pbv4si","ptr_bool_V4SI" },
+{ "pbv8hi","ptr_bool_V8HI" },
+{ "pcvoid","pcvoid" },
+{ "pdd",   "ptr_dfloat64" },
+{ "pdf",   "ptr_double" },
+{ "pdi",   "ptr_long_long_integer" },
+{ "phi",   "ptr_intHI" },
+{ "pif",   "ptr_ibm128_float" },
+{ "pld",   "ptr_long_double" },
+{ "plg",   "ptr_long_integer" },
+{ "pqi",   "ptr_intQI" },
+{ "psf",   "ptr_float" },
+{ "psi",   "ptr_intSI" },
+{ "ptd",   "ptr_dfloat128" },
+{ "ptf",   "ptr_float128" },
+{ "pti",   "ptr_intTI" },
+{ "pudi",  "ptr_long_long_unsigned" },
+{ "puhi",  "ptr_uintHI" },
+{ "pulg",  "ptr_long_unsigned" },
+{ "puqi",  "ptr_uintQI" },
+{ "pusi",  "ptr_uintSI" },
+{ "puti",  "ptr_uintTI" },
+{ "puv16qi",   "ptr_unsigned_V16QI" },
+{ "puv1ti","ptr_unsigned_V1TI" },
+{ "puv2di","ptr_unsigned_V2DI" },
+{ "puv4si","ptr_unsigned_V4SI" },
+{ "puv8hi","ptr_unsigned_V8HI" },
+{ "pv","ptr" },
+{ "pv16qi","ptr_V16QI" },
+{ "pv1poi","ptr_vector_pair" },
+{ "pv1pxi","ptr_vector_quad" },
+{ "pv1ti", "ptr_V1TI" },
+{ "pv2df", "ptr_V2DF" },
+{ "pv2di", "ptr_V2DI" },
+{ "pv4sf", "ptr_V4SF" },
+{ "pv4si", "ptr_V4SI" },
+{ "pv8hi", "ptr_V8HI" },
+{ "pvp8hi","ptr_pixel_V8HI" },
+{ "qi","intQI" },
+{ "sd","dfloat32" },
+{ "sf","float" },
+{ "si","intSI" },
+{ "st","const_str" },
+{ "td","dfloat128" },
+{ "tf","float128" },
+{ "ti","intTI" },
+{ "udi",   "long_long_unsigned" },
+{ "uhi",   "unsigned_intHI" },
+{ "ulg",   "long_unsigned" },
+{ "uqi",   "unsigned_intQI" },
+{ "usi",   "unsigned_intSI" },
+{ "uti",   "unsigned_intTI" },
+{ "uv16qi","unsigned_V16QI" },
+{ "uv1ti", "unsigned_V1TI" },
+{ "uv2di", "unsigned_V2DI" },
+{ "uv4si", "unsigned_V4SI" },
+{ "uv8hi", "unsigned_V8HI" },
+{ "v", "void" },
+{ "v16qi", "V16QI" },
+{ "v1poi", "vector_pair" },
+{ "v1pxi", "vector_quad" },
+{ "v1ti",  "V1TI" },
+{ "v2df",  "V2DF" },
+{ "v2di",  "V2DI" },
+{ "v4sf",  "V4SF" },
+{ "v4si",  "V4SI" },
+{ "v8hi",  "V8HI" },
+{ "vp8hi", "pixel_V8HI" },
+  };
+
 /* Pointer to a diagnostic function.  */
 static void (*diag) (const char *, ...)
   __attribute__ ((format (printf, 1, 

[PATCH 19/55] rs6000: Write output to the builtins init file, part 2 of 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (write_init_bif_table):
Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 81 +
 1 file changed, 81 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 2240dfc030f..a261da88097 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2238,6 +2238,87 @@ write_header_file (void)
 static void
 write_init_bif_table (void)
 {
+  for (int i = 0; i <= curr_bif; i++)
+{
+  fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].fntype"
+  "\n= %s;\n",
+  bifs[i].idname, bifs[i].fndecl);
+
+  /* Check whether we have a "tf" token in this string, representing
+a float128_type_node.  It's possible that float128_type_node is
+undefined (occurs for -maltivec -mno-vsx, for example), so we
+must guard against that.  */
+  int tf_found = strstr (bifs[i].fndecl, "tf") != NULL;
+
+  /* Similarly, look for decimal float tokens.  */
+  int dfp_found = (strstr (bifs[i].fndecl, "dd") != NULL
+  || strstr (bifs[i].fndecl, "td") != NULL
+  || strstr (bifs[i].fndecl, "sd") != NULL);
+
+  fprintf (init_file,
+  "  if (new_builtins_are_live)\n");
+  fprintf (init_file, "{\n");
+
+  if (tf_found)
+   {
+ fprintf (init_file, "  if (float128_type_node)\n");
+ fprintf (init_file, "{\n");
+   }
+  else if (dfp_found)
+   {
+ fprintf (init_file, "  if (dfloat64_type_node)\n");
+ fprintf (init_file, "{\n");
+   }
+
+  fprintf (init_file,
+  "  rs6000_builtin_decls_x[(int)RS6000_BIF_%s] = t\n",
+  bifs[i].idname);
+  fprintf (init_file,
+  "= add_builtin_function (\"%s\",\n",
+  bifs[i].proto.bifname);
+  fprintf (init_file,
+  "%s,\n",
+  bifs[i].fndecl);
+  fprintf (init_file,
+  "(int)RS6000_BIF_%s,"
+  " BUILT_IN_MD,\n",
+  bifs[i].idname);
+  fprintf (init_file,
+  "NULL, NULL_TREE);\n");
+  if (bifs[i].kind == FNK_CONST)
+   {
+ fprintf (init_file, "  TREE_READONLY (t) = 1;\n");
+ fprintf (init_file, "  TREE_NOTHROW (t) = 1;\n");
+   }
+  else if (bifs[i].kind == FNK_PURE)
+   {
+ fprintf (init_file, "  DECL_PURE_P (t) = 1;\n");
+ fprintf (init_file, "  TREE_NOTHROW (t) = 1;\n");
+   }
+  else if (bifs[i].kind == FNK_FPMATH)
+   {
+ fprintf (init_file, "  TREE_NOTHROW (t) = 1;\n");
+ fprintf (init_file, "  if (flag_rounding_math)\n");
+ fprintf (init_file, "{\n");
+ fprintf (init_file, "  DECL_PURE_P (t) = 1;\n");
+ fprintf (init_file, "  DECL_IS_NOVOPS (t) = 1;\n");
+ fprintf (init_file, "}\n");
+ fprintf (init_file, "  else\n");
+ fprintf (init_file, "TREE_READONLY (t) = 1;\n");
+   }
+
+  if (tf_found || dfp_found)
+   {
+ fprintf (init_file, "}\n");
+ fprintf (init_file, "  else\n");
+ fprintf (init_file, "{\n");
+ fprintf (init_file, "  rs6000_builtin_decls_x"
+  "[(int)RS6000_BIF_%s] = NULL_TREE;\n", bifs[i].idname);
+ fprintf (init_file, "}\n");
+   }
+  fprintf (init_file, "}\n\n");
+}
 }
 
 /* Write code to initialize the overload table.  */
-- 
2.27.0



[PATCH 18/55] rs6000: Write output to the builtins init file, part 1 of 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (write_fntype): New
callback function.
(write_fntype_init): New stub function.
(write_init_bif_table): Likewise.
(write_init_ovld_table): New function.
(write_init_file): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 163 
 1 file changed, 163 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 6f393ee46d3..2240dfc030f 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2202,6 +2202,18 @@ write_extern_fntype (char *str)
   fprintf (header_file, "extern GTY(()) tree %s;\n", str);
 }
 
+void
+write_fntype (char *str)
+{
+  fprintf (init_file, "tree %s;\n", str);
+}
+
+/* Write an initializer for a function type identified by STR.  */
+void
+write_fntype_init (char *str)
+{
+}
+
 /* Write everything to the header file (rs6000-builtins.h).  */
 static int
 write_header_file (void)
@@ -,10 +2234,161 @@ write_header_file (void)
   return 1;
 }
 
+/* Write code to initialize the built-in function table.  */
+static void
+write_init_bif_table (void)
+{
+}
+
+/* Write code to initialize the overload table.  */
+static void
+write_init_ovld_table (void)
+{
+  fprintf (init_file, "  int base = RS6000_OVLD_NONE;\n\n");
+
+  for (int i = 0; i <= curr_ovld; i++)
+{
+  fprintf (init_file,
+  "  rs6000_instance_info[RS6000_INST_%s].fntype"
+  "\n= %s;\n",
+  ovlds[i].ovld_id_name, ovlds[i].fndecl);
+
+  if (i == 0 || ovlds[i].stanza != ovlds[i-1].stanza)
+   {
+ ovld_stanza *stanza = _stanzas[ovlds[i].stanza];
+ fprintf (init_file, "\n");
+
+ /* Check whether we have a "tf" token in this string, representing
+a float128_type_node.  It's possible that float128_type_node is
+undefined (occurs for -maltivec -mno-vsx, for example), so we
+must guard against that.  */
+ int tf_found = strstr (ovlds[i].fndecl, "tf") != NULL;
+
+ /* Similarly, look for decimal float tokens.  */
+ int dfp_found = (strstr (ovlds[i].fndecl, "dd") != NULL
+  || strstr (ovlds[i].fndecl, "td") != NULL
+  || strstr (ovlds[i].fndecl, "sd") != NULL);
+
+ /* The fndecl for an overload is arbitrarily the first one
+for the overload.  We sort out the real types when
+processing the overload in the gcc front end.  */
+ fprintf (init_file,
+  "  if (new_builtins_are_live)\n");
+ fprintf (init_file, "{\n");
+
+ if (tf_found)
+   {
+ fprintf (init_file, "  if (float128_type_node)\n");
+ fprintf (init_file, "{\n");
+   }
+ else if (dfp_found)
+   {
+ fprintf (init_file, "  if (dfloat64_type_node)\n");
+ fprintf (init_file, "{\n");
+   }
+
+ fprintf (init_file,
+  "  rs6000_builtin_decls_x[(int)RS6000_OVLD_%s] = t\n",
+  stanza->stanza_id);
+ fprintf (init_file,
+  "= add_builtin_function (\"%s\",\n",
+  stanza->intern_name);
+ fprintf (init_file,
+  "%s,\n",
+  ovlds[i].fndecl);
+ fprintf (init_file,
+  "(int)RS6000_OVLD_%s,"
+  " BUILT_IN_MD,\n",
+  stanza->stanza_id);
+ fprintf (init_file,
+  "NULL, NULL_TREE);\n");
+
+ if (tf_found || dfp_found)
+   fprintf (init_file, "}\n");
+
+ fprintf (init_file, "}\n\n");
+
+ fprintf (init_file,
+  "  rs6000_overload_info[RS6000_OVLD_%s - base]"
+  ".first_instance\n",
+  stanza->stanza_id);
+ fprintf (init_file,
+  "= _instance_info[RS6000_INST_%s];\n\n",
+  ovlds[i].ovld_id_name);
+   }
+}
+}
+
 /* Write everything to the initialization file (rs6000-builtins.c).  */
 static int
 write_init_file (void)
 {
+  write_autogenerated_header (init_file);
+
+  fprintf (init_file, "#include \"config.h\"\n");
+  fprintf (init_file, "#include \"system.h\"\n");
+  fprintf (init_file, "#include \"coretypes.h\"\n");
+  fprintf (init_file, "#include \"backend.h\"\n");
+  fprintf (init_file, "#include \"rtl.h\"\n");
+  fprintf (init_file, "#include \"tree.h\"\n");
+  fprintf (init_file, "#include \"langhooks.h\"\n");
+  fprintf (init_file, "#include \"insn-codes.h\"\n");
+  fprintf (init_file, "#include \"rs6000-builtins.h\"\n");
+  fprintf (init_file, "\n");
+
+  fprintf (init_file, "int new_builtins_are_live = 0;\n\n");
+
+  fprintf (init_file, "tree 

[PATCH 17/55] rs6000: Write output to the builtins header file

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c
(write_autogenerated_header): New function.
(write_decls): Likewise.
(write_extern_fntype): New callback function.
(write_header_file): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 227 
 1 file changed, 227 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 18922d829ff..6f393ee46d3 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1988,10 +1988,237 @@ parse_ovld (void)
   return result;
 }
 
+/* Write a comment at the top of FILE about how the code was generated.  */
+static void
+write_autogenerated_header (FILE *file)
+{
+  fprintf (file, "/* Automatically generated by the program '%s'\n",
+  pgm_path);
+  fprintf (file, "   from the files '%s' and '%s'.  */\n\n",
+  bif_path, ovld_path);
+}
+
+/* Write declarations into the header file.  */
+static void
+write_decls (void)
+{
+  fprintf (header_file, "enum rs6000_gen_builtins\n{\n  RS6000_BIF_NONE,\n");
+  for (int i = 0; i <= curr_bif; i++)
+fprintf (header_file, "  RS6000_BIF_%s,\n", bifs[bif_order[i]].idname);
+  fprintf (header_file, "  RS6000_BIF_MAX,\n");
+  fprintf (header_file, "  RS6000_OVLD_NONE,\n");
+  for (int i = 0; i < num_ovld_stanzas; i++)
+fprintf (header_file, "  RS6000_OVLD_%s,\n", ovld_stanzas[i].stanza_id);
+  fprintf (header_file, "  RS6000_OVLD_MAX\n};\n\n");
+
+  fprintf (header_file,
+  "extern GTY(()) tree rs6000_builtin_decls_x[RS6000_OVLD_MAX];\n\n");
+
+  fprintf (header_file,
+  "enum rs6000_ovld_instances\n{\n  RS6000_INST_NONE,\n");
+  for (int i = 0; i <= curr_ovld; i++)
+fprintf (header_file, "  RS6000_INST_%s,\n", ovlds[i].ovld_id_name);
+  fprintf (header_file, "  RS6000_INST_MAX\n};\n\n");
+
+  fprintf (header_file, "#define MAX_OVLD_ARGS %d\n", max_ovld_args);
+
+  fprintf (header_file, "enum restriction {\n");
+  fprintf (header_file, "  RES_NONE,\n");
+  fprintf (header_file, "  RES_BITS,\n");
+  fprintf (header_file, "  RES_RANGE,\n");
+  fprintf (header_file, "  RES_VAR_RANGE,\n");
+  fprintf (header_file, "  RES_VALUES\n");
+  fprintf (header_file, "};\n\n");
+
+  fprintf (header_file, "enum bif_enable {\n");
+  fprintf (header_file, "  ENB_ALWAYS,\n");
+  fprintf (header_file, "  ENB_P5,\n");
+  fprintf (header_file, "  ENB_P6,\n");
+  fprintf (header_file, "  ENB_ALTIVEC,\n");
+  fprintf (header_file, "  ENB_CELL,\n");
+  fprintf (header_file, "  ENB_VSX,\n");
+  fprintf (header_file, "  ENB_P7,\n");
+  fprintf (header_file, "  ENB_P7_64,\n");
+  fprintf (header_file, "  ENB_P8,\n");
+  fprintf (header_file, "  ENB_P8V,\n");
+  fprintf (header_file, "  ENB_P9,\n");
+  fprintf (header_file, "  ENB_P9_64,\n");
+  fprintf (header_file, "  ENB_P9V,\n");
+  fprintf (header_file, "  ENB_IEEE128_HW,\n");
+  fprintf (header_file, "  ENB_DFP,\n");
+  fprintf (header_file, "  ENB_CRYPTO,\n");
+  fprintf (header_file, "  ENB_HTM,\n");
+  fprintf (header_file, "  ENB_P10,\n");
+  fprintf (header_file, "  ENB_P10_64,\n");
+  fprintf (header_file, "  ENB_MMA\n");
+  fprintf (header_file, "};\n\n");
+
+  fprintf (header_file, "#define PPC_MAXRESTROPNDS 3\n");
+  fprintf (header_file, "struct GTY((user)) bifdata\n");
+  fprintf (header_file, "{\n");
+  fprintf (header_file, "  const char *bifname;\n");
+  fprintf (header_file, "  bif_enable enable;\n");
+  fprintf (header_file, "  tree fntype;\n");
+  fprintf (header_file, "  insn_code icode;\n");
+  fprintf (header_file, "  int  nargs;\n");
+  fprintf (header_file, "  int  bifattrs;\n");
+  fprintf (header_file, "  int  restr_opnd[PPC_MAXRESTROPNDS];\n");
+  fprintf (header_file, "  restriction restr[PPC_MAXRESTROPNDS];\n");
+  fprintf (header_file, "  int  restr_val1[PPC_MAXRESTROPNDS];\n");
+  fprintf (header_file, "  int  restr_val2[PPC_MAXRESTROPNDS];\n");
+  fprintf (header_file, "  const char *attr_string;\n");
+  fprintf (header_file, "  rs6000_gen_builtins assoc_bif;\n");
+  fprintf (header_file, "};\n\n");
+
+  fprintf (header_file, "#define bif_init_bit\t\t(0x0001)\n");
+  fprintf (header_file, "#define bif_set_bit\t\t(0x0002)\n");
+  fprintf (header_file, "#define bif_extract_bit\t\t(0x0004)\n");
+  fprintf (header_file, "#define bif_nosoft_bit\t\t(0x0008)\n");
+  fprintf (header_file, "#define bif_ldvec_bit\t\t(0x0010)\n");
+  fprintf (header_file, "#define bif_stvec_bit\t\t(0x0020)\n");
+  fprintf (header_file, "#define bif_reve_bit\t\t(0x0040)\n");
+  fprintf (header_file, "#define bif_pred_bit\t\t(0x0080)\n");
+  fprintf (header_file, "#define bif_htm_bit\t\t(0x0100)\n");
+  fprintf (header_file, "#define bif_htmspr_bit\t\t(0x0200)\n");
+  fprintf (header_file, "#define bif_htmcr_bit\t\t(0x0400)\n");
+  fprintf (header_file, "#define bif_mma_bit\t\t(0x0800)\n");
+  fprintf (header_file, "#define 

[PATCH 16/55] rs6000: Write output to the builtin definition include file

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (write_defines_file):
Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 466fce1cdd2..18922d829ff 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2006,6 +2006,23 @@ write_init_file (void)
 static int
 write_defines_file (void)
 {
+  fprintf (defines_file, "#ifndef _RS6000_VECDEFINES_H\n");
+  fprintf (defines_file, "#define _RS6000_VECDEFINES_H 1\n\n");
+  fprintf (defines_file, "#if defined(_ARCH_PPC64) && defined (_ARCH_PWR9)\n");
+  fprintf (defines_file, "  #define _ARCH_PPC64_PWR9 1\n");
+  fprintf (defines_file, "#endif\n\n");
+  for (int i = 0; i < num_ovld_stanzas; i++)
+if (strcmp (ovld_stanzas[i].extern_name, "SKIP"))
+  {
+   if (ovld_stanzas[i].ifdef)
+ fprintf (defines_file, "#ifdef %s\n", ovld_stanzas[i].ifdef);
+   fprintf (defines_file, "#define %s %s\n",
+ovld_stanzas[i].extern_name,
+ovld_stanzas[i].intern_name);
+   if (ovld_stanzas[i].ifdef)
+ fprintf (defines_file, "#endif\n");
+  }
+  fprintf (defines_file, "\n#endif\n");
   return 1;
 }
 
-- 
2.27.0



[PATCH 15/55] rs6000: Build and store function type identifiers

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (complete_vector_type): New
function.
(complete_base_type): Likewise.
(construct_fntype_id): Likewise.
(parse_bif_entry): Call contruct_fntype_id.
(parse_ovld_entry): Likewise.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 233 
 1 file changed, 233 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index b38b7285acb..466fce1cdd2 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1280,6 +1280,231 @@ endian = %d.\n",
   return PC_OK;
 }
 
+/* Convert a vector type into a mode string.  */
+static void
+complete_vector_type (typeinfo *typeptr, char *buf, int *bufi)
+{
+  if (typeptr->isbool)
+buf[(*bufi)++] = 'b';
+  buf[(*bufi)++] = 'v';
+  if (typeptr->ispixel)
+{
+  memcpy ([*bufi], "p8hi", 4);
+  *bufi += 4;
+}
+  else
+{
+  switch (typeptr->base)
+   {
+   case BT_CHAR:
+ memcpy ([*bufi], "16qi", 4);
+ *bufi += 4;
+ break;
+   case BT_SHORT:
+ memcpy ([*bufi], "8hi", 3);
+ *bufi += 3;
+ break;
+   case BT_INT:
+ memcpy ([*bufi], "4si", 3);
+ *bufi += 3;
+ break;
+   case BT_LONGLONG:
+ memcpy ([*bufi], "2di", 3);
+ *bufi += 3;
+ break;
+   case BT_FLOAT:
+ memcpy ([*bufi], "4sf", 3);
+ *bufi += 3;
+ break;
+   case BT_DOUBLE:
+ memcpy ([*bufi], "2df", 3);
+ *bufi += 3;
+ break;
+   case BT_INT128:
+ memcpy ([*bufi], "1ti", 3);
+ *bufi += 3;
+ break;
+   case BT_FLOAT128:
+ memcpy ([*bufi], "1tf", 3);
+ *bufi += 3;
+ break;
+   case BT_VPAIR:
+ memcpy ([*bufi], "1poi", 4);
+ *bufi += 4;
+ break;
+   case BT_VQUAD:
+ memcpy ([*bufi], "1pxi", 4);
+ *bufi += 4;
+ break;
+   default:
+ (*diag) ("unhandled basetype %d.\n", typeptr->base);
+ exit (1);
+   }
+}
+}
+
+/* Convert a base type into a mode string.  */
+static void
+complete_base_type (typeinfo *typeptr, char *buf, int *bufi)
+{
+  switch (typeptr->base)
+{
+case BT_CHAR:
+  memcpy ([*bufi], "qi", 2);
+  break;
+case BT_SHORT:
+  memcpy ([*bufi], "hi", 2);
+  break;
+case BT_INT:
+  memcpy ([*bufi], "si", 2);
+  break;
+case BT_LONG:
+  memcpy ([*bufi], "lg", 2);
+  break;
+case BT_LONGLONG:
+  memcpy ([*bufi], "di", 2);
+  break;
+case BT_FLOAT:
+  memcpy ([*bufi], "sf", 2);
+  break;
+case BT_DOUBLE:
+  memcpy ([*bufi], "df", 2);
+  break;
+case BT_LONGDOUBLE:
+  memcpy ([*bufi], "ld", 2);
+  break;
+case BT_INT128:
+  memcpy ([*bufi], "ti", 2);
+  break;
+case BT_FLOAT128:
+  memcpy ([*bufi], "tf", 2);
+  break;
+case BT_BOOL:
+  memcpy ([*bufi], "bi", 2);
+  break;
+case BT_STRING:
+  memcpy ([*bufi], "st", 2);
+  break;
+case BT_DECIMAL32:
+  memcpy ([*bufi], "sd", 2);
+  break;
+case BT_DECIMAL64:
+  memcpy ([*bufi], "dd", 2);
+  break;
+case BT_DECIMAL128:
+  memcpy ([*bufi], "td", 2);
+  break;
+case BT_IBM128:
+  memcpy ([*bufi], "if", 2);
+  break;
+default:
+  (*diag) ("unhandled basetype %d.\n", typeptr->base);
+  exit (1);
+}
+
+  *bufi += 2;
+}
+
+/* Build a function type descriptor identifier from the return type
+   and argument types described by PROTOPTR, and store it if it does
+   not already exist.  Return the identifier.  */
+static char *
+construct_fntype_id (prototype *protoptr)
+{
+  /* Determine the maximum space for a function type descriptor id.
+ Each type requires at most 9 characters (6 for the mode*, 1 for
+ the optional 'u' preceding the mode, 1 for the optional 'p'
+ preceding the mode, and 1 for an underscore following the mode).
+ We also need 5 characters for the string "ftype" that separates
+ the return mode from the argument modes.  The last argument doesn't
+ need a trailing underscore, but we count that as the one trailing
+ "ftype" instead.  For the special case of zero arguments, we need 9
+ for the return type and 7 for "ftype_v".  Finally, we need one
+ character for the terminating null.  Thus for a function with N
+ arguments, we need at most 9N+15 characters for N>0, otherwise 17.
+ 
+   *Worst case is bv16qi for "vector bool char".  */
+  int len = protoptr->nargs ? (protoptr->nargs + 1) * 9 + 6 : 17;
+  char *buf = (char *) malloc (len);
+  int bufi = 0;
+
+  if (protoptr->rettype.ispointer)
+buf[bufi++] = 'p';
+
+  if (protoptr->rettype.isvoid)
+buf[bufi++] = 'v';
+  else
+{
+  if (protoptr->rettype.isunsigned)
+   buf[bufi++] = 'u';
+  

[PATCH 14/55] rs6000: Parsing of overload input file

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (ovld_stanza): New struct.
(MAXOVLDSTANZAS): New macro.
(ovld_stanzas): New variable.
(curr_ovld_stanza): Likewise.
(MAXOVLDS): New macro.
(ovlddata): New struct.
(ovlds): New variable.
(curr_ovld): Likewise.
(max_ovld_args): Likewise.
(parse_ovld_entry): New function.
(parse_ovld_stanza): Likewise.
(parse_ovld): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 235 +++-
 1 file changed, 234 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index ff3d3b71f3c..b38b7285acb 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -411,8 +411,35 @@ static int curr_bif;
 static int *bif_order;
 static int bif_index = 0;
 
+/* Stanzas are groupings of built-in functions and overloads by some
+   common feature/attribute.  These definitions are for overload stanzas.  */
+struct ovld_stanza
+{
+  char *stanza_id;
+  char *extern_name;
+  char *intern_name;
+  char *ifdef;
+};
+
+#define MAXOVLDSTANZAS 512
+static ovld_stanza ovld_stanzas[MAXOVLDSTANZAS];
 static int num_ovld_stanzas;
+static int curr_ovld_stanza;
+
+#define MAXOVLDS 16384
+struct ovlddata
+{
+  int stanza;
+  prototype proto;
+  char *bif_id_name;
+  char *ovld_id_name;
+  char *fndecl;
+};
+
+static ovlddata ovlds[MAXOVLDS];
 static int num_ovlds;
+static int curr_ovld;
+static int max_ovld_args = 0;
 
 /* Return codes for parsing routines.  */
 enum parse_codes
@@ -1515,11 +1542,217 @@ create_bif_order (void)
   rbt_inorder_callback (_rbt, bifo_rbt.rbt_root, set_bif_order);
 }
 
+/* Parse one two-line entry in the overload file.  */
+static parse_codes
+parse_ovld_entry (void)
+{
+  /* Check for end of stanza.  */
+  pos = 0;
+  consume_whitespace ();
+  if (linebuf[pos] == '[')
+return PC_EOSTANZA;
+
+  /* Allocate an entry in the overload table.  */
+  if (num_ovlds >= MAXOVLDS - 1)
+{
+  (*diag) ("too many overloads.\n");
+  return PC_PARSEFAIL;
+}
+
+  curr_ovld = num_ovlds++;
+  ovlds[curr_ovld].stanza = curr_ovld_stanza;
+
+  if (parse_prototype ([curr_ovld].proto) == PC_PARSEFAIL)
+return PC_PARSEFAIL;
+
+  if (ovlds[curr_ovld].proto.nargs > max_ovld_args)
+max_ovld_args = ovlds[curr_ovld].proto.nargs;
+
+  /* Now process line 2, which just contains the builtin id and an
+ optional overload id.  */
+  if (!advance_line (ovld_file))
+{
+  (*diag) ("unexpected EOF.\n");
+  return PC_EOFILE;
+}
+
+  pos = 0;
+  consume_whitespace ();
+  int oldpos = pos;
+  char *id = match_identifier ();
+  ovlds[curr_ovld].bif_id_name = id;
+  ovlds[curr_ovld].ovld_id_name = id;
+  if (!id)
+{
+  (*diag) ("missing overload id at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+
+#ifdef DEBUG
+  (*diag) ("ID name is '%s'.\n", id);
+#endif
+
+  /* The builtin id has to match one from the bif file.  */
+  if (!rbt_find (_rbt, id))
+{
+  (*diag) ("builtin ID '%s' not found in bif file.\n", id);
+  return PC_PARSEFAIL;
+}
+
+  /* Check for an optional overload id.  Usually we use the builtin
+ function id for that purpose, but sometimes we need multiple
+ overload entries for the same builtin id, and it needs to be unique.  */
+  consume_whitespace ();
+  if (linebuf[pos] != '\n')
+{
+  id = match_identifier ();
+  ovlds[curr_ovld].ovld_id_name = id;
+  consume_whitespace ();
+}
+
+ /* Save the overload ID in a lookup structure.  */
+  if (!rbt_insert (_rbt, id))
+{
+  (*diag) ("duplicate overload ID '%s' at column %d.\n", id, oldpos + 1);
+  return PC_PARSEFAIL;
+}
+
+  if (linebuf[pos] != '\n')
+{
+  (*diag) ("garbage at end of line at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  return PC_OK;
+}
+
+/* Parse one stanza of the input overload file.  linebuf already contains the
+   first line to parse.  */
+static parse_codes
+parse_ovld_stanza (void)
+{
+  /* Parse the stanza header.  */
+  pos = 0;
+  consume_whitespace ();
+
+  if (linebuf[pos] != '[')
+{
+  (*diag) ("ill-formed stanza header at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+
+  char *stanza_name = match_identifier ();
+  if (!stanza_name)
+{
+  (*diag) ("no identifier found in stanza header.\n");
+  return PC_PARSEFAIL;
+}
+
+  /* Add the identifier to a table and set the number to be recorded
+ with subsequent overload entries.  */
+  if (num_ovld_stanzas >= MAXOVLDSTANZAS)
+{
+  (*diag) ("too many stanza headers.\n");
+  return PC_PARSEFAIL;
+}
+
+  curr_ovld_stanza = num_ovld_stanzas++;
+  ovld_stanza *stanza = _stanzas[curr_ovld_stanza];
+  stanza->stanza_id = stanza_name;
+
+  consume_whitespace ();
+  if (linebuf[pos] != ',')
+{
+  

[PATCH 13/55] rs6000: Parsing built-in input file, part 3 of 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (parse_bif_attrs):
Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 102 
 1 file changed, 102 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 7985d2d9a71..ff3d3b71f3c 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1148,6 +1148,108 @@ base = %d, restr = %d, val1 = \"%s\", val2 = \"%s\", 
pos = %d.\n",
 static parse_codes
 parse_bif_attrs (attrinfo *attrptr)
 {
+  consume_whitespace ();
+  if (linebuf[pos] != '{')
+{
+  (*diag) ("missing attribute set at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+
+  memset (attrptr, 0, sizeof *attrptr);
+  char *attrname = NULL;
+
+  do {
+consume_whitespace ();
+int oldpos = pos;
+attrname = match_identifier ();
+if (attrname)
+  {
+   if (!strcmp (attrname, "init"))
+ attrptr->isinit = 1;
+   else if (!strcmp (attrname, "set"))
+ attrptr->isset = 1;
+   else if (!strcmp (attrname, "extract"))
+ attrptr->isextract = 1;
+   else if (!strcmp (attrname, "nosoft"))
+ attrptr->isnosoft = 1;
+   else if (!strcmp (attrname, "ldvec"))
+ attrptr->isldvec = 1;
+   else if (!strcmp (attrname, "stvec"))
+ attrptr->isstvec = 1;
+   else if (!strcmp (attrname, "reve"))
+ attrptr->isreve = 1;
+   else if (!strcmp (attrname, "pred"))
+ attrptr->ispred = 1;
+   else if (!strcmp (attrname, "htm"))
+ attrptr->ishtm = 1;
+   else if (!strcmp (attrname, "htmspr"))
+ attrptr->ishtmspr = 1;
+   else if (!strcmp (attrname, "htmcr"))
+ attrptr->ishtmcr = 1;
+   else if (!strcmp (attrname, "mma"))
+ attrptr->ismma = 1;
+   else if (!strcmp (attrname, "quad"))
+ attrptr->isquad = 1;
+   else if (!strcmp (attrname, "pair"))
+ attrptr->ispair = 1;
+   else if (!strcmp (attrname, "no32bit"))
+ attrptr->isno32bit = 1;
+   else if (!strcmp (attrname, "32bit"))
+ attrptr->is32bit = 1;
+   else if (!strcmp (attrname, "cpu"))
+ attrptr->iscpu = 1;
+   else if (!strcmp (attrname, "ldstmask"))
+ attrptr->isldstmask = 1;
+   else if (!strcmp (attrname, "lxvrse"))
+ attrptr->islxvrse = 1;
+   else if (!strcmp (attrname, "lxvrze"))
+ attrptr->islxvrze = 1;
+   else if (!strcmp (attrname, "endian"))
+ attrptr->isendian = 1;
+   else
+ {
+   (*diag) ("unknown attribute at column %d.\n", oldpos + 1);
+   return PC_PARSEFAIL;
+ }
+
+   consume_whitespace ();
+   if (linebuf[pos] == ',')
+ safe_inc_pos ();
+   else if (linebuf[pos] != '}')
+ {
+   (*diag) ("arg not followed by ',' or '}' at column %d.\n",
+pos + 1);
+   return PC_PARSEFAIL;
+ }
+  }
+else
+  {
+   pos = oldpos;
+   if (linebuf[pos] != '}')
+ {
+   (*diag) ("badly terminated attr set at column %d.\n", pos + 1);
+   return PC_PARSEFAIL;
+ }
+   safe_inc_pos ();
+  }
+  } while (attrname);
+
+#ifdef DEBUG
+  (*diag) ("attribute set: init = %d, set = %d, extract = %d, \
+nosoft = %d, ldvec = %d, stvec = %d, reve = %d, pred = %d, htm = %d, \
+htmspr = %d, htmcr = %d, mma = %d, quad = %d, pair = %d, no32bit = %d, \
+32bit = %d, cpu = %d, ldstmask = %d, lxvrse = %d, lxvrze = %d, \
+endian = %d.\n",
+  attrptr->isinit, attrptr->isset, attrptr->isextract,
+  attrptr->isnosoft, attrptr->isldvec, attrptr->isstvec,
+  attrptr->isreve, attrptr->ispred, attrptr->ishtm, attrptr->ishtmspr,
+  attrptr->ishtmcr, attrptr->ismma, attrptr->isquad, attrptr->ispair,
+  attrptr->isno32bit, attrptr->is32bit, attrptr->iscpu,
+  attrptr->isldstmask, attrptr->islxvrse, attrptr->islxvrze,
+  attrptr->isendian);
+#endif
+
   return PC_OK;
 }
 
-- 
2.27.0



[PATCH 12/55] rs6000: Parsing built-in input file, part 2 of 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (parse_args): New function.
(parse_prototype): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 142 
 1 file changed, 142 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 840b3f94295..7985d2d9a71 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1059,6 +1059,91 @@ match_type (typeinfo *typedata, int voidok)
   return 1;
 }
 
+/* Parse the argument list.  */
+static parse_codes
+parse_args (prototype *protoptr)
+{
+  typelist **argptr = >args;
+  int *nargs = >nargs;
+  int *restr_opnd = protoptr->restr_opnd;
+  restriction *restr = protoptr->restr;
+  char **val1 = protoptr->restr_val1;
+  char **val2 = protoptr->restr_val2;
+  int restr_cnt = 0;
+
+  int success;
+  *nargs = 0;
+
+  /* Start the argument list.  */
+  consume_whitespace ();
+  if (linebuf[pos] != '(')
+{
+  (*diag) ("missing '(' at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+
+  do {
+consume_whitespace ();
+int oldpos = pos;
+typelist *argentry = (typelist *) malloc (sizeof (typelist));
+memset (argentry, 0, sizeof *argentry);
+typeinfo *argtype = >info;
+success = match_type (argtype, VOID_NOTOK);
+if (success)
+  {
+   if (argtype->restr)
+ {
+   if (restr_cnt >= MAXRESTROPNDS)
+ {
+   (*diag) ("More than two %d operands\n", MAXRESTROPNDS);
+   return PC_PARSEFAIL;
+ }
+   restr_opnd[restr_cnt] = *nargs + 1;
+   restr[restr_cnt] = argtype->restr;
+   val1[restr_cnt] = argtype->val1;
+   val2[restr_cnt++] = argtype->val2;
+ }
+   (*nargs)++;
+   *argptr = argentry;
+   argptr = >next;
+   consume_whitespace ();
+   if (linebuf[pos] == ',')
+ safe_inc_pos ();
+   else if (linebuf[pos] != ')')
+ {
+   (*diag) ("arg not followed by ',' or ')' at column %d.\n",
+pos + 1);
+   return PC_PARSEFAIL;
+ }
+
+#ifdef DEBUG
+   (*diag) ("argument type: isvoid = %d, isconst = %d, isvector = %d, \
+issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, ispointer = %d, \
+base = %d, restr = %d, val1 = \"%s\", val2 = \"%s\", pos = %d.\n",
+argtype->isvoid, argtype->isconst, argtype->isvector,
+argtype->issigned, argtype->isunsigned, argtype->isbool,
+argtype->ispixel, argtype->ispointer, argtype->base,
+argtype->restr, argtype->val1, argtype->val2, pos + 1);
+#endif
+  }
+else
+  {
+   free (argentry);
+   *argptr = NULL;
+   pos = oldpos;
+   if (linebuf[pos] != ')')
+ {
+   (*diag) ("badly terminated arg list at column %d.\n", pos + 1);
+   return PC_PARSEFAIL;
+ }
+   safe_inc_pos ();
+  }
+  } while (success);
+
+  return PC_OK;
+}
+
 /* Parse the attribute list.  */
 static parse_codes
 parse_bif_attrs (attrinfo *attrptr)
@@ -1071,6 +1156,63 @@ parse_bif_attrs (attrinfo *attrptr)
 static parse_codes
 parse_prototype (prototype *protoptr)
 {
+  typeinfo *ret_type = >rettype;
+  char **bifname = >bifname;
+
+  /* Get the return type.  */
+  consume_whitespace ();
+  int oldpos = pos;
+  int success = match_type (ret_type, VOID_OK);
+  if (!success)
+{
+  (*diag) ("missing or badly formed return type at column %d.\n",
+  oldpos + 1);
+  return PC_PARSEFAIL;
+}
+
+#ifdef DEBUG
+  (*diag) ("return type: isvoid = %d, isconst = %d, isvector = %d, \
+issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, ispointer = %d, \
+base = %d, restr = %d, val1 = \"%s\", val2 = \"%s\", pos = %d.\n",
+  ret_type->isvoid, ret_type->isconst, ret_type->isvector,
+  ret_type->issigned, ret_type->isunsigned, ret_type->isbool,
+  ret_type->ispixel, ret_type->ispointer, ret_type->base,
+  ret_type->restr, ret_type->val1, ret_type->val2, pos + 1);
+#endif
+
+  /* Get the bif name.  */
+  consume_whitespace ();
+  oldpos = pos;
+  *bifname = match_identifier ();
+  if (!*bifname)
+{
+  (*diag) ("missing function name at column %d.\n", oldpos + 1);
+  return PC_PARSEFAIL;
+}
+
+#ifdef DEBUG
+  (*diag) ("function name is '%s'.\n", *bifname);
+#endif
+
+  /* Process arguments.  */
+  if (parse_args (protoptr) == PC_PARSEFAIL)
+return PC_PARSEFAIL;
+
+  /* Process terminating semicolon.  */
+  consume_whitespace ();
+  if (linebuf[pos] != ';')
+{
+  (*diag) ("missing semicolon at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+  consume_whitespace ();
+  if (linebuf[pos] != '\n')
+{
+  (*diag) ("garbage at end of line at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+
   return PC_OK;
 }
 
-- 

[PATCH 11/55] rs6000: Parsing built-in input file, part 1 of 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (bif_stanza): New enum.
(curr_bif_stanza): New variable.
(stanza_entry): New struct.
(stanza_map): New initialized variable.
(enable_string): Likewise.
(fnkinds): New enum.
(typelist): New struct.
(attrinfo): Likewise.
(MAXRESTROPNDS): New macro.
(prototype): New struct.
(MAXBIFS): New macro.
(bifdata): New struct.
(bifs): New variable.
(curr_bif): Likewise.
(bif_order): Likewise.
(bif_index): Likewise.
(stanza_name_to_stanza): New function.
(parse_bif_attrs): New stub function.
(parse_prototype): Likewise.
(parse_bif_entry): New function.
(parse_bif_stanza): Likewise.
(parse_bif): Implement.
(set_bif_order): New function.
(create_bif_order): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 369 +++-
 1 file changed, 368 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 69345b9de70..840b3f94295 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -194,6 +194,101 @@ enum void_status
  VOID_OK
 };
 
+/* Stanzas are groupings of built-in functions and overloads by some
+   common feature/attribute.  These definitions are for built-in function
+   stanzas.  */
+enum bif_stanza
+{
+ BSTZ_ALWAYS,
+ BSTZ_P5,
+ BSTZ_P6,
+ BSTZ_ALTIVEC,
+ BSTZ_CELL,
+ BSTZ_VSX,
+ BSTZ_P7,
+ BSTZ_P7_64,
+ BSTZ_P8,
+ BSTZ_P8V,
+ BSTZ_P9,
+ BSTZ_P9_64,
+ BSTZ_P9V,
+ BSTZ_IEEE128_HW,
+ BSTZ_DFP,
+ BSTZ_CRYPTO,
+ BSTZ_HTM,
+ BSTZ_P10,
+ BSTZ_P10_64,
+ BSTZ_MMA,
+ NUMBIFSTANZAS
+};
+
+static bif_stanza curr_bif_stanza;
+
+struct stanza_entry
+{
+  const char *stanza_name;
+  bif_stanza stanza;
+};
+
+static stanza_entry stanza_map[NUMBIFSTANZAS] =
+  {
+{ "always",BSTZ_ALWAYS },
+{ "power5",BSTZ_P5 },
+{ "power6",BSTZ_P6 },
+{ "altivec",   BSTZ_ALTIVEC},
+{ "cell",  BSTZ_CELL   },
+{ "vsx",   BSTZ_VSX},
+{ "power7",BSTZ_P7 },
+{ "power7-64", BSTZ_P7_64  },
+{ "power8",BSTZ_P8 },
+{ "power8-vector", BSTZ_P8V},
+{ "power9",BSTZ_P9 },
+{ "power9-64", BSTZ_P9_64  },
+{ "power9-vector", BSTZ_P9V},
+{ "ieee128-hw",BSTZ_IEEE128_HW },
+{ "dfp",   BSTZ_DFP},
+{ "crypto",BSTZ_CRYPTO },
+{ "htm",   BSTZ_HTM},
+{ "power10",   BSTZ_P10},
+{ "power10-64",BSTZ_P10_64 },
+{ "mma",   BSTZ_MMA}
+  };
+
+static const char *enable_string[NUMBIFSTANZAS] =
+  {
+"ENB_ALWAYS",
+"ENB_P5",
+"ENB_P6",
+"ENB_ALTIVEC",
+"ENB_CELL",
+"ENB_VSX",
+"ENB_P7",
+"ENB_P7_64",
+"ENB_P8",
+"ENB_P8V",
+"ENB_P9",
+"ENB_P9_64",
+"ENB_P9V",
+"ENB_IEEE128_HW",
+"ENB_DFP",
+"ENB_CRYPTO",
+"ENB_HTM",
+"ENB_P10",
+"ENB_P10_64",
+"ENB_MMA"
+  };
+
+/* Function modifiers provide special handling for const, pure, and fpmath
+   functions.  These are mutually exclusive, and therefore kept separate
+   from other bif attributes.  */
+enum fnkinds
+{
+  FNK_NONE,
+  FNK_CONST,
+  FNK_PURE,
+  FNK_FPMATH
+};
+
 /* Legal base types for an argument or return type.  */
 enum basetype
 {
@@ -250,7 +345,72 @@ struct typeinfo
   char *val2;
 };
 
+/* A list of argument types.  */
+struct typelist
+{
+  typeinfo info;
+  typelist *next;
+};
+
+/* Attributes of a builtin function.  */
+struct attrinfo
+{
+  char isinit;
+  char isset;
+  char isextract;
+  char isnosoft;
+  char isldvec;
+  char isstvec;
+  char isreve;
+  char ispred;
+  char ishtm;
+  char ishtmspr;
+  char ishtmcr;
+  char ismma;
+  char isquad;
+  char ispair;
+  char isno32bit;
+  char is32bit;
+  char iscpu;
+  char isldstmask;
+  char islxvrse;
+  char islxvrze;
+  char isendian;
+};
+
+/* Fields associated with a function prototype (bif or overload).  */
+#define MAXRESTROPNDS 3
+struct prototype
+{
+  typeinfo rettype;
+  char *bifname;
+  int nargs;
+  typelist *args;
+  int restr_opnd[MAXRESTROPNDS];
+  restriction restr[MAXRESTROPNDS];
+  char *restr_val1[MAXRESTROPNDS];
+  char *restr_val2[MAXRESTROPNDS];
+};
+
+/* Data associated with a builtin function, and a table of such data.  */
+#define MAXBIFS 16384
+struct bifdata
+{
+  int stanza;
+  fnkinds kind;
+  prototype proto;
+  char *idname;
+  char *patname;
+  attrinfo attrs;
+  char *fndecl;
+};
+
+static bifdata bifs[MAXBIFS];
 static int num_bifs;
+static int curr_bif;
+static int *bif_order;
+static int bif_index = 0;
+
 static int num_ovld_stanzas;
 static int num_ovlds;
 
@@ -420,6 +580,15 @@ 

[PATCH 10/55] rs6000: Main function with stubs for parsing and output

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-08  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (rbtree.h): New #include.
(num_bifs): New variable.
(num_ovld_stanzas): Likewise.
(num_ovlds): Likewise.
(parse_codes): New enum.
(bif_rbt): New variable.
(ovld_rbt): Likewise.
(fntype_rbt): Likewise.
(bifo_rbt): Likewise.
(parse_bif): New stub function.
(create_bif_order): Likewise.
(parse_ovld): Likewise.
(write_header_file): Likewise.
(write_init_file): Likewise.
(write_defines_file): Likewise.
(delete_output_files): New function.
(main): Likewise.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 211 
 1 file changed, 211 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index b964dc2298f..69345b9de70 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -163,6 +163,7 @@ along with GCC; see the file COPYING3.  If not see
 #include 
 #include 
 #include 
+#include "rbtree.h"
 
 /* Input and output file descriptors and pathnames.  */
 static FILE *bif_file;
@@ -249,6 +250,29 @@ struct typeinfo
   char *val2;
 };
 
+static int num_bifs;
+static int num_ovld_stanzas;
+static int num_ovlds;
+
+/* Return codes for parsing routines.  */
+enum parse_codes
+{
+  PC_OK,
+  PC_EOFILE,
+  PC_EOSTANZA,
+  PC_PARSEFAIL
+};
+
+/* The red-black trees for built-in function identifiers, built-in
+   overload identifiers, and function type descriptors.  */
+static rbt_strings bif_rbt;
+static rbt_strings ovld_rbt;
+static rbt_strings fntype_rbt;
+
+/* Another red-black tree containing a mapping from built-in function
+   identifiers to the order in which they were encountered.  */
+static rbt_strings bifo_rbt;
+
 /* Pointer to a diagnostic function.  */
 static void (*diag) (const char *, ...)
   __attribute__ ((format (printf, 1, 2)));
@@ -865,3 +889,190 @@ match_type (typeinfo *typedata, int voidok)
 
   return 1;
 }
+
+/* Parse the built-in file.  */
+static parse_codes
+parse_bif (void)
+{
+  return PC_OK;
+}
+
+/* Create a mapping from function IDs in their final order to the order
+   they appear in the built-in function file.  */
+static void
+create_bif_order (void)
+{
+}
+
+/* Parse the overload file.  */
+static parse_codes
+parse_ovld (void)
+{
+  return PC_OK;
+}
+
+/* Write everything to the header file (rs6000-builtins.h).  */
+static int
+write_header_file (void)
+{
+  return 1;
+}
+
+/* Write everything to the initialization file (rs6000-builtins.c).  */
+static int
+write_init_file (void)
+{
+  return 1;
+}
+
+/* Write everything to the include file (rs6000-vecdefines.h).  */
+static int
+write_defines_file (void)
+{
+  return 1;
+}
+
+/* Close and delete output files after any failure, so that subsequent
+   build dependencies will fail.  */
+static void
+delete_output_files (void)
+{
+  /* Depending on whence we're called, some of these may already be
+ closed.  Don't check for errors.  */
+  fclose (header_file);
+  fclose (init_file);
+  fclose (defines_file);
+
+  unlink (header_path);
+  unlink (init_path);
+  unlink (defines_path);
+}
+
+/* Main program to convert flat files into built-in initialization code.  */
+int
+main (int argc, const char **argv)
+{
+  if (argc != 6)
+{
+  fprintf (stderr,
+  "Five arguments required: two input file and three output "
+  "files.\n");
+  exit (1);
+}
+
+  pgm_path = argv[0];
+  bif_path = argv[1];
+  ovld_path = argv[2];
+  header_path = argv[3];
+  init_path = argv[4];
+  defines_path = argv[5];
+
+  bif_file = fopen (bif_path, "r");
+  if (!bif_file)
+{
+  fprintf (stderr, "Cannot find input built-in file '%s'.\n", bif_path);
+  exit (1);
+}
+  ovld_file = fopen (ovld_path, "r");
+  if (!ovld_file)
+{
+  fprintf (stderr, "Cannot find input overload file '%s'.\n", ovld_path);
+  exit (1);
+}
+  header_file = fopen (header_path, "w");
+  if (!header_file)
+{
+  fprintf (stderr, "Cannot open header file '%s' for output.\n",
+  header_path);
+  exit (1);
+}
+  init_file = fopen (init_path, "w");
+  if (!init_file)
+{
+  fprintf (stderr, "Cannot open init file '%s' for output.\n", init_path);
+  exit (1);
+}
+  defines_file = fopen (defines_path, "w");
+  if (!defines_file)
+{
+  fprintf (stderr, "Cannot open defines file '%s' for output.\n",
+  defines_path);
+  exit (1);
+}
+
+  /* Initialize the balanced trees containing built-in function ids,
+ overload function ids, and function type declaration ids.  */
+  rbt_new (_rbt);
+  rbt_new (_rbt);
+  rbt_new (_rbt);
+
+  /* Initialize another balanced tree that contains a map from built-in
+ function ids to the order in which they were encountered.  */
+  rbt_new (_rbt);
+
+  /* Parse the built-in function file.  */
+  num_bifs 

[PATCH 09/55] rs6000: Red-black tree implementation for balanced tree search

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-08  Bill Schmidt  

gcc/
* config/rs6000/rbtree.c: New file.
* config/rs6000/rbtree.h: New file.
---
 gcc/config/rs6000/rbtree.c | 242 +
 gcc/config/rs6000/rbtree.h |  52 
 2 files changed, 294 insertions(+)
 create mode 100644 gcc/config/rs6000/rbtree.c
 create mode 100644 gcc/config/rs6000/rbtree.h

diff --git a/gcc/config/rs6000/rbtree.c b/gcc/config/rs6000/rbtree.c
new file mode 100644
index 000..37a559c1fbc
--- /dev/null
+++ b/gcc/config/rs6000/rbtree.c
@@ -0,0 +1,242 @@
+/* Partial red-black tree implementation for rs6000-gen-builtins.c.
+   Copyright (C) 2020-21 Free Software Foundation, Inc.
+   Contributed by Bill Schmidt, IBM 
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#include 
+#include 
+#include 
+#include 
+#include "rbtree.h"
+
+/* Initialize a red-black tree.  */
+void
+rbt_new (struct rbt_strings *t)
+{
+  t->rbt_nil = (rbt_string_node *) malloc (sizeof (rbt_string_node));
+  t->rbt_nil->color = RBT_BLACK;
+  t->rbt_root = t->rbt_nil;
+}
+
+/* Create a new node to be inserted into the red-black tree.  An inserted
+   node starts out red.  */
+static struct rbt_string_node *
+rbt_create_node (struct rbt_strings *t, char *str)
+{
+  struct rbt_string_node *nodeptr
+= (struct rbt_string_node *) malloc (sizeof (rbt_string_node));
+  nodeptr->str = str;
+  nodeptr->left = t->rbt_nil;
+  nodeptr->right = t->rbt_nil;
+  nodeptr->par = NULL;
+  nodeptr->color = RBT_RED;
+  return nodeptr;
+}
+
+/* Perform a left-rotate operation on NODE in the red-black tree.  */
+static void
+rbt_left_rotate (struct rbt_strings *t, struct rbt_string_node *node)
+{
+  struct rbt_string_node *right = node->right;
+  assert (right);
+
+  /* Turn RIGHT's left subtree into NODE's right subtree.  */
+  node->right = right->left;
+  if (right->left != t->rbt_nil)
+right->left->par = node;
+
+  /* Link NODE's parent to RIGHT.  */
+  right->par = node->par;
+
+  if (node->par == t->rbt_nil)
+t->rbt_root = right;
+  else if (node == node->par->left)
+node->par->left = right;
+  else
+node->par->right = right;
+
+  /* Put NODE on RIGHT's left.  */
+  right->left = node;
+  node->par = right;
+}
+
+/* Perform a right-rotate operation on NODE in the red-black tree.  */
+static void
+rbt_right_rotate (struct rbt_strings *t, struct rbt_string_node *node)
+{
+  struct rbt_string_node *left = node->left;
+  assert (left);
+
+  /* Turn LEFT's right subtree into NODE's left subtree.  */
+  node->left = left->right;
+  if (left->right != t->rbt_nil)
+left->right->par = node;
+
+  /* Link NODE's parent to LEFT.  */
+  left->par = node->par;
+
+  if (node->par == t->rbt_nil)
+t->rbt_root = left;
+  else if (node == node->par->right)
+node->par->right = left;
+  else
+node->par->left = left;
+
+  /* Put NODE on LEFT's right.  */
+  left->right = node;
+  node->par = left;
+}
+
+/* Insert STR into the tree, returning 1 for success and 0 if STR already
+   appears in the tree.  */
+int
+rbt_insert (struct rbt_strings *t, char *str)
+{
+  struct rbt_string_node *curr = t->rbt_root;
+  struct rbt_string_node *trail = t->rbt_nil;
+
+  while (curr != t->rbt_nil)
+{
+  trail = curr;
+  int cmp = strcmp (str, curr->str);
+  if (cmp < 0)
+   curr = curr->left;
+  else if (cmp > 0)
+   curr = curr->right;
+  else
+   return 0;
+}
+
+  struct rbt_string_node *fresh = rbt_create_node (t, str);
+  fresh->par = trail;
+
+  if (trail == t->rbt_nil)
+t->rbt_root = fresh;
+  else if (strcmp (fresh->str, trail->str) < 0)
+trail->left = fresh;
+  else
+trail->right = fresh;
+
+  fresh->left = t->rbt_nil;
+  fresh->right = t->rbt_nil;
+
+  /* FRESH has now been inserted as a red leaf.  If we have invalidated
+ one of the following preconditions, we must fix things up:
+  (a) If a node is red, both of its children are black.
+  (b) The root must be black.
+ Note that only (a) or (b) applies at any given time during the
+ process.  This algorithm works up the tree from NEW looking
+ for a red child with a red parent, and cleaning that up.  If the
+ root ends up red, it gets turned black at the end.  */
+  curr = fresh;
+  while (curr->par->color == RBT_RED)
+if (curr->par == curr->par->par->left)
+  {
+   struct rbt_string_node *uncle = curr->par->par->right;
+   

[PATCH 08/55] rs6000: Add functions for matching types, part 3 of 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (restriction): New enum.
(typeinfo): Add restr field.
(match_bracketed_pair): New function.
(match_const_restriction): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 115 +++-
 1 file changed, 114 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index f850ea86a39..b964dc2298f 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -216,6 +216,22 @@ enum basetype
   BT_VQUAD
 };
 
+/* Ways in which a const int value can be restricted.  RES_BITS indicates
+   that the integer is restricted to val1 bits, interpreted as an unsigned
+   number.  RES_RANGE indicates that the integer is restricted to values
+   between val1 and val2, inclusive.  RES_VAR_RANGE is like RES_RANGE, but
+   the argument may be variable, so it can only be checked if it is constant.
+   RES_VALUES indicates that the integer must have one of the values val1
+   or val2.  */
+enum restriction
+{
+  RES_NONE,
+  RES_BITS,
+  RES_RANGE,
+  RES_VAR_RANGE,
+  RES_VALUES
+};
+
 /* Type modifiers for an argument or return type.  */
 struct typeinfo
 {
@@ -228,6 +244,7 @@ struct typeinfo
   char ispixel;
   char ispointer;
   basetype base;
+  restriction restr;
   char *val1;
   char *val2;
 };
@@ -453,6 +470,53 @@ match_basetype (typeinfo *typedata)
   return 1;
 }
 
+/* Helper routine for match_const_restriction.  */
+static int
+match_bracketed_pair (typeinfo *typedata, char open, char close,
+ restriction restr)
+{
+  if (linebuf[pos] == open)
+{
+  safe_inc_pos ();
+  int oldpos = pos;
+  char *x = match_integer ();
+  if (x == NULL)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  consume_whitespace ();
+  if (linebuf[pos] != ',')
+   {
+ (*diag) ("missing comma at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+  consume_whitespace ();
+  oldpos = pos;
+  char *y = match_integer ();
+  if (y == NULL)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  typedata->restr = restr;
+  typedata->val1 = x;
+  typedata->val2 = y;
+
+  consume_whitespace ();
+  if (linebuf[pos] != close)
+   {
+ (*diag) ("malformed restriction at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+  return 1;
+}
+
+  return 0;
+}
+
 /* A const int argument may be restricted to certain values.  This is
indicated by one of the following occurring after the "int' token:
 
@@ -470,7 +534,56 @@ match_basetype (typeinfo *typedata)
 static int
 match_const_restriction (typeinfo *typedata)
 {
-  return 1;
+  int oldpos = pos;
+  if (linebuf[pos] == '<')
+{
+  safe_inc_pos ();
+  oldpos = pos;
+  char *x = match_integer ();
+  if (x == NULL)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  consume_whitespace ();
+  if (linebuf[pos] == '>')
+   {
+ typedata->restr = RES_BITS;
+ typedata->val1 = x;
+ safe_inc_pos ();
+ return 1;
+   }
+  else if (linebuf[pos] != ',')
+   {
+ (*diag) ("malformed restriction at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+  oldpos = pos;
+  char *y = match_integer ();
+  if (y == NULL)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  typedata->restr = RES_RANGE;
+  typedata->val1 = x;
+  typedata->val2 = y;
+
+  consume_whitespace ();
+  if (linebuf[pos] != '>')
+   {
+ (*diag) ("malformed restriction at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+  return 1;
+}
+  else if (match_bracketed_pair (typedata, '{', '}', RES_VALUES)
+  || match_bracketed_pair (typedata, '[', ']', RES_VAR_RANGE))
+return 1;
+
+  return 0;
 }
 
 /* Look for a type, which can be terminated by a token that is not part of
-- 
2.27.0



[PATCH 07/55] rs6000: Add functions for matching types, part 2 of 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-04-02  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (match_basetype): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 64 +
 1 file changed, 64 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 38363f034d3..f850ea86a39 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -386,6 +386,70 @@ handle_pointer (typeinfo *typedata)
 static int
 match_basetype (typeinfo *typedata)
 {
+  consume_whitespace ();
+  int oldpos = pos;
+  char *token = match_identifier ();
+  if (!token)
+{
+  (*diag) ("missing base type in return type at column %d\n", pos + 1);
+  return 0;
+}
+
+  if (!strcmp (token, "char"))
+typedata->base = BT_CHAR;
+  else if (!strcmp (token, "short"))
+typedata->base = BT_SHORT;
+  else if (!strcmp (token, "int"))
+typedata->base = BT_INT;
+  else if (!strcmp (token, "long"))
+{
+  consume_whitespace ();
+  oldpos = pos;
+  char *mustbelongordbl = match_identifier ();
+  if (!mustbelongordbl)
+   typedata->base = BT_LONG;
+  else if (!strcmp (mustbelongordbl, "long"))
+   typedata->base = BT_LONGLONG;
+  else if (!strcmp (mustbelongordbl, "double"))
+   typedata->base = BT_LONGDOUBLE;
+  else
+   /* Speculatively accept "long" here and push back the token.
+  This occurs when "long" is a return type and the next token
+  is the function name.  */
+   {
+ typedata->base = BT_LONG;
+ pos = oldpos;
+   }
+}
+  else if (!strcmp (token, "float"))
+typedata->base = BT_FLOAT;
+  else if (!strcmp (token, "double"))
+typedata->base = BT_DOUBLE;
+  else if (!strcmp (token, "__int128"))
+typedata->base = BT_INT128;
+  else if (!strcmp (token, "_Float128"))
+typedata->base = BT_FLOAT128;
+  else if (!strcmp (token, "bool"))
+typedata->base = BT_BOOL;
+  /* A "string" is a special "const char *" -- we need it because it
+ cannot match either signed or unsigned char *.  */
+  else if (!strcmp (token, "string"))
+typedata->base = BT_STRING;
+  else if (!strcmp (token, "_Decimal32"))
+typedata->base = BT_DECIMAL32;
+  else if (!strcmp (token, "_Decimal64"))
+typedata->base = BT_DECIMAL64;
+  else if (!strcmp (token, "_Decimal128"))
+typedata->base = BT_DECIMAL128;
+  else if (!strcmp (token, "__ibm128"))
+typedata->base = BT_IBM128;
+  else
+{
+  (*diag) ("unrecognized base type at column %d\n", oldpos + 1);
+  return 0;
+}
+
+  handle_pointer (typedata);
   return 1;
 }
 
-- 
2.27.0



[PATCH 06/55] rs6000: Add functions for matching types, part 1 of 3

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (void_status): New enum.
(basetype): Likewise.
(typeinfo): Likewise.
(handle_pointer): New function.
(match_basetype): New stub function.
(match_const_restriction): Likewise.
(match_type): New function.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 367 
 1 file changed, 367 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index c5d5590e865..38363f034d3 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -186,6 +186,52 @@ static char linebuf[LINELEN];
 static int line;
 static int pos;
 
+/* Used to determine whether a type can be void (only return types).  */
+enum void_status
+{
+ VOID_NOTOK,
+ VOID_OK
+};
+
+/* Legal base types for an argument or return type.  */
+enum basetype
+{
+  BT_CHAR,
+  BT_SHORT,
+  BT_INT,
+  BT_LONG,
+  BT_LONGLONG,
+  BT_FLOAT,
+  BT_DOUBLE,
+  BT_LONGDOUBLE,
+  BT_INT128,
+  BT_FLOAT128,
+  BT_BOOL,
+  BT_STRING,
+  BT_DECIMAL32,
+  BT_DECIMAL64,
+  BT_DECIMAL128,
+  BT_IBM128,
+  BT_VPAIR,
+  BT_VQUAD
+};
+
+/* Type modifiers for an argument or return type.  */
+struct typeinfo
+{
+  char isvoid;
+  char isconst;
+  char isvector;
+  char issigned;
+  char isunsigned;
+  char isbool;
+  char ispixel;
+  char ispointer;
+  basetype base;
+  char *val1;
+  char *val2;
+};
+
 /* Pointer to a diagnostic function.  */
 static void (*diag) (const char *, ...)
   __attribute__ ((format (printf, 1, 2)));
@@ -321,3 +367,324 @@ match_to_right_bracket (void)
   pos = lastpos + 1;
   return buf;
 }
+
+static inline void
+handle_pointer (typeinfo *typedata)
+{
+  consume_whitespace ();
+  if (linebuf[pos] == '*')
+{
+  typedata->ispointer = 1;
+  safe_inc_pos ();
+}
+}
+
+/* Match one of the allowable base types.  Consumes one token unless the
+   token is "long", which must be paired with a second "long".  Optionally
+   consumes a following '*' token for pointers.  Return 1 for success,
+   0 for failure.  */
+static int
+match_basetype (typeinfo *typedata)
+{
+  return 1;
+}
+
+/* A const int argument may be restricted to certain values.  This is
+   indicated by one of the following occurring after the "int' token:
+
+restricts the constant to x bits, interpreted as unsigned
+  restricts the constant to the inclusive range [x,y]
+ [x,y] restricts the constant to the inclusive range [x,y],
+  but only applies if the argument is constant.
+ {x,y} restricts the constant to one of two values, x or y.
+
+   Here x and y are integer tokens.  Note that the "const" token is a
+   lie when the restriction is [x,y], but this simplifies the parsing
+   significantly and is hopefully forgivable.
+
+   Return 1 for success, else 0.  */
+static int
+match_const_restriction (typeinfo *typedata)
+{
+  return 1;
+}
+
+/* Look for a type, which can be terminated by a token that is not part of
+   a type, a comma, or a closing parenthesis.  Place information about the
+   type in TYPEDATA.  Return 1 for success, 0 for failure.  */
+static int
+match_type (typeinfo *typedata, int voidok)
+{
+  /* A legal type is of the form:
+
+   [const] [[signed|unsigned]  | ] [*]
+
+ Legal values of  are (for now):
+
+   char
+   short
+   int
+   long
+   long double
+   long long
+   float
+   double
+   __int128
+   _Float128
+   bool
+   string
+   _Decimal32
+   _Decimal64
+   _Decimal128
+   __ibm128
+
+ Legal values of  are as follows, and are shorthand for
+ the associated meaning:
+
+   vsc vector signed char
+   vuc vector unsigned char
+   vbc vector bool char
+   vss vector signed short
+   vus vector unsigned short
+   vbs vector bool short
+   vsi vector signed int
+   vui vector unsigned int
+   vbi vector bool int
+   vsllvector signed long long
+   vullvector unsigned long long
+   vbllvector bool long long
+   vsq vector signed __int128
+   vuq vector unsigned __int128
+   vbq vector bool __int128
+   vp  vector pixel
+   vf  vector float
+   vd  vector double
+   v256__vector_pair
+   v512__vector_quad
+
+ For simplicity, We don't support "short int" and "long long int".
+ We don't currently support a  of "_Float16".  "signed"
+ and "unsigned" only apply to integral base types.  The optional *
+ indicates a pointer type.  */
+
+  consume_whitespace ();
+  memset (typedata, 0, sizeof *typedata);
+  int oldpos = pos;
+
+  char *token = match_identifier ();
+  if (!token)
+return 0;
+
+  if (!strcmp (token, "const"))
+{
+  typedata->isconst = 1;
+  consume_whitespace ();
+  oldpos = pos;
+  token = match_identifier ();
+   

[PATCH 05/55] rs6000: Add helper functions for parsing

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (consume_whitespace): New
function.
(advance_line): Likewise.
(safe_inc_pos): Likewise.
(match_identifier): Likewise.
(match_integer): Likewise.
(match_to_right_bracket): Likewise.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 111 
 1 file changed, 111 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 3c53c3401b2..c5d5590e865 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -210,3 +210,114 @@ ovld_diag (const char * fmt, ...)
   vfprintf (stderr, fmt, args);
   va_end (args);
 }
+
+/* Pass over unprintable characters and whitespace (other than a newline,
+   which terminates the scan).  */
+static void
+consume_whitespace (void)
+{
+  while (pos < LINELEN && isspace(linebuf[pos]) && linebuf[pos] != '\n')
+pos++;
+  return;
+}
+
+/* Get the next nonblank, noncomment line, returning 0 on EOF, 1 otherwise.  */
+static int
+advance_line (FILE *file)
+{
+  while (1)
+{
+  /* Read ahead one line and check for EOF.  */
+  if (!fgets (linebuf, sizeof linebuf, file))
+   return 0;
+  line++;
+  size_t len = strlen (linebuf);
+  if (linebuf[len - 1] != '\n')
+   (*diag) ("line doesn't terminate with newline\n");
+  pos = 0;
+  consume_whitespace ();
+  if (linebuf[pos] != '\n' && linebuf[pos] != ';')
+   return 1;
+}
+}
+
+static inline void
+safe_inc_pos (void)
+{
+  if (pos++ >= LINELEN)
+{
+  (*diag) ("line length overrun.\n");
+  exit (1);
+}
+}
+
+/* Match an identifier, returning NULL on failure, else a pointer to a
+   buffer containing the identifier.  */
+static char *
+match_identifier (void)
+{
+  int lastpos = pos - 1;
+  while (isalnum (linebuf[lastpos + 1]) || linebuf[lastpos + 1] == '_')
+++lastpos;
+
+  if (lastpos < pos)
+return 0;
+
+  char *buf = (char *) malloc (lastpos - pos + 2);
+  memcpy (buf, [pos], lastpos - pos + 1);
+  buf[lastpos - pos + 1] = '\0';
+
+  pos = lastpos + 1;
+  return buf;
+}
+
+/* Match an integer and return the string representing its value,
+   or a null string on failure.  */
+static char *
+match_integer (void)
+{
+  int startpos = pos;
+  if (linebuf[pos] == '-')
+safe_inc_pos ();
+
+  int lastpos = pos - 1;
+  while (isdigit (linebuf[lastpos + 1]))
+++lastpos;
+
+  if (lastpos < pos)
+return NULL;
+
+  pos = lastpos + 1;
+  char *buf = (char *) malloc (lastpos - startpos + 2);
+  memcpy (buf, [startpos], lastpos - startpos + 1);
+  buf[lastpos - startpos + 1] = '\0';
+  return buf;
+}
+
+/* Match a string up to but not including a ']', and return its value,
+   or zero if there is nothing before the ']'.  Error if we don't find
+   such a character.  */
+static const char *
+match_to_right_bracket (void)
+{
+  int lastpos = pos - 1;
+  while (linebuf[lastpos + 1] != ']')
+{
+  if (linebuf[lastpos + 1] == '\n')
+   {
+ (*diag) ("no ']' found before end of line.\n");
+ exit (1);
+   }
+  ++lastpos;
+}
+
+  if (lastpos < pos)
+return 0;
+
+  char *buf = (char *) malloc (lastpos - pos + 2);
+  memcpy (buf, [pos], lastpos - pos + 1);
+  buf[lastpos - pos + 1] = '\0';
+
+  pos = lastpos + 1;
+  return buf;
+}
-- 
2.27.0



[PATCH 04/55] rs6000: Add file support and functions for diagnostic support

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-06-07  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (bif_file): New variable.
(ovld_file): Likewise.
(header_file): Likewise.
(init_file): Likewise.
(defines_file): Likewise.
(pgm_path): Likewise.
(bif_path): Likewise.
(ovld_path): Likewise.
(header_path): Likewise.
(init_path): Likewise.
(defines_path): Likewise.
(LINELEN): New macro.
(linebuf): New variable.
(line): Likewise.
(pos): Likewise.
(diag): Likewise.
(bif_diag): New function.
(ovld_diag): Likewise.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 47 +
 1 file changed, 47 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 6ab7d7bb189..3c53c3401b2 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -163,3 +163,50 @@ along with GCC; see the file COPYING3.  If not see
 #include 
 #include 
 #include 
+
+/* Input and output file descriptors and pathnames.  */
+static FILE *bif_file;
+static FILE *ovld_file;
+static FILE *header_file;
+static FILE *init_file;
+static FILE *defines_file;
+
+static const char *pgm_path;
+static const char *bif_path;
+static const char *ovld_path;
+static const char *header_path;
+static const char *init_path;
+static const char *defines_path;
+
+/* Position information.  Note that "pos" is zero-indexed, but users
+   expect one-indexed column information, so representations of "pos"
+   as columns in diagnostic messages must be adjusted.  */
+#define LINELEN 1024
+static char linebuf[LINELEN];
+static int line;
+static int pos;
+
+/* Pointer to a diagnostic function.  */
+static void (*diag) (const char *, ...)
+  __attribute__ ((format (printf, 1, 2)));
+
+/* Custom diagnostics.  */
+static void __attribute__ ((format (printf, 1, 2)))
+bif_diag (const char * fmt, ...)
+{
+  va_list args;
+  fprintf (stderr, "%s:%d: ", bif_path, line);
+  va_start (args, fmt);
+  vfprintf (stderr, fmt, args);
+  va_end (args);
+}
+
+static void __attribute__ ((format (printf, 1, 2)))
+ovld_diag (const char * fmt, ...)
+{
+  va_list args;
+  fprintf (stderr, "%s:%d: ", ovld_path, line);
+  va_start (args, fmt);
+  vfprintf (stderr, fmt, args);
+  va_end (args);
+}
-- 
2.27.0



[PATCH 03/55] rs6000: Add initial input files

2021-06-17 Thread Bill Schmidt via Gcc-patches
This patch adds a tiny subset of the built-in and overload descriptions.

2021-04-02  Bill Schmidt  

gcc/
* config/rs6000/rs6000-builtin-new.def: New.
* config/rs6000/rs6000-overload.def: New.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 199 +++
 gcc/config/rs6000/rs6000-overload.def|  82 ++
 2 files changed, 281 insertions(+)
 create mode 100644 gcc/config/rs6000/rs6000-builtin-new.def
 create mode 100644 gcc/config/rs6000/rs6000-overload.def

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
new file mode 100644
index 000..a84a3def2d5
--- /dev/null
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -0,0 +1,199 @@
+; Built-in functions for PowerPC.
+; Copyright (C) 2020-21 Free Software Foundation, Inc.
+; Contributed by Bill Schmidt, IBM 
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; .
+
+
+; Built-in functions in this file are organized into "stanzas", where
+; all built-ins in a given stanza are enabled together.  Each stanza
+; starts with a line identifying the circumstances in which the group of
+; functions is permitted, with the gating predicate in square brackets.
+; For example, this could be
+;
+; [altivec]
+;
+;   or it could be
+;
+; [power9]
+;
+; The bracketed gating predicate is the only information allowed on
+; the stanza header line, other than whitespace.
+;
+; Following the stanza header are two lines for each function: the
+; prototype line and the attributes line.  The prototype line has
+; this format, where the square brackets indicate optional
+; information and angle brackets indicate required information:
+;
+;   [kind]   ();
+;
+; Here [kind] can be one of "const", "pure", or "fpmath";
+;  is a legal type for a built-in function result;
+;  is the name by which the function can be called;
+; and  is a comma-separated list of legal types
+; for built-in function arguments.  The argument list may be
+; empty, but the parentheses and semicolon are required.
+;
+; A legal type is of the form:
+;
+;   [const] [[signed|unsigned]  | ] [*]
+;
+; where "const" applies only to a  of "int".  Legal values
+; of  are (for now):
+;
+;   char
+;   short
+;   int
+;   long
+;   long double
+;   long long
+;   float
+;   double
+;   __int128
+;   _Float128
+;   bool
+;   string
+;   _Decimal32
+;   _Decimal64
+;   _Decimal128
+;   __ibm128
+;
+; Legal values of  are as follows, and are shorthand for
+; the associated meaning:
+;
+;   vscvector signed char
+;   vucvector unsigned char
+;   vbcvector bool char
+;   vssvector signed short
+;   vusvector unsigned short
+;   vbsvector bool short
+;   vsivector signed int
+;   vuivector unsigned int
+;   vbivector bool int
+;   vsll   vector signed long long
+;   vull   vector unsigned long long
+;   vbll   vector bool long long
+;   vsqvector signed __int128
+;   vuqvector unsigned __int128
+;   vbqvector bool __int128
+;   vp vector pixel
+;   vf vector float
+;   vd vector double
+;   v256   __vector_pair
+;   v512   __vector_quad
+;
+; For simplicity, We don't support "short int" and "long long int".
+; We don't currently support a  of "_Float16".  "signed"
+; and "unsigned" only apply to integral base types.  The optional *
+; indicates a pointer type.
+;
+; The attributes line looks like this:
+;
+; {}
+;
+; Here  is a unique internal identifier for the built-in
+; function that will be used as part of an enumeration of all
+; built-in functions;  is the define_expand or
+; define_insn that will be invoked when the call is expanded;
+; and  is a comma-separated list of special
+; conditions that apply to the built-in function.  The attribute
+; list may be empty, but the braces are required.
+;
+; Attributes are strings, and the allowed ones are listed below.
+;
+;   init Process as a vec_init function
+;   set  Process as a vec_set function
+;   extract  Process as a vec_extract function
+;   nosoft   Not valid with -msoft-float
+;   ldvecNeeds special handling for vec_ld semantics
+;   stvecNeeds special handling for vec_st semantics
+;   reve Needs special handling 

[PATCH 02/55] rs6000: Initial create of rs6000-gen-builtins.c

2021-06-17 Thread Bill Schmidt via Gcc-patches
2021-04-02  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c: New.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 165 
 1 file changed, 165 insertions(+)
 create mode 100644 gcc/config/rs6000/rs6000-gen-builtins.c

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
new file mode 100644
index 000..6ab7d7bb189
--- /dev/null
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -0,0 +1,165 @@
+/* Generate built-in function initialization and recognition for Power.
+   Copyright (C) 2020-21 Free Software Foundation, Inc.
+   Contributed by Bill Schmidt, IBM 
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+/* This program generates built-in function initialization and
+   recognition code for Power targets, based on text files that
+   describe the built-in functions and vector overloads:
+
+ rs6000-builtin-new.def Table of built-in functions
+ rs6000-overload.defTable of overload functions
+
+   Both files group similar functions together in "stanzas," as
+   described below.
+
+   Each stanza in the built-in function file starts with a line
+   identifying the circumstances in which the group of functions is
+   permitted, with the gating predicate in square brackets.  For
+   example, this could be
+
+ [altivec]
+
+   or it could be
+
+ [power9]
+
+   The bracketed gating predicate is the only information allowed on
+   the stanza header line, other than whitespace.
+
+   Following the stanza header are two lines for each function: the
+   prototype line and the attributes line.  The prototype line has
+   this format, where the square brackets indicate optional
+   information and angle brackets indicate required information:
+
+ [kind]   ();
+
+   Here [kind] can be one of "const", "pure", or "fpmath";
+is a legal type for a built-in function result;
+is the name by which the function can be called;
+   and  is a comma-separated list of legal types
+   for built-in function arguments.  The argument list may be
+   empty, but the parentheses and semicolon are required.
+
+   The attributes line looks like this:
+
+   {}
+
+   Here  is a unique internal identifier for the built-in
+   function that will be used as part of an enumeration of all
+   built-in functions;  is the define_expand or
+   define_insn that will be invoked when the call is expanded;
+   and  is a comma-separated list of special
+   conditions that apply to the built-in function.  The attribute
+   list may be empty, but the braces are required.
+
+   Attributes are strings, such as these:
+
+ init Process as a vec_init function
+ set  Process as a vec_set function
+ extract  Process as a vec_extract function
+ nosoft   Not valid with -msoft-float
+ ldvecNeeds special handling for vec_ld semantics
+ stvecNeeds special handling for vec_st semantics
+ reve Needs special handling for element reversal
+ pred Needs special handling for comparison predicates
+ htm  Needs special handling for transactional memory
+ htmspr   HTM function using an SPR
+ htmcrHTM function using a CR
+ mma  Needs special handling for MMA instructions
+ quad MMA instruction using a register quad as an input operand
+ pair MMA instruction using a register pair as an input operand
+ no32bit  Not valid for TARGET_32BIT
+ 32bitRequires different handling for TARGET_32BIT
+ cpu  This is a "cpu_is" or "cpu_supports" builtin
+ ldstmask Altivec mask for load or store
+ lxvrse   Needs special handling for load-rightmost, sign-extended
+ lxvrze   Needs special handling for load-rightmost, zero-extended
+ endian   Needs special handling for endianness
+
+   An example stanza might look like this:
+
+[altivec]
+  const vsc __builtin_altivec_abs_v16qi (vsc);
+ABS_V16QI absv16qi2 {}
+  const vss __builtin_altivec_abs_v8hi (vss);
+ABS_V8HI absv8hi2 {}
+
+   Here "vsc" and "vss" are shorthand for "vector signed char" and
+   "vector signed short" to shorten line lengths and improve readability.
+   Note the use of indentation, which is recommended but not required.
+
+   The overload file has more complex stanza headers.  Here the stanza
+   represents all functions with the same overloaded function name:
+
+ [, , [[, ]] 

[PATCH 01/55] Support scanning of build-time GC roots in gengtype

2021-06-17 Thread Bill Schmidt via Gcc-patches
Currently gengtype supports scanning target-specific files for GC roots,
but those files must exist in the source tree.  This patch extends the
support to include header files generated into the build directory.  It
also allows targets to specify build dependencies for s-gtype to ensure
the built headers are up to date prior to running gengtype.

2021-06-15  Bill Schmidt  

gcc/
* Makefile.in (EXTRA_GTYPE_DEPS): New variable.
(s-gtype): Depend on EXTRA_GTYPE_DEPS.
* gengtype-state.c (state_writer::write_state_file_list): Add a
parameter to the fileslist expression for the number of build
headers to scan.
(read_state_files_list): Detect build headers and strip the
initial "./" or ".\" from their names.
* gengtype.c (build_headers): New global variable.
(num_build_headers): Likewise.
(open_base_files): Emit #include for each build header.
(main): Detect and count build headers.
* gengtype.h (build_headers): New extern variable.
(num_build_headers): Likewise.
---
 gcc/Makefile.in  |  5 +++--
 gcc/gengtype-state.c | 32 ++--
 gcc/gengtype.c   | 22 +++---
 gcc/gengtype.h   |  5 +
 4 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 4cb2966157e..f651b61481b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -560,6 +560,7 @@ out_file=$(srcdir)/config/@out_file@
 out_object_file=@out_object_file@
 common_out_file=$(srcdir)/common/config/@common_out_file@
 common_out_object_file=@common_out_object_file@
+EXTRA_GTYPE_DEPS=
 md_file=$(srcdir)/common.md $(srcdir)/config/@md_file@
 tm_file_list=@tm_file_list@
 tm_include_list=@tm_include_list@
@@ -2734,8 +2735,8 @@ s-gtyp-input: Makefile
$(SHELL) $(srcdir)/../move-if-change tmp-gi.list gtyp-input.list
$(STAMP) s-gtyp-input
 
-s-gtype: build/gengtype$(build_exeext) $(filter-out [%], $(GTFILES)) \
-gtyp-input.list
+s-gtype: $(EXTRA_GTYPE_DEPS) build/gengtype$(build_exeext) \
+   $(filter-out [%], $(GTFILES)) gtyp-input.list
 # First, parse all files and save a state file.
$(RUN_GEN) build/gengtype$(build_exeext) $(GENGTYPE_FLAGS) \
 -S $(srcdir) -I gtyp-input.list -w tmp-gtype.state
diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c
index e9775ed633e..ac9d536963f 100644
--- a/gcc/gengtype-state.c
+++ b/gcc/gengtype-state.c
@@ -1269,7 +1269,7 @@ state_writer::write_state_files_list (void)
   int i = 0;
   /* Write the list of files with their lang_bitmap.  */
   begin_s_expr ("fileslist");
-  fprintf (state_file, "%d", (int) num_gt_files);
+  fprintf (state_file, "%d %d", (int) num_gt_files, (int) num_build_headers);
   for (i = 0; i < (int) num_gt_files; i++)
 {
   const char *cursrcrelpath = NULL;
@@ -2456,16 +2456,20 @@ read_state_files_list (void)
   struct state_token_st *t0 = peek_state_token (0);
   struct state_token_st *t1 = peek_state_token (1);
   struct state_token_st *t2 = peek_state_token (2);
+  struct state_token_st *t3 = peek_state_token (3);
 
   if (state_token_kind (t0) == STOK_LEFTPAR
   && state_token_is_name (t1, "!fileslist")
-  && state_token_kind (t2) == STOK_INTEGER)
+  && state_token_kind (t2) == STOK_INTEGER
+  && state_token_kind (t3) == STOK_INTEGER)
 {
-  int i = 0;
+  int i = 0, j = 0;
   num_gt_files = t2->stok_un.stok_num;
-  next_state_tokens (3);
-  t0 = t1 = t2 = NULL;
+  num_build_headers = t3->stok_un.stok_num;
+  next_state_tokens (4);
+  t0 = t1 = t2 = t3 = NULL;
   gt_files = XCNEWVEC (const input_file *, num_gt_files);
+  build_headers = XCNEWVEC (const char *, num_build_headers);
   for (i = 0; i < (int) num_gt_files; i++)
{
  bool issrcfile = FALSE;
@@ -2498,7 +2502,23 @@ read_state_files_list (void)
  free (fullpath);
}
  else
-   curgt = input_file_by_name (fnam);
+   {
+ curgt = input_file_by_name (fnam);
+ /* Look for a header file created during the build,
+which looks like "./.h".  */
+ int len = strlen (fnam);
+ if (len >= 5
+ && fnam[0] == '.'
+ && IS_DIR_SEPARATOR (fnam[1])
+ && fnam[len-2] == '.'
+ && fnam[len-1] == 'h')
+   {
+ char *buf = (char *) xmalloc (len - 1);
+ /* Strip the leading "./" from the filename.  */
+ strcpy (buf, [2]);
+ build_headers[j++] = buf;
+   }
+   }
  set_lang_bitmap (curgt, bmap);
  gt_files[i] = curgt;
  next_state_tokens (2);
diff --git 

[PATCHv3 00/55] Replace the Power target-specific builtin machinery

2021-06-17 Thread Bill Schmidt via Gcc-patches
Original patch series here:
https://gcc.gnu.org/pipermail/gcc-patches/2021-April/568840.html

V2 patch series here:
https://gcc.gnu.org/pipermail/gcc-patches/2021-June/572231.html

I've made some slight changes to the V2 series because of recent updates
to trunk from Carl Love and Peter Bergner.  Carl added some new P10
builtins, and Peter made some changes to the MMA builtins.  This series
is compatible with all builtins that are currently upstream.

As a reminder, as a result of reviews, the original patch 0001 has been
dropped, so the patch numbering is off by one compared with the original
series.  Status of the remaining patches (using new numbering):

0001: Approved
0002: Approved
0003: Approved
0004: Approved
0005: Needs re-review
0006: Approved
0007: Approved
0008: Approved
0009: Approved
0010-0055: Not yet reviewed

Thanks again for the ongoing reviews!

Bill

Bill Schmidt (55):
  Support scanning of build-time GC roots in gengtype
  rs6000: Initial create of rs6000-gen-builtins.c
  rs6000: Add initial input files
  rs6000: Add file support and functions for diagnostic support
  rs6000: Add helper functions for parsing
  rs6000: Add functions for matching types, part 1 of 3
  rs6000: Add functions for matching types, part 2 of 3
  rs6000: Add functions for matching types, part 3 of 3
  rs6000: Red-black tree implementation for balanced tree search
  rs6000: Main function with stubs for parsing and output
  rs6000: Parsing built-in input file, part 1 of 3
  rs6000: Parsing built-in input file, part 2 of 3
  rs6000: Parsing built-in input file, part 3 of 3
  rs6000: Parsing of overload input file
  rs6000: Build and store function type identifiers
  rs6000: Write output to the builtin definition include file
  rs6000: Write output to the builtins header file
  rs6000: Write output to the builtins init file, part 1 of 3
  rs6000: Write output to the builtins init file, part 2 of 3
  rs6000: Write output to the builtins init file, part 3 of 3
  rs6000: Write static initializations for built-in table
  rs6000: Write static initializations for overload tables
  rs6000: Incorporate new builtins code into the build machinery
  rs6000: Add gengtype handling to the build machinery
  rs6000: Add the rest of the [altivec] stanza to the builtins file
  rs6000: Add VSX builtins
  rs6000: Add available-everywhere and ancient builtins
  rs6000: Add power7 and power7-64 builtins
  rs6000: Add power8-vector builtins
  rs6000: Add Power9 builtins
  rs6000: Add more type nodes to support builtin processing
  rs6000: Add Power10 builtins
  rs6000: Add MMA builtins
  rs6000: Add miscellaneous builtins
  rs6000: Add Cell builtins
  rs6000: Add remaining overloads
  rs6000: Execute the automatic built-in initialization code
  rs6000: Darwin builtin support
  rs6000: Add sanity to V2DI_type_node definitions
  rs6000: Always initialize vector_pair and vector_quad nodes
  rs6000: Handle overloads during program parsing
  rs6000: Handle gimple folding of target built-ins
  rs6000: Support for vectorizing built-in functions
  rs6000: Builtin expansion, part 1
  rs6000: Builtin expansion, part 2
  rs6000: Builtin expansion, part 3
  rs6000: Builtin expansion, part 4
  rs6000: Builtin expansion, part 5
  rs6000: Builtin expansion, part 6
  rs6000: Update rs6000_builtin_decl
  rs6000: Miscellaneous uses of rs6000_builtin_decls_x
  rs6000: Debug support
  rs6000: Update altivec.h for automated interfaces
  rs6000: Test case adjustments
  rs6000: Enable the new builtin support

 gcc/Makefile.in   |5 +-
 gcc/config.gcc|2 +
 gcc/config/rs6000/altivec.h   |  522 +-
 gcc/config/rs6000/darwin.h|8 +-
 gcc/config/rs6000/rbtree.c|  242 +
 gcc/config/rs6000/rbtree.h|   52 +
 gcc/config/rs6000/rs6000-builtin-new.def  | 3998 +++
 gcc/config/rs6000/rs6000-c.c  | 1083 +++
 gcc/config/rs6000/rs6000-call.c   | 3399 -
 gcc/config/rs6000/rs6000-gen-builtins.c   | 2984 
 gcc/config/rs6000/rs6000-overload.def | 6186 +
 gcc/config/rs6000/rs6000.c|  219 +-
 gcc/config/rs6000/rs6000.h|   84 +
 gcc/config/rs6000/t-rs6000|   45 +-
 gcc/gengtype-state.c  |   32 +-
 gcc/gengtype.c|   22 +-
 gcc/gengtype.h|5 +
 .../powerpc/bfp/scalar-extract-exp-2.c|2 +-
 .../powerpc/bfp/scalar-extract-sig-2.c|2 +-
 .../powerpc/bfp/scalar-insert-exp-2.c |2 +-
 .../powerpc/bfp/scalar-insert-exp-5.c |2 +-
 .../powerpc/bfp/scalar-insert-exp-8.c |2 +-
 .../powerpc/bfp/scalar-test-neg-2.c   |2 +-
 .../powerpc/bfp/scalar-test-neg-3.c   |2 +-
 .../powerpc/bfp/scalar-test-neg-5.c   |2 +-
 

Re: [PATCH 5/6] make get_domminated_by_region return a auto_vec

2021-06-17 Thread Martin Sebor via Gcc-patches

On 6/17/21 12:03 AM, Richard Biener wrote:

On Wed, Jun 16, 2021 at 6:01 PM Martin Sebor  wrote:


On 6/16/21 6:46 AM, Richard Sandiford via Gcc-patches wrote:

Richard Biener via Gcc-patches  writes:

On Tue, Jun 15, 2021 at 8:02 AM Trevor Saunders  wrote:


This makes it clear the caller owns the vector, and ensures it is cleaned up.

Signed-off-by: Trevor Saunders 

bootstrapped and regtested on x86_64-linux-gnu, ok?


OK.

Btw, are "standard API" returns places we can use 'auto'?  That would avoid
excessive indent for

-  dom_bbs = get_dominated_by_region (CDI_DOMINATORS,
-bbs.address (),
-bbs.length ());
+  auto_vec dom_bbs = get_dominated_by_region (CDI_DOMINATORS,
+  bbs.address (),
+  bbs.length ());

and just uses

auto dom_bbs = get_dominated_by_region (...

Not asking you to do this, just a question for the audience.


Personally I think this would be surprising for something that doesn't
have copy semantics.  (Not that I'm trying to reopen that debate here :-)
FWIW, I agree not having copy semantics is probably the most practical
way forward for now.)


But you did open the door for me to reiterate my strong disagreement
with that.  The best C++ practice going back to the early 1990's is
to make types safely copyable and assignable.  It is the default for
all types, in both C++ and C, and so natural and expected.

Preventing copying is appropriate in special and rare circumstances
(e.g, a mutex may not be copyable, or a file or iostream object may
not be because they represent a unique physical resource.)

In the absence of such special circumstances preventing copying is
unexpected, and in the case of an essential building block such as
a container, makes the type difficult to use.

The only argument for disabling copying that has been given is
that it could be surprising(*).  But because all types are copyable
by default the "surprise" is usually when one can't be.

I think Richi's "surprising" has to do with the fact that it lets
one inadvertently copy a large amount of data, thus leading to
an inefficiency.  But by analogy, there are infinitely many ways
to end up with inefficient code (e.g., deep recursion, or heap
allocation in a loop), and they are not a reason to ban the coding
constructs that might lead to it.

IIUC, Jason's comment about surprising effects was about implicit
conversion from auto_vec to vec.  I share that concern, and agree
that it should be addressed by preventing the conversion (as Jason
suggested).


But fact is that how vec<> and auto_vec<> are used today in GCC
do not favor that.  In fact your proposed vec<> would be quite radically
different (and IMHO vec<> and auto_vec<> should be unified then to
form your proposed new container).  auto_vec<> at the moment simply
maintains ownership like a smart pointer - which is _also_ not copyable.


Yes, as we discussed in the review below, vec is not a good model
because (as you note again above) it's constrained by its legacy
uses.  The best I think we can do for it is to make it safer to
use.
https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571622.html

(Smart pointers don't rule out copying.  A std::unique_ptr does
and std::shared_ptr doesn't.  But vec and especially auto_vec
are designed to be containers, not "unique pointers" so any
relationship there is purely superficial and a distraction.)

That auto_vec and vec share a name and an is-a relationship is
incidental, an implementation detail leaked into the API.  A better
name than vector is hard to come up with, but the public inheritance
is a design flaw, a bug waiting to be introduced due to the conversion
and the assumptions the base vec makes about POD-ness and shallow
copying.  Hindsight is always 20/20 but past mistakes should not
dictate the design of a general purpose vector-like container in
GCC.

I fully support fixing or at least mitigating the problems with
the vec base class (unsafe copying, pass-by-value etc.).  As I
mentioned, I already started working on this cleanup.  I also
have no objection to introducing a non-copyable form of a vector
template (I offered one in my patch), or even to making auto_vec
non-copyable provided a copyable and assignable one is introduced
at the same time, under some other name.

Having said that, and although I don't mind the cleanup being taken
off my plate, I would have expected the courtesy of at least a heads
up first.  I do find it disrespectful for someone else involved in
the review of my work to at the same time submit a patch of their
own that goes in the opposite direction, and for you to unilaterally
approve it while the other review hasn't concluded yet.

Martin



Richard.


Martin



Thanks,
Richard


Thanks,
Richard.


gcc/ChangeLog:

  * dominance.c (get_dominated_by_region): Return auto_vec.
  * 

Re: [PATCH 3/6] return auto_vec from get_loop_hot_path

2021-06-17 Thread Trevor Saunders
On Thu, Jun 17, 2021 at 03:48:28PM +0200, Christophe Lyon wrote:
> On Tue, 15 Jun 2021 at 08:47, Richard Biener via Gcc-patches
>  wrote:
> >
> > On Tue, Jun 15, 2021 at 8:01 AM Trevor Saunders  
> > wrote:
> > >
> > > This ensures callers take ownership of the returned vector.
> > >
> > > Signed-off-by: Trevor Saunders 
> > >
> > > bootstrapped and regtested on x86_64-linux-gnu, ok?
> >
> > OK.
> 
> Since this was committed, I've noticed build errors (for cross-compilers):
> /tmp/9562118_6.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cfgloopanal.c:
> In function 'auto_vec get_loop_hot_path(const
> loop*)':
> /tmp/9562118_6.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cfgloopanal.c:528:10:
> error: could not convert 'path' from 'vec' to
> 'auto_vec'
>return path;
>   ^
> /tmp/9562118_6.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/gcc/cfgloopanal.c:529:1:
> warning: control reaches end of non-void function [-Wreturn-type]
>  }
>  ^
> 
> I'm using gcc-4.8.5 as host compiler

Ah, interesting, I believe the following patch corrects the oversight
here.  Its interesting that newer compilers use the auto_vec(vec &&)
constructor to fix this up but 4.8.5 refuses.

diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index fdd8d3f43fe..2db46c81036 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -504,7 +504,7 @@ auto_vec
 get_loop_hot_path (const class loop *loop)
  {
 basic_block bb = loop->header;
 -  vec path = vNULL;
 +  auto_vec path;
bitmap visited = BITMAP_ALLOC (NULL);

   while (true)

   Sorry about the trouble, will commit the above as obvious if
   it bootstraps.

   Trev

> 
> Christophe
> 
> >
> > > gcc/ChangeLog:
> > >
> > > * cfgloop.h (get_loop_hot_path): Return auto_vec.
> > > * cfgloopanal.c (get_loop_hot_path): Likewise.
> > > * tree-ssa-loop-ivcanon.c (tree_estimate_loop_size): Likewise.
> > > ---
> > >  gcc/cfgloop.h   | 2 +-
> > >  gcc/cfgloopanal.c   | 2 +-
> > >  gcc/tree-ssa-loop-ivcanon.c | 5 ++---
> > >  3 files changed, 4 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
> > > index 113241da130..5e699276c88 100644
> > > --- a/gcc/cfgloop.h
> > > +++ b/gcc/cfgloop.h
> > > @@ -840,7 +840,7 @@ enum
> > >
> > >  extern void doloop_optimize_loops (void);
> > >  extern void move_loop_invariants (void);
> > > -extern vec get_loop_hot_path (const class loop *loop);
> > > +extern auto_vec get_loop_hot_path (const class loop *loop);
> > >
> > >  /* Returns the outermost loop of the loop nest that contains LOOP.*/
> > >  static inline class loop *
> > > diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
> > > index d0eade3dd34..e7b7ae2163e 100644
> > > --- a/gcc/cfgloopanal.c
> > > +++ b/gcc/cfgloopanal.c
> > > @@ -500,7 +500,7 @@ single_likely_exit (class loop *loop, vec exits)
> > > order against direction of edges from latch.  Specially, if
> > > header != latch, latch is the 1-st block.  */
> > >
> > > -vec
> > > +auto_vec
> > >  get_loop_hot_path (const class loop *loop)
> > >  {
> > >basic_block bb = loop->header;
> > > diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
> > > index 3f9e9d0869f..b1971f83544 100644
> > > --- a/gcc/tree-ssa-loop-ivcanon.c
> > > +++ b/gcc/tree-ssa-loop-ivcanon.c
> > > @@ -218,7 +218,7 @@ tree_estimate_loop_size (class loop *loop, edge exit, 
> > > edge edge_to_cancel,
> > >gimple_stmt_iterator gsi;
> > >unsigned int i;
> > >bool after_exit;
> > > -  vec path = get_loop_hot_path (loop);
> > > +  auto_vec path = get_loop_hot_path (loop);
> > >
> > >size->overall = 0;
> > >size->eliminated_by_peeling = 0;
> > > @@ -342,7 +342,6 @@ tree_estimate_loop_size (class loop *loop, edge exit, 
> > > edge edge_to_cancel,
> > >   - size->last_iteration_eliminated_by_peeling) > upper_bound)
> > > {
> > >free (body);
> > > - path.release ();
> > >   return true;
> > > }
> > > }
> > > @@ -379,7 +378,7 @@ tree_estimate_loop_size (class loop *loop, edge exit, 
> > > edge edge_to_cancel,
> > > size->num_branches_on_hot_path++;
> > > }
> > >  }
> > > -  path.release ();
> > > +
> > >if (dump_file && (dump_flags & TDF_DETAILS))
> > >  fprintf (dump_file, "size: %i-%i, last_iteration: %i-%i\n", 
> > > size->overall,
> > >  size->eliminated_by_peeling, size->last_iteration,
> > > --
> > > 2.20.1
> > >


[Ada] Crash on overriding of an abstract primitive on an incomplete type

2021-06-17 Thread Pierre-Marie de Rodat
This combination breaks an assumption in
Sem_Ch3.Check_Ops_From_Incomplete_Type.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch3.adb (Check_Ops_From_Incomplete_Type): Protect against
no Primitive_Operations.diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -3072,6 +3072,7 @@ package body Sem_Ch3 is
and then Ekind (Prev) = E_Incomplete_Type
and then Is_Tagged_Type (Prev)
and then Is_Tagged_Type (T)
+   and then Present (Primitive_Operations (Prev))
  then
 Elmt := First_Elmt (Primitive_Operations (Prev));
 while Present (Elmt) loop




[Ada] Fix operations on Unbounded_String...

2021-06-17 Thread Pierre-Marie de Rodat
... when its length is close to Natural'Last.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* libgnat/a-strunb__shared.ads (Allocate): Additional parameter
to provide additional amount of space to be allocated.
* libgnat/a-strunb__shared.adb (Aligned_Max_Length): Limit
length to Natural'Last when requested length is larger than it.
(Allocate): Merge two slightly different implementations into
one.diff --git a/gcc/ada/libgnat/a-strunb__shared.adb b/gcc/ada/libgnat/a-strunb__shared.adb
--- a/gcc/ada/libgnat/a-strunb__shared.adb
+++ b/gcc/ada/libgnat/a-strunb__shared.adb
@@ -50,11 +50,13 @@ package body Ada.Strings.Unbounded is
--  align the returned memory on the maximum alignment as malloc does not
--  know the target alignment.
 
-   function Aligned_Max_Length (Max_Length : Natural) return Natural;
+   function Aligned_Max_Length
+ (Required_Length : Natural;
+  Reserved_Length : Natural) return Natural;
--  Returns recommended length of the shared string which is greater or
-   --  equal to specified length. Calculation take in sense alignment of the
-   --  allocated memory segments to use memory effectively by Append/Insert/etc
-   --  operations.
+   --  equal to specified required length and desired reserved length.
+   --  Calculation takes into account alignment of the allocated memory
+   --  segments to use memory effectively by Append/Insert/etc operations.
 
function Sum (Left : Natural; Right : Integer) return Natural with Inline;
--  Returns summary of Left and Right, raise Constraint_Error on overflow
@@ -63,11 +65,6 @@ package body Ada.Strings.Unbounded is
--  Returns multiplication of Left and Right, raise Constraint_Error on
--  overflow
 
-   function Allocate
- (Length, Growth : Natural) return not null Shared_String_Access;
-   --  Allocates new Shared_String with at least specified Length plus optional
-   --  Growth.
-
-
-- "&" --
-
@@ -490,17 +487,24 @@ package body Ada.Strings.Unbounded is
-- Aligned_Max_Length --

 
-   function Aligned_Max_Length (Max_Length : Natural) return Natural is
+   function Aligned_Max_Length
+ (Required_Length : Natural;
+  Reserved_Length : Natural) return Natural
+   is
   Static_Size : constant Natural :=
   Empty_Shared_String'Size / Standard'Storage_Unit;
   --  Total size of all Shared_String static components
begin
-  if Max_Length > Natural'Last - Static_Size then
+  if Required_Length > Natural'Last - Static_Size - Reserved_Length then
+ --  Total requested length is larger than maximum possible length.
+ --  Use of Static_Size needed to avoid overflows in expression to
+ --  compute aligned length.
  return Natural'Last;
+
   else
  return
-   ((Static_Size + Max_Length - 1) / Min_Mul_Alloc + 2) * Min_Mul_Alloc
- - Static_Size;
+   ((Static_Size + Required_Length + Reserved_Length - 1)
+  / Min_Mul_Alloc + 2) * Min_Mul_Alloc - Static_Size;
   end if;
end Aligned_Max_Length;
 
@@ -509,35 +513,21 @@ package body Ada.Strings.Unbounded is
--
 
function Allocate
- (Max_Length : Natural) return not null Shared_String_Access
+ (Required_Length : Natural;
+  Reserved_Length : Natural := 0) return not null Shared_String_Access
is
begin
   --  Empty string requested, return shared empty string
 
-  if Max_Length = 0 then
+  if Required_Length = 0 then
  return Empty_Shared_String'Access;
 
   --  Otherwise, allocate requested space (and probably some more room)
 
   else
- return new Shared_String (Aligned_Max_Length (Max_Length));
-  end if;
-   end Allocate;
-
-   --
-   -- Allocate --
-   --
-
-   function Allocate
- (Length, Growth : Natural) return not null Shared_String_Access is
-   begin
-  if Natural'Last - Growth < Length then
- --  Then Length + Growth would be more than Natural'Last
-
- return new Shared_String (Integer'Last);
-
-  else
- return Allocate (Length + Growth);
+ return
+   new Shared_String
+ (Aligned_Max_Length (Required_Length, Reserved_Length));
   end if;
end Allocate;
 
@@ -657,7 +647,7 @@ package body Ada.Strings.Unbounded is
 System.Atomic_Counters.Is_One (Item.Counter)
   and then Item.Max_Length >= Length
   and then Item.Max_Length <=
- Aligned_Max_Length (Length + Length / Growth_Factor);
+ Aligned_Max_Length (Length, Length / Growth_Factor);
end Can_Be_Reused;
 
---


diff --git a/gcc/ada/libgnat/a-strunb__shared.ads b/gcc/ada/libgnat/a-strunb__shared.ads
--- a/gcc/ada/libgnat/a-strunb__shared.ads
+++ b/gcc/ada/libgnat/a-strunb__shared.ads
@@ -725,10 +725,12 @@ 

[Ada] Warn on 'in out' param containing access in predefined private type

2021-06-17 Thread Pierre-Marie de Rodat
Normally the warnings:

warning: formal parameter "..." is not modified
warning: mode could be "in" instead of "in out"

are disabled if the type contains components of an access type.  This
patch enables such warnings if the only such components are in internal
private types.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_util.adb, sem_util.ads (Has_Access_Values): New formal
Include_Internal to indicate whether internal types should be
included.
* sem_warn.adb (Check_References): Change E_Out_Parameter to
Formal_Kind, to match the comment about Spec_Entity.  Pass
Include_Internal => False to Has_Access_Values, so that we warn
on types with access values that happen to be in internal types,
such as Unbounded_String.
* sem_attr.adb (Attribute_Has_Access_Values): Pass
Include_Internal => True to Has_Access_Values, to preserve
existing behavior.
* libgnat/g-rewdat.adb (Do_Output): Change B from 'in out' to
'in', to avoid warning enabled by the change to sem_warn.adb.
* libgnat/s-objrea.adb (Check_Read_Offset): Change S from 'in
out' to 'in', to avoid warning enabled by the change to
sem_warn.adb.diff --git a/gcc/ada/libgnat/g-rewdat.adb b/gcc/ada/libgnat/g-rewdat.adb
--- a/gcc/ada/libgnat/g-rewdat.adb
+++ b/gcc/ada/libgnat/g-rewdat.adb
@@ -37,7 +37,7 @@ package body GNAT.Rewrite_Data is
subtype SEO is Stream_Element_Offset;
 
procedure Do_Output
- (B  : in out Buffer;
+ (B  : Buffer;
   Data   : Stream_Element_Array;
   Output : not null access procedure (Data : Stream_Element_Array));
--  Do the actual output. This ensures that we properly send the data
@@ -81,7 +81,7 @@ package body GNAT.Rewrite_Data is
---
 
procedure Do_Output
- (B  : in out Buffer;
+ (B  : Buffer;
   Data   : Stream_Element_Array;
   Output : not null access procedure (Data : Stream_Element_Array))
is


diff --git a/gcc/ada/libgnat/s-objrea.adb b/gcc/ada/libgnat/s-objrea.adb
--- a/gcc/ada/libgnat/s-objrea.adb
+++ b/gcc/ada/libgnat/s-objrea.adb
@@ -47,7 +47,7 @@ package body System.Object_Reader is
function Trim_Trailing_Nuls (Str : String) return String;
--  Return a copy of a string with any trailing NUL characters truncated
 
-   procedure Check_Read_Offset (S : in out Mapped_Stream; Size : uint32);
+   procedure Check_Read_Offset (S : Mapped_Stream; Size : uint32);
--  Check that the SIZE bytes at the current offset are still in the stream
 
-
@@ -1931,7 +1931,7 @@ package body System.Object_Reader is
   return To_String_Ptr_Len (Read (S));
end Read;
 
-   procedure Check_Read_Offset (S : in out Mapped_Stream; Size : uint32) is
+   procedure Check_Read_Offset (S : Mapped_Stream; Size : uint32) is
begin
   if S.Off + Offset (Size) > Offset (Last (S.Region)) then
  raise IO_Error with "could not read from object file";


diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -8830,7 +8830,9 @@ package body Sem_Attr is
 
   when Attribute_Has_Access_Values =>
  Rewrite (N, New_Occurrence_Of
-   (Boolean_Literals (Has_Access_Values (P_Root_Type)), Loc));
+   (Boolean_Literals
+ (Has_Access_Values (P_Root_Type, Include_Internal => True)),
+  Loc));
  Analyze_And_Resolve (N, Standard_Boolean);
 
   ---


diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -11539,7 +11539,9 @@ package body Sem_Util is
-- Has_Access_Values --
---
 
-   function Has_Access_Values (T : Entity_Id) return Boolean is
+   function Has_Access_Values
+ (T : Entity_Id; Include_Internal : Boolean) return Boolean
+   is
   Typ : constant Entity_Id := Underlying_Type (T);
 
begin
@@ -11552,11 +11554,17 @@ package body Sem_Util is
   if No (Typ) then
  return False;
 
+  elsif not Include_Internal
+and then T /= Typ
+and then In_Internal_Unit (Typ)
+  then
+ return False;
+
   elsif Is_Access_Type (Typ) then
  return True;
 
   elsif Is_Array_Type (Typ) then
- return Has_Access_Values (Component_Type (Typ));
+ return Has_Access_Values (Component_Type (Typ), Include_Internal);
 
   elsif Is_Record_Type (Typ) then
  declare
@@ -11571,7 +11579,7 @@ package body Sem_Util is
--  Check for access component, tag field does not count, even
--  though it is implemented internally using an access type.
 
-   if Has_Access_Values (Etype (Comp))
+   if Has_Access_Values (Etype (Comp), Include_Internal)
  and then Chars (Comp) /= Name_uTag
then
   

[Ada] Implementation of Inox feature of fixed lower bounds on array types/subtypes

2021-06-17 Thread Pierre-Marie de Rodat
This is a prototype implementation of the feature for defining array
types and subtypes with fixed lower bounds for index ranges as proposed
as part of the "Inox" language design effort. This feature is currently
supported under control of the -gnatX (language extensions) switch, and
allows unconstrained array types as well as unconstrained subtypes to be
declared with indexes that use the special syntax "expression .. <>", to
indicate that the lower bound of the array type or subtype is fixed at a
value given by an expression. In contexts such as actual parameters,
object declarations, return statements, and type conversions, if the
context is such an unconstrained array subtype with a fixed lower bound,
bounds sliding is performed. Also, in certain contexts, such as index
constraints, consistency of the range imposed by the constraint with the
fixed lower bound of the array type being constrained is enforced.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* checks.adb (Discrete_Range_Cond): For an index subtype that
has a fixed lower bound, require that the range's lower bound
match that of the subtype.
(Selected_Range_Checks): Warn about the case where a static
lower bound does not equal an index subtype's fixed lower bound.
* einfo.ads (Is_Fixed_Lower_Bound_Array_Subtype,
Is_Fixed_Lower_Bound_Index_Subtype): Document new entity flag.
* exp_ch4.adb (Expand_N_Type_Conversion): If the operand is of
an unconstrained array subtype with fixed lower bound, then
Expand_Sliding_Conversion is applied to the operand.
* exp_ch6.adb (Expand_Simple_Function_Return): If the result
subtype is an unconstrained array subtype with fixed lower
bound, then Expand_Sliding_Conversion is applied to the return
object.
* exp_util.ads (Expand_Sliding_Conversion): New procedure for
applying a sliding subtype conversion to an array object of a
fixed-lower-bound subtype when needed.
* exp_util.adb: Add with_clause for Freeze.
(Expand_Sliding_Conversion): New procedure for applying a
sliding subtype conversion to an array object of a
fixed-lower-bound subtype when needed.  It traverses the indexes
of the unconstrained array type/subtype to create a target
constrained subtype and rewrites the array object to be a
conversion to that subtype, when there's at least one index
whose lower bound does not statically match the fixed-lower
bound of the target subtype.
* gen_il-fields.ads (type Opt_Field_Enum): Add literals
Is_Fixed_Lower_Bound_Array_Subtype and
Is_Fixed_Lower_Bound_Index_Subtype for new flags on type
entities.
* gen_il-gen-gen_entities.adb: Add calls to
Create_Semantic_Field for the new fixed-lower-bound flags on
type entities.
* par-ch3.adb (P_Array_Type_Definition): Add handling for
parsing of fixed-lower-bound index ranges in unconstrained array
types. Report an error if such an index is encountered and GNAT
language extensions are not enabled.
(P_Index_Subtype_Def_With_Fixed_Lower_Bound): Support procedure
for parsing unconstrained index ranges.
(P_Index_Or_Discriminant_Constraint): Add handling for parsing
of index constraints that specify ranges with fixed lower
bounds. Report an error if such an index is encountered and GNAT
language extensions are not enabled.
* sem_ch3.adb (Analyze_Object_Declaration): If the object's
nominal subtype is an array subtype with fixed lower bound, then
Expand_Sliding_Conversion is applied to the object.
(Array_Type_Declaration): Mark the array type and the subtypes
of any indexes that specify a fixed lower bound as being
fixed-lower-bound subtypes, and set the High_bound of the range
of such an index to the upper bound of the named subtype.
(Constrain_Array): For an array subtype with one or more index
ranges specifying a fixed lower bound, set Is_Constrained to
False and set the array subtype's
Is_Fixed_Lower_Bound_Array_Subtype flag to True.
(Constrain_Index): Mark the subtypes of an index that specifies
a fixed lower bound as being a fixed-lower-bound index subtype,
and set the High_bound of the range of such an index to the
upper bound of the base type of the array type's corresponding
index.
* sem_res.adb (Resolve_Actuals): If a formal is of an
unconstrained array subtype with fixed lower bound, then
Expand_Sliding_Conversion is applied to the actual.
* sem_util.adb (Build_Actual_Subtype): If the actual subtype
corresponds to an unconstrained array subtype having any indexes
with fixed lower bounds, then set the lower bounds of any such
indexes of 

[Ada] Casing on composite values

2021-06-17 Thread Pierre-Marie de Rodat
Initial support for casing on composite values if extensions are allowed
(e.g., if -gnatX is specified). The implementation is far from complete.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch5.adb
(Expand_N_Case_Statement.Expand_General_Case_Statement): New
subprogram.
(Expand_N_Case_Statement): If extensions are allowed and the
case selector is not of a discrete type, then call
Expand_General_Case_Statement to generate expansion instead of
flagging the non-discrete selector as an error.
* sem_case.ads (Is_Case_Choice_Pattern): New Boolean-valued
function for testing whether a given expression occurs as part
of a case choice pattern.
* sem_case.adb (Composite_Case_Ops): New package providing
support routines for the new form of case statements. This
includes a nested package, Composite_Case_Ops.Value_Sets, which
encapsulates the "representative values" implementation of
composite value sets.
(Check_Choices.Check_Case_Pattern_Choices): New procedure for
semantic checking of non-discrete case choices. This includes
the checks pertaining to coverage and overlapping.
(Check_Choices.Check_Composite_Case_Selector): New procedure for
semantic checking of non-discrete case selectors.
(Check_Choices): If extensions are allowed then a non-discrete
selector type no longer implies that an error must have been
flagged earlier.  Instead of simply returning, call
Check_Composite_Case_Selector and Check_Case_Pattern_Choices.
(Is_Case_Choice_Pattern): Body of new function declared in
sem_case.ads .
* sem_ch5.adb (Analyze_Case_Statement): If extensions are
allowed, then we can't use RM 5.4's "The selecting_expression is
expected to be of any discrete type" name resolution rule.
Handle the case where the type of the selecting expression is
not discrete, as well as the new ambiguous-name-resolution error
cases made possible by this change.
* sem_res.adb (Resolve_Entity_Name): It is ok to treat the name
of a type or subtype as an expression if it is part of a case
choice pattern, as in "(Field1 => Positive, Field2 => <>)".
* exp_aggr.adb (Expand_Record_Aggregate): Do not expand case
choice aggregates.
* gen_il-fields.ads: Define two new node attributes,
Binding_Chars and Multidefined_Bindings.
* gen_il-gen-gen_nodes.adb: The new Multidefined_Bindings
attribute is Boolean-valued and may be set on
N_Case_Statement_Alternative nodes. The new Binding_Chars
attribute is Name_Id-valued and may be set on
N_Component_Association nodes.
* par-ch4.adb (P_Record_Or_Array_Component_Association): When
parsing a component association, check for both new syntax forms
used to specify a bound value in a case-choice aggregate.  In
the case of a box value, an identifier may occur within the box,
as in "Foo => " instead of "Foo => <>". In the more general
case, an expression (or a box) may be followed by "is
", as in
"Foo => Bar is Abc" instead of just "Foo => Bar".
* sem_aggr.adb (Resolve_Record_Aggregate): Do not transform box
component values in a case-choice aggregate.
* sinfo.ads: Provide comments for the new attributes added in
gen_il-fields.ads.
* doc/gnat_rm/implementation_defined_pragmas.rst: Describe this
new feature in documentation for pragma Extensions_Allowed.
* gnat_rm.texi: Regenerate.

patch.diff.gz
Description: application/gzip


[Ada] Missing finalization on nested expression with action

2021-06-17 Thread Pierre-Marie de Rodat
Finalization may be missed when at least two if or case expressions
are nested together and a controlled object is created after the nested
expression.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch4.adb (Expand_N_Expression_With_Actions.Process_Action):
Do not abandon processing on a nested N_Expression_With_Actions
or N_Loop_Statement, otherwise we may miss some transient
declarations.diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -5780,15 +5780,14 @@ package body Exp_Ch4 is
 
  --  Avoid processing temporary function results multiple times when
  --  dealing with nested expression_with_actions.
+ --  Similarly, do not process temporary function results in loops.
+ --  This is done by Expand_N_Loop_Statement and Build_Finalizer.
+ --  Note that we used to wrongly return Abandon instead of Skip here:
+ --  this is wrong since it means that we were ignoring lots of
+ --  relevant subsequent statements.
 
- elsif Nkind (Act) = N_Expression_With_Actions then
-return Abandon;
-
- --  Do not process temporary function results in loops. This is done
- --  by Expand_N_Loop_Statement and Build_Finalizer.
-
- elsif Nkind (Act) = N_Loop_Statement then
-return Abandon;
+ elsif Nkind (Act) in N_Expression_With_Actions | N_Loop_Statement then
+return Skip;
  end if;
 
  return OK;




[Ada] Crash on a nested aggregate containing controlled objects

2021-06-17 Thread Pierre-Marie de Rodat
Exp_Util.Find_Hook_Context wasn't prepared to handle this case properly
and we ended up inserting a statement in the middle of an aggregate,
causing chaos.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_util.adb (Find_Hook_Context): Do not stop on an aggregate
node.diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -6220,6 +6220,9 @@ package body Exp_Util is
 | N_Discriminant_Association
 | N_Parameter_Association
 | N_Pragma_Argument_Association
+| N_Aggregate
+| N_Delta_Aggregate
+| N_Extension_Aggregate
   and then Nkind (Parent (Par)) not in N_Function_Call
  | N_Procedure_Call_Statement
  | N_Entry_Call_Statement




[Ada] Remove dubious wrapper of a recursive function

2021-06-17 Thread Pierre-Marie de Rodat
Routine Is_Valid_Renaming was a wrapper subprogram that simply called
its nested function. Code cleanup; semantics is unaffected.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_util.adb (Is_Valid_Renaming): Body moved from its nested
routine.diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -7294,70 +7294,56 @@ package body Sem_Util is
   ---
 
   function Is_Valid_Renaming (N : Node_Id) return Boolean is
- function Check_Renaming (N : Node_Id) return Boolean;
- --  Recursive function used to traverse all the prefixes of N
-
- 
- -- Check_Renaming --
- 
-
- function Check_Renaming (N : Node_Id) return Boolean is
- begin
-if Is_Renaming (N)
-  and then not Check_Renaming (Renamed_Entity (Entity (N)))
-then
-   return False;
-end if;
-
-if Nkind (N) = N_Indexed_Component then
-   declare
-  Indx : Node_Id;
-
-   begin
-  Indx := First (Expressions (N));
-  while Present (Indx) loop
- if not Is_OK_Static_Expression (Indx) then
-return False;
- end if;
-
- Next_Index (Indx);
-  end loop;
-   end;
-end if;
+  begin
+ if Is_Renaming (N)
+   and then not Is_Valid_Renaming (Renamed_Entity (Entity (N)))
+ then
+return False;
+ end if;
 
-if Has_Prefix (N) then
-   declare
-  P : constant Node_Id := Prefix (N);
+ if Nkind (N) = N_Indexed_Component then
+declare
+   Indx : Node_Id;
 
-   begin
-  if Nkind (N) = N_Explicit_Dereference
-and then Is_Variable (P)
-  then
+begin
+   Indx := First (Expressions (N));
+   while Present (Indx) loop
+  if not Is_OK_Static_Expression (Indx) then
  return False;
+  end if;
 
-  elsif Is_Entity_Name (P)
-and then Ekind (Entity (P)) = E_Function
-  then
- return False;
+  Next_Index (Indx);
+   end loop;
+end;
+ end if;
 
-  elsif Nkind (P) = N_Function_Call then
- return False;
-  end if;
+ if Has_Prefix (N) then
+declare
+   P : constant Node_Id := Prefix (N);
+
+begin
+   if Nkind (N) = N_Explicit_Dereference
+ and then Is_Variable (P)
+   then
+  return False;
 
-  --  Recursion to continue traversing the prefix of the
-  --  renaming expression
+   elsif Is_Entity_Name (P)
+ and then Ekind (Entity (P)) = E_Function
+   then
+  return False;
 
-  return Check_Renaming (P);
-   end;
-end if;
+   elsif Nkind (P) = N_Function_Call then
+  return False;
+   end if;
 
-return True;
- end Check_Renaming;
+   --  Recursion to continue traversing the prefix of the
+   --  renaming expression
 
-  --  Start of processing for Is_Valid_Renaming
+   return Is_Valid_Renaming (P);
+end;
+ end if;
 
-  begin
- return Check_Renaming (N);
+ return True;
   end Is_Valid_Renaming;
 
   --  Local variables




[Ada] Don't check No_Wide_Characters restriction for illegal types

2021-06-17 Thread Pierre-Marie de Rodat
On illegal declarations of illegal types, e.g.:

   type X;
   type X is new X;

the No_Wide_Characters restriction was checked using an incomplete
entity of type X, which caused a crash.

Now restriction No_Wide_Characters in derived types is checked after the
legality of the parent type has been established.

Also, by moving the call to Check_Wide_Character_Restriction out of
Find_Type_Of_Subtype_Indic, we don't check this restriction on types
from the interface list. This is safe, because wide character types are
not allowed in the interface list anyway (as they are not tagged).

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch3.adb (Analyze_Private_Extension_Declaration): Check
No_Wide_Characters restriction after rejecting illegal parent
types.
(Derived_Type_Declaration): Likewise.
(Find_Type_Of_Subtype_Indic): Remove check for
No_Wide_Characters restriction, which was done too early.diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -5121,6 +5121,8 @@ package body Sem_Ch3 is
  goto Leave;
   end if;
 
+  Check_Wide_Character_Restriction (Parent_Type, Indic);
+
   --  Perhaps the parent type should be changed to the class-wide type's
   --  specific type in this case to prevent cascading errors ???
 
@@ -17120,6 +17122,8 @@ package body Sem_Ch3 is
  Error_Msg_N ("null exclusion can only apply to an access type", N);
   end if;
 
+  Check_Wide_Character_Restriction (Parent_Type, Indic);
+
   --  Avoid deriving parent primitives of underlying record views
 
   Build_Derived_Type (N, Parent_Type, T, Is_Completion,
@@ -17979,10 +17983,6 @@ package body Sem_Ch3 is
  Typ := Entity (S);
   end if;
 
-  --  Check No_Wide_Characters restriction
-
-  Check_Wide_Character_Restriction (Typ, S);
-
   return Typ;
end Find_Type_Of_Subtype_Indic;
 




  1   2   >