Re: [PATCH] tree-optimization/99912 - delete trivially dead stmts during DSE

2021-04-27 Thread Richard Biener
On Tue, 27 Apr 2021, Prathamesh Kulkarni wrote:

> On Tue, 27 Apr 2021 at 19:19, Richard Biener  wrote:
> >
> > DSE performs a backwards walk over stmts removing stores but it
> > leaves removing resulting dead SSA defs to later passes.  This
> > eats into its own alias walking budget if the removed stores kept
> > loads live.  The following patch adds removal of trivially dead
> > SSA defs which helps in this situation and reduces the amount of
> > garbage followup passes need to deal with.
> >
> > Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
> >
> > 2021-04-27  Richard Biener  
> >
> > PR tree-optimization/99912
> > * tree-ssa-dse.c (dse_dom_walker::m_need_cfg_cleanup): New.
> > (dse_dom_walker::todo): Likewise.
> > (dse_dom_walker::dse_optimize_stmt): Move VDEF check to the
> > caller.
> > (dse_dom_walker::before_dom_children): Remove trivially
> > dead SSA defs and schedule CFG cleanup if we removed all
> > PHIs in a block.
> > (pass_dse::execute): Get TODO as computed by the DOM walker
> > and return it.  Wipe dominator info earlier.
> > ---
> >  gcc/tree-ssa-dse.c | 65 +-
> >  1 file changed, 53 insertions(+), 12 deletions(-)
> >
> > diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
> > index 4967a5a9927..f5f39cbe903 100644
> > --- a/gcc/tree-ssa-dse.c
> > +++ b/gcc/tree-ssa-dse.c
> > @@ -963,16 +963,25 @@ public:
> >dse_dom_walker (cdi_direction direction)
> >  : dom_walker (direction),
> >  m_live_bytes (param_dse_max_object_size),
> > -m_byte_tracking_enabled (false) {}
> > +m_byte_tracking_enabled (false),
> > +m_need_cfg_cleanup (false) {}
> >
> >virtual edge before_dom_children (basic_block);
> > +  unsigned todo () const;
> >
> >  private:
> >auto_sbitmap m_live_bytes;
> >bool m_byte_tracking_enabled;
> > +  bool m_need_cfg_cleanup;
> >void dse_optimize_stmt (gimple_stmt_iterator *);
> >  };
> >
> > +unsigned
> > +dse_dom_walker::todo () const
> > +{
> > +  return m_need_cfg_cleanup ? TODO_cleanup_cfg : 0;
> > +}
> > +
> >  /* Delete a dead call at GSI, which is mem* call of some kind.  */
> >  static void
> >  delete_dead_or_redundant_call (gimple_stmt_iterator *gsi, const char *type)
> > @@ -1049,11 +1058,6 @@ dse_dom_walker::dse_optimize_stmt 
> > (gimple_stmt_iterator *gsi)
> >  {
> >gimple *stmt = gsi_stmt (*gsi);
> >
> > -  /* If this statement has no virtual defs, then there is nothing
> > - to do.  */
> > -  if (!gimple_vdef (stmt))
> > -return;
> > -
> >/* Don't return early on *this_2(D) ={v} {CLOBBER}.  */
> >if (gimple_has_volatile_ops (stmt)
> >&& (!gimple_clobber_p (stmt)
> > @@ -1180,12 +1184,47 @@ dse_dom_walker::before_dom_children (basic_block bb)
> >
> >for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
> >  {
> > -  dse_optimize_stmt ();
> > +  gimple *stmt = gsi_stmt (gsi);
> > +
> > +  if (gimple_vdef (stmt))
> > +   dse_optimize_stmt ();
> > +  else if (def_operand_p def_p = single_ssa_def_operand (stmt, 
> > SSA_OP_DEF))
> > +   {
> > + /* When we remove dead stores make sure to also delete trivially
> > +dead SSA defs.  */
> > + if (has_zero_uses (DEF_FROM_PTR (def_p))
> > + && !gimple_has_side_effects (stmt))
> > +   {
> > + if (dump_file && (dump_flags & TDF_DETAILS))
> > +   {
> > + fprintf (dump_file, "  Deleted trivially dead stmt: ");
> > + print_gimple_stmt (dump_file, stmt, 0, dump_flags);
> > + fprintf (dump_file, "\n");
> > +   }
> > + if (gsi_remove (, true) && need_eh_cleanup)
> > +   bitmap_set_bit (need_eh_cleanup, bb->index);
> > + release_defs (stmt);
> > +   }
> > +   }
> >if (gsi_end_p (gsi))
> > gsi = gsi_last_bb (bb);
> >else
> > gsi_prev ();
> >  }
> > +  bool removed_phi = false;
> > +  for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);)
> > +{
> > +  gphi *phi = si.phi ();
> > +  if (has_zero_uses (gimple_phi_result (phi)))
> > +   {
> > + remove_phi_node (, true);
> > + removed_phi = true;
> > +   }
> Hi Richard,
> Just curious if this is missing dumping info about removed phi node to
> dump_file ?

Yes, I'll add this.  I also have to investigate some testsuite fallout,
so there'll be v2.

Richard.

> Thanks,
> Prathamesh
> > +  else
> > +   gsi_next ();
> > +}
> > +  if (removed_phi && gimple_seq_empty_p (phi_nodes (bb)))
> > +m_need_cfg_cleanup = true;
> >return NULL;
> >  }
> >
> > @@ -1234,21 +1273,23 @@ pass_dse::execute (function *fun)
> >
> >/* Dead store elimination is fundamentally a walk of the post-dominator
> >   tree and a backwards walk of statements within each block.  */
> > -  dse_dom_walker 

[PATCH 1/1] PR100281 Fix SImode pointer handling

2021-04-27 Thread Andreas Krebbel via Gcc-patches
The problem appears to be triggered by two locations in the front-end
where non-POINTER_SIZE pointers aren't handled right now.

1. An assertion in strip_typedefs is triggered because the alignment
of the types don't match. This in turn is caused by creating the new
type with build_pointer_type instead of taking the type of the
original pointer into account.

2. An assertion in cp_convert_to_pointer is triggered which expects
the target type to always have POINTER_SIZE.

Ok for mainline?

gcc/cp/ChangeLog:

PR c++/100281
* cvt.c (cp_convert_to_pointer): Use the size of the target
pointer type.
* tree.c (strip_typedefs): Use build_pointer_type_for_mode for
non-POINTER_SIZE pointers.

gcc/testsuite/ChangeLog:

PR c++/100281
* g++.target/s390/pr100281.C: New test.
---
 gcc/cp/cvt.c |  2 +-
 gcc/cp/tree.c|  5 -
 gcc/testsuite/g++.target/s390/pr100281.C | 10 ++
 3 files changed, 15 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/s390/pr100281.C

diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index f1687e804d1..7fa6e8df52b 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -232,7 +232,7 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold,
 {
   if (TYPE_PRECISION (intype) == POINTER_SIZE)
return build1 (CONVERT_EXPR, type, expr);
-  expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr,
+  expr = cp_convert (c_common_type_for_size (TYPE_PRECISION (type), 0), 
expr,
 complain);
   /* Modes may be different but sizes should be the same.  There
 is supposed to be some integral type that is the same width
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a8bfd5fc053..6f6b732c9c9 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1556,7 +1556,10 @@ strip_typedefs (tree t, bool *remove_attributes, 
unsigned int flags)
 {
 case POINTER_TYPE:
   type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
-  result = build_pointer_type (type);
+  if (TYPE_PRECISION (t) == POINTER_SIZE)
+   result = build_pointer_type (type);
+  else
+   result = build_pointer_type_for_mode (type, TYPE_MODE (t), false);
   break;
 case REFERENCE_TYPE:
   type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
diff --git a/gcc/testsuite/g++.target/s390/pr100281.C 
b/gcc/testsuite/g++.target/s390/pr100281.C
new file mode 100644
index 000..f45798c3879
--- /dev/null
+++ b/gcc/testsuite/g++.target/s390/pr100281.C
@@ -0,0 +1,10 @@
+// PR C++/100281
+// { dg-do compile }
+
+typedef void * __attribute__((mode (SI))) __ptr32_t;
+
+void foo(){
+  unsigned int b = 100;
+  __ptr32_t a;
+  a = b; /* { dg-error "invalid conversion from 'unsigned int' to 
'__ptr32_t'.*" } */
+}
-- 
2.30.2



[PATCH v2] IBM Z: Handle hard registers in s390_md_asm_adjust()

2021-04-27 Thread Ilya Leoshkevich via Gcc-patches
Bootstrapped and regtested on s390x-redhat-linux.  Tested with valgrind
too (PR 100278 is now fixed).  Ok for master?

v1: https://gcc.gnu.org/pipermail/gcc-patches/2021-April/568771.html
v1 -> v2: Use the UNSPEC pattern, which is less efficient, but is more
  on the "obviously correct" side than gen_raw_SUBREG().



gen_fprx2_to_tf() and gen_tf_to_fprx2() cannot handle hard registers,
since the subregs they create do not pass validation.  Change
s390_md_asm_adjust() to manually copy between hard VRs and FPRs instead
of using these two functions.

gcc/ChangeLog:

PR target/100217
* config/s390/s390.c (s390_hard_fp_reg_p): New function.
(s390_md_asm_adjust): Handle hard registers.

gcc/testsuite/ChangeLog:

PR target/100217
* gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c: New test.
* gcc.target/s390/vector/long-double-asm-inout-hard-fp-reg.c: New test.
---
 gcc/config/s390/s390.c| 52 +--
 .../long-double-asm-in-out-hard-fp-reg.c  | 33 
 .../long-double-asm-inout-hard-fp-reg.c   | 31 +++
 3 files changed, 112 insertions(+), 4 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c
 create mode 100644 
gcc/testsuite/gcc.target/s390/vector/long-double-asm-inout-hard-fp-reg.c

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index a9c945c5ee9..88361f98c7e 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -16754,6 +16754,23 @@ f_constraint_p (const char *constraint)
   return seen_f_p && !seen_v_p;
 }
 
+/* Return TRUE iff X is a hard floating-point (and not a vector) register.  */
+
+static bool
+s390_hard_fp_reg_p (rtx x)
+{
+  if (!(REG_P (x) && HARD_REGISTER_P (x) && REG_ATTRS (x)))
+return false;
+
+  tree decl = REG_EXPR (x);
+  if (!(HAS_DECL_ASSEMBLER_NAME_P (decl) && DECL_ASSEMBLER_NAME_SET_P (decl)))
+return false;
+
+  const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+  return name[0] == '*' && name[1] == 'f';
+}
+
 /* Implement TARGET_MD_ASM_ADJUST hook in order to fix up "f"
constraints when long doubles are stored in vector registers.  */
 
@@ -16787,9 +16804,24 @@ s390_md_asm_adjust (vec , vec 
,
   gcc_assert (allows_reg);
   gcc_assert (!is_inout);
   /* Copy output value from a FPR pair into a vector register.  */
-  rtx fprx2 = gen_reg_rtx (FPRX2mode);
+  rtx fprx2;
   push_to_sequence2 (after_md_seq, after_md_end);
-  emit_insn (gen_fprx2_to_tf (outputs[i], fprx2));
+  if (s390_hard_fp_reg_p (outputs[i]))
+   {
+ fprx2 = gen_rtx_REG (FPRX2mode, REGNO (outputs[i]));
+ /* The first half is already at the correct location, copy only the
+  * second one.  Use the UNSPEC pattern instead of the SUBREG one,
+  * since s390_can_change_mode_class() rejects
+  * (subreg:DF (reg:TF %fN) 8) and thus subreg validation fails.  */
+ rtx v1 = gen_rtx_REG (V2DFmode, REGNO (outputs[i]));
+ rtx v3 = gen_rtx_REG (V2DFmode, REGNO (outputs[i]) + 1);
+ emit_insn (gen_vec_permiv2df (v1, v1, v3, const0_rtx));
+   }
+  else
+   {
+ fprx2 = gen_reg_rtx (FPRX2mode);
+ emit_insn (gen_fprx2_to_tf (outputs[i], fprx2));
+   }
   after_md_seq = get_insns ();
   after_md_end = get_last_insn ();
   end_sequence ();
@@ -16813,8 +16845,20 @@ s390_md_asm_adjust (vec , vec 
,
continue;
   gcc_assert (allows_reg);
   /* Copy input value from a vector register into a FPR pair.  */
-  rtx fprx2 = gen_reg_rtx (FPRX2mode);
-  emit_insn (gen_tf_to_fprx2 (fprx2, inputs[i]));
+  rtx fprx2;
+  if (s390_hard_fp_reg_p (inputs[i]))
+   {
+ fprx2 = gen_rtx_REG (FPRX2mode, REGNO (inputs[i]));
+ /* Copy only the second half.  */
+ rtx v1 = gen_rtx_REG (V2DFmode, REGNO (inputs[i]) + 1);
+ rtx v2 = gen_rtx_REG (V2DFmode, REGNO (inputs[i]));
+ emit_insn (gen_vec_permiv2df (v1, v2, v1, GEN_INT (3)));
+   }
+  else
+   {
+ fprx2 = gen_reg_rtx (FPRX2mode);
+ emit_insn (gen_tf_to_fprx2 (fprx2, inputs[i]));
+   }
   inputs[i] = fprx2;
   input_modes[i] = FPRX2mode;
 }
diff --git 
a/gcc/testsuite/gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c 
b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c
new file mode 100644
index 000..2dcaf08f00b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
+#include 
+#include 
+
+__attribute__ ((noipa)) static long double
+sqxbr (long double x)
+{
+  register long double in asm("f0") = x;
+  register long double out asm("f1");
+
+  asm("sqxbr\t%0,%1" : "=f"(out) : "f"(in));
+  

Re: [PATCH] Synchronize Rocket Lake's processor_names and processor_cost_table with processor_type

2021-04-27 Thread Hongtao Liu via Gcc-patches
On Tue, Apr 27, 2021 at 9:28 AM Hongtao Liu  wrote:
>
> On Mon, Apr 26, 2021 at 8:35 PM Uros Bizjak via Gcc-patches
>  wrote:
> >
> > On Sat, Apr 24, 2021 at 3:43 PM Cui, Lili  wrote:
> > >
> > > Hi Uros,
> > >
> > > This patch is  to synchronize Rocket Lake's processor_names and 
> > > processor_cost_table with processor_type.
> > >
> > > Bootstrap is ok, and no regressions for i386/x86-64 testsuite.
> > >
> > > OK for master?
> > >
> > > [PATCH] Synchronize Rocket Lake's processor_names and
> > >  processor_cost_table with processor_type
> > >
> > > gcc/ChangeLog
> > >
> > > * common/config/i386/i386-common.c (processor_names):
> > > Sync processor_names with processor_type.
> > > * config/i386/i386-options.c (processor_cost_table):
> > > Sync processor_cost_table with processor_type.
> >
> > OK.
> >
>
> Ok for backport to GCC11 ?
>
I've backported this patch to GCC11 as an obvious fix.
> > Thanks,
> > Uros.
> >
> > > ---
> > >  gcc/common/config/i386/i386-common.c | 2 +-
> > >  gcc/config/i386/i386-options.c   | 2 +-
> > >  2 files changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/gcc/common/config/i386/i386-common.c 
> > > b/gcc/common/config/i386/i386-common.c
> > > index 1e6c1590ac4..6a7b5c8312f 100644
> > > --- a/gcc/common/config/i386/i386-common.c
> > > +++ b/gcc/common/config/i386/i386-common.c
> > > @@ -1743,13 +1743,13 @@ const char *const processor_names[] =
> > >"skylake-avx512",
> > >"cannonlake",
> > >"icelake-client",
> > > -  "rocketlake",
> > >"icelake-server",
> > >"cascadelake",
> > >"tigerlake",
> > >"cooperlake",
> > >"sapphirerapids",
> > >"alderlake",
> > > +  "rocketlake",
> > >"intel",
> > >"geode",
> > >"k6",
> > > diff --git a/gcc/config/i386/i386-options.c 
> > > b/gcc/config/i386/i386-options.c
> > > index 7e59ccd988d..eafa3d4f715 100644
> > > --- a/gcc/config/i386/i386-options.c
> > > +++ b/gcc/config/i386/i386-options.c
> > > @@ -726,12 +726,12 @@ static const struct processor_costs 
> > > *processor_cost_table[] =
> > >_cost,
> > >_cost,
> > >_cost,
> > > -  _cost,
> > >_cost,
> > >_cost,
> > >_cost,
> > >_cost,
> > >_cost,
> > > +  _cost,
> > >_cost,
> > >_cost,
> > >_cost,
> > > --
> > > 2.17.1
> > >
> > > Thanks,
> > > Lili.
>
>
>
> --
> BR,
> Hongtao



-- 
BR,
Hongtao


[PATCH v2 14/21] libcc1: share basic context code

2021-04-27 Thread Tom Tromey
Both plugins in libcc1 share a fair amount of boilerplate.  They both
share error-emission code, context management code, and tree GC code.
This patch unifies these two bodies of code, avoiding needless
duplication.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcc1plugin.cc: Move code to context.cc.
* libcp1plugin.cc: Move code to context.cc.
* context.hh: New file.
* context.cc: New file.
* Makefile.in: Rebuild.
* Makefile.am (AM_CPPFLAGS): Add more gcc flags.
(CPPFLAGS_FOR_C, CPPFLAGS_FOR_CXX): Update.
(libcc1plugin_la_SOURCES): Add context.hh, context.cc.
(libcp1plugin_la_SOURCES): Likewise.
---
 libcc1/ChangeLog   |  12 +++
 libcc1/Makefile.am |  15 +--
 libcc1/Makefile.in |  27 +++---
 libcc1/context.cc  | 171 ++
 libcc1/context.hh  | 121 
 libcc1/libcc1plugin.cc | 204 +
 libcc1/libcp1plugin.cc | 203 +---
 7 files changed, 333 insertions(+), 420 deletions(-)
 create mode 100644 libcc1/context.cc
 create mode 100644 libcc1/context.hh

diff --git a/libcc1/Makefile.am b/libcc1/Makefile.am
index 3f20513d11b7..9ec021030e2d 100644
--- a/libcc1/Makefile.am
+++ b/libcc1/Makefile.am
@@ -19,11 +19,10 @@
 ACLOCAL_AMFLAGS = -I .. -I ../config
 gcc_build_dir = ../gcc
 AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \
-   -I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC)
-CPPFLAGS_FOR_C_FAMILY = -I $(srcdir)/../gcc/c-family \
-   -I $(srcdir)/../libcpp/include
-CPPFLAGS_FOR_C = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/c
-CPPFLAGS_FOR_CXX = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/cp
+   -I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) \
+   -I $(srcdir)/../gcc/c-family -I $(srcdir)/../libcpp/include
+CPPFLAGS_FOR_C = -I $(srcdir)/../gcc/c
+CPPFLAGS_FOR_CXX = -I $(srcdir)/../gcc/cp
 AM_CXXFLAGS = $(WARN_FLAGS) $(WERROR) $(visibility) $(CET_HOST_FLAGS)
 if DARWIN_DYNAMIC_LOOKUP
 AM_CXXFLAGS += -Wl,-undefined,dynamic_lookup
@@ -55,7 +54,8 @@ marshall_c_source = marshall-c.hh
 marshall_cxx_source = marshall-cp.hh
 
 libcc1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1plugin.sym
-libcc1plugin_la_SOURCES = libcc1plugin.cc $(shared_source) $(marshall_c_source)
+libcc1plugin_la_SOURCES = libcc1plugin.cc context.cc context.hh \
+   $(shared_source) $(marshall_c_source)
 libcc1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_C)
 libcc1plugin_la_LIBADD = $(libiberty)
 libcc1plugin_la_DEPENDENCIES = $(libiberty_dep)
@@ -64,7 +64,8 @@ libcc1plugin_la_LINK = $(LIBTOOL) --tag=CXX 
$(AM_LIBTOOLFLAGS) \
$(CXXFLAGS) $(libcc1plugin_la_LDFLAGS) $(LTLDFLAGS) -o $@
 
 libcp1plugin_la_LDFLAGS = -module -export-symbols $(srcdir)/libcp1plugin.sym
-libcp1plugin_la_SOURCES = libcp1plugin.cc $(shared_source) 
$(marshall_cxx_source)
+libcp1plugin_la_SOURCES = libcp1plugin.cc context.cc context.hh \
+   $(shared_source) $(marshall_cxx_source)
 libcp1plugin.lo_CPPFLAGS = $(CPPFLAGS_FOR_CXX)
 libcp1plugin_la_LIBADD = $(libiberty)
 libcp1plugin_la_DEPENDENCIES = $(libiberty_dep)
diff --git a/libcc1/Makefile.in b/libcc1/Makefile.in
index d76893e3a24e..395f01a98215 100644
--- a/libcc1/Makefile.in
+++ b/libcc1/Makefile.in
@@ -148,12 +148,12 @@ am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo libcp1.lo 
compiler.lo \
names.lo $(am__objects_1) $(am__objects_2) $(am__objects_2)
 libcc1_la_OBJECTS = $(am_libcc1_la_OBJECTS)
 @ENABLE_PLUGIN_TRUE@am_libcc1_la_rpath = -rpath $(cc1libdir)
-am_libcc1plugin_la_OBJECTS = libcc1plugin.lo $(am__objects_1) \
-   $(am__objects_2)
+am_libcc1plugin_la_OBJECTS = libcc1plugin.lo context.lo \
+   $(am__objects_1) $(am__objects_2)
 libcc1plugin_la_OBJECTS = $(am_libcc1plugin_la_OBJECTS)
 @ENABLE_PLUGIN_TRUE@am_libcc1plugin_la_rpath = -rpath $(plugindir)
-am_libcp1plugin_la_OBJECTS = libcp1plugin.lo $(am__objects_1) \
-   $(am__objects_2)
+am_libcp1plugin_la_OBJECTS = libcp1plugin.lo context.lo \
+   $(am__objects_1) $(am__objects_2)
 libcp1plugin_la_OBJECTS = $(am_libcp1plugin_la_OBJECTS)
 @ENABLE_PLUGIN_TRUE@am_libcp1plugin_la_rpath = -rpath $(plugindir)
 AM_V_P = $(am__v_P_@AM_V@)
@@ -379,13 +379,11 @@ visibility = @visibility@
 ACLOCAL_AMFLAGS = -I .. -I ../config
 gcc_build_dir = ../gcc
 AM_CPPFLAGS = -I $(srcdir)/../include -I $(srcdir)/../libgcc \
-   -I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC)
+   -I $(gcc_build_dir) -I$(srcdir)/../gcc $($@_CPPFLAGS) $(GMPINC) \
+   -I $(srcdir)/../gcc/c-family -I $(srcdir)/../libcpp/include
 
-CPPFLAGS_FOR_C_FAMILY = -I $(srcdir)/../gcc/c-family \
-   -I $(srcdir)/../libcpp/include
-
-CPPFLAGS_FOR_C = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/c
-CPPFLAGS_FOR_CXX = $(CPPFLAGS_FOR_C_FAMILY) -I $(srcdir)/../gcc/cp
+CPPFLAGS_FOR_C = -I $(srcdir)/../gcc/c
+CPPFLAGS_FOR_CXX = -I $(srcdir)/../gcc/cp
 AM_CXXFLAGS = 

[PATCH v2 11/21] libcc1: unify compiler handling

2021-04-27 Thread Tom Tromey
Both libcc1 plugins have nearly identical copies of code to find the
underlying compiler.  This seemed wasteful to me, so this patch
unifies the copies.

Two minor API changes were needed.

First, the old code used a back-link from the compiler object to the
plugin object to check the 'verbose' setting.  This patch adds a
'verbose' setting directly to the compiler object instead.

Second, the 'find' method implicitly knew which compiler base name
("gcc" or "g++") to use.  This patch makes this a parameter that is
passed in by the plugin.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcc1.cc (compiler, compiler_triplet_regexp)
(compiler_driver_filename): Remove.
(libcp1::libcp1): Update.
(make_regexp, libcp1::compiler::find)
(libcp1::compiler_triplet_regexp::find)
(libcp1::compiler_driver_filename::find): Remove.
(libcp1_set_verbose, libcp1_set_arguments)
(libcp1_set_triplet_regexp, libcp1_set_driver_filename): Update.
* libcc1.cc (compiler, compiler_triplet_regexp)
(compiler_driver_filename): Remove.
(libcc1::libcc1): Update.
(make_regexp, libcc1::compiler::find)
(libcc1::compiler_triplet_regexp::find)
(libcc1::compiler_driver_filename::find): Remove.
(libcc1_set_verbose, libcc1_set_arguments)
(libcc1_set_triplet_regexp, libcc1_set_driver_filename): Update.
* compiler.cc: New file.
* compiler.hh: New file.
* Makefile.in: Rebuild.
* Makefile.am (libcc1_la_SOURCES): Add compiler.hh, compiler.cc.
---
 libcc1/ChangeLog   |  23 +++
 libcc1/Makefile.am |   2 +-
 libcc1/Makefile.in |   7 +-
 libcc1/compiler.cc | 118 +
 libcc1/compiler.hh |  83 +++
 libcc1/libcc1.cc   | 159 -
 libcc1/libcp1.cc   | 159 -
 7 files changed, 253 insertions(+), 298 deletions(-)
 create mode 100644 libcc1/compiler.cc
 create mode 100644 libcc1/compiler.hh

diff --git a/libcc1/Makefile.am b/libcc1/Makefile.am
index f148fdd7aa28..3f20513d11b7 100644
--- a/libcc1/Makefile.am
+++ b/libcc1/Makefile.am
@@ -75,7 +75,7 @@ libcp1plugin_la_LINK = $(LIBTOOL) --tag=CXX 
$(AM_LIBTOOLFLAGS) \
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
 libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym
 libcc1_la_SOURCES = findcomp.cc libcc1.cc libcp1.cc \
-   names.cc names.hh $(shared_source) \
+   compiler.cc compiler.hh names.cc names.hh $(shared_source) \
$(marshall_c_source) $(marshall_cxx_source)
 libcc1_la_LIBADD = $(libiberty)
 libcc1_la_DEPENDENCIES = $(libiberty_dep)
diff --git a/libcc1/Makefile.in b/libcc1/Makefile.in
index 753d435c9cbe..d76893e3a24e 100644
--- a/libcc1/Makefile.in
+++ b/libcc1/Makefile.in
@@ -144,8 +144,8 @@ am__installdirs = "$(DESTDIR)$(cc1libdir)" 
"$(DESTDIR)$(plugindir)"
 LTLIBRARIES = $(cc1lib_LTLIBRARIES) $(plugin_LTLIBRARIES)
 am__objects_1 = callbacks.lo connection.lo marshall.lo
 am__objects_2 =
-am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo libcp1.lo names.lo \
-   $(am__objects_1) $(am__objects_2) $(am__objects_2)
+am_libcc1_la_OBJECTS = findcomp.lo libcc1.lo libcp1.lo compiler.lo \
+   names.lo $(am__objects_1) $(am__objects_2) $(am__objects_2)
 libcc1_la_OBJECTS = $(am_libcc1_la_OBJECTS)
 @ENABLE_PLUGIN_TRUE@am_libcc1_la_rpath = -rpath $(cc1libdir)
 am_libcc1plugin_la_OBJECTS = libcc1plugin.lo $(am__objects_1) \
@@ -428,7 +428,7 @@ libcp1plugin_la_LINK = $(LIBTOOL) --tag=CXX 
$(AM_LIBTOOLFLAGS) \
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
 libcc1_la_LDFLAGS = -module -export-symbols $(srcdir)/libcc1.sym
 libcc1_la_SOURCES = findcomp.cc libcc1.cc libcp1.cc \
-   names.cc names.hh $(shared_source) \
+   compiler.cc compiler.hh names.cc names.hh $(shared_source) \
$(marshall_c_source) $(marshall_cxx_source)
 
 libcc1_la_LIBADD = $(libiberty)
@@ -577,6 +577,7 @@ distclean-compile:
-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callbacks.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compiler.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connection.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findcomp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcc1.Plo@am__quote@
diff --git a/libcc1/compiler.cc b/libcc1/compiler.cc
new file mode 100644
index ..fede84968625
--- /dev/null
+++ b/libcc1/compiler.cc
@@ -0,0 +1,118 @@
+/* Compiler handling for plugin
+   Copyright (C) 2014-2021 Free Software Foundation, Inc.
+
+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

[PATCH v2 19/21] libcc1: use variadic templates for callbacks

2021-04-27 Thread Tom Tromey
This patch completes the transition of libcc1 from the use of separate
template functions for different arities to the use of variadic
functions.  This is how I had wanted it to work from the very
beginning, and is possible now with C++11.

I had thought that variadic callbacks required C++17, but it turns out
that the approach taken here is basically equivalent to std::apply --
just a bit wordier.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* rpc.hh (argument_wrapper) : Replace cast operator.
(argument_wrapper) : Likewise.
(unmarshall): Add std::tuple overloads.
(callback): Remove.
(class invoker): New.
* libcp1plugin.cc (plugin_init): Update.
* libcp1.cc (libcp1::add_callbacks): Update.
* libcc1plugin.cc (plugin_init): Update.
* libcc1.cc (libcc1::add_callbacks): Update.
* connection.cc (cc1_plugin::connection::do_wait): Update.
---
 libcc1/ChangeLog   |  13 +++
 libcc1/connection.cc   |   2 +-
 libcc1/libcc1.cc   |  12 +--
 libcc1/libcc1plugin.cc |  20 ++--
 libcc1/libcp1.cc   |  17 ++--
 libcc1/libcp1plugin.cc |  20 ++--
 libcc1/rpc.hh  | 219 +++--
 7 files changed, 101 insertions(+), 202 deletions(-)

diff --git a/libcc1/connection.cc b/libcc1/connection.cc
index 66d573911080..45560b9b790e 100644
--- a/libcc1/connection.cc
+++ b/libcc1/connection.cc
@@ -129,7 +129,7 @@ cc1_plugin::connection::do_wait (bool want_result)
  return FAIL;
 
callback_ftype *callback
- = m_callbacks.find_callback (method_name);
+ = m_callbacks.find_callback (method_name.get ());
// The call to CALLBACK is where we may end up in a
// reentrant call.
if (callback == NULL || !callback (this))
diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index cbc54ee0a044..febadc8420b0 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -143,15 +143,13 @@ void
 libcc1::add_callbacks ()
 {
   cc1_plugin::callback_ftype *fun
-= cc1_plugin::callback;
+= cc1_plugin::invoker::invoke;
   connection->add_callback ("binding_oracle", fun);
 
-  fun = cc1_plugin::callback;
+  fun = cc1_plugin::invoker::invoke;
   connection->add_callback ("address_oracle", fun);
 }
 
diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index d6951ab1a4d2..4d6a3a11ee22 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -762,46 +762,46 @@ plugin_init (struct plugin_name_args *plugin_info,
 #define GCC_METHOD0(R, N)  \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback; \
+  = cc1_plugin::invoker::invoke;  \
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD1(R, N, A)   \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback;  \
+  = cc1_plugin::invoker::invoke;   \
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD2(R, N, A, B)\
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback;   \
+  = cc1_plugin::invoker::invoke;\
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD3(R, N, A, B, C) \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback;\
+  = cc1_plugin::invoker::invoke; \
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD4(R, N, A, B, C, D)  \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback; \
+  = cc1_plugin::invoker::invoke;   \
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD5(R, N, A, B, C, D, E)   \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback; \
+  = cc1_plugin::invoker::invoke;   \
 current_context->add_callback (# N, fun);  \
   }
 #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
   {\
 cc1_plugin::callback_ftype *fun\
-  = cc1_plugin::callback; \
+  = cc1_plugin::invoker::invoke; \
 current_context->add_callback (# N, fun);  \
   }
 
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index d22d9dc6af8c..a93349833901 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -166,23 +166,18 @@ void
 libcp1::add_callbacks ()
 {
   cc1_plugin::callback_ftype *fun
-= cc1_plugin::callback;
+= cc1_plugin::invoker::invoke;
   

[PATCH v2 21/21] libcc1: avoid a call to c_str

2021-04-27 Thread Tom Tromey
This is a trivial change to libcc1 to avoid an explicit call to c_str.
Passing by const reference is slightly less wordy.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* compiler.cc (make_regexp): Take const std::string.
(cc1_plugin::compiler_triplet_regexp::find): Update.
---
 libcc1/ChangeLog   | 5 +
 libcc1/compiler.cc | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/libcc1/compiler.cc b/libcc1/compiler.cc
index fede84968625..a12843c538ae 100644
--- a/libcc1/compiler.cc
+++ b/libcc1/compiler.cc
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 
 // Construct an appropriate regexp to match the compiler name.
 static std::string
-make_regexp (const char *triplet_regexp, const char *compiler)
+make_regexp (const std::string _regexp, const char *compiler)
 {
   std::stringstream buf;
 
@@ -71,7 +71,7 @@ char *
 cc1_plugin::compiler_triplet_regexp::find (const char *base,
   std::string ) const
 {
-  std::string rx = make_regexp (triplet_regexp_.c_str (), base);
+  std::string rx = make_regexp (triplet_regexp_, base);
   if (verbose)
 fprintf (stderr, _("searching for compiler matching regex %s\n"),
 rx.c_str());
-- 
2.26.2



[PATCH v2 13/21] libcc1: use static_assert

2021-04-27 Thread Tom Tromey
This changes one spot in libcc1 to use static_assert rather than the
old-style array declaration.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1plugin.cc: Use static assert.
---
 libcc1/ChangeLog   | 4 
 libcc1/libcp1plugin.cc | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 3cbad5c6f021..ba6c5ef2efce 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -82,8 +82,8 @@ int plugin_is_GPL_compatible;
 
 
 
-static int ATTRIBUTE_UNUSED
-check_symbol_mask[GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END ? 1 : -1];
+static_assert (GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END,
+  "GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END");
 
 // This is put into the lang hooks when the plugin starts.
 
-- 
2.26.2



[PATCH v2 15/21] libcc1: share GDB plugin code

2021-04-27 Thread Tom Tromey
The two GDB plugins in libcc1 share a fair amount of code.  This was
done by copy-and-paste, though in reality the underlying code is
nearly identical.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1.cc (struct libcp1): Derive from base_gdb_plugin.  Remove
shared code.
(class libcp1_connection): Remove.
(rpc): Remove.
(libcp1_set_verbose, libcp1_compile): Update.
(cp_call_binding_oracle, cp_call_symbol_address)
(cp_call_enter_scope, cp_call_leave_scope): Update.
* libcc1.cc (struct libcc1): Derive from base_gdb_plugin.  Remove
shared code.
(class libcc1_connection): Remove.
(c_call_binding_oracle, c_call_symbol_address): Update.
(rpc): Remove.
(libcc1_set_verbose, libcc1_compile): Update.
* gdbctx.hh: New file.
---
 libcc1/ChangeLog |  17 +++
 libcc1/gdbctx.hh | 105 +++
 libcc1/libcc1.cc | 105 ---
 libcc1/libcp1.cc | 113 +--
 4 files changed, 162 insertions(+), 178 deletions(-)
 create mode 100644 libcc1/gdbctx.hh

diff --git a/libcc1/gdbctx.hh b/libcc1/gdbctx.hh
new file mode 100644
index ..1c8d87dff021
--- /dev/null
+++ b/libcc1/gdbctx.hh
@@ -0,0 +1,105 @@
+/* Generic GDB-side plugin
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+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
+.  */
+
+#ifndef CC1_PLUGIN_GDBCTX_HH
+#define CC1_PLUGIN_GDBCTX_HH
+
+namespace cc1_plugin
+{
+  // The compiler context that we hand back to our caller.
+  template
+  struct base_gdb_plugin : public T
+  {
+explicit base_gdb_plugin (const gcc_base_vtable *v)
+  : verbose (false),
+   compilerp (new compiler (verbose))
+{
+  this->base.ops = v;
+}
+
+// A convenience function to print something.
+void print (const char *str)
+{
+  this->print_function (this->print_datum, str);
+}
+
+// Set the verbose flag.
+void set_verbose (bool v)
+{
+  verbose = v;
+  if (compilerp != nullptr)
+   compilerp->set_verbose (v);
+}
+
+// Make a new connection.
+void set_connection (int fd, int aux_fd)
+{
+  connection.reset (new local_connection (fd, aux_fd, this));
+}
+
+// A local subclass of connection that holds a back-pointer to the
+// context object that we provide to our caller.
+class local_connection : public cc1_plugin::connection
+{
+public:
+
+  local_connection (int fd, int aux_fd, base_gdb_plugin *b)
+   : connection (fd, aux_fd),
+ back_ptr (b)
+  {
+  }
+
+  void print (const char *buf) override
+  {
+   back_ptr->print (buf);
+  }
+
+  base_gdb_plugin *back_ptr;
+};
+
+std::unique_ptr connection;
+
+void (*print_function) (void *datum, const char *message) = nullptr;
+void *print_datum = nullptr;
+
+std::vector args;
+std::string source_file;
+
+/* Non-zero as an equivalent to gcc driver option "-v".  */
+bool verbose;
+
+std::unique_ptr compilerp;
+  };
+
+  // Instances of this rpc<> template function are installed into the
+  // "vtable"s.  These functions are parameterized by type and method
+  // name and forward the call via the connection.
+  template
+  R rpc (CTX *s, Arg... rest)
+  {
+base_gdb_plugin *self = (base_gdb_plugin *) s;
+R result;
+
+if (!cc1_plugin::call (self->connection.get (), NAME, , rest...))
+  return 0;
+return result;
+  }
+}
+
+#endif // CC1_PLUGIN_GDBCTX_HH
diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index ea52c26d7832..b9f1eb343aaf 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -37,73 +37,21 @@ along with GCC; see the file COPYING3.  If not see
 #include "compiler-name.hh"
 #include "gcc-c-interface.h"
 #include "compiler.hh"
-
-struct libcc1;
-
-class libcc1_connection;
+#include "gdbctx.hh"
 
 // The C compiler context that we hand back to our caller.
-struct libcc1 : public gcc_c_context
+struct libcc1 : public cc1_plugin::base_gdb_plugin
 {
   libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *);
 
-  // A convenience function to print something.
-  void print (const char *str)
-  {
-this->print_function (this->print_datum, str);
-  }
-
-  std::unique_ptr connection;
-
-  gcc_c_oracle_function *binding_oracle;
-  

[PATCH v2 17/21] libcc1: share the GCC interface code

2021-04-27 Thread Tom Tromey
Both the C and C++ side of the GDB plugin in libcc1 share a lot of
code relating to the base GCC interface.  It was all copy-and-pasted,
but is essentially identical between the two.  This is by design, as
the base GCC API is intended to be shared.

This patch merges the implementations into base_gdb_plugin, which was
introduced earlier for this purpose.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1.cc (libcp1): Change parameters.  Update.
(libcp1_set_verbose, libcp1_set_arguments)
(libcp1_set_triplet_regexp, libcp1_set_driver_filename)
(libcp1_set_source_file, libcp1_set_print_callback, fork_exec)
(libcp1_compile, libcp1_destroy, vtable): Remove.
(libcp1::add_callbacks): New method, extracted from
libcp1_compile.
(gcc_c_fe_context): Update.
* libcc1.cc (libcc1): Change parameters.  Update.
(libcc1_set_verbose, libcc1_set_arguments)
(libcc1_set_triplet_regexp, libcc1_set_driver_filename)
(libcc1_set_source_file, libcc1_set_print_callback, fork_exec)
(libcc1_compile, libcc1_destroy, vtable): Remove.
(libcc1::add_callbacks): New method, extracted from
libcc1_compile.
(gcc_c_fe_context): Update.
* gdbctx.hh (base_gdb_plugin): Change parameters.
(~base_gdb_plugin): New.
: New virtual method.
: New members.
(get_self, do_set_verbose, do_set_arguments)
(do_set_triplet_regexp, do_set_driver_filename)
(do_set_arguments_v0, do_set_source_file, do_set_print_callback)
(fork_exec, do_compile, do_compile_v0, do_destroy): New methods.
---
 libcc1/ChangeLog |  27 +
 libcc1/gdbctx.hh | 253 ++-
 libcc1/libcc1.cc | 242 +++--
 libcc1/libcp1.cc | 246 +++--
 4 files changed, 304 insertions(+), 464 deletions(-)

diff --git a/libcc1/gdbctx.hh b/libcc1/gdbctx.hh
index 1c8d87dff021..4a48381f2b4a 100644
--- a/libcc1/gdbctx.hh
+++ b/libcc1/gdbctx.hh
@@ -23,16 +23,38 @@ along with GCC; see the file COPYING3.  If not see
 namespace cc1_plugin
 {
   // The compiler context that we hand back to our caller.
+  // Due to this, the entire implementation is in this header.
   template
   struct base_gdb_plugin : public T
   {
-explicit base_gdb_plugin (const gcc_base_vtable *v)
+base_gdb_plugin (const char *plugin_name_, const char *base_name,
+int version)
   : verbose (false),
+   plugin_name (plugin_name_),
+   fe_version (version),
+   compiler_name (base_name),
compilerp (new compiler (verbose))
 {
-  this->base.ops = v;
+  vtable =
+   {
+ GCC_FE_VERSION_1,
+ do_set_arguments_v0,
+ do_set_source_file,
+ do_set_print_callback,
+ do_compile_v0,
+ do_destroy,
+ do_set_verbose,
+ do_compile,
+ do_set_arguments,
+ do_set_triplet_regexp,
+ do_set_driver_filename,
+   };
+
+  this->base.ops = 
 }
 
+virtual ~base_gdb_plugin () = default;
+
 // A convenience function to print something.
 void print (const char *str)
 {
@@ -53,6 +75,10 @@ namespace cc1_plugin
   connection.reset (new local_connection (fd, aux_fd, this));
 }
 
+// This is called just before compilation begins.  It should set
+// any needed callbacks on the connection.
+virtual void add_callbacks () = 0;
+
 // A local subclass of connection that holds a back-pointer to the
 // context object that we provide to our caller.
 class local_connection : public cc1_plugin::connection
@@ -84,7 +110,230 @@ namespace cc1_plugin
 /* Non-zero as an equivalent to gcc driver option "-v".  */
 bool verbose;
 
+const char *plugin_name;
+int fe_version;
+
+const char *compiler_name;
 std::unique_ptr compilerp;
+
+  private:
+
+struct gcc_base_vtable vtable;
+
+static inline base_gdb_plugin *
+get_self (gcc_base_context *s)
+{
+  T *sub = (T *) s;
+  return static_cast *> (sub);
+}
+
+static void
+do_set_verbose (struct gcc_base_context *s, int /* bool */ verbose)
+{
+  base_gdb_plugin *self = get_self (s);
+
+  self->set_verbose (verbose != 0);
+}
+
+static char *
+do_set_arguments (struct gcc_base_context *s,
+ int argc, char **argv)
+{
+  base_gdb_plugin *self = get_self (s);
+
+  std::string compiler;
+  char *errmsg = self->compilerp->find (self->compiler_name, compiler);
+  if (errmsg != NULL)
+   return errmsg;
+
+  self->args.push_back (compiler);
+
+  for (int i = 0; i < argc; ++i)
+   self->args.push_back (argv[i]);
+
+  return NULL;
+}
+
+static char *
+do_set_triplet_regexp (struct gcc_base_context *s,
+  const char *triplet_regexp)
+{
+  base_gdb_plugin *self = 

[PATCH v2 16/21] libcc1: use GCC_FE_VERSION_1 in C++ plugin

2021-04-27 Thread Tom Tromey
The C++ plugin defaults to version 0 of the base compiler API.
However, this is a mistake -- version 1 was introduced before the C++
API was even implemented.  This switches the default to version 1.
Note that the compiler-side plugin will accept this version, so it
should remain compatible.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1.cc (vtable): Use GCC_FE_VERSION_1.
---
 libcc1/ChangeLog | 4 
 libcc1/libcp1.cc | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index 6fb9fb4c9a6c..65e9770205c0 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -391,7 +391,7 @@ libcp1_destroy (struct gcc_base_context *s)
 
 static const struct gcc_base_vtable vtable =
 {
-  GCC_FE_VERSION_0,
+  GCC_FE_VERSION_1,
   libcp1_set_arguments_v0,
   libcp1_set_source_file,
   libcp1_set_print_callback,
-- 
2.26.2



[PATCH v2 18/21] libcc1: fix a memory leak

2021-04-27 Thread Tom Tromey
libcc1 has a memory leak when calling fork_exec -- it allocates a new
vector of arguments, but then does not free it anywhere.  This patch
changes this code to use std::vector instead.

Note that the previous code tried to avoid bad_alloc.  I don't believe
this is very important.  For one thing, plenty of other allocations do
not bother with this.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* gdbctx.hh (do_compile): Use std::vector.
---
 libcc1/ChangeLog | 4 
 libcc1/gdbctx.hh | 8 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libcc1/gdbctx.hh b/libcc1/gdbctx.hh
index 4a48381f2b4a..4d2488344bc8 100644
--- a/libcc1/gdbctx.hh
+++ b/libcc1/gdbctx.hh
@@ -308,15 +308,11 @@ namespace cc1_plugin
 
   self->add_callbacks ();
 
-  char **argv = new (std::nothrow) char *[self->args.size () + 1];
-  if (argv == NULL)
-   return 0;
-
+  std::vector argv (self->args.size () + 1);
   for (unsigned int i = 0; i < self->args.size (); ++i)
argv[i] = const_cast (self->args[i].c_str ());
-  argv[self->args.size ()] = NULL;
 
-  return self->fork_exec (argv, fds, stderr_fds);
+  return self->fork_exec (argv.data (), fds, stderr_fds);
 }
 
 static int
-- 
2.26.2



[PATCH v2 20/21] libcc1: avoid extra string copies

2021-04-27 Thread Tom Tromey
PR c/94669 points out that a couple of spots in libcc1 take a
std::string where a reference would do.  This changes these spots to
take a const char *, to reduce the number of copies.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

PR c/94669:
* compiler.hh (compiler_driver_filename): Take const char *.
(compiler_triplet_regexp): Likewise.
---
 libcc1/ChangeLog   | 6 ++
 libcc1/compiler.hh | 4 ++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/libcc1/compiler.hh b/libcc1/compiler.hh
index 638f7c09f634..d10d409f9d35 100644
--- a/libcc1/compiler.hh
+++ b/libcc1/compiler.hh
@@ -58,7 +58,7 @@ namespace cc1_plugin
 
 char *find (const char *base, std::string ) const override;
 
-compiler_triplet_regexp (bool v, std::string triplet_regexp)
+compiler_triplet_regexp (bool v, const char *triplet_regexp)
   : compiler (v), triplet_regexp_ (triplet_regexp)
 {
 }
@@ -72,7 +72,7 @@ namespace cc1_plugin
   public:
 char *find (const char *base, std::string ) const override;
 
-compiler_driver_filename (bool v, std::string driver_filename)
+compiler_driver_filename (bool v, const char *driver_filename)
   : compiler (v), driver_filename_ (driver_filename)
 {
 }
-- 
2.26.2



[PATCH v2 12/21] libcc1: use foreach

2021-04-27 Thread Tom Tromey
This changes libcc1 to ues foreach in a couple of spots.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1plugin.cc (plugin_context::mark): Use foreach.
* libcc1plugin.cc (plugin_context::mark): Use foreach.
---
 libcc1/ChangeLog   |  5 +
 libcc1/libcc1plugin.cc | 13 +
 libcc1/libcp1plugin.cc | 13 +
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index 65e748258f40..2a75faba7652 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -235,17 +235,14 @@ plugin_context::plugin_context (int fd)
 void
 plugin_context::mark ()
 {
-  for (hash_table::iterator it = address_map.begin ();
-   it != address_map.end ();
-   ++it)
+  for (const auto  : address_map)
 {
-  ggc_mark ((*it)->decl);
-  ggc_mark ((*it)->address);
+  ggc_mark (item->decl);
+  ggc_mark (item->address);
 }
 
-  for (hash_table< nofree_ptr_hash >::iterator
-it = preserved.begin (); it != preserved.end (); ++it)
-ggc_mark (&*it);
+  for (const auto  : preserved)
+ggc_mark ();
 }
 
 static void
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 1fc8e269f075..3cbad5c6f021 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -225,17 +225,14 @@ plugin_context::plugin_context (int fd)
 void
 plugin_context::mark ()
 {
-  for (hash_table::iterator it = address_map.begin ();
-   it != address_map.end ();
-   ++it)
+  for (const auto  : address_map)
 {
-  ggc_mark ((*it)->decl);
-  ggc_mark ((*it)->address);
+  ggc_mark (item->decl);
+  ggc_mark (item->address);
 }
 
-  for (hash_table< nofree_ptr_hash >::iterator
-it = preserved.begin (); it != preserved.end (); ++it)
-ggc_mark (&*it);
+  for (const auto  : preserved)
+ggc_mark ();
 }
 
 static void
-- 
2.26.2



[PATCH v2 09/21] libcc1: add more uses of 'deleter'

2021-04-27 Thread Tom Tromey
This changes libcc1 to use the 'deleter' template in a few more
places.  The template and basic specializations are moved to a new
header, then some unmarshall functions are changed to use this code.
This change avoids the need to repeat cleanup code in the
unmarshallers.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* rpc.hh (deleter): Move template and some specializations to
deleter.hh.
(argument_wrapper): Use cc1_plugin::unique_ptr.
* marshall.cc (cc1_plugin::unmarshall): Use
cc1_plugin::unique_ptr.
* marshall-cp.hh (deleter): New specializations.
(unmarshall): Use cc1_plugin::unique_ptr.
* deleter.hh: New file.
---
 libcc1/ChangeLog  | 11 ++
 libcc1/deleter.hh | 53 +
 libcc1/marshall-cp.hh | 79 +--
 libcc1/marshall.cc| 11 +++---
 libcc1/rpc.hh | 62 ++---
 5 files changed, 116 insertions(+), 100 deletions(-)
 create mode 100644 libcc1/deleter.hh

diff --git a/libcc1/deleter.hh b/libcc1/deleter.hh
new file mode 100644
index ..70553eef8f8c
--- /dev/null
+++ b/libcc1/deleter.hh
@@ -0,0 +1,53 @@
+/* Deleter objects
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+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
+.  */
+
+#ifndef CC1_PLUGIN_DELETER_HH
+#define CC1_PLUGIN_DELETER_HH
+
+#include 
+
+namespace cc1_plugin
+{
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template struct deleter;
+
+  template<>
+  struct deleter
+  {
+void operator() (char *s)
+{
+  delete[] s;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_type_array *p)
+{
+  delete[] p->elements;
+  delete p;
+}
+  };
+
+  template using unique_ptr = std::unique_ptr>;
+}
+
+#endif // CC1_PLUGIN_DELETER_HH
diff --git a/libcc1/marshall-cp.hh b/libcc1/marshall-cp.hh
index 3d6ae4126aee..ec616e09d952 100644
--- a/libcc1/marshall-cp.hh
+++ b/libcc1/marshall-cp.hh
@@ -22,9 +22,42 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "marshall.hh"
 #include "gcc-cp-interface.h"
+#include "deleter.hh"
 
 namespace cc1_plugin
 {
+  template<>
+  struct deleter
+  {
+void operator() (gcc_vbase_array *p)
+{
+  delete[] p->flags;
+  delete[] p->elements;
+  delete p;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_cp_template_args *p)
+{
+  delete[] p->elements;
+  delete[] p->kinds;
+  delete p;
+}
+  };
+
+  template<>
+  struct deleter
+  {
+void operator() (gcc_cp_function_args *p)
+{
+  delete[] p->elements;
+  delete p;
+}
+  };
+
   // Send a gcc_vbase_array marker followed by the array.
   status
   marshall (connection *conn, const gcc_vbase_array *a)
@@ -67,7 +100,7 @@ namespace cc1_plugin
return OK;
   }
 
-struct gcc_vbase_array *gva = new gcc_vbase_array;
+cc1_plugin::unique_ptr gva (new gcc_vbase_array {});
 
 gva->n_elements = len;
 gva->elements = new gcc_type[len];
@@ -75,25 +108,16 @@ namespace cc1_plugin
 if (!unmarshall_array_elmts (conn,
 len * sizeof (gva->elements[0]),
 gva->elements))
-  {
-   delete[] gva->elements;
-   delete gva;
-   return FAIL;
-  }
+  return FAIL;
 
 gva->flags = new enum gcc_cp_symbol_kind[len];
 
 if (!unmarshall_array_elmts (conn,
 len * sizeof (gva->flags[0]),
 gva->flags))
-  {
-   delete[] gva->flags;
-   delete[] gva->elements;
-   delete gva;
-   return FAIL;
-  }
+  return FAIL;
 
-*result = gva;
+*result = gva.release ();
 return OK;
   }
 
@@ -139,7 +163,8 @@ namespace cc1_plugin
return OK;
   }
 
-struct gcc_cp_template_args *gva = new gcc_cp_template_args;
+cc1_plugin::unique_ptr gva
+  (new gcc_cp_template_args {});
 
 gva->n_elements = len;
 gva->kinds = new char[len];
@@ -147,25 +172,16 @@ namespace cc1_plugin
 if (!unmarshall_array_elmts (conn,
 len * sizeof (gva->kinds[0]),
 gva->kinds))
-  {
-   delete[] gva->kinds;
-   delete gva;
-   return FAIL;

[PATCH v2 10/21] libcc1: use unique_ptr more

2021-04-27 Thread Tom Tromey
This changes libcc1 to use unique_ptr in a few more places, removing
some manual memory management.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1.cc (struct libcp1) : Use
unique_ptr.
(~libcp1): Remove.
(libcp1_compile, libcp1_set_triplet_regexp)
(libcp1_set_driver_filename): Update.
* libcc1.cc (struct libcc1) : Use
unique_ptr.
(~libcc1): Remove.
(libcc1_set_triplet_regexp, libcc1_set_driver_filename)
(libcc1_compile): Update.
---
 libcc1/ChangeLog | 13 +
 libcc1/libcc1.cc | 32 +---
 libcc1/libcp1.cc | 32 +---
 3 files changed, 39 insertions(+), 38 deletions(-)

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 3432f4e8b212..e00355955b6e 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -49,7 +49,6 @@ class libcc1_connection;
 struct libcc1 : public gcc_c_context
 {
   libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *);
-  ~libcc1 ();
 
   // A convenience function to print something.
   void print (const char *str)
@@ -57,7 +56,7 @@ struct libcc1 : public gcc_c_context
 this->print_function (this->print_datum, str);
   }
 
-  libcc1_connection *connection;
+  std::unique_ptr connection;
 
   gcc_c_oracle_function *binding_oracle;
   gcc_c_symbol_address_function *address_oracle;
@@ -85,7 +84,9 @@ struct libcc1 : public gcc_c_context
 virtual ~compiler ()
 {
 }
-  } *compilerp;
+  };
+
+  std::unique_ptr compilerp;
 
   /* Compiler to set by set_triplet_regexp.  */
   class compiler_triplet_regexp : public compiler
@@ -142,8 +143,7 @@ public:
 
 libcc1::libcc1 (const gcc_base_vtable *v,
const gcc_c_fe_vtable *cv)
-  : connection (NULL),
-binding_oracle (NULL),
+  : binding_oracle (NULL),
 address_oracle (NULL),
 oracle_datum (NULL),
 print_function (NULL),
@@ -157,12 +157,6 @@ libcc1::libcc1 (const gcc_base_vtable *v,
   c_ops = cv;
 }
 
-libcc1::~libcc1 ()
-{
-  delete connection;
-  delete compilerp;
-}
-
 
 
 // Enclose these functions in an anonymous namespace because they
@@ -220,7 +214,7 @@ R rpc (struct gcc_c_context *s, Arg... rest)
   libcc1 *self = (libcc1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, , rest...))
+  if (!cc1_plugin::call (self->connection.get (), NAME, , rest...))
 return 0;
   return result;
 }
@@ -380,8 +374,8 @@ libcc1_set_triplet_regexp (struct gcc_base_context *s,
 {
   libcc1 *self = (libcc1 *) s;
 
-  delete self->compilerp;
-  self->compilerp = new libcc1::compiler_triplet_regexp (self, triplet_regexp);
+  self->compilerp.reset (new libcc1::compiler_triplet_regexp (self,
+ triplet_regexp));
   return NULL;
 }
 
@@ -391,9 +385,8 @@ libcc1_set_driver_filename (struct gcc_base_context *s,
 {
   libcc1 *self = (libcc1 *) s;
 
-  delete self->compilerp;
-  self->compilerp = new libcc1::compiler_driver_filename (self,
- driver_filename);
+  self->compilerp.reset (new libcc1::compiler_driver_filename (self,
+  
driver_filename));
   return NULL;
 }
 
@@ -464,7 +457,8 @@ fork_exec (libcc1 *self, char **argv, int spair_fds[2], int 
stderr_fds[2])
 
   cc1_plugin::status result = cc1_plugin::FAIL;
   if (self->connection->send ('H')
- && ::cc1_plugin::marshall (self->connection, GCC_C_FE_VERSION_1))
+ && ::cc1_plugin::marshall (self->connection.get (),
+GCC_C_FE_VERSION_1))
result = self->connection->wait_for_query ();
 
   close (spair_fds[0]);
@@ -527,7 +521,7 @@ libcc1_compile (struct gcc_base_context *s,
   if (self->verbose)
 self->args.push_back ("-v");
 
-  self->connection = new libcc1_connection (fds[0], stderr_fds[0], self);
+  self->connection.reset (new libcc1_connection (fds[0], stderr_fds[0], self));
 
   cc1_plugin::callback_ftype *fun
 = cc1_plugin::callbackprint_function (this->print_datum, str);
   }
 
-  libcp1_connection *connection;
+  std::unique_ptr connection;
 
   gcc_cp_oracle_function *binding_oracle;
   gcc_cp_symbol_address_function *address_oracle;
@@ -86,7 +85,9 @@ struct libcp1 : public gcc_cp_context
 virtual ~compiler ()
 {
 }
-  } *compilerp;
+  };
+
+  std::unique_ptr compilerp;
 
   /* Compiler to set by set_triplet_regexp.  */
   class compiler_triplet_regexp : public compiler
@@ -143,8 +144,7 @@ public:
 
 libcp1::libcp1 (const gcc_base_vtable *v,
  const gcc_cp_fe_vtable *cv)
-  : connection (NULL),
-binding_oracle (NULL),
+  : binding_oracle (NULL),
 address_oracle (NULL),
 oracle_datum (NULL),
 print_function (NULL),
@@ -158,12 +158,6 @@ libcp1::libcp1 (const gcc_base_vtable *v,
   cp_ops = cv;
 }
 
-libcp1::~libcp1 ()
-{
-  delete connection;
-  delete compilerp;
-}
-
 
 
 // Enclose these 

[PATCH v2 08/21] libcc1: add deleter objects

2021-04-27 Thread Tom Tromey
This adds deleter objects for various kinds of protocol pointers to
libcc1.  Existing specializations of argument_wrapper are then
replaced with a single specialization that handles all pointer types
via the appropriate deleter.  The result here is a bit nicer because
the argument_wrapper boilerplate code is completely shared, leaving
just the memory-management detail to the particular specializations.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* rpc.hh (struct deleter): New template class and
specializations.
(argument_wrapper): Remove specializations.  Add specialization
for any pointer type.
---
 libcc1/ChangeLog |   7 ++
 libcc1/rpc.hh| 176 ---
 2 files changed, 52 insertions(+), 131 deletions(-)

diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index a3631cb5d7e2..4e00d61ee98d 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "status.hh"
 #include "connection.hh"
+#include 
 
 namespace cc1_plugin
 {
@@ -54,182 +55,95 @@ namespace cc1_plugin
 T m_object;
   };
 
-  // Specialization for any kind of pointer.  This is declared but not
-  // defined to avoid bugs if a new pointer type is introduced into
-  // the API.  Instead you will just get a compilation error.
-  template
-  class argument_wrapper;
+  // Any pointer type requires a deleter object that knows how to
+  // clean up.  These are used in multiple places.
+  template struct deleter;
 
-  // Specialization for string types.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  public:
-argument_wrapper () : m_object (NULL) { }
-~argument_wrapper ()
+void operator() (char *s)
 {
-  delete[] m_object;
+  delete[] s;
 }
-
-argument_wrapper (const argument_wrapper &) = delete;
-argument_wrapper = (const argument_wrapper &) = delete;
-
-operator const char * () const
-{
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, _object);
-}
-
-  private:
-
-char *m_object;
   };
 
-  // Specialization for gcc_type_array.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  public:
-argument_wrapper () : m_object (NULL) { }
-~argument_wrapper ()
+void operator() (gcc_type_array *p)
 {
-  // It would be nicer if gcc_type_array could have a destructor.
-  // But, it is in code shared with gdb and cannot.
-  if (m_object != NULL)
-   delete[] m_object->elements;
-  delete m_object;
+  delete[] p->elements;
+  delete p;
 }
-
-argument_wrapper (const argument_wrapper &) = delete;
-argument_wrapper = (const argument_wrapper &) = delete;
-
-operator const gcc_type_array * () const
-{
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, _object);
-}
-
-  private:
-
-gcc_type_array *m_object;
   };
 
 #ifdef GCC_CP_INTERFACE_H
-  // Specialization for gcc_vbase_array.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  public:
-argument_wrapper () : m_object (NULL) { }
-~argument_wrapper ()
-{
-  // It would be nicer if gcc_type_array could have a destructor.
-  // But, it is in code shared with gdb and cannot.
-  if (m_object != NULL)
-   {
- delete[] m_object->flags;
- delete[] m_object->elements;
-   }
-  delete m_object;
-}
-
-argument_wrapper (const argument_wrapper &) = delete;
-argument_wrapper = (const argument_wrapper &) = delete;
-
-operator const gcc_vbase_array * () const
+void operator() (gcc_vbase_array *p)
 {
-  return m_object;
-}
-
-status unmarshall (connection *conn)
-{
-  return ::cc1_plugin::unmarshall (conn, _object);
+  delete[] p->flags;
+  delete[] p->elements;
+  delete p;
 }
-
-  private:
-
-gcc_vbase_array *m_object;
   };
 
-  // Specialization for gcc_cp_template_args.
   template<>
-  class argument_wrapper
+  struct deleter
   {
-  public:
-argument_wrapper () : m_object (NULL) { }
-~argument_wrapper ()
-{
-  // It would be nicer if gcc_type_array could have a destructor.
-  // But, it is in code shared with gdb and cannot.
-  if (m_object != NULL)
-   {
- delete[] m_object->elements;
- delete[] m_object->kinds;
-   }
-  delete m_object;
-}
-
-argument_wrapper (const argument_wrapper &) = delete;
-argument_wrapper = (const argument_wrapper &) = delete;
-
-operator const gcc_cp_template_args * () const
+void operator() (gcc_cp_template_args *p)
 {
-  return m_object;
+  delete[] p->elements;
+  delete[] p->kinds;
+  delete p;
 }
+  };
 
-status unmarshall (connection *conn)
+  template<>
+  struct deleter
+  {
+void operator() (gcc_cp_function_args *p)
 

[PATCH v2 07/21] libcc1: use std::vector when building function types

2021-04-27 Thread Tom Tromey
This changes libcc1 to use std::vector in the code that builds
function types.  This avoids some explicit memory management.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1plugin.cc (plugin_build_function_type): Use std::vector.
* libcc1plugin.cc (plugin_build_function_type): Use std::vector.
---
 libcc1/ChangeLog   |  5 +
 libcc1/libcc1plugin.cc | 11 +--
 libcc1/libcp1plugin.cc | 11 +--
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index 59e4851064a2..65e748258f40 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -67,6 +67,8 @@
 #include "rpc.hh"
 #include "gcc-c-interface.h"
 
+#include 
+
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
 #endif
@@ -672,24 +674,21 @@ plugin_build_function_type (cc1_plugin::connection *self,
const struct gcc_type_array *argument_types_in,
int is_varargs)
 {
-  tree *argument_types;
   tree return_type = convert_in (return_type_in);
   tree result;
 
-  argument_types = new tree[argument_types_in->n_elements];
+  std::vector argument_types (argument_types_in->n_elements);
   for (int i = 0; i < argument_types_in->n_elements; ++i)
 argument_types[i] = convert_in (argument_types_in->elements[i]);
 
   if (is_varargs)
 result = build_varargs_function_type_array (return_type,
argument_types_in->n_elements,
-   argument_types);
+   argument_types.data ());
   else
 result = build_function_type_array (return_type,
argument_types_in->n_elements,
-   argument_types);
-
-  delete[] argument_types;
+   argument_types.data ());
 
   plugin_context *ctx = static_cast (self);
   return convert_out (ctx->preserve (result));
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 27a6175e34e6..1fc8e269f075 100644
--- a/libcc1/libcp1plugin.cc
+++ b/libcc1/libcp1plugin.cc
@@ -70,6 +70,8 @@
 #include "marshall-cp.hh"
 #include "rpc.hh"
 
+#include 
+
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
 #endif
@@ -1980,24 +1982,21 @@ plugin_build_function_type (cc1_plugin::connection 
*self,
const struct gcc_type_array *argument_types_in,
int is_varargs)
 {
-  tree *argument_types;
   tree return_type = convert_in (return_type_in);
   tree result;
 
-  argument_types = new tree[argument_types_in->n_elements];
+  std::vector argument_types (argument_types_in->n_elements);
   for (int i = 0; i < argument_types_in->n_elements; ++i)
 argument_types[i] = convert_in (argument_types_in->elements[i]);
 
   if (is_varargs)
 result = build_varargs_function_type_array (return_type,
argument_types_in->n_elements,
-   argument_types);
+   argument_types.data ());
   else
 result = build_function_type_array (return_type,
argument_types_in->n_elements,
-   argument_types);
-
-  delete[] argument_types;
+   argument_types.data ());
 
   plugin_context *ctx = static_cast (self);
   return convert_out (ctx->preserve (result));
-- 
2.26.2



[PATCH v2 05/21] libcc1: use variadic templates for "call"

2021-04-27 Thread Tom Tromey
This changes libcc1 to use variadic templates for the "call"
functions.  The primary benefit is that this simplifies the code.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* rpc.hh (call): Use variadic template.  Remove overloads.
* marshall.hh (marshall): Add base overload.  Use variadic
template.
---
 libcc1/ChangeLog   |   6 ++
 libcc1/marshall.hh |  16 +
 libcc1/rpc.hh  | 168 +++--
 3 files changed, 31 insertions(+), 159 deletions(-)

diff --git a/libcc1/marshall.hh b/libcc1/marshall.hh
index 8d890eb9b6c7..4a28a8fe4ae2 100644
--- a/libcc1/marshall.hh
+++ b/libcc1/marshall.hh
@@ -52,6 +52,14 @@ namespace cc1_plugin
   status unmarshall_array_start (connection *, char, size_t *);
   status unmarshall_array_elmts (connection *, size_t, void *);
 
+  // An "empty" marshall call -- used to handle the base case for some
+  // variadic templates.
+  static inline
+  status marshall (connection *)
+  {
+return OK;
+  }
+
   // A template function that can handle marshalling various integer
   // objects to the connection.
   template
@@ -103,6 +111,14 @@ namespace cc1_plugin
   // resulting array must be freed by the caller, using 'delete[]' on
   // the elements, and 'delete' on the array object itself.
   status unmarshall (connection *, struct gcc_type_array **);
+
+  template
+  status marshall (connection *c, T1 arg1, T2 arg2, Arg... rest)
+  {
+if (!marshall (c, arg1))
+  return FAIL;
+return marshall (c, arg2, rest...);
+  }
 };
 
 #endif // CC1_PLUGIN_MARSHALL_HH
diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index 429aeb3c1278..a3631cb5d7e2 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -232,10 +232,10 @@ namespace cc1_plugin
 #endif /* GCC_CP_INTERFACE_H */
 
   // There are two kinds of template functions here: "call" and
-  // "callback".  They are each repeated multiple times to handle
-  // different numbers of arguments.  (This would be improved with
-  // C++11, though applying a call is still tricky until C++14 can be
-  // used.)
+  // "callback".  "call" is implemented with variadic templates, but
+  // "callback" is repeated multiple times to handle different numbers
+  // of arguments.  (This could be improved with C++17 and
+  // std::apply.)
 
   // The "call" template is used for making a remote procedure call.
   // It starts a query ('Q') packet, marshalls its arguments, waits
@@ -248,15 +248,17 @@ namespace cc1_plugin
   // arguments, passes them to the wrapped function, and finally
   // marshalls a reply packet.
 
-  template
+  template
   status
-  call (connection *conn, const char *method, R *result)
+  call (connection *conn, const char *method, R *result, Arg... args)
   {
 if (!conn->send ('Q'))
   return FAIL;
 if (!marshall (conn, method))
   return FAIL;
-if (!marshall (conn, 0))
+if (!marshall (conn, (int) sizeof... (Arg)))
+  return FAIL;
+if (!marshall (conn, args...))
   return FAIL;
 if (!conn->wait_for_result ())
   return FAIL;
@@ -279,25 +281,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  template
-  status
-  call (connection *conn, const char *method, R *result, A arg)
-  {
-if (!conn->send ('Q'))
-  return FAIL;
-if (!marshall (conn, method))
-  return FAIL;
-if (!marshall (conn, 1))
-  return FAIL;
-if (!marshall (conn, arg))
-  return FAIL;
-if (!conn->wait_for_result ())
-  return FAIL;
-if (!unmarshall (conn, result))
-  return FAIL;
-return OK;
-  }
-
   template
   status
   callback (connection *conn)
@@ -315,27 +298,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  template
-  status
-  call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2)
-  {
-if (!conn->send ('Q'))
-  return FAIL;
-if (!marshall (conn, method))
-  return FAIL;
-if (!marshall (conn, 2))
-  return FAIL;
-if (!marshall (conn, arg1))
-  return FAIL;
-if (!marshall (conn, arg2))
-  return FAIL;
-if (!conn->wait_for_result ())
-  return FAIL;
-if (!unmarshall (conn, result))
-  return FAIL;
-return OK;
-  }
-
   template
   status
@@ -357,30 +319,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  template
-  status
-  call (connection *conn, const char *method, R *result, A1 arg1, A2 arg2,
-   A3 arg3)
-  {
-if (!conn->send ('Q'))
-  return FAIL;
-if (!marshall (conn, method))
-  return FAIL;
-if (!marshall (conn, 3))
-  return FAIL;
-if (!marshall (conn, arg1))
-  return FAIL;
-if (!marshall (conn, arg2))
-  return FAIL;
-if (!marshall (conn, arg3))
-  return FAIL;
-if (!conn->wait_for_result ())
-  return FAIL;
-if (!unmarshall (conn, result))
-  return FAIL;
-return OK;
-  }
-
   template
   status
@@ -405,32 +343,6 @@ namespace cc1_plugin
 return marshall (conn, result);
   }
 
-  

[PATCH v2 06/21] libcc1: use variadic templates for "rpc"

2021-04-27 Thread Tom Tromey
This changes libcc1 to use variadic templates for the "rpc" functions.
This simplifies the code and removes some possibility for mistakes.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1.cc (rpc): Use variadic template.  Remove overloads.
* libcc1.cc (rpc): Use variadic template.  Remove overloads.
---
 libcc1/ChangeLog |  5 +++
 libcc1/libcc1.cc | 81 +++-
 libcc1/libcp1.cc | 81 +++-
 3 files changed, 13 insertions(+), 154 deletions(-)

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 2c08dabb1a49..3432f4e8b212 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -210,90 +210,17 @@ set_callbacks (struct gcc_c_context *s,
   self->oracle_datum = datum;
 }
 
-// Instances of these rpc<> template functions are installed into the
+// Instances of this rpc<> template function are installed into the
 // "c_vtable".  These functions are parameterized by type and method
 // name and forward the call via the connection.
 
-template
-R rpc (struct gcc_c_context *s)
+template
+R rpc (struct gcc_c_context *s, Arg... rest)
 {
   libcc1 *self = (libcc1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, ))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A arg)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2, arg3))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2, arg3,
-arg4))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2, arg3,
-arg4, arg5))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
-   A6 arg6, A7 arg7)
-{
-  libcc1 *self = (libcc1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2, arg3,
-arg4, arg5, arg6, arg7))
+  if (!cc1_plugin::call (self->connection, NAME, , rest...))
 return 0;
   return result;
 }
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index fb91125ef0cf..4273f8d83826 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -233,90 +233,17 @@ set_callbacks (struct gcc_cp_context *s,
   self->oracle_datum = datum;
 }
 
-// Instances of these rpc<> template functions are installed into the
+// Instances of this rpc<> template function are installed into the
 // "cp_vtable".  These functions are parameterized by type and method
 // name and forward the call via the connection.
 
-template
-R rpc (struct gcc_cp_context *s)
+template
+R rpc (struct gcc_cp_context *s, Arg... rest)
 {
   libcp1 *self = (libcp1 *) s;
   R result;
 
-  if (!cc1_plugin::call (self->connection, NAME, ))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A arg)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2, arg3))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2, arg3,
-arg4))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call (self->connection, NAME, , arg1, arg2, arg3,
-arg4, arg5))
-return 0;
-  return result;
-}
-
-template
-R rpc (struct gcc_cp_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
-   A6 arg6, A7 arg7)
-{
-  libcp1 *self = (libcp1 *) s;
-  R result;
-
-  if (!cc1_plugin::call 

[PATCH v2 04/21] libcc1: delete copy constructor and assignment operators

2021-04-27 Thread Tom Tromey
Change libcc1 to use "= delete" for the copy constructor and
assignment operator, rather than the old approach of private methods
that are nowhere defined.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* rpc.hh (argument_wrapper): Use delete for copy constructor.
* connection.hh (class connection): Use delete for copy
constructor.
* callbacks.hh (class callbacks): Use delete for copy constructor.
---
 libcc1/ChangeLog |  7 +++
 libcc1/callbacks.hh  |  7 +++
 libcc1/connection.hh |  7 +++
 libcc1/rpc.hh| 42 ++
 4 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/libcc1/callbacks.hh b/libcc1/callbacks.hh
index b1f3e98d917b..dc470c62c48d 100644
--- a/libcc1/callbacks.hh
+++ b/libcc1/callbacks.hh
@@ -42,6 +42,9 @@ namespace cc1_plugin
 callbacks ();
 ~callbacks ();
 
+callbacks (const callbacks &) = delete;
+callbacks = (const callbacks &) = delete;
+
 // Add a callback named NAME.  FUNC is the function to call when
 // this method is invoked.
 void add_callback (const char *name, callback_ftype *func);
@@ -52,10 +55,6 @@ namespace cc1_plugin
 
   private:
 
-// Declared but not defined to avoid use.
-callbacks (const callbacks &);
-callbacks = (const callbacks &);
-
 // The mapping.
 htab_t m_registry;
   };
diff --git a/libcc1/connection.hh b/libcc1/connection.hh
index a0e99bdbd98f..15ad1716a29e 100644
--- a/libcc1/connection.hh
+++ b/libcc1/connection.hh
@@ -48,6 +48,9 @@ namespace cc1_plugin
 
 virtual ~connection () = default;
 
+connection (const connection &) = delete;
+connection = (const connection &) = delete;
+
 // Send a single character.  This is used to introduce various
 // higher-level protocol elements.
 status send (char c);
@@ -95,10 +98,6 @@ namespace cc1_plugin
 
   private:
 
-// Declared but not defined, to prevent use.
-connection (const connection &);
-connection = (const connection &);
-
 // Helper function for the wait_* methods.
 status do_wait (bool);
 
diff --git a/libcc1/rpc.hh b/libcc1/rpc.hh
index a8e33577ea18..429aeb3c1278 100644
--- a/libcc1/rpc.hh
+++ b/libcc1/rpc.hh
@@ -39,6 +39,9 @@ namespace cc1_plugin
 argument_wrapper () { }
 ~argument_wrapper () { }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper = (const argument_wrapper &) = delete;
+
 operator T () const { return m_object; }
 
 status unmarshall (connection *conn)
@@ -49,10 +52,6 @@ namespace cc1_plugin
   private:
 
 T m_object;
-
-// No copying or assignment allowed.
-argument_wrapper (const argument_wrapper &);
-argument_wrapper = (const argument_wrapper &);
   };
 
   // Specialization for any kind of pointer.  This is declared but not
@@ -72,6 +71,9 @@ namespace cc1_plugin
   delete[] m_object;
 }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper = (const argument_wrapper &) = delete;
+
 operator const char * () const
 {
   return m_object;
@@ -85,10 +87,6 @@ namespace cc1_plugin
   private:
 
 char *m_object;
-
-// No copying or assignment allowed.
-argument_wrapper (const argument_wrapper &);
-argument_wrapper = (const argument_wrapper &);
   };
 
   // Specialization for gcc_type_array.
@@ -106,6 +104,9 @@ namespace cc1_plugin
   delete m_object;
 }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper = (const argument_wrapper &) = delete;
+
 operator const gcc_type_array * () const
 {
   return m_object;
@@ -119,10 +120,6 @@ namespace cc1_plugin
   private:
 
 gcc_type_array *m_object;
-
-// No copying or assignment allowed.
-argument_wrapper (const argument_wrapper &);
-argument_wrapper = (const argument_wrapper &);
   };
 
 #ifdef GCC_CP_INTERFACE_H
@@ -144,6 +141,9 @@ namespace cc1_plugin
   delete m_object;
 }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper = (const argument_wrapper &) = delete;
+
 operator const gcc_vbase_array * () const
 {
   return m_object;
@@ -157,10 +157,6 @@ namespace cc1_plugin
   private:
 
 gcc_vbase_array *m_object;
-
-// No copying or assignment allowed.
-argument_wrapper (const argument_wrapper &);
-argument_wrapper = (const argument_wrapper &);
   };
 
   // Specialization for gcc_cp_template_args.
@@ -181,6 +177,9 @@ namespace cc1_plugin
   delete m_object;
 }
 
+argument_wrapper (const argument_wrapper &) = delete;
+argument_wrapper = (const argument_wrapper &) = delete;
+
 operator const gcc_cp_template_args * () const
 {
   return m_object;
@@ -194,10 +193,6 @@ namespace cc1_plugin
   private:
 
 gcc_cp_template_args *m_object;
-
-// No copying or assignment allowed.
-argument_wrapper (const argument_wrapper &);
-argument_wrapper = (const argument_wrapper &);
  

[PATCH v2 02/21] libcc1: use "override"

2021-04-27 Thread Tom Tromey
This changes libcc1 to use "override" where appropriate.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1.cc (class compiler_triplet_regexp)
(class compiler_driver_filename, class libcp1_connection): Use
"override".
* libcc1.cc (class compiler_triplet_regexp)
(class compiler_driver_filename, class libcc1_connection): Use
"override".
---
 libcc1/ChangeLog | 9 +
 libcc1/libcc1.cc | 6 +++---
 libcc1/libcp1.cc | 6 +++---
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index 68d366a72871..2c08dabb1a49 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -93,7 +93,7 @@ struct libcc1 : public gcc_c_context
   private:
 std::string triplet_regexp_;
   public:
-virtual char *find (std::string ) const;
+char *find (std::string ) const override;
 compiler_triplet_regexp (libcc1 *self, std::string triplet_regexp)
   : compiler (self), triplet_regexp_ (triplet_regexp)
 {
@@ -109,7 +109,7 @@ struct libcc1 : public gcc_c_context
   private:
 std::string driver_filename_;
   public:
-virtual char *find (std::string ) const;
+char *find (std::string ) const override;
 compiler_driver_filename (libcc1 *self, std::string driver_filename)
   : compiler (self), driver_filename_ (driver_filename)
 {
@@ -132,7 +132,7 @@ public:
   {
   }
 
-  virtual void print (const char *buf)
+  void print (const char *buf) override
   {
 back_ptr->print (buf);
   }
diff --git a/libcc1/libcp1.cc b/libcc1/libcp1.cc
index 34d89579c31c..fb91125ef0cf 100644
--- a/libcc1/libcp1.cc
+++ b/libcc1/libcp1.cc
@@ -94,7 +94,7 @@ struct libcp1 : public gcc_cp_context
   private:
 std::string triplet_regexp_;
   public:
-virtual char *find (std::string ) const;
+char *find (std::string ) const override;
 compiler_triplet_regexp (libcp1 *self, std::string triplet_regexp)
   : compiler (self), triplet_regexp_ (triplet_regexp)
 {
@@ -110,7 +110,7 @@ struct libcp1 : public gcc_cp_context
   private:
 std::string driver_filename_;
   public:
-virtual char *find (std::string ) const;
+char *find (std::string ) const override;
 compiler_driver_filename (libcp1 *self, std::string driver_filename)
   : compiler (self), driver_filename_ (driver_filename)
 {
@@ -133,7 +133,7 @@ public:
   {
   }
 
-  virtual void print (const char *buf)
+  void print (const char *buf) override
   {
 back_ptr->print (buf);
   }
-- 
2.26.2



[PATCH v2 03/21] libcc1: inline some simple methods

2021-04-27 Thread Tom Tromey
This changes libcc1 to inline a trivial method and to use the default
constructor.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* connection.hh (~connection): Use default.
(print): Inline.
* connection.cc (cc1_plugin::connection::~connection)
(cc1_plugin::connection::print): Remove definitions.
---
 libcc1/ChangeLog | 7 +++
 libcc1/connection.cc | 9 -
 libcc1/connection.hh | 6 --
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/libcc1/connection.cc b/libcc1/connection.cc
index 64a6d4922c15..66d573911080 100644
--- a/libcc1/connection.cc
+++ b/libcc1/connection.cc
@@ -27,15 +27,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "connection.hh"
 #include "rpc.hh"
 
-cc1_plugin::connection::~connection ()
-{
-}
-
-void
-cc1_plugin::connection::print (const char *)
-{
-}
-
 cc1_plugin::status
 cc1_plugin::connection::send (char c)
 {
diff --git a/libcc1/connection.hh b/libcc1/connection.hh
index 50e8a8b5a032..a0e99bdbd98f 100644
--- a/libcc1/connection.hh
+++ b/libcc1/connection.hh
@@ -46,7 +46,7 @@ namespace cc1_plugin
 {
 }
 
-virtual ~connection ();
+virtual ~connection () = default;
 
 // Send a single character.  This is used to introduce various
 // higher-level protocol elements.
@@ -89,7 +89,9 @@ namespace cc1_plugin
   m_callbacks.add_callback (name, func);
 }
 
-virtual void print (const char *);
+virtual void print (const char *)
+{
+}
 
   private:
 
-- 
2.26.2



[PATCH v2 01/21] libcc1: use templates to unmarshall enums

2021-04-27 Thread Tom Tromey
Now that C++11 can be used in GCC, libcc1 can be changed to use
templates and type traits to handle unmarshalling all kinds of enums.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* marshall.hh (cc1_plugin::unmarshall): Use type traits.
* marshall-cp.hh (cc1_plugin::unmarshall): Remove overloads.
* marshall-c.hh: Remove.
* libcc1plugin.cc: Update includes.
* libcc1.cc: Update includes.
---
 libcc1/ChangeLog   |  8 ++
 libcc1/libcc1.cc   |  3 ++-
 libcc1/libcc1plugin.cc |  3 ++-
 libcc1/marshall-c.hh   | 59 --
 libcc1/marshall-cp.hh  | 40 
 libcc1/marshall.hh | 26 +++
 6 files changed, 33 insertions(+), 106 deletions(-)
 delete mode 100644 libcc1/marshall-c.hh

diff --git a/libcc1/libcc1.cc b/libcc1/libcc1.cc
index e4c200c8abd5..68d366a72871 100644
--- a/libcc1/libcc1.cc
+++ b/libcc1/libcc1.cc
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include 
 #include 
 #include 
-#include "marshall-c.hh"
+#include "marshall.hh"
 #include "rpc.hh"
 #include "connection.hh"
 #include "names.hh"
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "findcomp.hh"
 #include "compiler-name.hh"
 #include "intl.h"
+#include "gcc-c-interface.h"
 
 struct libcc1;
 
diff --git a/libcc1/libcc1plugin.cc b/libcc1/libcc1plugin.cc
index e80ecd8f4b35..59e4851064a2 100644
--- a/libcc1/libcc1plugin.cc
+++ b/libcc1/libcc1plugin.cc
@@ -63,8 +63,9 @@
 
 #include "callbacks.hh"
 #include "connection.hh"
-#include "marshall-c.hh"
+#include "marshall.hh"
 #include "rpc.hh"
+#include "gcc-c-interface.h"
 
 #ifdef __GNUC__
 #pragma GCC visibility push(default)
diff --git a/libcc1/marshall-c.hh b/libcc1/marshall-c.hh
deleted file mode 100644
index 212603ebb819..
--- a/libcc1/marshall-c.hh
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Marshalling and unmarshalling of C-specific types.
-   Copyright (C) 2014-2021 Free Software Foundation, Inc.
-
-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
-.  */
-
-#ifndef CC1_PLUGIN_MARSHALL_C_HH
-#define CC1_PLUGIN_MARSHALL_C_HH
-
-#include "marshall.hh"
-#include "gcc-c-interface.h"
-
-namespace cc1_plugin
-{
-  status
-  unmarshall (connection *conn, enum gcc_c_symbol_kind *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, ))
-  return FAIL;
-*result = (enum gcc_c_symbol_kind) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_c_oracle_request *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, ))
-  return FAIL;
-*result = (enum gcc_c_oracle_request) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_qualifiers *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, ))
-  return FAIL;
-*result = (enum gcc_qualifiers) p;
-return OK;
-  }
-}
-
-#endif // CC1_PLUGIN_MARSHALL_C_HH
diff --git a/libcc1/marshall-cp.hh b/libcc1/marshall-cp.hh
index ff80bfe41870..3d6ae4126aee 100644
--- a/libcc1/marshall-cp.hh
+++ b/libcc1/marshall-cp.hh
@@ -25,46 +25,6 @@ along with GCC; see the file COPYING3.  If not see
 
 namespace cc1_plugin
 {
-  status
-  unmarshall (connection *conn, enum gcc_cp_symbol_kind *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, ))
-  return FAIL;
-*result = (enum gcc_cp_symbol_kind) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_cp_oracle_request *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, ))
-  return FAIL;
-*result = (enum gcc_cp_oracle_request) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_cp_qualifiers *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, ))
-  return FAIL;
-*result = (enum gcc_cp_qualifiers) p;
-return OK;
-  }
-
-  status
-  unmarshall (connection *conn, enum gcc_cp_ref_qualifiers *result)
-  {
-protocol_int p;
-if (!unmarshall_intlike (conn, ))
-  return FAIL;
-*result = (enum gcc_cp_ref_qualifiers) p;
-return OK;
-  }
-
   // Send a gcc_vbase_array marker followed by the array.
   status
   marshall (connection *conn, const gcc_vbase_array *a)
diff --git a/libcc1/marshall.hh b/libcc1/marshall.hh
index 6999c4ff8fd1..8d890eb9b6c7 100644
--- a/libcc1/marshall.hh
+++ b/libcc1/marshall.hh
@@ -20,6 +20,8 @@ 

[PATCH v2 00/21] C++11-based improvements for libcc1

2021-04-27 Thread Tom Tromey
Here is v2 of my series to simplify libcc1 through the use of C++11
constructs.

v1 is here:

https://gcc.gnu.org/pipermail/gcc-patches/2021-January/562668.html

I never pinged it because I'd sent it in the wrong stage.

As with v1, this brings libcc1 much closer to how I originally wanted
it to work.  Back then, C++11 couldn't be used, so some things had to
be written in a verbose way.  C++11 brings variadic templates, which
make it possible to simplify this code.

This version of the series brings more improvements.

The plugin for the C++ compiler was apparently written by copying much
of the C compiler code.  However, the original design was to unify
these, and this series eliminates much of the duplication.

This version also removes some manual memory management; typically in
favor of either unique_ptr or vector, but also via custom 'deleter'
classes for the rpc code.

Finally, a couple of minor bugs are fixed along the way.

I built and tested this against git GDB on x86-64 Fedora 32.

Note that the C++ plugin currently does not for git GCC -- it crashes.
This series doesn't make it worse (it may slightly change the reported
failures), but nor does it improve it.

Tom




Re: [PATCH 1/5 ver4] RS6000: Add 128-bit Integer Operations

2021-04-27 Thread will schmidt via Gcc-patches
On Mon, 2021-04-26 at 09:35 -0700, Carl Love wrote:
> Will, Segher:
> 
> This patch fixes the order of the argument in the vec_rlmi and
> vec_rlnm builtins.  The patch also adds a new test cases to verify
> the fix.
> 
> The patch has been tested on
> powerpc64-linux instead (Power 8 BE)
> powerpc64-linux instead (Power 9 LE)
> powerpc64-linux instead (Power 10 LE)
> 
> Please let me know if the patch is acceptable for mainline.
> 
>Carl Love

Hi,

Is there an existing PR for this one? 

The subject line does not reflect this patch.
subject: Re: [PATCH 1/5 ver4] RS6000: Add 128-bit Integer Operations


> 
> 
> 
> 2021-04-26  Carl Love  
> 
> gcc/
>   * config/rs6000/altivec.md (altivec_vrlmi): Fix
>   bug in argument generation.
> 
> gcc/testsuite/
>   gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c:
>   New runnable test case.
>   gcc.target/powerpc/vec-rlmi-rlnm.c: Update scan assembler times
>   for xxlor instruction.

Need leading "*" on the file names above.


> ---
>  gcc/config/rs6000/altivec.md  |   6 +-
>  .../powerpc/check-builtin-vec_rlnm-runnable.c | 231 ++
>  .../gcc.target/powerpc/vec-rlmi-rlnm.c|   2 +-
>  3 files changed, 235 insertions(+), 4 deletions(-)
>  create mode 100644 
> gcc/testsuite/gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c
> 
> diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
> index 1351dafbc41..97dc9d2bda9 100644
> --- a/gcc/config/rs6000/altivec.md
> +++ b/gcc/config/rs6000/altivec.md
> @@ -1987,12 +1987,12 @@
> 
>  (define_insn "altivec_vrlmi"
>[(set (match_operand:VIlong 0 "register_operand" "=v")
> -(unspec:VIlong [(match_operand:VIlong 1 "register_operand" "0")
> - (match_operand:VIlong 2 "register_operand" "v")
> +(unspec:VIlong [(match_operand:VIlong 1 "register_operand" "v")
> + (match_operand:VIlong 2 "register_operand" "0")
>   (match_operand:VIlong 3 "register_operand" "v")]
>  UNSPEC_VRLMI))]
>"TARGET_P9_VECTOR"
> -  "vrlmi %0,%2,%3"
> +  "vrlmi %0,%1,%3"
>[(set_attr "type" "veclogical")])

ok

> 
>  (define_insn "altivec_vrlnm"
> diff --git 
> a/gcc/testsuite/gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c 
> b/gcc/testsuite/gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c
> new file mode 100644
> index 000..be8f82d8a06
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/check-builtin-vec_rlnm-runnable.c
> @@ -0,0 +1,231 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target powerpc_p9vector_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power9 -save-temps" } */
> +
> +/* Verify the vec_rlm and vec_rlmi builtins works correctly.  */
> +/* { dg-final { scan-assembler-times {\mvrldmi\M} 1 } } */
> +
> +#include 
> +
> +#ifdef DEBUG
> +#include 
> +#include 
> +#endif
> +
> +void abort (void);
> +
> +int main ()
> +{
> +  int i;
> +
> +  vector unsigned int vec_arg1_int, vec_arg2_int, vec_arg3_int;
> +  vector unsigned int vec_result_int, vec_expected_result_int;
> +  
> +  vector unsigned long long int vec_arg1_di, vec_arg2_di, vec_arg3_di;
> +  vector unsigned long long int vec_result_di, vec_expected_result_di;
> +
> +  unsigned int mask_begin, mask_end, shift;
> +  unsigned long long int mask;
> +
> +/* Check vec int version of vec_rlmi builtin */
> +  mask = 0;
> +  mask_begin = 0;
> +  mask_end   = 4;
> +  shift = 16;
> +
> +  for (i = 0; i < 31; i++)
> +if ((i >= mask_begin) && (i <= mask_end))
> +  mask |= 0x8000ULL >> i;
> +
> +  for (i = 0; i < 4; i++) {
> +vec_arg1_int[i] = 0x12345678 + i*0x;
> +vec_arg2_int[i] = 0xA1B1CDEF;
> +vec_arg3_int[i] = mask_begin << 16 | mask_end << 8 | shift;
> +
> +/* do rotate */
> +vec_expected_result_int[i] =  ( vec_arg2_int[i] & ~mask) 
> +  | ((vec_arg1_int[i] << shift) | (vec_arg1_int[i] >> (32-shift))) & 
> mask;
> +  
> +  }
> +
> +  /* vec_rlmi(arg1, arg2, arg3)
> + result - rotate each element of arg2 left and inserting it into arg1 
> +   element based on the mask specified in arg3.  The shift, mask
> +   start and end is specified in arg3.  */
> +  vec_result_int = vec_rlmi (vec_arg1_int, vec_arg2_int, vec_arg3_int);

s/inserting /inserts /


> +
> +  for (i = 0; i < 4; i++) {
> +if (vec_result_int[i] != vec_expected_result_int[i])
> +#ifdef DEBUG
> +  printf("ERROR: i = %d, vec_rlmi int result 0x%x, does not match "
> +  "expected result 0x%x\n", i, vec_result_int[i],
> +  vec_expected_result_int[i]);
> +#else
> +  abort();
> +#endif
> +}
> +
> +/* Check vec long long int version of vec_rlmi builtin */
> +  mask = 0;
> +  mask_begin = 0;
> +  mask_end   = 4;
> +  shift = 16;
> +
> +  for (i = 0; i < 31; i++)
> +if ((i >= mask_begin) && (i <= mask_end))
> +  mask |= 0x8000ULL >> 

Re: [PATCH 3/5 ver4] RS6000: Add TI to TD (128-bit DFP) and TD to TI support

2021-04-27 Thread will schmidt via Gcc-patches
On Mon, 2021-04-26 at 09:36 -0700, Carl Love wrote:
> Will, Segher:
> 


Hi,


> This patch adds support for converting to/from 128-bit integers and
> 128-bit decimal floating point formats.


You reference TI,TD in the subject, would be helpful to elaborate a bit in your 
description.


> 
> The patch has been tested on
> powerpc64-linux instead (Power 8 BE)
> powerpc64-linux instead (Power 9 LE)
> powerpc64-linux instead (Power 10 LE)
> 
> Please let me know if the patch is acceptable for mainline.
> 
>Carl Love
> 
> 
> gcc/ChangeLog
> dje@gmail.com, gcc-patches@gcc.gnu.org, Bill Schmidt 
> , Peter Bergner ,  
> 2021-04-26  Carl Love  


Something there seems wrong.

> * config/rs6000/dfp.md (floattitd2, fixtdti2): New define_insns.


> * config/rs6000/rs6000-call.c (P10V_BUILTIN_VCMPNET_P,
>   P10V_BUILTIN_VCMPAET_P): New overloaded definitions.

I don't see this below.

> 
> gcc/testsuite/ChangeLog
> 
> 2021-04-26  Carl Love  
> * gcc.target/powerpc/int_128bit-runnable.c: Add 128-bit DFP
> conversion tests.

ok

> ---
>  gcc/config/rs6000/dfp.md  | 14 +
>  .../gcc.target/powerpc/int_128bit-runnable.c  | 61 

> +++
>  2 files changed, 75 insertions(+)
> 
> diff --git a/gcc/config/rs6000/dfp.md b/gcc/config/rs6000/dfp.md
> index 026be5d48a6..b89d5ecc91d 100644
> --- a/gcc/config/rs6000/dfp.md
> +++ b/gcc/config/rs6000/dfp.md
> @@ -226,6 +226,13 @@
>[(set_attr "type" "dfp")
> (set_attr "size" "128")])
> 
> +(define_insn "floattitd2"
> +  [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
> + (float:TD (match_operand:TI 1 "gpc_reg_operand" "v")))]
> +  "TARGET_POWER10"
> +  "dcffixqq %0,%1"
> +  [(set_attr "type" "dfp")])
> +
>  ;; Convert a decimal64/128 to a decimal64/128 whose value is an integer.
>  ;; This is the first stage of converting it to an integer type.
> 
> @@ -247,6 +254,13 @@
>"dctfix %0,%1"
>[(set_attr "type" "dfp")
> (set_attr "size" "")])
> +
> +(define_insn "fixtdti2"
> +  [(set (match_operand:TI 0 "gpc_reg_operand" "=v")
> + (fix:TI (match_operand:TD 1 "gpc_reg_operand" "d")))]
> +  "TARGET_POWER10"
> +  "dctfixqq %0,%1"
> +  [(set_attr "type" "dfp")])

ok


>  
>  ;; Decimal builtin support
> 
> diff --git a/gcc/testsuite/gcc.target/powerpc/int_128bit-runnable.c 
> b/gcc/testsuite/gcc.target/powerpc/int_128bit-runnable.c
> index 042758c8684..625b3869118 100644
> --- a/gcc/testsuite/gcc.target/powerpc/int_128bit-runnable.c
> +++ b/gcc/testsuite/gcc.target/powerpc/int_128bit-runnable.c
> @@ -37,6 +37,7 @@
>  #if DEBUG
>  #include 
>  #include 
> +#include 
> 
> 
>  void print_i128(__int128_t val)
> @@ -58,6 +59,13 @@ int main ()
>__int128_t arg1, result;
>__uint128_t uarg2;
> 
> +  _Decimal128 arg1_dfp128, result_dfp128, expected_result_dfp128;
> +
> +  struct conv_t {
> +__uint128_t u128;
> +_Decimal128 d128;
> +  } conv, conv2;
> +
>vector signed long long int vec_arg1_di, vec_arg2_di;
>vector signed long long int vec_result_di, vec_expected_result_di;
>vector unsigned long long int vec_uarg1_di, vec_uarg2_di, vec_uarg3_di;
> @@ -2258,6 +2266,59 @@ int main ()
>  abort();
>  #endif
>}
> +  
> +  /* DFP to __int128 and __int128 to DFP conversions */
> +  /* Print the DFP value as an unsigned int so we can see the bit patterns.  
> */
> +  conv.u128 = 0x2208ULL;
> +  conv.u128 = (conv.u128 << 64) | 0x4ULL;   //DFP bit pattern for integer 4
> +  expected_result_dfp128 = conv.d128;
> 
> +  arg1 = 4;
> +
> +  conv.d128 = (_Decimal128) arg1;
> +
> +  result_dfp128 = (_Decimal128) arg1;
> +  if (((conv.u128 >>64) != 0x2208ULL) &&
> +  ((conv.u128 & 0x) != 0x4ULL)) {
> +#if DEBUG
> +printf("ERROR:  convert int128 value ");
> +print_i128 (arg1);
> +conv.d128 = result_dfp128;
> +printf("\nto DFP value 0x%llx %llx (printed as hex bit string) ",
> +(unsigned long long)((conv.u128) >>64),
> +(unsigned long long)((conv.u128) & 0x));
> +
> +conv.d128 = expected_result_dfp128;
> +printf("\ndoes not match expected_result = 0x%llx %llx\n\n",
> +(unsigned long long) (conv.u128>>64),
> +(unsigned long long) (conv.u128 & 0x));
> +#else

> +abort();
> +#endif
> +  }
> +
> +  expected_result = 4;
> +
> +  conv.u128 = 0x2208ULL;
> +  conv.u128 = (conv.u128 << 64) | 0x4ULL;  // 4 as DFP
> +  arg1_dfp128 = conv.d128;
> +
> +  result = (__int128_t) arg1_dfp128;
> +
> +  if (result != expected_result) {
> +#if DEBUG
> +printf("ERROR:  convert DFP value ");
> +printf("0x%llx %llx (printed as hex bit string) ",
> +(unsigned long long)(conv.u128>>64),
> +(unsigned long long)(conv.u128 & 0x));
> +printf("to __int128 value = ");
> +print_i128 (result);
> +printf("\ndoes not match expected_result = ");

Re: [PATCH 4/5 ver4] RS6000, Add test 128-bit shifts for just the int128 type.

2021-04-27 Thread will schmidt via Gcc-patches
On Mon, 2021-04-26 at 09:36 -0700, Carl Love wrote:
> Will, Segher:
> 
> The previous patch added the vector 128-bit integer shift instruction
> support for the V1TI type.  This patch renames and moves the VSX_TI
> iterator from vsx.md to VEC_TI in vector.md.  The uses of VEC_TI are
> also updated.
> 
> The patch has been tested on
> powerpc64-linux instead (Power 8 BE)
> powerpc64-linux instead (Power 9 LE)
> powerpc64-linux instead (Power 10 LE)
> 
> Please let me know if the patch is acceptable for mainline.
> 
>Carl Love
> 
> 
> gcc/ChangeLog
> 
> 2021-04-26  Carl Love  
>   * config/rs6000/altivec.md (altivec_vslq, altivec_vsrq):
>   Rename to altivec_vslq_, altivec_vsrq_, mode VEC_TI.
>   * config/rs6000/vector.md (VEC_TI): Was named VSX_TI in vsx.md.
>   (vashlv1ti3): Change to vashl3, mode VEC_TI.
>   (vlshrv1ti3): Change to vlshr3, mode VEC_TI.
>   * config/rs6000/vsx.md (VSX_TI): Remove define_mode_iterator. Update
>   uses of VSX_TI to VEC_TI.
> 
> gcc/testsuite/ChangeLog
> 
> 2021-04-26  Carl Love  
>   gcc.target/powerpc/int_128bit-runnable.c: Add shift_right, shift_left
>   tests.
> ---
>  gcc/config/rs6000/altivec.md  | 16 -
>  gcc/config/rs6000/vector.md   | 27 ---
>  gcc/config/rs6000/vsx.md  | 33 +--
>  .../gcc.target/powerpc/int_128bit-runnable.c  | 16 +++--
>  4 files changed, 52 insertions(+), 40 deletions(-)
> 
> diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
> index c4c82b33f8d..c7d2cd0aa88 100644
> --- a/gcc/config/rs6000/altivec.md
> +++ b/gcc/config/rs6000/altivec.md
> @@ -2226,10 +2226,10 @@
>"vsl %0,%1,%2"
>[(set_attr "type" "vecsimple")])
> 
> -(define_insn "altivec_vslq"
> -  [(set (match_operand:V1TI 0 "vsx_register_operand" "=v")
> - (ashift:V1TI (match_operand:V1TI 1 "vsx_register_operand" "v")
> -  (match_operand:V1TI 2 "vsx_register_operand" "v")))]
> +(define_insn "altivec_vslq_"
> +  [(set (match_operand:VEC_TI 0 "vsx_register_operand" "=v")
> + (ashift:VEC_TI (match_operand:VEC_TI 1 "vsx_register_operand" "v")
> +  (match_operand:VEC_TI 2 "vsx_register_operand" "v")))]
>"TARGET_POWER10"
>/* Shift amount in needs to be in bits[57:63] of 128-bit operand. */
>"vslq %0,%1,%2"
> @@ -2243,10 +2243,10 @@
>"vsr %0,%1,%2"
>[(set_attr "type" "vecsimple")])
> 
> -(define_insn "altivec_vsrq"
> -  [(set (match_operand:V1TI 0 "vsx_register_operand" "=v")
> - (lshiftrt:V1TI (match_operand:V1TI 1 "vsx_register_operand" "v")
> -(match_operand:V1TI 2 "vsx_register_operand" "v")))]
> +(define_insn "altivec_vsrq_"
> +  [(set (match_operand:VEC_TI 0 "vsx_register_operand" "=v")
> + (lshiftrt:VEC_TI (match_operand:VEC_TI 1 "vsx_register_operand" "v")
> +(match_operand:VEC_TI 2 "vsx_register_operand" 
> "v")))]
>"TARGET_POWER10"
>/* Shift amount in needs to be in bits[57:63] of 128-bit operand. */
>"vsrq %0,%1,%2"

ok

> diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
> index 55bbaa9c32f..5695154e316 100644
> --- a/gcc/config/rs6000/vector.md
> +++ b/gcc/config/rs6000/vector.md
> @@ -26,6 +26,9 @@
>  ;; Vector int modes
>  (define_mode_iterator VEC_I [V16QI V8HI V4SI V2DI])
> 
> +;; 128-bit int modes
> +(define_mode_iterator VEC_TI [V1TI TI])
> +
>  ;; Vector int modes for parity
>  (define_mode_iterator VEC_IP [V8HI
> V4SI
> @@ -1627,17 +1630,17 @@
>"")
> 
>  ;; No immediate version of this 128-bit instruction
> -(define_expand "vashlv1ti3"
> -  [(set (match_operand:V1TI 0 "vsx_register_operand" "=v")
> - (ashift:V1TI (match_operand:V1TI 1 "vsx_register_operand" "v")
> -  (match_operand:V1TI 2 "vsx_register_operand" "v")))]
> +(define_expand "vashl3"
> +  [(set (match_operand:VEC_TI 0 "vsx_register_operand" "=v")
> + (ashift:VEC_TI (match_operand:VEC_TI 1 "vsx_register_operand")
> +  (match_operand:VEC_TI 2 "vsx_register_operand")))]
>"TARGET_POWER10"
>  {
>/* Shift amount in needs to be put in bits[57:63] of 128-bit operand2. */
> -  rtx tmp = gen_reg_rtx (V1TImode);
> +  rtx tmp = gen_reg_rtx (mode);
> 
>emit_insn (gen_xxswapd_v1ti (tmp, operands[2]));
> -  emit_insn (gen_altivec_vslq (operands[0], operands[1], tmp));
> +  emit_insn(gen_altivec_vslq_ (operands[0], operands[1], tmp));
>DONE;
>  })
> 
> @@ -1650,17 +1653,17 @@
>"")
> 
>  ;; No immediate version of this 128-bit instruction
> -(define_expand "vlshrv1ti3"
> -  [(set (match_operand:V1TI 0 "vsx_register_operand" "=v")
> - (lshiftrt:V1TI (match_operand:V1TI 1 "vsx_register_operand" "v")
> -(match_operand:V1TI 2 "vsx_register_operand" "v")))]
> +(define_expand "vlshr3"
> +  [(set (match_operand:VEC_TI 0 "vsx_register_operand" 

Re: [PATCH 2/5 ver4] RS6000: Add 128-bit Integer Operations

2021-04-27 Thread will schmidt via Gcc-patches
On Mon, 2021-04-26 at 09:36 -0700, Carl Love wrote:
> Will, Segher:
> 
> This patch adds the 128-bit integer support for divide, modulo, shift,
> compare of 128-bit integers instructions and builtin support.

Hi,

> 
> The patch has been tested on
> powerpc64-linux instead (Power 8 BE)
> powerpc64-linux instead (Power 9 LE)
> powerpc64-linux instead (Power 10 LE)
> 
> Please let me know if the patch is acceptable for mainline.
> 
>Carl Love
> 
> ---
> 
> gcc/ChangeLog
> 
> 2021-04-26  Carl Love  
>   * config/rs6000/altivec.h (vec_dive, vec_mod): Add define for new
>   builtins.
>   * config/rs6000/altivec.md (UNSPEC_VMULEUD, UNSPEC_VMULESD,
>   UNSPEC_VMULOUD, UNSPEC_VMULOSD): New unspecs.
>   (altivec_eqv1ti, altivec_gtv1ti, altivec_gtuv1ti, altivec_vmuleud,
>   altivec_vmuloud, altivec_vmulesd, altivec_vmulosd, altivec_vrlq,
>   altivec_vrlqmi, altivec_vrlqmi_inst, altivec_vrlqnm,
>   altivec_vrlqnm_inst, altivec_vslq, altivec_vsrq, altivec_vsraq,
>   altivec_vcmpequt_p, altivec_vcmpgtst_p, altivec_vcmpgtut_p): New
>   define_insn.
>   (vec_widen_umult_even_v2di, vec_widen_smult_even_v2di,
>   vec_widen_umult_odd_v2di, vec_widen_smult_odd_v2di, altivec_vrlqmi,
>   altivec_vrlqnm): New define_expands.
>   * config/rs6000/rs6000-builtin.def (VCMPEQUT_P, VCMPGTST_P,
>   VCMPGTUT_P): Add macro expansions.
>   (BU_P10V_AV_P): Add builtin predicate definition.
>   (VCMPGTUT, VCMPGTST, VCMPEQUT, CMPNET, CMPGE_1TI,
>   CMPGE_U1TI, CMPLE_1TI, CMPLE_U1TI, VNOR_V1TI_UNS, VNOR_V1TI, VCMPNET_P,
>   VCMPAET_P, VMULEUD, VMULESD, VMULOUD, VMULOSD, VRLQ,
>   VSLQ, VSRQ, VSRAQ, VRLQNM, DIV_V1TI, UDIV_V1TI, DIVES_V1TI, DIVEU_V1TI,
>   MODS_V1TI, MODU_V1TI, VRLQMI): New macro expansions.
>   (VRLQ, VSLQ, VSRQ, VSRAQ, DIVE, MOD): New overload expansions.
>   * config/rs6000/rs6000-call.c (P10_BUILTIN_VCMPEQUT,
>   P10V_BUILTIN_CMPGE_1TI, P10V_BUILTIN_CMPGE_U1TI,
>   P10V_BUILTIN_VCMPGTUT, P10V_BUILTIN_VCMPGTST,
>   P10V_BUILTIN_CMPLE_1TI, P10V_BUILTIN_VCMPLE_U1TI,
>   P10V_BUILTIN_DIV_V1TI, P10V_BUILTIN_UDIV_V1TI,
>   P10V_BUILTIN_VMULESD, P10V_BUILTIN_VMULEUD,
>   P10V_BUILTIN_VMULOSD, P10V_BUILTIN_VMULOUD,
>   P10V_BUILTIN_VNOR_V1TI, P10V_BUILTIN_VNOR_V1TI_UNS,
>   P10V_BUILTIN_VRLQ, P10V_BUILTIN_VRLQMI,
>   P10V_BUILTIN_VRLQNM, P10V_BUILTIN_VSLQ,
>   P10V_BUILTIN_VSRQ, P10V_BUILTIN_VSRAQ,
>   P10V_BUILTIN_VCMPGTUT_P, P10V_BUILTIN_VCMPGTST_P,
>   P10V_BUILTIN_VCMPEQUT_P, P10V_BUILTIN_VCMPGTUT_P,
>   P10V_BUILTIN_VCMPGTST_P, P10V_BUILTIN_CMPNET,
>   P10V_BUILTIN_VCMPNET_P, P10V_BUILTIN_VCMPAET_P,
>   P10V_BUILTIN_DIVES_V1TI, P10V_BUILTIN_MODS_V1TI,
>   P10V_BUILTIN_MODU_V1TI):
>   New overloaded definitions.
>   (rs6000_gimple_fold_builtin) [P10V_BUILTIN_VCMPEQUT,
>   P10_BUILTIN_CMPNET, P10_BUILTIN_CMPGE_1TI,
>   P10_BUILTIN_CMPGE_U1TI, P10_BUILTIN_VCMPGTUT,
>   P10_BUILTIN_VCMPGTST, P10_BUILTIN_CMPLE_1TI,
>   P10_BUILTIN_CMPLE_U1TI]: New case statements.

No signs of P10_BUILTIN_CMPNET below.  possibly P10V_BUILTIN_CMPNET?  
S
ame through at least P10_BUILTIN_CMPLE_U1TI.


>   (rs6000_init_builtins) [bool_V1TI_type_node, int_ftype_int_v1ti_v1ti]:
>   New assignments.
>   (altivec_init_builtins): New E_V1TImode case statement.
>   (builtin_function_type)[P10_BUILTIN_128BIT_VMULEUD,
>   P10_BUILTIN_128BIT_VMULOUD, P10_BUILTIN_128BIT_DIVEU_V1TI,
>   P10_BUILTIN_128BIT_MODU_V1TI, P10_BUILTIN_CMPGE_U1TI,
>   P10_BUILTIN_VCMPGTUT, P10_BUILTIN_VCMPEQUT]: New case statements.
>   * config/rs6000/r6000.c (rs6000_handle_altivec_attribute)[E_TImode,
>   E_V1TImode]: New case statements.
>   * config/rs6000/r6000.h (rs6000_builtin_type_index): New enum
>   value RS6000_BTI_bool_V1TI.
>   * config/rs6000/vector.md (vector_gtv1ti,vector_nltv1ti,
>   vector_gtuv1ti, vector_nltuv1ti, vector_ngtv1ti, vector_ngtuv1ti,
>   vector_eq_v1ti_p, vector_ne_v1ti_p, vector_ae_v1ti_p,
>   vector_gt_v1ti_p, vector_gtu_v1ti_p, vrotlv1ti3, vashlv1ti3,
>   vlshrv1ti3, vashrv1ti3): New define_expands.
>   * config/rs6000/vsx.md (UNSPEC_VSX_DIVSQ, UNSPEC_VSX_DIVUQ,
>   UNSPEC_VSX_DIVESQ, UNSPEC_VSX_DIVEUQ, UNSPEC_VSX_MODSQ,
>   UNSPEC_VSX_MODUQ): New unspecs.
>   (mulv2di3, vsx_div_v1ti, vsx_udiv_v1ti, vsx_dives_v1ti,
>   vsx_diveu_v1ti, vsx_mods_v1ti, vsx_modu_v1ti, xxswapd_v1ti): New
>   define_insns.
>   (vcmpnet): New define_expand.
>   * gcc/doc/extend.texi: Add documentation for the new builtins vec_rl,
>   vec_rlmi, vec_rlnm, vec_sl, vec_sr, vec_sra, vec_mule, vec_mulo,
>   vec_div, vec_dive, vec_mod, vec_cmpeq, vec_cmpne, vec_cmpgt, vec_cmplt,
>   vec_cmpge, vec_cmple, vec_all_eq, vec_all_ne, vec_all_gt, vec_all_lt,
>   vec_all_ge, vec_all_le, vec_any_eq, vec_any_ne, 

Re: [PATCH 5/5 ver4] RS6000: Conversions between 128-bit integer and floating point values.

2021-04-27 Thread will schmidt via Gcc-patches
On Mon, 2021-04-26 at 09:36 -0700, Carl Love wrote:
> Will, Segher:
> 
> This patch adds support for converting to/from 128-bit integers and
> 128-bit decimal floating point formats using the new P10 instructions
> dcffixqq and dctfixqq.  The new instructions are only used on P10 HW,
> otherwise the conversions continue to use the existing SW routines.
> 
> The files fixkfti-sw.c and fixunskfti-sw.c are renamed versions of
> fixkfti.c and fixunskfti.c respectively.  The function names in the
> files were updated with the rename as well as some white spaces fixes.
> 
> The patch has been tested on
> powerpc64-linux instead (Power 8 BE)
> powerpc64-linux instead (Power 9 LE)
> powerpc64-linux instead (Power 10 LE)
> 
> Please let me know if the patch is acceptable for mainline.
> 
>Carl Love
> 
> 
> gcc/ChangeLog
> 
> 2021-04-26  Carl Love  
>   * config/rs6000/rs6000.md (floatti2, floatunsti2,
>   fix_truncti2, fixuns_truncti2): Add
>   define_insn for mode IEEE 128.
> 
> gcc/testsuite/ChangeLog
> 
> 2021-04-26  Carl Love  
>   * gcc.target/powerpc/fp128_conversions.c: New file.
>   * gcc.target/powerpc/int_128bit-runnable.c(vextsd2ppc_native_128bitq,

^ vextsd2ppc_native_128bitq ?   

>   vcmpuq, vcmpsq, vcmpequq, vcmpequq., vcmpgtsq, vcmpgtsq.
>   vcmpgtuq, vcmpgtuq.): Update scan-assembler-times.

>   (ppc_native_128bit): Remove dg-require-effective-target.
> 
> libgcc/ChangeLog
> 2021-04-26  Carl Love  
>   * config.host: Add if test and set for
>   libgcc_cv_powerpc_3_1_float128_hw.
>   * libgcc/config/rs6000/fixkfti.c: Renamed to fixkfti-sw.c.
>   Change calls of __fixkfti to __fixkfti_sw.
>   * libgcc/config/rs6000/fixunskfti.c: Renamed to fixunskfti-sw.c.
>   Change calls of __fixunskfti to __fixunskfti_sw.
>   * libgcc/config/rs6000/float128-p10.c (__floattikf_hw,
>   __floatuntikf_hw, __fixkfti_hw, __fixunskfti_hw): New file.
>   * libgcc/config/rs6000/float128-ifunc.c (SW_OR_HW_ISA3_1): New macro.
>   (__floattikf_resolve, __floatuntikf_resolve, __fixkfti_resolve,
>   __fixunskfti_resolve): Add resolve functions.
>   (__floattikf, __floatuntikf, __fixkfti, __fixunskfti): New functions.
>   * libgcc/config/rs6000/float128-sed (floattitf, __floatuntitf,
>   __fixtfti, __fixunstfti): Add editor commands to change names.
>   * libgcc/config/rs6000/float128-sed-hw (__floattitf,
>   __floatuntitf, __fixtfti, __fixunstfti): Add editor commands to
>   change names.
>   * libgcc/config/rs6000/floattikf.c: Renamed to floattikf-sw.c.
>   * libgcc/config/rs6000/floatuntikf.c: Renamed to floatuntikf-sw.c.
>   * libgcc/config/rs6000/quaad-float128.h (__floattikf_sw,
>   __floatuntikf_sw, __fixkfti_sw, __fixunskfti_sw, __floattikf_hw,
>   __floatuntikf_hw, __fixkfti_hw, __fixunskfti_hw, __floattikf,
>   __floatuntikf, __fixkfti, __fixunskfti): New extern declarations.
>   * libgcc/config/rs6000/t-float128 (floattikf, floatuntikf,
>   fixkfti, fixunskfti): Remove file names from fp128_ppc_funcs.
>   (floattikf-sw, floatuntikf-sw, fixkfti-sw, fixunskfti-sw): Add
>   file names to fp128_ppc_funcs.
>   * libgcc/config/rs6000/t-float128-hw(fp128_3_1_hw_funcs,
>   fp128_3_1_hw_src, fp128_3_1_hw_static_obj, fp128_3_1_hw_shared_obj,
>   fp128_3_1_hw_obj): Add variables for ISA 3.1 support.
>   * libgcc/config/rs6000/t-float128-p10-hw: New file.
>   * configure: Update script for isa 3.1 128-bit float support.
>   * configure.ac: Add check for 128-bit float hardware support.


Ok.

Only skimmed, nothing else jumped out at me from below.

thanks
-Will





Re: [PATCH v11] Practical improvement to libgcc complex divide

2021-04-27 Thread Joseph Myers
This patch version is OK.

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


[PATCH,AIX] Alias -m64 to -maix64 and -m32 to -maix32

2021-04-27 Thread David Edelsohn via Gcc-patches
GCC on AIX historically has used -maix64 and -maix32 to switch to
64 bit mode
or 32 bit mode, unlike other ports that use -m64 and -m32.  The Alias()
directive for options cannot be used because aix64 is expected in multiple
parts of the compiler infrastructure and one cannot switch to -m64 due to
backward compatibility.

This patch defines DRIVER_SELF_SPECS to translate -m64 to -maix64 and
-m32 to -maix32 so that the command line option compatible with other
targets can be used while continuing to allow the historical options.

Bootstrapped on powerpc-ibm-aix7.2.3.0

Thanks, David

gcc/ChangeLog:

* config/rs6000/aix.h (SUBTARGET_DRIVER_SELF_SPECS): New.
* config/rs6000/aix64.opt (m64): New.
(m32): New.

diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h
index b116e1a36bb..662785cc7db 100644
--- a/gcc/config/rs6000/aix.h
+++ b/gcc/config/rs6000/aix.h
@@ -280,3 +280,9 @@
 #define RS6000_USE_DWARF_NUMBERING

 #define TARGET_PRECOMPUTE_TLS_P rs6000_aix_precompute_tls_p
+
+/* Replace -m64 with -maix64 and -m32 with -maix32.  */
+#undef SUBTARGET_DRIVER_SELF_SPECS
+#define SUBTARGET_DRIVER_SELF_SPECS\
+"%{m64:-maix64} %

Re: [PATCH] libstdc++: Fix various bugs in ranges_algo.h [PR100187, ...]

2021-04-27 Thread Jonathan Wakely via Gcc-patches
On Tue, 27 Apr 2021, 21:37 Patrick Palka via Libstdc++, <
libstd...@gcc.gnu.org> wrote:

> This fixes some bugs with our ranges algorithms in uncommon situations,
> such as when the return type of a predicate is a non-copyable class type
> that's implicitly convertible to bool (PR100187), when a comparison
> predicate isn't invocable as an rvalue (PR100237), and when the return
> type of a projection function is non-copyable (PR100249).
>
> This also fixes PR100287, which reports that we're moving __first twice
> when constructing an empty subrange with it in ranges::partition.
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps
> the releases branches?  I wasn't sure if it's worthwhile to include
> tests for these bugs given their relatively obscure nature.
>

OK for trunk.

I think they're also find for the branches, after some time to bake on
trunk. They might be obscure, but the changes are also safe and so there's
little downside to backporting them.




> libstdc++-v3/ChangeLog:
>
> PR libstdc++/100187
> PR libstdc++/100237
> PR libstdc++/100249
> PR libstdc++/100287
> * include/bits/ranges_algo.h (__search_n_fn::operator()): Give
> __value_comp lambda an explicit bool return type.
> (__is_permutation_fn::operator()): Give __proj_scan local
> variable auto&& return type.  Give __comp_scan lambda an
> explicit bool return type.
> (__remove_fn::operator()): Give __pred lambda an explicit
> bool return type.
> (__partition_fn::operator()): Don't std::move __first twice
> when returning an empty range.
> (__min_fn::operator()): Don't std::move __comp.
> (__max_fn::operator()): Likewise.
> (__minmax_fn::operator()): Likewise.
> ---
>  libstdc++-v3/include/bits/ranges_algo.h | 18 +-
>  1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/ranges_algo.h
> b/libstdc++-v3/include/bits/ranges_algo.h
> index 23e6480b9a8..cda3042c11f 100644
> --- a/libstdc++-v3/include/bits/ranges_algo.h
> +++ b/libstdc++-v3/include/bits/ranges_algo.h
> @@ -562,7 +562,7 @@ namespace ranges
> if (__count <= 0)
>   return {__first, __first};
>
> -   auto __value_comp = [&]  (_Rp&& __arg) {
> +   auto __value_comp = [&]  (_Rp&& __arg) -> bool {
> return std::__invoke(__pred, std::forward<_Rp>(__arg),
> __value);
> };
> if (__count == 1)
> @@ -805,8 +805,8 @@ namespace ranges
>
> for (auto __scan = __first1; __scan != __last1; ++__scan)
>   {
> -   auto __proj_scan = std::__invoke(__proj1, *__scan);
> -   auto __comp_scan = [&]  (_Tp&& __arg) {
> +   auto&& __proj_scan = std::__invoke(__proj1, *__scan);
> +   auto __comp_scan = [&]  (_Tp&& __arg) -> bool {
>   return std::__invoke(__pred, __proj_scan,
>std::forward<_Tp>(__arg));
> };
> @@ -1256,7 +1256,7 @@ namespace ranges
>operator()(_Iter __first, _Sent __last,
>  const _Tp& __value, _Proj __proj = {}) const
>{
> -   auto __pred = [&] (auto&& __arg) {
> +   auto __pred = [&] (auto&& __arg) -> bool {
>   return std::forward(__arg) == __value;
> };
> return ranges::remove_if(__first, __last,
> @@ -2537,11 +2537,11 @@ namespace ranges
> else
>   {
> if (__first == __last)
> - return {std::move(__first), std::move(__first)};
> + return {__first, __first};
>
> while (std::__invoke(__pred, std::__invoke(__proj, *__first)))
>   if (++__first == __last)
> -   return {std::move(__first), std::move(__first)};
> +   return {__first, __first};
>
> auto __next = __first;
> while (++__next != __last)
> @@ -3118,7 +3118,7 @@ namespace ranges
>operator()(const _Tp& __a, const _Tp& __b,
>  _Comp __comp = {}, _Proj __proj = {}) const
>{
> -   if (std::__invoke(std::move(__comp),
> +   if (std::__invoke(__comp,
>   std::__invoke(__proj, __b),
>   std::__invoke(__proj, __a)))
>   return __b;
> @@ -3172,7 +3172,7 @@ namespace ranges
>operator()(const _Tp& __a, const _Tp& __b,
>  _Comp __comp = {}, _Proj __proj = {}) const
>{
> -   if (std::__invoke(std::move(__comp),
> +   if (std::__invoke(__comp,
>   std::__invoke(__proj, __a),
>   std::__invoke(__proj, __b)))
>   return __b;
> @@ -3272,7 +3272,7 @@ namespace ranges
>operator()(const _Tp& __a, const _Tp& __b,
>  _Comp __comp = {}, _Proj __proj = {}) const
>{
> -   if (std::__invoke(std::move(__comp),
> +   if (std::__invoke(__comp,
>   

Re: [PATCH] avoid dereferencing a null pointer (PR 100250)

2021-04-27 Thread Jeff Law via Gcc-patches



On 4/26/2021 5:30 PM, Martin Sebor via Gcc-patches wrote:

The VLA bounds that are included by the C front end to attribute
access added to functions with VLA parameters to help detect
redeclaratations of function with "mismatched" VLA bounds are
cleared by the free_lang_data pass before the IL reaches the middle
end.  The clearing was done to fix pr97172 on the basis that
the bounds aren't used by the middle end to trigger any warnings.
While that's true, it turns out that the bounds are sometimes used
when formatting informational notes.  I forgot about that when
implementing the final revision of the patch for pr97172 and
removing the assumptions that the bounds are nonnull.

The attached patch removes the (hopefully last) assumption that
the bounds are nonnull.  I reviewed the code and didn't find any
others.

Bootstrapped & tested on x86_64-linux.

Martin

gcc-100250.diff

PR middle-end/100250 - ICE related to -Wmaybe-uninitialized

gcc/ChangeLog:

PR middle-end/100250
* attribs.c (attr_access::array_as_string): Avoid dereferencing
a pointer when it's null.

gcc/testsuite/ChangeLog:

PR middle-end/100250
* gcc.dg/uninit-pr100250.c: New test.


OK

jeff



Re: fix asm-not pattern in dwarf2/inline5.c

2021-04-27 Thread Jeff Law via Gcc-patches



On 4/27/2021 9:32 AM, Alexandre Oliva wrote:

The test is supposed to check that the abstract lexical block of a
function that was inlined doesn't have attributes, and that the
concrete inlined lexical block does.

There are two patterns to verify the absence of attributes in the
abstract lexical block, one for the case in which the concrete block
appears after the abstract one, and another for the case in which it's
before.

The former has a problem that is not visible when asm comments start
with a single character, but that becomes apparent when they start
with "/ ".

The pattern starts by matching the abstract DW_TAG_lexical_block DIE
header, and checking that the next line has, after any of the
comment-starter characters (e.g. '/'), there are one or more blanks '
+', and then a character other than the '(' that would start another
DIE.

The problem is that '[.../...]+ +[^(].*' matches '/  (DIE...', because
'[^(]' may match the second blank, and after that anything goes.  So
we end up recognizing the pattern, as if it was an abstract lexical
block with an attribute.

This could be minimally fixed by changing '[^(]' to '[^ (]', but the
pattern that matches concrete before abstract checks for an explicit
DW_AT after the abstract DIE, so I'm using that in the other pattern
as well.

For reference, the lines that start the unwanted match are:
.uleb128 0xc/  (DIE (0xa4) DW_TAG_lexical_block)
.uleb128 0xd/  (DIE (0xa5) DW_TAG_variable)

Regstrapped on x86-64-linux-gnu, also tested with a cross to x86-vx7r2.
Ok to install?


for  gcc/testsuite/ChangeLog

* gcc.dg/debug/dwarf2/inline5.c: Adjust pattern to avoid
mismatch when asm comments start with "/ ".


OK

jeff



[PATCH] PR fortran/100274 - [9/10/11/12 Regression] ICE in gfc_conv_procedure_call, at fortran/trans-expr.c:6131

2021-04-27 Thread Harald Anlauf via Gcc-patches
Dear Fortranners,

Gerhard found a case where the mismatch of actual and formal argument lead
to an ICE instead of the relevant warning.  Furthermore, the special case
of character argument avoided the check that the actual argument must be
definable if the formal one is INTENT-OUT or -INOUT.  The check was already
there, it just did not get triggered here.

The patch is close to obvious, trivial and self-explaining.  I chose to
continue doing the argument checking after emitting the warning.

Regtested on x86_64-pc-linux-gnu.

OK for mainline?  OK for backports to the affected branches?

Thanks,
Harald


PR fortran/100274 - ICE in gfc_conv_procedure_call, at fortran/trans-expr.c:6131

When the check for the length of formal and actual character arguments
found a mismatch and emitted a warning, it would skip further checks
like that could lead to errors.  Fix that by continuing the checking.
Also catch a NULL pointer dereference.

gcc/fortran/ChangeLog:

PR fortran/100274
* interface.c (gfc_compare_actual_formal): Continue checks after
emitting warning for argument length mismatch.
* trans-expr.c (gfc_conv_procedure_call): Check for NULL pointer
dereference.

gcc/testsuite/ChangeLog:

PR fortran/100274
* gfortran.dg/argument_checking_25.f90: New test.

diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 60736123550..9e3e8aa9da9 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -3255,10 +3255,13 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
 	  && f->sym->attr.flavor != FL_PROCEDURE)
 	{
 	  if (a->expr->ts.type == BT_CHARACTER && !f->sym->as && where)
-	gfc_warning (0, "Character length of actual argument shorter "
-			 "than of dummy argument %qs (%lu/%lu) at %L",
-			 f->sym->name, actual_size, formal_size,
-			 >expr->where);
+	{
+	  gfc_warning (0, "Character length of actual argument shorter "
+			   "than of dummy argument %qs (%lu/%lu) at %L",
+			   f->sym->name, actual_size, formal_size,
+			   >expr->where);
+	  goto skip_size_check;
+	}
   else if (where)
 	{
 	  /* Emit a warning for -std=legacy and an error otherwise. */
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 213f32b0a67..a10170c7dff 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -6128,6 +6128,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 		  bool add_clobber;
 		  add_clobber = fsym && fsym->attr.intent == INTENT_OUT
 			&& !fsym->attr.allocatable && !fsym->attr.pointer
+			&& e->symtree && e->symtree->n.sym
 			&& !e->symtree->n.sym->attr.dimension
 			&& !e->symtree->n.sym->attr.pointer
 			&& !e->symtree->n.sym->attr.allocatable
diff --git a/gcc/testsuite/gfortran.dg/argument_checking_25.f90 b/gcc/testsuite/gfortran.dg/argument_checking_25.f90
new file mode 100644
index 000..e699160fee1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/argument_checking_25.f90
@@ -0,0 +1,12 @@
+! { dg-do compile }
+! PR fortran/100274 - ICE in gfc_conv_procedure_call, at fortran/trans-expr.c:6131
+
+program p
+  call s('y')   ! { dg-warning "Character length of actual argument" }
+contains
+  subroutine s(x)
+character(8), intent(out) :: x
+  end
+end
+
+! { dg-error "in variable definition context"  " " { target *-*-* } 5 }


[PATCH] move pass free_lang_data to its own file

2021-04-27 Thread Martin Sebor via Gcc-patches

The free_lang_data pass is defined entirely in tree.c.  Its code
changes only rarely (only 13% commits to tree.c), and unlike
the rest of tree.c, is even more rarely read.  The pass is also
right in the middle of tree.c, surrounded by various utility
functions many of which do tend to be frequently referenced (IME),
making the rest of the code harder to find and navigate in than
it should be.  The pass contributes nearly 1300 lines of code to
the already quite sizable tree.c (over 16,000 LOC).

To help alleviate some of these problems the attached change moves
the free_lang_data code to its own file where it's easier to find
and work with separately from the rest of tree.c.  There are no
functional changes.

Tested on x86_64-linux.

Martin
Move pass free_lang_data to its own file.

gcc/ChangeLog:
	* free-lang-data.c: New file.
	* tree.c: Move pass free_lang_data to file above.
	 (build_array_type_1): Declare extern.
	* tree.h (build_array_type_1): Declare.

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 8a5fb3fd99c..71a997efec1 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1373,6 +1373,7 @@ OBJS = \
 	fixed-value.o \
 	fold-const.o \
 	fold-const-call.o \
+	free-lang-data.o \
 	function.o \
 	function-abi.o \
 	function-tests.o \
diff --git a/gcc/free-lang-data.c b/gcc/free-lang-data.c
new file mode 100644
index 000..9fb0cb2c3c5
--- /dev/null
+++ b/gcc/free-lang-data.c
@@ -0,0 +1,1298 @@
+/* Pass to free or clear language-specific data structures from
+   the IL before they reach the middle end.
+
+   Copyright (C) 1987-2021 Free Software Foundation, Inc.
+
+   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 file contains the low level primitives for operating on tree nodes,
+   including allocation, list operations, interning of identifiers,
+   construction of data type nodes and statement nodes,
+   and construction of type conversion nodes.  It also contains
+   tables index by tree code that describe how to take apart
+   nodes of that code.
+
+   It is intended to be language-independent but can occasionally
+   calls language-dependent routines.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "target.h"
+#include "tree.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "ssa.h"
+#include "cgraph.h"
+#include "diagnostic.h"
+#include "alias.h"
+#include "attribs.h"
+#include "langhooks.h"
+#include "gimple-iterator.h"
+#include "langhooks-def.h"
+#include "tree-diagnostic.h"
+#include "except.h"
+#include "ipa-utils.h"
+
+/* Data used when collecting DECLs and TYPEs for language data removal.  */
+
+class free_lang_data_d
+{
+public:
+  free_lang_data_d () : decls (100), types (100) {}
+
+  /* Worklist to avoid excessive recursion.  */
+  auto_vec worklist;
+
+  /* Set of traversed objects.  Used to avoid duplicate visits.  */
+  hash_set pset;
+
+  /* Array of symbols to process with free_lang_data_in_decl.  */
+  auto_vec decls;
+
+  /* Array of types to process with free_lang_data_in_type.  */
+  auto_vec types;
+};
+
+
+/* Add type or decl T to one of the list of tree nodes that need their
+   language data removed.  The lists are held inside FLD.  */
+
+static void
+add_tree_to_fld_list (tree t, class free_lang_data_d *fld)
+{
+  if (DECL_P (t))
+fld->decls.safe_push (t);
+  else if (TYPE_P (t))
+fld->types.safe_push (t);
+  else
+gcc_unreachable ();
+}
+
+/* Push tree node T into FLD->WORKLIST.  */
+
+static inline void
+fld_worklist_push (tree t, class free_lang_data_d *fld)
+{
+  if (t && !is_lang_specific (t) && !fld->pset.contains (t))
+fld->worklist.safe_push ((t));
+}
+
+
+
+/* Return simplified TYPE_NAME of TYPE.  */
+
+static tree
+fld_simplified_type_name (tree type)
+{
+  if (!TYPE_NAME (type) || TREE_CODE (TYPE_NAME (type)) != TYPE_DECL)
+return TYPE_NAME (type);
+  /* Drop TYPE_DECLs in TYPE_NAME in favor of the identifier in the
+ TYPE_DECL if the type doesn't have linkage.
+ this must match fld_  */
+  if (type != TYPE_MAIN_VARIANT (type)
+  || (!DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (type))
+	  && (TREE_CODE (type) != RECORD_TYPE
+	  || !TYPE_BINFO (type)
+	  || !BINFO_VTABLE (TYPE_BINFO (type)
+return DECL_NAME (TYPE_NAME (type));
+  return TYPE_NAME (type);
+}
+
+/* Do same comparsion as check_qualified_type skipping lang 

Re: [gcc r11-8294] c++: Remove #error for release builds

2021-04-27 Thread Jakub Jelinek via Gcc-patches
On Tue, Apr 27, 2021 at 08:46:21PM +, Joseph Myers wrote:
> On Tue, 27 Apr 2021, Jakub Jelinek via Gcc-cvs wrote:
> 
> > https://gcc.gnu.org/g:50bc9185c2821350f0b785d6e23a6e9dcde58466
> > 
> > commit r11-8294-g50bc9185c2821350f0b785d6e23a6e9dcde58466
> > Author: Jakub Jelinek 
> > Date:   Tue Apr 27 11:37:30 2021 +0200
> > 
> > c++: Remove #error for release builds
> > 
> > * module.cc: Remove #error that triggers if DEV-PHASE is empty.
> 
> This looks like it needs to be applied to master as well.

Yes, though it is less urgent there (will trigger in ~ a year).
I'll commit it there tomorrow.

Jakub



Re: [gcc r11-8294] c++: Remove #error for release builds

2021-04-27 Thread Joseph Myers
On Tue, 27 Apr 2021, Jakub Jelinek via Gcc-cvs wrote:

> https://gcc.gnu.org/g:50bc9185c2821350f0b785d6e23a6e9dcde58466
> 
> commit r11-8294-g50bc9185c2821350f0b785d6e23a6e9dcde58466
> Author: Jakub Jelinek 
> Date:   Tue Apr 27 11:37:30 2021 +0200
> 
> c++: Remove #error for release builds
> 
> * module.cc: Remove #error that triggers if DEV-PHASE is empty.

This looks like it needs to be applied to master as well.

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


Re: omit frame pointer in pr89676

2021-04-27 Thread Jeff Law via Gcc-patches



On 4/27/2021 9:35 AM, Alexandre Oliva wrote:

This i386 test expects only two movl instructions.

In configurations that --enable-frame-pointer, -O2 won't implicitly
enable -fomit-frame-pointer, so we end up with a third movl to set up
the frame pointer.

This patch enables -fomit-frame-pointer explicitly, so that the result
no longer depends on that configuration option.

Regstrapped on x86_64-linux-gnu, also tested with a cross to x86-vx7r2.
Ok to install?


for  gcc/testsuite/ChangeLog

* gcc.target/i386/pr89676.c: Add -fomit-frame-pointer.


OK

jeff



Recent change breaking Wrestrict8 on various targets

2021-04-27 Thread Jeff Law via Gcc-patches

This change:

d8e1f1d24179690fd9c0f63c27b12e030010d9ea is the first bad commit
commit d8e1f1d24179690fd9c0f63c27b12e030010d9ea
Author: Richard Biener 
Date:   Wed Apr 7 12:09:44 2021 +0200

    tree-optimization/99912 - schedule DSE before SRA

    For the testcase in the PR the main SRA pass is unable to do some
    important scalarizations because dead stores of addresses make
    the candiate variables disqualified.  The following patch adds
    another DSE pass before SRA forming a DCE/DSE pair and moves the
    DSE pass that is currently closely after SRA up to after the
    next DCE pass, forming another DCE/DSE pair now residing after PRE.

    2021-04-07  Richard Biener  

    PR tree-optimization/99912
    * passes.def (pass_all_optimizations): Add pass_dse before
    the first pass_dce, move the first pass_dse before the
    pass_dce following pass_pre.

    * gcc.dg/tree-ssa/ldist-33.c: Disable PRE and LIM.
    * gcc.dg/tree-ssa/pr96789.c: Adjust dump file scanned.
    * gcc.dg/tree-ssa/ssa-dse-28.c: Likewise.
    * gcc.dg/tree-ssa/ssa-dse-29.c: Likewise.

Is breaking gcc.dg/Wrestrict-8.c on various targets (bfin-elf, lm32-elf, 
nds32le-elf, or1k-elf rx-elf).  I haven't dug into it all except for 
quickly bisecting.


http://3.14.90.209:8080/job/bfin-elf/


If you want the full logs...


Jeff



[pushed] c++: -Wdeprecated-copy and using operator= [PR92145]

2021-04-27 Thread Jason Merrill via Gcc-patches
For the purpose of [depr.impldec] "if the class has a user-declared copy
assignment operator", an operator= brought in from a base class with 'using'
may be a copy-assignment operator, but it isn't a copy-assignment operator
for the derived class.

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

gcc/cp/ChangeLog:

PR c++/92145
* class.c (classtype_has_depr_implicit_copy): Check DECL_CONTEXT
of operator=.

gcc/testsuite/ChangeLog:

PR c++/92145
* g++.dg/cpp0x/depr-copy3.C: New test.
---
 gcc/cp/class.c  |  3 ++-
 gcc/testsuite/g++.dg/cpp0x/depr-copy3.C | 35 +
 2 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/depr-copy3.C

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 90b343803a0..2cf527e4a84 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5670,7 +5670,8 @@ classtype_has_depr_implicit_copy (tree t)
 iter; ++iter)
   {
tree fn = *iter;
-   if (user_provided_p (fn) && copy_fn_p (fn))
+   if (DECL_CONTEXT (fn) == t
+   && user_provided_p (fn) && copy_fn_p (fn))
  return fn;
   }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/depr-copy3.C 
b/gcc/testsuite/g++.dg/cpp0x/depr-copy3.C
new file mode 100644
index 000..c303c9d5d40
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/depr-copy3.C
@@ -0,0 +1,35 @@
+// PR c++/92145
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wdeprecated-copy" }
+
+struct base
+{
+  base() { }
+  base(const base&) { }
+  base(base&&) { }
+  base& operator=(const base&) { return *this; }
+  base& operator=(base&&) { return *this; }
+};
+
+struct foo : base
+{
+  //using base::base;
+  using base::operator=;
+};
+
+struct bar
+{
+  bar& operator=(foo v)
+  {
+value = v;
+return *this;
+  }
+
+  foo value;
+};
+
+int main()
+{
+  foo a;
+  foo{a};
+}

base-commit: dfdc02bf29670c1c7f5f2820b6db11c66c258716
-- 
2.27.0



Re: [DWARF] Fix signedness issue in DWARF functions (2)

2021-04-27 Thread Eric Botcazou
> Yes, but even bitsizetype is undistinguishable from other (usually 2 *
> pointer size) precision integral types.

OK, I can propose the attached patch.  The typed_binop_from_tree computation 
works on my Ada testcase in 32-bit mode from within GDB, but not in 64-bit 
mode because GDB chokes with:

That operation is not available on integers of more than 8 bytes.

This is worked around by the div->shift transformation, but then the previous 
change is not exercised any more...  Btw, is the rationale for using unsigned 
types for wide integer modes documented anywhere?  That's not very obvious.


* dwarf2out.c (mem_loc_descriptor) : Fix typo.
(typed_binop_from_tree): New function.
(loc_list_from_tree_1) : For an unsigned type,
turn a divide by a power of 2 into a shift.
: For an unsigned type, use a signed divide if the
size of the mode is lower than DWARF2_ADDR_SIZE; otherwise, do a
typed divide by calling typed_binop_from_tree.

-- 
Eric Botcazoudiff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 73543190c2d..21ae7fb5ef3 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -16317,11 +16317,13 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
   if ((!dwarf_strict || dwarf_version >= 5)
 	  && is_a  (mode, _mode))
 	{
-	  if (GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE)
+	  /* We can use a signed divide if the sign bit is not set.  */
+	  if (GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE)
 	{
 	  op = DW_OP_div;
 	  goto do_binop;
 	}
+
 	  mem_loc_result = typed_binop (DW_OP_div, rtl,
 	base_type_for_mode (int_mode, 1),
 	int_mode, mem_mode);
@@ -18413,6 +18415,48 @@ function_to_dwarf_procedure (tree fndecl)
   return dwarf_proc_die;
 }
 
+/* Helper function for loc_list_from_tree.  Perform OP binary op,
+   but after converting arguments to type_die, afterwards convert
+   back to unsigned.  */
+
+static dw_loc_list_ref
+typed_binop_from_tree (enum dwarf_location_atom op, tree loc,
+		   dw_die_ref type_die, scalar_int_mode mode,
+		   struct loc_descr_context *context)
+{
+  dw_loc_list_ref op0, op1;
+  dw_loc_descr_ref cvt, binop;
+
+  if (type_die == NULL)
+return NULL;
+
+  op0 = loc_list_from_tree (TREE_OPERAND (loc, 0), 0, context);
+  op1 = loc_list_from_tree (TREE_OPERAND (loc, 1), 0, context);
+  if (op0 == NULL || op1 == NULL)
+return NULL;
+
+  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
+  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+  add_loc_descr_to_each (op0, cvt);
+
+  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
+  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
+  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
+  add_loc_descr_to_each (op1, cvt);
+
+  add_loc_list (, op1);
+  if (op0 == NULL)
+return NULL;
+
+  binop = new_loc_descr (op, 0, 0);
+  convert_descriptor_to_mode (mode, binop);
+  add_loc_descr_to_each (op0, binop);
+
+  return op0;
+}
 
 /* Generate Dwarf location list representing LOC.
If WANT_ADDRESS is false, expression computing LOC will be computed
@@ -18994,13 +19038,53 @@ loc_list_from_tree_1 (tree loc, int want_address,
   op = DW_OP_or;
   goto do_binop;
 
+case EXACT_DIV_EXPR:
 case FLOOR_DIV_EXPR:
+case TRUNC_DIV_EXPR:
+  /* Turn a divide by a power of 2 into a shift when possible.  */
+  if (TYPE_UNSIGNED (TREE_TYPE (loc))
+	  && tree_fits_uhwi_p (TREE_OPERAND (loc, 1)))
+	{
+	  const int log2 = exact_log2 (tree_to_uhwi (TREE_OPERAND (loc, 1)));
+	  if (log2 > 0)
+	{
+	  list_ret
+		= loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
+	  if (list_ret == 0)
+		return 0;
+
+	  add_loc_descr_to_each (list_ret, uint_loc_descriptor (log2));
+	  add_loc_descr_to_each (list_ret,
+ new_loc_descr (DW_OP_shr, 0, 0));
+	  break;
+	}
+	}
+
+  /* fall through */
+
 case CEIL_DIV_EXPR:
 case ROUND_DIV_EXPR:
-case TRUNC_DIV_EXPR:
-case EXACT_DIV_EXPR:
   if (TYPE_UNSIGNED (TREE_TYPE (loc)))
-	return 0;
+	{
+	  enum machine_mode mode = TYPE_MODE (TREE_TYPE (loc));
+	  scalar_int_mode int_mode;
+
+	  if ((dwarf_strict && dwarf_version < 5)
+	  || !is_a  (mode, _mode))
+	return 0;
+
+	  /* We can use a signed divide if the sign bit is not set.  */
+	  if (GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE)
+	{
+	  op = DW_OP_div;
+	  goto do_binop;
+	}
+
+	  list_ret = typed_binop_from_tree (DW_OP_div, loc,
+	base_type_for_mode (int_mode, 1),
+	int_mode, context);
+	  break;
+	}
   op = DW_OP_div;
   goto do_binop;
 


Re: [PATCH 0/3] VAX backend preparatory updates for switching to LRA

2021-04-27 Thread Maciej W. Rozycki
On Thu, 22 Apr 2021, Richard Biener wrote:

> >  I think 3/3 is worth backporting to GCC 11 at one point, perhaps 11.2, so
> > that it can be easily picked downstream, as it improves code generation
> > with old reload and we may not have another major release still using it.
> >
> >  OTOH switching to LRA regresses code generation seriously, by making the
> > indexed and indirect VAX address modes severely underutilised, so while
> > with these changes in place the backend can be switched to LRA with just a
> > trivial to remove the redefinition of TARGET_LRA_P, I think it is not yet
> > the right time to do it.
> >
> >  It is not a hard show-stopper though, so while I plan to look into LRA
> > now to figure out what is missing there that the old reload has to satisfy
> > the VAX backend, the switch to LRA can now be made anytime if so required
> > and I am preempted for whatever reason (and nobody else gets to it).
> >
> >  Questions, comments, OK to apply?
> 
> Sounds like a reasonable stance to me.  The patches look all good, thus
> they are OK to apply.

 With GCC 11.1 out now I have committed these changes.  Thank you for your 
review.

 FAOD, as noted above will it be OK if I backport 3/3 to GCC 11 now, for 
inclusion with 11.2?

 While not a regression fix the change is contained in the VAX backend, 
not a mainstream one, and now it is possibly the final opportunity to have 
old reload improved for the VAX target as it's quite likely we'll switch 
to LRA and dump old reload with GCC 12, and we may not be able to get LRA 
on a par with old reload for VAX for a while yet.  Conversely, with the 
improvement in place downstream users (NetBSD) may be able to pick it 
easily enough to make a good use of it now.

 WDYT?

  Maciej


Re: fix asm-not pattern in dwarf2/inline5.c

2021-04-27 Thread Mike Stump via Gcc-patches
On Apr 27, 2021, at 8:32 AM, Alexandre Oliva  wrote:
> 
> The test is supposed to check that the abstract lexical block of a
> function that was inlined doesn't have attributes, and that the
> concrete inlined lexical block does.

> The problem is that '[.../...]+ +[^(].*' matches '/  (DIE...', because
> '[^(]' may match the second blank, and after that anything goes.


> Ok to install?

Ok.


Re: [PATCH 0/6] Add missing calls to `onlyjump_p'

2021-04-27 Thread Maciej W. Rozycki
On Tue, 8 Dec 2020, Maciej W. Rozycki wrote:

> On Thu, 3 Dec 2020, Jeff Law wrote:
> 
> > >  Note that I have included unrelated though contextually connected 6/6 as
> > > an RFC to verify whether this potential anomaly I have spotted has been
> > > intentional.  I'll be happy to drop it if that is the case.  The remaining
> > > changes are I believe actual bug fixes.
> > I doubt it's intentional.? I'd tend to think this specific patch in the
> > series should wait until gcc-12 out of an abundance of caution.
> 
>  Makes sense to me.  Since we have a working instance of patchwork and I 
> actively use it for patch management (for own patches anyway, as I can't 
> update the status of other people's patches) all I need to do is to just 
> get back to it once we reopen for GCC 12 and see what's been outstanding 
> there.

 With GCC 11 out of the door I have committed this change now.

 Thank you, Jeff, for your review again!

  Maciej


Re: [PATCH 2/2] bpf: allow BSS symbols to be global symbols

2021-04-27 Thread Jose E. Marchesi via Gcc-patches


Hi David.

>> Hi YiFei.
>> 
>>> Prior to this, a BSS declaration such as:
>>>
>>>   int foo;
>>>   static int bar;
>>>
>>> Generates:
>>>
>>>   .global foo
>>>   .local  foo
>>>   .comm   foo,4,4
>>>   .local  bar
>>>   .comm   bar,4,4
>>>
>>> Creating symbols:
>>>
>>>    b foo
>>>   0004 b bar
>>>
>>> Both symbols are local. However, libbpf bpf_object__variable_offset
>>> rquires symbols to be STB_GLOBAL & STT_OBJECT for data section lookup.
>>> This patch makes the same declaration generate:
>>>
>>>   .global foo
>>>   .type   foo, @object
>>>   .lcomm  foo,4,4
>>>   .local  bar
>>>   .comm   bar,4,4
>>>
>>> Creating symbols:
>>>
>>>    B foo
>>>   0004 b bar
>>>
>>> And libbpf will be okay with looking up the global symbol "foo".
>> 
>> Thanks for the patch.
>> This is OK for both master and GCC 10.
>> 
>
> OK for backport to GCC 11 (both patches)?

Yes please. Provided releases/gcc-11 is open for backports..


Re: [PATCH 01/57] Allow targets to specify build dependencies for out_object_file

2021-04-27 Thread Bill Schmidt via Gcc-patches

On 4/27/21 11:47 AM, Jakub Jelinek wrote:

On Tue, Apr 27, 2021 at 11:14:00AM -0500, Bill Schmidt wrote:

On 4/27/21 10:57 AM, Jakub Jelinek wrote:

On Tue, Apr 27, 2021 at 10:32:36AM -0500, Bill Schmidt wrote:

2021-03-03  Bill Schmidt  

gcc/
* Makefile.in (OUT_FILE_DEPS): New variable.
(out_object_file): Depend on OUT_FILE_DEPS.

Why?

E.g. gcc/config/i386/t-i386 contains:
i386.o: i386-builtin-types.inc
Similarly gcc/config/{arm/t-arm,ia64/t-ia64}

Interesting!  Thanks.  This was probably an excess of caution on my part.
When I specify something like this, I get a warning message that I am
overriding an automatically generated dependency.  If it's okay for me to
ignore that warning, then I can withdraw this patch and simply specify the
dependency directly.  Sorry, I should have specified the reason for this in
the patch note.

Can you state what exact warning is it and perhaps can you try to reproduce
that warning with a minimal Makefile example?
I don't remember seeing any such warning on i386 or arm.
Whether the dependency is specified on the goal with the commands to build
it or separately shouldn't really matter.


It turns out that this was me simply misreading the warning.  If I 
provide the dependency *and* a recipe, I get:


Makefile:2401: warning: overriding recipe for target 'rs6000.o'
/home/wschmidt/newgcc/gcc/config/rs6000/t-rs6000:89: warning: ignoring 
old recipe for target 'rs6000.o'


But if I provide just the dependency, the warning doesn't show up, as 
expected.  So I withdraw this patch, and will change t-rs6000 
accordingly instead.


Thanks for the help!
Bill




Jakub



Re: [PATCH 2/2] bpf: allow BSS symbols to be global symbols

2021-04-27 Thread David Faust via Gcc-patches



On 4/22/21 11:54 PM, Jose E. Marchesi via Gcc-patches wrote:
> 
> Hi YiFei.
> 
>> Prior to this, a BSS declaration such as:
>>
>>   int foo;
>>   static int bar;
>>
>> Generates:
>>
>>   .global foo
>>   .local  foo
>>   .comm   foo,4,4
>>   .local  bar
>>   .commbar,4,4
>>
>> Creating symbols:
>>
>>    b foo
>>   0004 b bar
>>
>> Both symbols are local. However, libbpf bpf_object__variable_offset
>> rquires symbols to be STB_GLOBAL & STT_OBJECT for data section lookup.
>> This patch makes the same declaration generate:
>>
>>   .global foo
>>   .type   foo, @object
>>   .lcomm  foo,4,4
>>   .local  bar
>>   .comm   bar,4,4
>>
>> Creating symbols:
>>
>>    B foo
>>   0004 b bar
>>
>> And libbpf will be okay with looking up the global symbol "foo".
> 
> Thanks for the patch.
> This is OK for both master and GCC 10.
> 

OK for backport to GCC 11 (both patches)?


Re: omit frame pointer in pr89676

2021-04-27 Thread Uros Bizjak via Gcc-patches
On Tue, Apr 27, 2021 at 5:35 PM Alexandre Oliva  wrote:
>
>
> This i386 test expects only two movl instructions.
>
> In configurations that --enable-frame-pointer, -O2 won't implicitly
> enable -fomit-frame-pointer, so we end up with a third movl to set up
> the frame pointer.
>
> This patch enables -fomit-frame-pointer explicitly, so that the result
> no longer depends on that configuration option.
>
> Regstrapped on x86_64-linux-gnu, also tested with a cross to x86-vx7r2.
> Ok to install?

OK.

Thanks,
Uros.

>
> for  gcc/testsuite/ChangeLog
>
> * gcc.target/i386/pr89676.c: Add -fomit-frame-pointer.
> ---
>  gcc/testsuite/gcc.target/i386/pr89676.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gcc/testsuite/gcc.target/i386/pr89676.c 
> b/gcc/testsuite/gcc.target/i386/pr89676.c
> index 164a9da468046..7afa1a1778d71 100644
> --- a/gcc/testsuite/gcc.target/i386/pr89676.c
> +++ b/gcc/testsuite/gcc.target/i386/pr89676.c
> @@ -1,6 +1,6 @@
>  /* PR rtl-optimization/89676 */
>  /* { dg-do compile { target ia32 } } */
> -/* { dg-options "-O2 -mno-stv" } */
> +/* { dg-options "-O2 -mno-stv -fomit-frame-pointer" } */
>
>  unsigned long long
>  foo (unsigned long long i)
>
> --
> Alexandre Oliva, happy hacker  https://FSFLA.org/blogs/lxo/
>Free Software Activist GNU Toolchain Engineer
> Vim, Vi, Voltei pro Emacs -- GNUlius Caesar


Re: RFC: Changing AC_PROG_CC to AC_PROG_CC_C99 in top level configure

2021-04-27 Thread Joseph Myers
On Tue, 27 Apr 2021, Nick Clifton via Binutils wrote:

> > and instead AC_PROG_CC enables C11 mode if supported.  (So moving to the
> > latest Autoconf and Automake releases would supersede this change.)
> 
> Makes sense.  Is changing to autoconf 2.70 something that is planned for the
> near future ?

It would be 2.71, and I don't know.  (Simon Marchi did the previous update 
for binutils-gdb, I then used that as a basis for updating GCC.)

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


[PATCH] libstdc++: Fix various bugs in ranges_algo.h [PR100187, ...]

2021-04-27 Thread Patrick Palka via Gcc-patches
This fixes some bugs with our ranges algorithms in uncommon situations,
such as when the return type of a predicate is a non-copyable class type
that's implicitly convertible to bool (PR100187), when a comparison
predicate isn't invocable as an rvalue (PR100237), and when the return
type of a projection function is non-copyable (PR100249).

This also fixes PR100287, which reports that we're moving __first twice
when constructing an empty subrange with it in ranges::partition.

Tested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps
the releases branches?  I wasn't sure if it's worthwhile to include
tests for these bugs given their relatively obscure nature.

libstdc++-v3/ChangeLog:

PR libstdc++/100187
PR libstdc++/100237
PR libstdc++/100249
PR libstdc++/100287
* include/bits/ranges_algo.h (__search_n_fn::operator()): Give
__value_comp lambda an explicit bool return type.
(__is_permutation_fn::operator()): Give __proj_scan local
variable auto&& return type.  Give __comp_scan lambda an
explicit bool return type.
(__remove_fn::operator()): Give __pred lambda an explicit
bool return type.
(__partition_fn::operator()): Don't std::move __first twice
when returning an empty range.
(__min_fn::operator()): Don't std::move __comp.
(__max_fn::operator()): Likewise.
(__minmax_fn::operator()): Likewise.
---
 libstdc++-v3/include/bits/ranges_algo.h | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/libstdc++-v3/include/bits/ranges_algo.h 
b/libstdc++-v3/include/bits/ranges_algo.h
index 23e6480b9a8..cda3042c11f 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -562,7 +562,7 @@ namespace ranges
if (__count <= 0)
  return {__first, __first};
 
-   auto __value_comp = [&]  (_Rp&& __arg) {
+   auto __value_comp = [&]  (_Rp&& __arg) -> bool {
return std::__invoke(__pred, std::forward<_Rp>(__arg), __value);
};
if (__count == 1)
@@ -805,8 +805,8 @@ namespace ranges
 
for (auto __scan = __first1; __scan != __last1; ++__scan)
  {
-   auto __proj_scan = std::__invoke(__proj1, *__scan);
-   auto __comp_scan = [&]  (_Tp&& __arg) {
+   auto&& __proj_scan = std::__invoke(__proj1, *__scan);
+   auto __comp_scan = [&]  (_Tp&& __arg) -> bool {
  return std::__invoke(__pred, __proj_scan,
   std::forward<_Tp>(__arg));
};
@@ -1256,7 +1256,7 @@ namespace ranges
   operator()(_Iter __first, _Sent __last,
 const _Tp& __value, _Proj __proj = {}) const
   {
-   auto __pred = [&] (auto&& __arg) {
+   auto __pred = [&] (auto&& __arg) -> bool {
  return std::forward(__arg) == __value;
};
return ranges::remove_if(__first, __last,
@@ -2537,11 +2537,11 @@ namespace ranges
else
  {
if (__first == __last)
- return {std::move(__first), std::move(__first)};
+ return {__first, __first};
 
while (std::__invoke(__pred, std::__invoke(__proj, *__first)))
  if (++__first == __last)
-   return {std::move(__first), std::move(__first)};
+   return {__first, __first};
 
auto __next = __first;
while (++__next != __last)
@@ -3118,7 +3118,7 @@ namespace ranges
   operator()(const _Tp& __a, const _Tp& __b,
 _Comp __comp = {}, _Proj __proj = {}) const
   {
-   if (std::__invoke(std::move(__comp),
+   if (std::__invoke(__comp,
  std::__invoke(__proj, __b),
  std::__invoke(__proj, __a)))
  return __b;
@@ -3172,7 +3172,7 @@ namespace ranges
   operator()(const _Tp& __a, const _Tp& __b,
 _Comp __comp = {}, _Proj __proj = {}) const
   {
-   if (std::__invoke(std::move(__comp),
+   if (std::__invoke(__comp,
  std::__invoke(__proj, __a),
  std::__invoke(__proj, __b)))
  return __b;
@@ -3272,7 +3272,7 @@ namespace ranges
   operator()(const _Tp& __a, const _Tp& __b,
 _Comp __comp = {}, _Proj __proj = {}) const
   {
-   if (std::__invoke(std::move(__comp),
+   if (std::__invoke(__comp,
  std::__invoke(__proj, __b),
  std::__invoke(__proj, __a)))
  return {__b, __a};
-- 
2.31.1.362.g311531c9de



Re: [PATCH] Fix handling of VEC_COND_EXPR trap tests [PR100284]

2021-04-27 Thread Richard Biener
On April 27, 2021 5:22:56 PM GMT+02:00, Richard Sandiford 
 wrote:
>Richard Biener  writes:
>> On April 27, 2021 5:12:35 PM GMT+02:00, Richard Sandiford
> wrote:
>>>Now that VEC_COND_EXPR has normal unnested operands,
>>>operation_could_trap_p can treat it like any other expression.
>>>
>>>This fixes many testsuite ICEs for SVE, but it turns out that none
>>>of the tests in gcc.target/aarch64/sve were affected.  Anyone testing
>>>on non-SVE aarch64 therefore wouldn't have seen it.
>>>
>>>Tested on aarch64-linux-gnu (with and without SVE).  OK to install?
>>
>> Hmm, I now remember why I didn't adjust this. Because on GENERIC the
>compares are still there and tree_could_trap_p uses the same helper in
>the end, thus it cannot handle VEC_COND_EXPR this way I think. 
>
>But is it meaningful to ask this question about one node of a GENERIC
>expression in isolation?  I thought you'd need a recursive test.
>E.g. an EQ_EXPR could be comparing two integers that are the result
>of a potentially-trapping FP operation.

True. 

>If a caller does ask about only the VEC_COND_EXPR and not its operands,
>then false seems like the right answer.

So the patch is OK. 

Richard. 

>Thanks,
>Richard
>
>> Can you double check? 
>>
>> Richard. 
>>
>>>Richard
>>>
>>>
>>>gcc/
>>> PR middle-end/100284
>>> * gimple.c (gimple_could_trap_p_1): Remove VEC_COND_EXPR test.
>>> * tree-eh.c (operation_could_trap_p): Handle VEC_COND_EXPR rather
>>> than asserting on it.
>>>
>>>gcc/testsuite/
>>> PR middle-end/100284
>>> * gcc.target/aarch64/sve/pr81003.c: New test.
>>>---
>>> gcc/gimple.c   |  3 ---
>>> gcc/testsuite/gcc.target/aarch64/sve/pr81003.c | 10 ++
>>> gcc/tree-eh.c  |  6 +++---
>>> 3 files changed, 13 insertions(+), 6 deletions(-)
>>> create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/pr81003.c
>>>
>>>diff --git a/gcc/gimple.c b/gcc/gimple.c
>>>index d067656d315..f1044e9c630 100644
>>>--- a/gcc/gimple.c
>>>+++ b/gcc/gimple.c
>>>@@ -2161,9 +2161,6 @@ gimple_could_trap_p_1 (gimple *s, bool
>>>include_mem, bool include_stores)
>>>   /* For COND_EXPR only the condition may trap.  */
>>>   if (op == COND_EXPR)
>>> return tree_could_trap_p (gimple_assign_rhs1 (s));
>>>-  /* A VEC_COND_EXPR cannot trap.  */
>>>-  else if (op == VEC_COND_EXPR)
>>>-return false;
>>> 
>>>/* For comparisons we need to check rhs operand types instead of rhs
>>>type
>>>  (which is BOOLEAN_TYPE).  */
>>>diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
>>>index a68778b9809..601285c401c 100644
>>>--- a/gcc/tree-eh.c
>>>+++ b/gcc/tree-eh.c
>>>@@ -2541,9 +2541,9 @@ operation_could_trap_p (enum tree_code op, bool
>>>fp_operation, bool honor_trapv,
>>>   bool honor_snans = fp_operation && flag_signaling_nans != 0;
>>>   bool handled;
>>> 
>>>-  /* This function cannot tell whether or not COND_EXPR and
>>>VEC_COND_EXPR could
>>>- trap, because that depends on the respective condition op.  */
>>>-  gcc_assert (op != COND_EXPR && op != VEC_COND_EXPR);
>>>+  /* This function cannot tell whether or not COND_EXPR could trap,
>>>+ because that depends on its condition op.  */
>>>+  gcc_assert (op != COND_EXPR);
>>> 
>>>   if (TREE_CODE_CLASS (op) != tcc_comparison
>>>   && TREE_CODE_CLASS (op) != tcc_unary
>>>diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr81003.c
>>>b/gcc/testsuite/gcc.target/aarch64/sve/pr81003.c
>>>new file mode 100644
>>>index 000..661a6f97d6d
>>>--- /dev/null
>>>+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr81003.c
>>>@@ -0,0 +1,10 @@
>>>+/* { dg-options "-O3" } */
>>>+
>>>+unsigned int a, b;
>>>+
>>>+void
>>>+foo (void)
>>>+{
>>>+  for (b = 0; b < 13; b += 2)
>>>+a &= !!b;
>>>+}



Re: [PATCH 01/57] Allow targets to specify build dependencies for out_object_file

2021-04-27 Thread Jakub Jelinek via Gcc-patches
On Tue, Apr 27, 2021 at 11:14:00AM -0500, Bill Schmidt wrote:
> On 4/27/21 10:57 AM, Jakub Jelinek wrote:
> > On Tue, Apr 27, 2021 at 10:32:36AM -0500, Bill Schmidt wrote:
> > > 2021-03-03  Bill Schmidt  
> > > 
> > > gcc/
> > >   * Makefile.in (OUT_FILE_DEPS): New variable.
> > >   (out_object_file): Depend on OUT_FILE_DEPS.
> > Why?
> > 
> > E.g. gcc/config/i386/t-i386 contains:
> > i386.o: i386-builtin-types.inc
> > Similarly gcc/config/{arm/t-arm,ia64/t-ia64}
> 
> Interesting!  Thanks.  This was probably an excess of caution on my part. 
> When I specify something like this, I get a warning message that I am
> overriding an automatically generated dependency.  If it's okay for me to
> ignore that warning, then I can withdraw this patch and simply specify the
> dependency directly.  Sorry, I should have specified the reason for this in
> the patch note.

Can you state what exact warning is it and perhaps can you try to reproduce
that warning with a minimal Makefile example?
I don't remember seeing any such warning on i386 or arm.
Whether the dependency is specified on the goal with the commands to build
it or separately shouldn't really matter.

Jakub



Re: [PATCH 01/57] Allow targets to specify build dependencies for out_object_file

2021-04-27 Thread Bill Schmidt via Gcc-patches

On 4/27/21 10:57 AM, Jakub Jelinek wrote:

On Tue, Apr 27, 2021 at 10:32:36AM -0500, Bill Schmidt wrote:

2021-03-03  Bill Schmidt  

gcc/
* Makefile.in (OUT_FILE_DEPS): New variable.
(out_object_file): Depend on OUT_FILE_DEPS.

Why?

E.g. gcc/config/i386/t-i386 contains:
i386.o: i386-builtin-types.inc
Similarly gcc/config/{arm/t-arm,ia64/t-ia64}


Interesting!  Thanks.  This was probably an excess of caution on my 
part.  When I specify something like this, I get a warning message that 
I am overriding an automatically generated dependency.  If it's okay for 
me to ignore that warning, then I can withdraw this patch and simply 
specify the dependency directly.  Sorry, I should have specified the 
reason for this in the patch note.


Thanks,
Bill



Jakub



Re: [PATCH] tree-optimization/99912 - delete trivially dead stmts during DSE

2021-04-27 Thread Prathamesh Kulkarni via Gcc-patches
On Tue, 27 Apr 2021 at 19:19, Richard Biener  wrote:
>
> DSE performs a backwards walk over stmts removing stores but it
> leaves removing resulting dead SSA defs to later passes.  This
> eats into its own alias walking budget if the removed stores kept
> loads live.  The following patch adds removal of trivially dead
> SSA defs which helps in this situation and reduces the amount of
> garbage followup passes need to deal with.
>
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
>
> 2021-04-27  Richard Biener  
>
> PR tree-optimization/99912
> * tree-ssa-dse.c (dse_dom_walker::m_need_cfg_cleanup): New.
> (dse_dom_walker::todo): Likewise.
> (dse_dom_walker::dse_optimize_stmt): Move VDEF check to the
> caller.
> (dse_dom_walker::before_dom_children): Remove trivially
> dead SSA defs and schedule CFG cleanup if we removed all
> PHIs in a block.
> (pass_dse::execute): Get TODO as computed by the DOM walker
> and return it.  Wipe dominator info earlier.
> ---
>  gcc/tree-ssa-dse.c | 65 +-
>  1 file changed, 53 insertions(+), 12 deletions(-)
>
> diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
> index 4967a5a9927..f5f39cbe903 100644
> --- a/gcc/tree-ssa-dse.c
> +++ b/gcc/tree-ssa-dse.c
> @@ -963,16 +963,25 @@ public:
>dse_dom_walker (cdi_direction direction)
>  : dom_walker (direction),
>  m_live_bytes (param_dse_max_object_size),
> -m_byte_tracking_enabled (false) {}
> +m_byte_tracking_enabled (false),
> +m_need_cfg_cleanup (false) {}
>
>virtual edge before_dom_children (basic_block);
> +  unsigned todo () const;
>
>  private:
>auto_sbitmap m_live_bytes;
>bool m_byte_tracking_enabled;
> +  bool m_need_cfg_cleanup;
>void dse_optimize_stmt (gimple_stmt_iterator *);
>  };
>
> +unsigned
> +dse_dom_walker::todo () const
> +{
> +  return m_need_cfg_cleanup ? TODO_cleanup_cfg : 0;
> +}
> +
>  /* Delete a dead call at GSI, which is mem* call of some kind.  */
>  static void
>  delete_dead_or_redundant_call (gimple_stmt_iterator *gsi, const char *type)
> @@ -1049,11 +1058,6 @@ dse_dom_walker::dse_optimize_stmt 
> (gimple_stmt_iterator *gsi)
>  {
>gimple *stmt = gsi_stmt (*gsi);
>
> -  /* If this statement has no virtual defs, then there is nothing
> - to do.  */
> -  if (!gimple_vdef (stmt))
> -return;
> -
>/* Don't return early on *this_2(D) ={v} {CLOBBER}.  */
>if (gimple_has_volatile_ops (stmt)
>&& (!gimple_clobber_p (stmt)
> @@ -1180,12 +1184,47 @@ dse_dom_walker::before_dom_children (basic_block bb)
>
>for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
>  {
> -  dse_optimize_stmt ();
> +  gimple *stmt = gsi_stmt (gsi);
> +
> +  if (gimple_vdef (stmt))
> +   dse_optimize_stmt ();
> +  else if (def_operand_p def_p = single_ssa_def_operand (stmt, 
> SSA_OP_DEF))
> +   {
> + /* When we remove dead stores make sure to also delete trivially
> +dead SSA defs.  */
> + if (has_zero_uses (DEF_FROM_PTR (def_p))
> + && !gimple_has_side_effects (stmt))
> +   {
> + if (dump_file && (dump_flags & TDF_DETAILS))
> +   {
> + fprintf (dump_file, "  Deleted trivially dead stmt: ");
> + print_gimple_stmt (dump_file, stmt, 0, dump_flags);
> + fprintf (dump_file, "\n");
> +   }
> + if (gsi_remove (, true) && need_eh_cleanup)
> +   bitmap_set_bit (need_eh_cleanup, bb->index);
> + release_defs (stmt);
> +   }
> +   }
>if (gsi_end_p (gsi))
> gsi = gsi_last_bb (bb);
>else
> gsi_prev ();
>  }
> +  bool removed_phi = false;
> +  for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);)
> +{
> +  gphi *phi = si.phi ();
> +  if (has_zero_uses (gimple_phi_result (phi)))
> +   {
> + remove_phi_node (, true);
> + removed_phi = true;
> +   }
Hi Richard,
Just curious if this is missing dumping info about removed phi node to
dump_file ?

Thanks,
Prathamesh
> +  else
> +   gsi_next ();
> +}
> +  if (removed_phi && gimple_seq_empty_p (phi_nodes (bb)))
> +m_need_cfg_cleanup = true;
>return NULL;
>  }
>
> @@ -1234,21 +1273,23 @@ pass_dse::execute (function *fun)
>
>/* Dead store elimination is fundamentally a walk of the post-dominator
>   tree and a backwards walk of statements within each block.  */
> -  dse_dom_walker (CDI_POST_DOMINATORS).walk (fun->cfg->x_exit_block_ptr);
> +  dse_dom_walker walker (CDI_POST_DOMINATORS);
> +  walker.walk (fun->cfg->x_exit_block_ptr);
> +  free_dominance_info (CDI_POST_DOMINATORS);
> +
> +  unsigned todo = walker.todo ();
>
>/* Removal of stores may make some EH edges dead.  Purge such edges from
>   the CFG as needed.  */
>if (!bitmap_empty_p (need_eh_cleanup))
>  {
>

Re: [PATCH 01/57] Allow targets to specify build dependencies for out_object_file

2021-04-27 Thread Jakub Jelinek via Gcc-patches
On Tue, Apr 27, 2021 at 10:32:36AM -0500, Bill Schmidt wrote:
> 2021-03-03  Bill Schmidt  
> 
> gcc/
>   * Makefile.in (OUT_FILE_DEPS): New variable.
>   (out_object_file): Depend on OUT_FILE_DEPS.

Why?

E.g. gcc/config/i386/t-i386 contains:
i386.o: i386-builtin-types.inc
Similarly gcc/config/{arm/t-arm,ia64/t-ia64}

Jakub



Re: [PATCH] define auto_vec copy ctor and assignment (PR 90904)

2021-04-27 Thread Martin Sebor via Gcc-patches

On 4/27/21 8:04 AM, Richard Biener wrote:

On Tue, Apr 27, 2021 at 3:59 PM Martin Sebor  wrote:


On 4/27/21 1:58 AM, Richard Biener wrote:

On Tue, Apr 27, 2021 at 2:46 AM Martin Sebor via Gcc-patches
 wrote:


PR 90904 notes that auto_vec is unsafe to copy and assign because
the class manages its own memory but doesn't define (or delete)
either special function.  Since I first ran into the problem,
auto_vec has grown a move ctor and move assignment from
a dynamically-allocated vec but still no copy ctor or copy
assignment operator.

The attached patch adds the two special functions to auto_vec along
with a few simple tests.  It makes auto_vec safe to use in containers
that expect copyable and assignable element types and passes bootstrap
and regression testing on x86_64-linux.


The question is whether we want such uses to appear since those
can be quite inefficient?  Thus the option is to delete those operators?


I would strongly prefer the generic vector class to have the properties
expected of any other generic container: copyable and assignable.  If
we also want another vector type with this restriction I suggest to add
another "noncopyable" type and make that property explicit in its name.
I can submit one in a followup patch if you think we need one.


I'm not sure (and not strictly against the copy and assign).  Looking around
I see that vec<> does not do deep copying.  Making auto_vec<> do it
might be surprising (I added the move capability to match how vec<>
is used - as "reference" to a vector)


The vec base classes are special: they have no ctors at all (because
of their use in unions).  That's something we might have to live with
but it's not a model to follow in ordinary containers.

The auto_vec class was introduced to fill the need for a conventional
sequence container with a ctor and dtor.  The missing copy ctor and
assignment operators were an oversight, not a deliberate feature.
This change fixes that oversight.

The revised patch also adds a copy ctor/assignment to the auto_vec
primary template (that's also missing it).  In addition, it adds
a new class called auto_vec_ncopy that disables copying and
assignment as you prefer.  It also disables copying for
the auto_string_vec class.

Martin
PR middle-end/90904 - vec assignment and copying undefined

gcc/ChangeLog:

	PR middle-end/90904
	* vec.c (test_copy_assign): New function.
	(vec_c_tests): Call it.
	* vec.h (vec_assign): New function.
	(auto_vec copy ctor): Define.
	(auto_vec::operator=): Define.
	(auto_vec_no_copy): New class template.
	(auto_string_vec): Disable copying/assignment.

diff --git a/gcc/vec.c b/gcc/vec.c
index f9dbb2cac31..f15530d1e43 100644
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -317,6 +317,86 @@ test_safe_push ()
   ASSERT_EQ (7, v[2]);
 }
 
+
+/* Verify that auto_vec copy ctor and assignment work correctly.  */
+
+template 
+void test_copy_assign ()
+{
+  typedef auto_vec  test_vec;
+
+  test_vec a0;
+  test_vec b0 (0);
+  test_vec c0 (7);
+  ASSERT_EQ (0, b0.length ());
+  ASSERT_EQ (0, c0.length ());
+
+  a0 = a0;
+  ASSERT_EQ (0, a0.length ());
+  b0 = a0;
+  ASSERT_EQ (0, b0.length ());
+  c0 = a0;
+  ASSERT_EQ (0, c0.length ());
+
+  test_vec a3;
+  a3.safe_push (5);
+  a3.safe_push (6);
+  a3.safe_push (7);
+
+  test_vec b3 (a3);
+  ASSERT_EQ (3, b3.length ());
+  ASSERT_EQ (5, b3[0]);
+  ASSERT_EQ (6, b3[1]);
+  ASSERT_EQ (7, b3[2]);
+
+  test_vec c3;
+  c3 = b3;
+  ASSERT_EQ (3, c3.length ());
+  ASSERT_EQ (5, c3[0]);
+  ASSERT_EQ (6, c3[1]);
+  ASSERT_EQ (7, c3[2]);
+
+  test_vec d4;
+  d4.safe_push (1);
+  d4.safe_push (2);
+  d4.safe_push (3);
+  d4.safe_push (4);
+
+  c3 = d4;
+  ASSERT_EQ (4, c3.length ());
+  ASSERT_EQ (1, c3[0]);
+  ASSERT_EQ (2, c3[1]);
+  ASSERT_EQ (3, c3[2]);
+  ASSERT_EQ (4, c3[3]);
+
+  d4 = a3;
+  ASSERT_EQ (3, d4.length ());
+  ASSERT_EQ (5, d4[0]);
+  ASSERT_EQ (6, d4[1]);
+  ASSERT_EQ (7, d4[2]);
+
+  a3 = b0;
+  ASSERT_EQ (0, a3.length ());
+
+  b3 = b0;
+  ASSERT_EQ (0, b3.length ());
+
+  c3 = c0;
+  ASSERT_EQ (0, c3.length ());
+
+  b0 = d4;
+  ASSERT_EQ (3, b0.length ());
+  ASSERT_EQ (5, b0[0]);
+  ASSERT_EQ (6, b0[1]);
+  ASSERT_EQ (7, b0[2]);
+
+  c0 = d4;
+  ASSERT_EQ (3, c0.length ());
+  ASSERT_EQ (5, c0[0]);
+  ASSERT_EQ (6, c0[1]);
+  ASSERT_EQ (7, c0[2]);
+}
+
 /* Verify that vec::truncate works correctly.  */
 
 static void
@@ -549,6 +629,8 @@ vec_c_tests ()
 {
   test_quick_push ();
   test_safe_push ();
+  test_copy_assign<0> ();
+  test_copy_assign<2> ();
   test_truncate ();
   test_safe_grow_cleared ();
   test_pop ();
diff --git a/gcc/vec.h b/gcc/vec.h
index 24df2db0eeb..f5dd5bb329a 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1509,7 +1509,41 @@ public:
want to ask for internal storage for vectors on the stack because if the
size of the vector is larger than the internal storage that space is wasted.
*/
+
 template
+class auto_vec;
+
+/* Safely assign elements from SRC to DST, invoking the copy assignment
+   operator on the initial elements 

Re: [PATCH] libstdc++: Fix up lambda in join_view::_Iterator::operator++ [PR100290]

2021-04-27 Thread Jonathan Wakely via Gcc-patches

On 27/04/21 10:55 -0400, Patrick Palka via Libstdc++ wrote:

Currently, the return type of this lambda is decltype(auto), so it ends
up returning a copy of _M_parent->_M_inner rather than a reference to it
when _S_ref_glvalue is false.  Hence _M_inner and ranges::end(__inner_range)
are respectively an iterator and sentinel for different ranges, so
comparing them is undefined.

Tested on x86_64-pc-linux-gnu, does this look OK for trunk/11/10?


Yes for all three, thanks.


libstdc++-v3/ChangeLog:

PR libstdc++/100290
* include/std/ranges (join_view::_Iterator::operator++): Correct
the return type of the lambda to avoid returning a copy of
_M_parent->_M_inner.
* testsuite/std/ranges/adaptors/join.cc (test10): New test.
---
libstdc++-v3/include/std/ranges|  2 +-
libstdc++-v3/testsuite/std/ranges/adaptors/join.cc | 11 +++
2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 74075a2d6d3..09115e9b45f 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -2389,7 +2389,7 @@ namespace views::__adaptor
  constexpr _Iterator&
  operator++()
  {
-   auto&& __inner_range = [this] () -> decltype(auto) {
+   auto&& __inner_range = [this] () -> auto&& {
  if constexpr (_S_ref_is_glvalue)
return *_M_outer;
  else
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc 
b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
index fb06a7698af..e6c71d771de 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/join.cc
@@ -160,6 +160,16 @@ test09()
  static_assert(!requires { 0 | join; });
}

+void
+test10()
+{
+  // PR libstdc++/100290
+  auto v = views::single(0)
+| views::transform([](const auto& s) { return views::single(s); })
+| views::join;
+  VERIFY( ranges::next(v.begin()) == v.end() );
+}
+
int
main()
{
@@ -172,4 +182,5 @@ main()
  test07();
  test08();
  test09();
+  test10();
}
--
2.31.1.362.g311531c9de





[PATCH 42/57] rs6000: Handle overloads during program parsing

2021-04-27 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-03-05  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 0f8a629ff5a..1e6fe7699ea 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
@@ -808,6 +812,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)
 {
@@ -924,6 +952,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
@@ -1927,3 +1959,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 21/57] rs6000: Write output to the builtins init file, part 3 of 3

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-03  Bill Schmidt  

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

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 82c0567756b..7ef297d04f5 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -468,6 +468,106 @@ 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 84
+static typemap type_map[TYPE_MAP_SIZE] =
+  {
+{ "bi","bool_int" },
+{ "bv16qi","bool_V16QI" },
+{ "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" },
+{ "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.  */
 void (*diag) (const char *, ...) __attribute__ ((format (printf, 1, 2)))
   = NULL;
@@ -2242,10 +2342,83 @@ write_fntype (char *str)
   fprintf 

[PATCH 05/57] rs6000: Add file support and functions for diagnostic support

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-03  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (bif_file): New filescope
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 defined constant.
(linebuf): New filescope 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 0afbff8e3ab..0e8b315208b 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.  */
+void (*diag) (const char *, ...) __attribute__ ((format (printf, 1, 2)))
+  = NULL;
+
+/* 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



omit frame pointer in pr89676

2021-04-27 Thread Alexandre Oliva


This i386 test expects only two movl instructions.

In configurations that --enable-frame-pointer, -O2 won't implicitly
enable -fomit-frame-pointer, so we end up with a third movl to set up
the frame pointer.

This patch enables -fomit-frame-pointer explicitly, so that the result
no longer depends on that configuration option.

Regstrapped on x86_64-linux-gnu, also tested with a cross to x86-vx7r2.
Ok to install?


for  gcc/testsuite/ChangeLog

* gcc.target/i386/pr89676.c: Add -fomit-frame-pointer.
---
 gcc/testsuite/gcc.target/i386/pr89676.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/pr89676.c 
b/gcc/testsuite/gcc.target/i386/pr89676.c
index 164a9da468046..7afa1a1778d71 100644
--- a/gcc/testsuite/gcc.target/i386/pr89676.c
+++ b/gcc/testsuite/gcc.target/i386/pr89676.c
@@ -1,6 +1,6 @@
 /* PR rtl-optimization/89676 */
 /* { dg-do compile { target ia32 } } */
-/* { dg-options "-O2 -mno-stv" } */
+/* { dg-options "-O2 -mno-stv -fomit-frame-pointer" } */
 
 unsigned long long
 foo (unsigned long long i)

-- 
Alexandre Oliva, happy hacker  https://FSFLA.org/blogs/lxo/
   Free Software Activist GNU Toolchain Engineer
Vim, Vi, Voltei pro Emacs -- GNUlius Caesar


[PATCH 55/57] rs6000: Test case adjustments

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-24  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/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/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 +-
 35 files changed, 62 insertions(+), 59 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 
"'__builtin_vsx_scalar_extract_exp' requires the" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-2.c 

[PATCH 57/57] rs6000: Adjust to late-breaking change

2021-04-27 Thread Bill Schmidt via Gcc-patches
After this patch set was developed, a small change was made to overload
handling for VEC_INSERT.  Reflecting that into the new support here.

2021-04-27  Bill Schmidt  

gcc/
* config/rs6000/rs6000-c.c
(altivec_resolve_new_overloaded_builtin): Change P8-vector test to
less-restrictive VSX test in VEC_INSERT handling.
---
 gcc/config/rs6000/rs6000-c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 1e6fe7699ea..5370dc7608e 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -2710,7 +2710,7 @@ altivec_resolve_new_overloaded_builtin (location_t loc, 
tree fndecl,
  stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
}
 
-  if (TARGET_P8_VECTOR && TARGET_DIRECT_MOVE_64BIT)
+  if (TARGET_VSX)
{
  stmt = build_array_ref (loc, stmt, arg2);
  stmt = fold_build2 (MODIFY_EXPR, TREE_TYPE (arg0), stmt,
-- 
2.27.0



[PATCH 54/57] rs6000: Update altivec.h for automated interfaces

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-01  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 | 516 +++-
 1 file changed, 41 insertions(+), 475 deletions(-)

diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index 961621a0841..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,438 +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 56/57] rs6000: Enable the new builtin support

2021-04-27 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 39080e838f3..e7df7c8caab 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2758,7 +2758,7 @@ write_init_file ()
   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 53/57] rs6000: Debug support

2021-04-27 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 406fb9ce2cb..288bc6b455a 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -8779,6 +8779,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)
 {
@@ -8807,7 +8907,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)
 {
@@ -8815,7 +8915,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)
 {
@@ -8829,12 +8929,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 52/57] rs6000: Miscellaneous uses of rs6000_builtin_decls_x

2021-04-27 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 080e6a70221..1b5c65b6f2d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -22711,12 +22711,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:
@@ -25280,7 +25284,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);
@@ -27491,8 +27498,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 51/57] rs6000: Update rs6000_builtin_decl

2021-04-27 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 16dd99f381e..406fb9ce2cb 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -16108,11 +16108,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 50/57] rs6000: Builtin expansion, part 6

2021-04-27 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 3bd6731dd13..16dd99f381e 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14932,11 +14932,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 49/57] rs6000: Builtin expansion, part 5

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-25  Bill Schmidt  

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

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 2d8a784a3c8..3bd6731dd13 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14837,6 +14837,98 @@ stv_expand_builtin (insn_code icode, rtx *op,
 static rtx
 new_mma_expand_builtin (tree exp, rtx target, insn_code icode)
 {
+  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:
+  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:
+  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 48/57] rs6000: Builtin expansion, part 4

2021-04-27 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 a568682592c..2d8a784a3c8 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14586,12 +14586,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;
 }
 
@@ -14599,6 +14701,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 47/57] rs6000: Builtin expansion, part 3

2021-04-27 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 87b8698c9f5..a568682592c 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -14480,6 +14480,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/57] rs6000: Builtin expansion, part 1

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-02  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 | 525 
 1 file changed, 525 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 197c611c592..d2aa64cc19d 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);
 
 
@@ -11552,6 +11553,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.  */
 
@@ -14069,6 +14078,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);
@@ -14361,6 +14373,519 @@ 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)
+{
+  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 built-in function, and switch the code
+ when 

[PATCH 46/57] rs6000: Builtin expansion, part 2

2021-04-27 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 d2aa64cc19d..87b8698c9f5 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -11559,6 +11559,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
@@ -14377,7 +14446,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.  */
@@ -15262,6 +15357,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 43/57] rs6000: Handle gimple folding of target built-ins

2021-04-27 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-03-25  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 | 1148 +++
 1 file changed, 1148 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 9cefa38202c..197c611c592 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.  */
@@ -11880,6 +11881,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);
@@ -12819,6 +12823,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
@@ -12910,6 +12943,1121 @@ 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 = make_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 44/57] rs6000: Support for vectorizing built-in functions

2021-04-27 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 844fee88cf3..080e6a70221 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.  */
@@ -5454,6 +5455,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 41/57] rs6000: Always initialize vector_pair and vector_quad nodes

2021-04-27 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 12f8a14b514..553c5d43bce 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -13388,34 +13388,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 40/57] rs6000: Add sanity to V2DI_type_node definitions

2021-04-27 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 dd548edd1b8..12f8a14b514 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -13150,9 +13150,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));
@@ -13203,7 +13207,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 39/57] rs6000: Darwin builtin support

2021-04-27 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 5609e29affd..0ff2a0e1ed1 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 36/57] rs6000: Add Cell builtins

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-01  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 05bff08db36..5609e29affd 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -1099,6 +1099,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 vsq __builtin_altivec_lvx_v1ti (signed long, const void *);
-- 
2.27.0



[PATCH 35/57] rs6000: Add miscellaneous builtins

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-01  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 71fe0431da6..05bff08db36 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -2796,6 +2796,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 38/57] rs6000: Execute the automatic built-in initialization code

2021-04-27 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 c207d3719e9..dd548edd1b8 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 */
@@ -13488,6 +13489,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 34/57] rs6000: Add MMA builtins

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-24  Bill Schmidt  

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

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index dcb455ed6dd..71fe0431da6 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -3221,3 +3221,407 @@
 
   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_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 
int<4>);
+PMXVF32GERNN nothing {mma,quad}
+
+  v512 __builtin_mma_pmxvf32gernn_internal (v512, vuc, vuc, const int<4>, 
const int<4>);
+PMXVF32GERNN_INTERNAL mma_pmxvf32gernn {mma,quad}
+
+  void 

[PATCH 33/57] rs6000: Add Power10 builtins

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-01  Bill Schmidt  

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

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index f0944ef417b..dcb455ed6dd 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -2794,3 +2794,430 @@
 
   pure vsc __builtin_vsx_xl_len_r (void *, signed long);
 XL_LEN_R xl_len_r {}
+
+
+[power10]
+  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 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 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 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 __builtin_altivec_vdivsw (vsi, vsi);
+VDIVSW divv4si3 {}
+
+  const vull __builtin_altivec_vdivud (vull, vull);
+VDIVUD udivv2di3 {}
+
+  const vui __builtin_altivec_vdivuw (vui, vui);
+VDIVUW udivv4si3 {}
+
+  const vuc __builtin_altivec_vexpandmb (vuc);
+VEXPANDMB vec_expand_v16qi {}
+
+  const vull __builtin_altivec_vexpandmd (vull);
+VEXPANDMD vec_expand_v2di {}
+
+  const vus __builtin_altivec_vexpandmh (vus);
+VEXPANDMH vec_expand_v8hi {}
+
+  const vuq __builtin_altivec_vexpandmq (vuq);
+VEXPANDMQ vec_expand_v1ti {}
+
+  const vui __builtin_altivec_vexpandmw (vui);
+VEXPANDMW vec_expand_v4si {}
+
+  const vull __builtin_altivec_vextddvhx (vull, vull, unsigned int);
+VEXTRACTDR vextractrv2di {}
+
+  const vull __builtin_altivec_vextddvlx (vull, vull, unsigned int);
+VEXTRACTDL vextractlv2di {}
+
+  const vull __builtin_altivec_vextdubvhx (vuc, vuc, unsigned int);
+VEXTRACTBR vextractrv16qi {}
+
+  const vull __builtin_altivec_vextdubvlx (vuc, vuc, unsigned int);
+VEXTRACTBL vextractlv16qi {}
+
+  const vull __builtin_altivec_vextduhvhx (vus, vus, unsigned int);
+VEXTRACTHR vextractrv8hi {}
+
+  const vull __builtin_altivec_vextduhvlx (vus, vus, unsigned int);
+VEXTRACTHL vextractlv8hi {}
+
+  const vull __builtin_altivec_vextduwvhx (vui, vui, unsigned int);
+VEXTRACTWR vextractrv4si {}
+
+  const vull __builtin_altivec_vextduwvlx (vui, vui, unsigned int);
+VEXTRACTWL vextractlv4si {}
+
+  const signed int __builtin_altivec_vextractmb (vsc);
+VEXTRACTMB vec_extract_v16qi {}
+
+  const signed int __builtin_altivec_vextractmd (vsll);
+VEXTRACTMD vec_extract_v2di {}
+
+  const signed int __builtin_altivec_vextractmh (vss);
+

[PATCH 31/57] rs6000: Add Power9 builtins

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-01  Bill Schmidt  

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

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 4fccfc36419..f0944ef417b 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -2434,3 +2434,363 @@
 
   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 30/57] rs6000: Add power8-vector builtins

2021-04-27 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 7ea8598bf16..4fccfc36419 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 32/57] rs6000: Add more type nodes to support builtin processing

2021-04-27 Thread Bill Schmidt via Gcc-patches
Previously we created pointer types on the fly from their base types
whenever we needed one.  It's more efficient to create them up front,
and the new mechanism requires that.

2021-04-02  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): Define.
(ptr_V1TI_type_node): Define.
(ptr_V2DI_type_node): Define.
(ptr_V2DF_type_node): Define.
(ptr_V4SI_type_node): Define.
(ptr_V4SF_type_node): Define.
(ptr_V8HI_type_node): Define.
(ptr_unsigned_V16QI_type_node): Define.
(ptr_unsigned_V1TI_type_node): Define.
(ptr_unsigned_V8HI_type_node): Define.
(ptr_unsigned_V4SI_type_node): Define.
(ptr_unsigned_V2DI_type_node): Define.
(ptr_bool_V16QI_type_node): Define.
(ptr_bool_V8HI_type_node): Define.
(ptr_bool_V4SI_type_node): Define.
(ptr_bool_V2DI_type_node): Define.
(ptr_pixel_V8HI_type_node): Define.
(ptr_intQI_type_node): Define.
(ptr_uintQI_type_node): Define.
(ptr_intHI_type_node): Define.
(ptr_uintHI_type_node): Define.
(ptr_intSI_type_node): Define.
(ptr_uintSI_type_node): Define.
(ptr_intDI_type_node): Define.
(ptr_uintDI_type_node): Define.
(ptr_intTI_type_node): Define.
(ptr_uintTI_type_node): Define.
(ptr_long_integer_type_node): Define.
(ptr_long_unsigned_type_node): Define.
(ptr_float_type_node): Define.
(ptr_double_type_node): Define.
(ptr_long_double_type_node): Define.
(ptr_dfloat64_type_node): Define.
(ptr_dfloat128_type_node): Define.
(ptr_ieee128_type_node): Define.
(ptr_ibm128_type_node): Define.
(ptr_vector_pair_type_node): Define.
(ptr_vector_quad_type_node): Define.
(ptr_long_long_integer_type_node): Define.
(ptr_long_long_unsigned_type_node): Define.
---
 gcc/config/rs6000/rs6000-call.c | 139 
 gcc/config/rs6000/rs6000.h  |  80 ++
 2 files changed, 219 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 19e5b0d2c58..c207d3719e9 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -13152,25 +13152,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",
   

[PATCH 27/57] rs6000: Add VSX builtins

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-02  Bill Schmidt  

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

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index be94f3d0ce4..eface30455e 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -1025,3 +1025,863 @@
 
   const vss __builtin_vec_set_v8hi (vss, signed short, const int<3>);
 VEC_SET_V8HI nothing {set}
+
+
+; VSX builtins.
+[vsx]
+  pure vsq __builtin_altivec_lvx_v1ti (signed long, const void *);
+LVX_V1TI altivec_lvx_v1ti {ldvec}
+
+  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 

[PATCH 26/57] rs6000: Add the rest of the [altivec] stanza to the builtins file

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-02  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): Define.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 828 +++
 gcc/config/rs6000/rs6000-call.c  |   7 +-
 gcc/config/rs6000/rs6000.h   |   2 +
 3 files changed, 833 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index a84a3def2d5..be94f3d0ce4 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -197,3 +197,831 @@
 
   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 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 __builtin_altivec_stvewx (vsi, signed long, void *);
+STVEWX altivec_stvewx {stvec}
+
+  void __builtin_altivec_stvx (vsi, signed 

[PATCH 29/57] rs6000: Add power7 and power7-64 builtins

2021-04-27 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 0dc2cd2c99e..7ea8598bf16 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 19/57] rs6000: Write output to the builtins init file, part 1 of 3

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-01  Bill Schmidt  

gcc/
* config/rs6000/rs6000-gen-builtins.c (write_fntype): New
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 | 153 
 1 file changed, 153 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 48d28af6366..28810f56ec2 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2236,6 +2236,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 ()
@@ -2256,10 +2268,151 @@ write_header_file ()
   return 1;
 }
 
+/* Write code to initialize the built-in function table.  */
+static void
+write_init_bif_table ()
+{
+}
+
+/* Write code to initialize the overload table.  */
+static void
+write_init_ovld_table ()
+{
+  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;
+
+ /* 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");
+   }
+
+ 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)
+   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 ()
 {
+  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 rs6000_builtin_decls_x[RS6000_OVLD_MAX];\n\n");
+
+  rbt_inorder_callback (_rbt, fntype_rbt.rbt_root, write_fntype);
+  fprintf (init_file, "\n");
+
+  fprintf (init_file, "void\n");
+  fprintf (init_file, "rs6000_autoinit_builtins ()\n");
+  fprintf (init_file, "{\n");
+  fprintf (init_file, "  tree t;\n");
+  rbt_inorder_callback (_rbt, fntype_rbt.rbt_root, write_fntype_init);
+  fprintf (init_file, "\n");
+
+  fprintf (init_file,
+  "  

[PATCH 22/57] rs6000: Write static initializations for built-in table

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-24  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 | 104 
 1 file changed, 104 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 7ef297d04f5..aeedb77faf5 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2441,6 +2441,108 @@ write_header_file ()
   return 1;
 }
 
+/* Write the decl and initializer for rs6000_builtin_info_x[].  */
+static void
+write_bif_static_init ()
+{
+  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{%d, %d, %d},\n",
+  bifp->proto.restr_val1[0], bifp->proto.restr_val1[1],
+  bifp->proto.restr_val1[2]);
+  fprintf (init_file, "  /* restr_val2 */\t{%d, %d, %d},\n",
+  bifp->proto.restr_val2[0], bifp->proto.restr_val2[1],
+  bifp->proto.restr_val2[2]);
+  fprintf (init_file, "  /* attr_string */\t\"%s\",\n",
+  (bifp->kind == FNK_CONST ? "= const"
+   : (bifp->kind == FNK_PURE ? "= pure"
+  : (bifp->kind == FNK_FPMATH ? "= fp, const"
+ : "";
+  bool no_icode = !strcmp 

[PATCH 28/57] rs6000: Add available-everywhere and ancient builtins

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-04-02  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 eface30455e..0dc2cd2c99e 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 {}
+
+  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 {}
+
+
+; Builtins that have been around just about forever, but not quite.
+[power5]
+; This will break for long double == _Float128.  libgcc history.
+  const long double __builtin_pack_longdouble (double, double);
+PACK_TF packtf {}
+
+  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 {}
+
+; This will break for long double == _Float128.  libgcc history.
+  const double __builtin_unpack_longdouble (long double, const int<1>);
+UNPACK_TF unpacktf {}
+
+
+; 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 23/57] rs6000: Write static initializations for overload tables

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-03  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 aeedb77faf5..39080e838f3 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2543,6 +2543,58 @@ write_bif_static_init ()
   fprintf (init_file, "  };\n\n");
 }
 
+/* Write the decls and initializers for rs6000_overload_info[] and
+   rs6000_instance_info[].  */
+static void
+write_ovld_static_init ()
+{
+  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 ()
@@ -2711,6 +2763,7 @@ write_init_file ()
   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 25/57] rs6000: Add gengtype handling to the build machinery

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-04  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 5b923354ebb..af913bfed32 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -529,6 +529,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 ed97dc3303f..c8d1a14cf9d 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -23,6 +23,7 @@ TM_H += $(srcdir)/config/rs6000/rs6000-cpus.def
 TM_H += $(srcdir)/config/rs6000/rs6000-modes.h
 PASSES_EXTRA += $(srcdir)/config/rs6000/rs6000-passes.def
 OUT_FILE_DEPS += rs6000-builtins.h
+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 24/57] rs6000: Incorporate new builtins code into the build machinery

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-04  Bill Schmidt  

gcc/
* config.gcc (extra_objs): Include rs6000-builtins.o and
rs6000-c.o.
* config/rs6000/t-rs6000 (OUT_FILE_DEPS): Add rs6000-builtins.h.
(rs6000-gen-builtins.o): New target.
(rbtree.o): Likewise.
(rs6000-gen-builtins): Likewise.
(rs6000-builtins.c): Likewise.
(rs6000-builtins.h): Likewise.
(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 | 43 +-
 2 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index e49e40fbfa1..5b923354ebb 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -513,6 +513,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..ed97dc3303f 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -22,15 +22,12 @@ 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
+OUT_FILE_DEPS += rs6000-builtins.h
 
 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 +44,43 @@ 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
+
+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 20/57] rs6000: Write output to the builtins init file, part 2 of 3

2021-04-27 Thread Bill Schmidt via Gcc-patches
2021-03-03  Bill Schmidt  

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

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 28810f56ec2..82c0567756b 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2272,6 +2272,77 @@ write_header_file ()
 static void
 write_init_bif_table ()
 {
+  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;
+
+  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");
+   }
+
+  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)
+   {
+ 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



  1   2   >