Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-29 Thread Oleg Endo
On Wed, 2013-08-07 at 21:24 +0200, Oleg Endo wrote:
 On Wed, 2013-08-07 at 15:08 -0400, Michael Meissner wrote:
  On Tue, Aug 06, 2013 at 11:45:40PM +0200, Oleg Endo wrote:
   On Mon, 2013-08-05 at 13:25 -1000, Richard Henderson wrote:
On 08/05/2013 12:32 PM, Oleg Endo wrote:
 Thanks, committed as rev 201513.
 4.8 also has the same problem.  The patch applies on 4.8 branch 
 without
 problems and make all-gcc works.
 OK for 4.8, too?

Hum.  I suppose so, since it's relatively self-contained.  I suppose the
out-of-tree openrisc port will thank us...
   
   Maybe it's better to wait for a while and collect follow up patches such
   as the rs6000 one.
  
  The tree right now is broken for the powerpc.  I would prefer to get patches
  installed ASAP rather than waiting for additional ports.
 
 I've just committed the PPC fix for trunk.  Sorry for the delay.
 I haven't committed anything related to this issue on the 4.8 branch
 yet.  I'll do that next week if nothing else comes up.

Sorry for the delay.  I've just backported the 2 patches to 4.8.
Tested with 'make all-gcc' for SH and PPC cross compilers.
Committed as rev 202083.

Cheers,
Oleg
Index: gcc/expr.c
===
--- gcc/expr.c	(revision 202080)
+++ gcc/expr.c	(working copy)
@@ -119,7 +119,7 @@
   int reverse;
 };
 
-static void move_by_pieces_1 (rtx (*) (rtx, ...), enum machine_mode,
+static void move_by_pieces_1 (insn_gen_fn, machine_mode,
 			  struct move_by_pieces_d *);
 static bool block_move_libcall_safe_for_call_parm (void);
 static bool emit_block_move_via_movmem (rtx, rtx, rtx, unsigned, unsigned, HOST_WIDE_INT);
@@ -128,7 +128,7 @@
 static rtx clear_by_pieces_1 (void *, HOST_WIDE_INT, enum machine_mode);
 static void clear_by_pieces (rtx, unsigned HOST_WIDE_INT, unsigned int);
 static void store_by_pieces_1 (struct store_by_pieces_d *, unsigned int);
-static void store_by_pieces_2 (rtx (*) (rtx, ...), enum machine_mode,
+static void store_by_pieces_2 (insn_gen_fn, machine_mode,
 			   struct store_by_pieces_d *);
 static tree clear_storage_libcall_fn (int);
 static rtx compress_float_constant (rtx, rtx);
@@ -1043,7 +1043,7 @@
to make a move insn for that mode.  DATA has all the other info.  */
 
 static void
-move_by_pieces_1 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
+move_by_pieces_1 (insn_gen_fn genfun, machine_mode mode,
 		  struct move_by_pieces_d *data)
 {
   unsigned int size = GET_MODE_SIZE (mode);
@@ -2657,7 +2657,7 @@
to make a move insn for that mode.  DATA has all the other info.  */
 
 static void
-store_by_pieces_2 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
+store_by_pieces_2 (insn_gen_fn genfun, machine_mode mode,
 		   struct store_by_pieces_d *data)
 {
   unsigned int size = GET_MODE_SIZE (mode);
Index: gcc/recog.h
===
--- gcc/recog.h	(revision 202080)
+++ gcc/recog.h	(working copy)
@@ -256,8 +256,58 @@
 
 typedef int (*insn_operand_predicate_fn) (rtx, enum machine_mode);
 typedef const char * (*insn_output_fn) (rtx *, rtx);
-typedef rtx (*insn_gen_fn) (rtx, ...);
 
+struct insn_gen_fn
+{
+  typedef rtx (*f0) (void);
+  typedef rtx (*f1) (rtx);
+  typedef rtx (*f2) (rtx, rtx);
+  typedef rtx (*f3) (rtx, rtx, rtx);
+  typedef rtx (*f4) (rtx, rtx, rtx, rtx);
+  typedef rtx (*f5) (rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f6) (rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f12) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f13) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f14) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f15) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f16) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+
+  typedef f0 stored_funcptr;
+
+  rtx operator () (void) const { return ((f0)func) (); }
+  rtx operator () (rtx a0) const { return ((f1)func) (a0); }
+  rtx operator () (rtx a0, rtx a1) const { return ((f2)func) (a0, a1); }
+  rtx operator () (rtx a0, rtx a1, rtx a2) const { return ((f3)func) (a0, a1, a2); }
+  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3) const { return ((f4)func) (a0, a1, a2, a3); }
+  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4) const { return ((f5)func) (a0, a1, a2, a3, a4); }
+  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5) const { return ((f6)func) (a0, a1, a2, a3, a4, a5); }
+  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx 

Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-29 Thread Jakub Jelinek
On Thu, Aug 29, 2013 at 08:45:33PM +0200, Oleg Endo wrote:
 Sorry for the delay.  I've just backported the 2 patches to 4.8.
 Tested with 'make all-gcc' for SH and PPC cross compilers.
 Committed as rev 202083.

Please fix the overly long lines as a follow-up.

 +struct insn_gen_fn
 +{
 +  typedef rtx (*f0) (void);
 +  typedef rtx (*f1) (rtx);
 +  typedef rtx (*f2) (rtx, rtx);
 +  typedef rtx (*f3) (rtx, rtx, rtx);
 +  typedef rtx (*f4) (rtx, rtx, rtx, rtx);
 +  typedef rtx (*f5) (rtx, rtx, rtx, rtx, rtx);
 +  typedef rtx (*f6) (rtx, rtx, rtx, rtx, rtx, rtx);
 +  typedef rtx (*f7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +  typedef rtx (*f8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +  typedef rtx (*f9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +  typedef rtx (*f10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +  typedef rtx (*f11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +  typedef rtx (*f12) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
 rtx);
 +  typedef rtx (*f13) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
 rtx, rtx);
 +  typedef rtx (*f14) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
 rtx, rtx, rtx);
 +  typedef rtx (*f15) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
 rtx, rtx, rtx, rtx);
 +  typedef rtx (*f16) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
 rtx, rtx, rtx, rtx, rtx);
 +
 +  typedef f0 stored_funcptr;
 +
 +  rtx operator () (void) const { return ((f0)func) (); }
 +  rtx operator () (rtx a0) const { return ((f1)func) (a0); }
 +  rtx operator () (rtx a0, rtx a1) const { return ((f2)func) (a0, a1); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2) const { return ((f3)func) (a0, 
 a1, a2); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3) const { return ((f4)func) 
 (a0, a1, a2, a3); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4) const { return 
 ((f5)func) (a0, a1, a2, a3, a4); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5) const { 
 return ((f6)func) (a0, a1, a2, a3, a4, a5); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6) 
 const { return ((f7)func) (a0, a1, a2, a3, a4, a5, a6); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
 rtx a7) const { return ((f8)func) (a0, a1, a2, a3, a4, a5, a6, a7); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
 rtx a7, rtx a8) const { return ((f9)func) (a0, a1, a2, a3, a4, a5, a6, a7, 
 a8); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
 rtx a7, rtx a8, rtx a9) const { return ((f10)func) (a0, a1, a2, a3, a4, a5, 
 a6, a7, a8, a9); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
 rtx a7, rtx a8, rtx a9, rtx a10) const { return ((f11)func) (a0, a1, a2, a3, 
 a4, a5, a6, a7, a8, a9, a10); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
 rtx a7, rtx a8, rtx a9, rtx a10, rtx a11) const { return ((f12)func) (a0, a1, 
 a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
 rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12) const { return ((f13)func) 
 (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
 rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13) const { return 
 ((f14)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
 rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14) const { 
 return ((f15)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, 
 a13, a14); }
 +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
 rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14, rtx a15) 
 const { return ((f16)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, 
 a12, a13, a14, a15); }
 +
 +  // This is for compatibility of code that invokes functions like
 +  //   (*funcptr) (arg)
 +  insn_gen_fn operator * (void) const { return *this; }
 +
 +  // The wrapped function pointer must be public and there must not be any
 +  // constructors.  Otherwise the insn_data_d struct initializers generated
 +  // by genoutput.c will result in static initializer functions, which 
 defeats
 +  // the purpose of the generated insn_data_d array.
 +  stored_funcptr func;
 +};

Jakub


Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-29 Thread Oleg Endo
On Thu, 2013-08-29 at 20:51 +0200, Jakub Jelinek wrote:
 On Thu, Aug 29, 2013 at 08:45:33PM +0200, Oleg Endo wrote:
  Sorry for the delay.  I've just backported the 2 patches to 4.8.
  Tested with 'make all-gcc' for SH and PPC cross compilers.
  Committed as rev 202083.
 
 Please fix the overly long lines as a follow-up.
 

In m original mail
http://gcc.gnu.org/ml/gcc-patches/2013-07/msg01315.html
I wrote:

* I don't know whether it's really needed to properly format the code of
class insn_gen_fn.  After reading the first two or three overloads
(which do fit into 80 columns) one gets the idea and so I guess nobody
is going to read that stuff completely anyway.

Nobody commented on it and after Richard's OK to the patch I assumed
it's fine that way as an exception.

Of course I'll do it if you insist :)

Cheers,
Oleg


  +struct insn_gen_fn
  +{
  +  typedef rtx (*f0) (void);
  +  typedef rtx (*f1) (rtx);
  +  typedef rtx (*f2) (rtx, rtx);
  +  typedef rtx (*f3) (rtx, rtx, rtx);
  +  typedef rtx (*f4) (rtx, rtx, rtx, rtx);
  +  typedef rtx (*f5) (rtx, rtx, rtx, rtx, rtx);
  +  typedef rtx (*f6) (rtx, rtx, rtx, rtx, rtx, rtx);
  +  typedef rtx (*f7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
  +  typedef rtx (*f8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
  +  typedef rtx (*f9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
  +  typedef rtx (*f10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
  +  typedef rtx (*f11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
  rtx);
  +  typedef rtx (*f12) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
  rtx, rtx);
  +  typedef rtx (*f13) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
  rtx, rtx, rtx);
  +  typedef rtx (*f14) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
  rtx, rtx, rtx, rtx);
  +  typedef rtx (*f15) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
  rtx, rtx, rtx, rtx, rtx);
  +  typedef rtx (*f16) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, 
  rtx, rtx, rtx, rtx, rtx, rtx);
  +
  +  typedef f0 stored_funcptr;
  +
  +  rtx operator () (void) const { return ((f0)func) (); }
  +  rtx operator () (rtx a0) const { return ((f1)func) (a0); }
  +  rtx operator () (rtx a0, rtx a1) const { return ((f2)func) (a0, a1); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2) const { return ((f3)func) (a0, 
  a1, a2); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3) const { return 
  ((f4)func) (a0, a1, a2, a3); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4) const { return 
  ((f5)func) (a0, a1, a2, a3, a4); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5) const { 
  return ((f6)func) (a0, a1, a2, a3, a4, a5); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6) 
  const { return ((f7)func) (a0, a1, a2, a3, a4, a5, a6); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
  rtx a7) const { return ((f8)func) (a0, a1, a2, a3, a4, a5, a6, a7); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
  rtx a7, rtx a8) const { return ((f9)func) (a0, a1, a2, a3, a4, a5, a6, a7, 
  a8); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
  rtx a7, rtx a8, rtx a9) const { return ((f10)func) (a0, a1, a2, a3, a4, a5, 
  a6, a7, a8, a9); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
  rtx a7, rtx a8, rtx a9, rtx a10) const { return ((f11)func) (a0, a1, a2, 
  a3, a4, a5, a6, a7, a8, a9, a10); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
  rtx a7, rtx a8, rtx a9, rtx a10, rtx a11) const { return ((f12)func) (a0, 
  a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
  rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12) const { return 
  ((f13)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
  rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13) const { return 
  ((f14)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
  rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14) const 
  { return ((f15)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, 
  a12, a13, a14); }
  +  rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, 
  rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14, rtx 
  a15) const { return ((f16)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, 
  a10, a11, a12, a13, a14, a15); }
  +
  +  // This is for compatibility of code that invokes functions like
  +  //   (*funcptr) (arg)
  +  insn_gen_fn operator * (void) const { return *this; }
  +
  +  // The wrapped function pointer must be public and there must not be any
  +  // constructors.  Otherwise the insn_data_d struct initializers generated

Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-27 Thread Stefan Kristiansson
On Tue, Aug 27, 2013 at 11:03:32AM +0200, Richard Biener wrote:
 On Wed, Jul 10, 2013 at 3:14 AM, Stefan Kristiansson
 stefan.kristians...@saunalahti.fi wrote:
  The (static arg) generator functions are casted to a var arg
  function pointer, making the assumption that the ABI for passing
  the arguments will be the same as for static arguments.
  This isn't a valid assumption on all architectures, var args might for
  example be passed on the stack, even if there would be function argument
  registers still available.
 
  There exists a bugreport for the problem here:
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12081
 
  This patch is taken from the suggestion by Rask Ingemann Lambertsen
  and updated to the current svn tip of trunk.
 
  gcc/Changelog:
 
  2013-07-10  Stefan Kristiansson  stefan.kristians...@saunalahti.fi
 
  PR target/12081
  * recog.h (rtx (*insn_gen_fn) (rtx, ...)): Remove typedef.
  (genfun): Replace var arg function pointer with static argument
  function pointers.
  * optabs.h (GEN_FCN): Replace single define with ones of the
  form GEN_FCN?, where ? is the number of arguments.
  * reload1.c: Use GEN_FCN? instead of GEN_FCN
 
 Can't we use a template for all this to avoid the union and *[12345] mess?
 

Oleg Endo proposed a cleaner approach using functors here:
http://gcc.gnu.org/ml/gcc-patches/2013-07/msg01315.html
and AFAIK that (or something close to it) is already applied.

Stefan


Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-07 Thread Michael Meissner
On Tue, Aug 06, 2013 at 11:45:40PM +0200, Oleg Endo wrote:
 On Mon, 2013-08-05 at 13:25 -1000, Richard Henderson wrote:
  On 08/05/2013 12:32 PM, Oleg Endo wrote:
   Thanks, committed as rev 201513.
   4.8 also has the same problem.  The patch applies on 4.8 branch without
   problems and make all-gcc works.
   OK for 4.8, too?
  
  Hum.  I suppose so, since it's relatively self-contained.  I suppose the
  out-of-tree openrisc port will thank us...
 
 Maybe it's better to wait for a while and collect follow up patches such
 as the rs6000 one.

The tree right now is broken for the powerpc.  I would prefer to get patches
installed ASAP rather than waiting for additional ports.

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



Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-07 Thread Oleg Endo
On Wed, 2013-08-07 at 15:08 -0400, Michael Meissner wrote:
 On Tue, Aug 06, 2013 at 11:45:40PM +0200, Oleg Endo wrote:
  On Mon, 2013-08-05 at 13:25 -1000, Richard Henderson wrote:
   On 08/05/2013 12:32 PM, Oleg Endo wrote:
Thanks, committed as rev 201513.
4.8 also has the same problem.  The patch applies on 4.8 branch without
problems and make all-gcc works.
OK for 4.8, too?
   
   Hum.  I suppose so, since it's relatively self-contained.  I suppose the
   out-of-tree openrisc port will thank us...
  
  Maybe it's better to wait for a while and collect follow up patches such
  as the rs6000 one.
 
 The tree right now is broken for the powerpc.  I would prefer to get patches
 installed ASAP rather than waiting for additional ports.

I've just committed the PPC fix for trunk.  Sorry for the delay.
I haven't committed anything related to this issue on the 4.8 branch
yet.  I'll do that next week if nothing else comes up.

Cheers,
Oleg



Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-06 Thread Oleg Endo
On Mon, 2013-08-05 at 13:25 -1000, Richard Henderson wrote:
 On 08/05/2013 12:32 PM, Oleg Endo wrote:
  Thanks, committed as rev 201513.
  4.8 also has the same problem.  The patch applies on 4.8 branch without
  problems and make all-gcc works.
  OK for 4.8, too?
 
 Hum.  I suppose so, since it's relatively self-contained.  I suppose the
 out-of-tree openrisc port will thank us...

Maybe it's better to wait for a while and collect follow up patches such
as the rs6000 one.

Cheers,
Oleg



[PING] Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-05 Thread Oleg Endo
Hello,

Any comments?
(patch is here: http://gcc.gnu.org/ml/gcc-patches/2013-07/msg01315.html)

Cheers,
Oleg

On Sat, 2013-07-27 at 14:52 +0200, Oleg Endo wrote:
 Hi,
 
 On Fri, 2013-07-26 at 08:51 +0200, Uros Bizjak wrote:
 
  BTW: I am not c++ expert, but doesn't c++ offer some sort of
  abstraction to get rid of
  
  +  union {
  +rtx (*argc0) (void);
  +rtx (*argc1) (rtx);
  +rtx (*argc2) (rtx, rtx);
  +rtx (*argc3) (rtx, rtx, rtx);
  +rtx (*argc4) (rtx, rtx, rtx, rtx);
  +rtx (*argc5) (rtx, rtx, rtx, rtx, rtx);
  +rtx (*argc6) (rtx, rtx, rtx, rtx, rtx, rtx);
  +rtx (*argc7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
  +rtx (*argc8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
  +rtx (*argc9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
  +rtx (*argc10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
  +rtx (*argc11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
  +  } genfun;
  
 
 Variadic templates maybe, but we can't use them since that requires C
 ++11.
 
 Anyway, I think it's better to turn the insn_gen_fn typedef in recog.h
 into a functor.  The change is quite transparent to the users, as the
 attached patch shows.  There really is no need for things like GEN_FCN?,
 nor do we need to fixup all the backends etc.
 
 I've tested the attached patch on my SH cross setup with 'make all-gcc'
 and it can still produce a valid 'hello world'.  Not sure whether it's
 sufficient.
 
 Some notes regarding the patch:
 
 * The whole arg list thing could probably be folded with x-macros or
 something like that, but I don't think it's worth doing it for this
 single case.  If we can use C++11 in GCC at some point in time in the
 future, the insn_gen_fn implementation can be folded with variadic
 templates without touching all the code that uses it.
 
 * I had to extend the number of max. args to 16, otherwise the SH
 backend's sync.md code wouldn't compile.
 
 * I don't know whether it's really needed to properly format the code of
 class insn_gen_fn.  After reading the first two or three overloads
 (which do fit into 80 columns) one gets the idea and so I guess nobody
 is going to read that stuff completely anyway.
 
 * The class insn_gen_fn is a POD, so it can be passed by value without
 any overhead, just like a normal function pointer.  Same goes for the
 function call through the wrapper class.
 
 * Initially I had overloaded constructors in class insn_gen_fn which
 worked and didn't require the cast in genoutput.c.  However, it
 introduced static initializer functions and defeated the purpose of the
 generated const struct insn_data_d insn_data[].  This is worked around
 by casting the function pointer to insn_gen_fn::stored_funcptr. (Since
 it's C++ and not C it won't implicitly cast to void*).
 
 * The whole thing will fall apart if the stored pointer to a function
 'rtx (*)(void)' is different from a stored pointer to e.g. 'rtx
 (*)(rtx)'.  But I guess this is not likely to happen.
 
 Cheers,
 Oleg
 
 gcc/ChangeLog:
   * recog.h (rtx (*insn_gen_fn) (rtx, ...)): Replace typedef with
   new class insn_gen_fn.
   * expr.c (move_by_pieces_1, store_by_pieces_2): Replace
   argument rtx (*) (rtx, ...) with insn_gen_fn.
   * genoutput.c (output_insn_data): Cast gen_? function pointers
   to insn_gen_fn::stored_funcptr.  Add initializer braces.




Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-05 Thread Richard Henderson
On 07/27/2013 02:52 AM, Oleg Endo wrote:
 gcc/ChangeLog:
   * recog.h (rtx (*insn_gen_fn) (rtx, ...)): Replace typedef with
   new class insn_gen_fn.
   * expr.c (move_by_pieces_1, store_by_pieces_2): Replace
   argument rtx (*) (rtx, ...) with insn_gen_fn.
   * genoutput.c (output_insn_data): Cast gen_? function pointers
   to insn_gen_fn::stored_funcptr.  Add initializer braces.

Ok.


r~


Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-05 Thread Oleg Endo
On Mon, 2013-08-05 at 11:42 -1000, Richard Henderson wrote:
 On 07/27/2013 02:52 AM, Oleg Endo wrote:
  gcc/ChangeLog:
  * recog.h (rtx (*insn_gen_fn) (rtx, ...)): Replace typedef with
  new class insn_gen_fn.
  * expr.c (move_by_pieces_1, store_by_pieces_2): Replace
  argument rtx (*) (rtx, ...) with insn_gen_fn.
  * genoutput.c (output_insn_data): Cast gen_? function pointers
  to insn_gen_fn::stored_funcptr.  Add initializer braces.
 
 Ok.
 

Thanks, committed as rev 201513.
4.8 also has the same problem.  The patch applies on 4.8 branch without
problems and make all-gcc works.
OK for 4.8, too?

Cheers,
Oleg



Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-08-05 Thread Richard Henderson
On 08/05/2013 12:32 PM, Oleg Endo wrote:
 Thanks, committed as rev 201513.
 4.8 also has the same problem.  The patch applies on 4.8 branch without
 problems and make all-gcc works.
 OK for 4.8, too?

Hum.  I suppose so, since it's relatively self-contained.  I suppose the
out-of-tree openrisc port will thank us...


r~


Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-07-27 Thread Oleg Endo
Hi,

On Fri, 2013-07-26 at 08:51 +0200, Uros Bizjak wrote:

 BTW: I am not c++ expert, but doesn't c++ offer some sort of
 abstraction to get rid of
 
 +  union {
 +rtx (*argc0) (void);
 +rtx (*argc1) (rtx);
 +rtx (*argc2) (rtx, rtx);
 +rtx (*argc3) (rtx, rtx, rtx);
 +rtx (*argc4) (rtx, rtx, rtx, rtx);
 +rtx (*argc5) (rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc6) (rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +  } genfun;
 

Variadic templates maybe, but we can't use them since that requires C
++11.

Anyway, I think it's better to turn the insn_gen_fn typedef in recog.h
into a functor.  The change is quite transparent to the users, as the
attached patch shows.  There really is no need for things like GEN_FCN?,
nor do we need to fixup all the backends etc.

I've tested the attached patch on my SH cross setup with 'make all-gcc'
and it can still produce a valid 'hello world'.  Not sure whether it's
sufficient.

Some notes regarding the patch:

* The whole arg list thing could probably be folded with x-macros or
something like that, but I don't think it's worth doing it for this
single case.  If we can use C++11 in GCC at some point in time in the
future, the insn_gen_fn implementation can be folded with variadic
templates without touching all the code that uses it.

* I had to extend the number of max. args to 16, otherwise the SH
backend's sync.md code wouldn't compile.

* I don't know whether it's really needed to properly format the code of
class insn_gen_fn.  After reading the first two or three overloads
(which do fit into 80 columns) one gets the idea and so I guess nobody
is going to read that stuff completely anyway.

* The class insn_gen_fn is a POD, so it can be passed by value without
any overhead, just like a normal function pointer.  Same goes for the
function call through the wrapper class.

* Initially I had overloaded constructors in class insn_gen_fn which
worked and didn't require the cast in genoutput.c.  However, it
introduced static initializer functions and defeated the purpose of the
generated const struct insn_data_d insn_data[].  This is worked around
by casting the function pointer to insn_gen_fn::stored_funcptr. (Since
it's C++ and not C it won't implicitly cast to void*).

* The whole thing will fall apart if the stored pointer to a function
'rtx (*)(void)' is different from a stored pointer to e.g. 'rtx
(*)(rtx)'.  But I guess this is not likely to happen.

Cheers,
Oleg

gcc/ChangeLog:
* recog.h (rtx (*insn_gen_fn) (rtx, ...)): Replace typedef with
new class insn_gen_fn.
* expr.c (move_by_pieces_1, store_by_pieces_2): Replace
argument rtx (*) (rtx, ...) with insn_gen_fn.
* genoutput.c (output_insn_data): Cast gen_? function pointers
to insn_gen_fn::stored_funcptr.  Add initializer braces.
Index: gcc/expr.c
===
--- gcc/expr.c	(revision 201282)
+++ gcc/expr.c	(working copy)
@@ -119,7 +119,7 @@
   int reverse;
 };
 
-static void move_by_pieces_1 (rtx (*) (rtx, ...), enum machine_mode,
+static void move_by_pieces_1 (insn_gen_fn, machine_mode,
 			  struct move_by_pieces_d *);
 static bool block_move_libcall_safe_for_call_parm (void);
 static bool emit_block_move_via_movmem (rtx, rtx, rtx, unsigned, unsigned, HOST_WIDE_INT);
@@ -128,7 +128,7 @@
 static rtx clear_by_pieces_1 (void *, HOST_WIDE_INT, enum machine_mode);
 static void clear_by_pieces (rtx, unsigned HOST_WIDE_INT, unsigned int);
 static void store_by_pieces_1 (struct store_by_pieces_d *, unsigned int);
-static void store_by_pieces_2 (rtx (*) (rtx, ...), enum machine_mode,
+static void store_by_pieces_2 (insn_gen_fn, machine_mode,
 			   struct store_by_pieces_d *);
 static tree clear_storage_libcall_fn (int);
 static rtx compress_float_constant (rtx, rtx);
@@ -1043,7 +1043,7 @@
to make a move insn for that mode.  DATA has all the other info.  */
 
 static void
-move_by_pieces_1 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
+move_by_pieces_1 (insn_gen_fn genfun, machine_mode mode,
 		  struct move_by_pieces_d *data)
 {
   unsigned int size = GET_MODE_SIZE (mode);
@@ -2657,7 +2657,7 @@
to make a move insn for that mode.  DATA has all the other info.  */
 
 static void
-store_by_pieces_2 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
+store_by_pieces_2 (insn_gen_fn genfun, machine_mode mode,
 		   struct store_by_pieces_d *data)
 {
   unsigned int size = GET_MODE_SIZE (mode);
Index: gcc/genoutput.c
===
--- gcc/genoutput.c	(revision 201282)
+++ gcc/genoutput.c	(working copy)
@@ -404,9 +404,9 @@
 

Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-07-27 Thread Oleg Endo
On Sat, 2013-07-27 at 14:52 +0200, Oleg Endo wrote:

 * I had to extend the number of max. args to 16, otherwise the SH
 backend's sync.md code wouldn't compile.

The error message was misleading.  It wasn't sync.md but some other SH
insn gen func that takes 16 args.  Anyway, doesn't change the original
fact that 11 args are not enough for all :)

Cheers,
Oleg



Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-07-26 Thread Uros Bizjak
Hello!

 The (static arg) generator functions are casted to a var arg
 function pointer, making the assumption that the ABI for passing
 the arguments will be the same as for static arguments.
 This isn't a valid assumption on all architectures, var args might for
 example be passed on the stack, even if there would be function argument
 registers still available.

 There exists a bugreport for the problem here:
 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12081

 This patch is taken from the suggestion by Rask Ingemann Lambertsen
 and updated to the current svn tip of trunk.

Stefan, can you resubmit an updated patch (with proposed update from [1])?

I would really like to see this patch in the mainline.

BTW: I am not c++ expert, but doesn't c++ offer some sort of
abstraction to get rid of

+  union {
+rtx (*argc0) (void);
+rtx (*argc1) (rtx);
+rtx (*argc2) (rtx, rtx);
+rtx (*argc3) (rtx, rtx, rtx);
+rtx (*argc4) (rtx, rtx, rtx, rtx);
+rtx (*argc5) (rtx, rtx, rtx, rtx, rtx);
+rtx (*argc6) (rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  } genfun;

[1] http://gcc.gnu.org/ml/gcc-patches/2013-07/msg00448.html

Thanks,
Uros.


Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-07-11 Thread Stefan Kristiansson
On Wed, Jul 10, 2013 at 09:18:53AM +0200, Andreas Schwab wrote:
 
 I don't think there is a need to conditionalize this on
 HAVE_DESIGNATED_UNION_INITIALIZERS.  All function pointers are alike, so
 it should be good enough to cast on assignment and use the right
 alternative on call.

You mean something like this?

gcc/recog.h:
@@ -298,7 +297,21 @@
 insn_output_fn function;
   } output;
 #endif
-  const insn_gen_fn genfun;
+  union {
+rtx (*argc0)   (void);
+rtx (*argc1)   (rtx);
+rtx (*argc2)   (rtx, rtx);
+rtx (*argc3)   (rtx, rtx, rtx);
+rtx (*argc4)   (rtx, rtx, rtx, rtx);
+rtx (*argc5)   (rtx, rtx, rtx, rtx, rtx);
+rtx (*argc6)   (rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc7)   (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc8)   (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc9)   (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc10)  (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+rtx (*argc11)  (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  } genfun;
+
   const struct insn_operand_data *const operand;
 
   const char n_generator_args;

gcc/genoutput.c:
@@ -404,9 +404,9 @@
}
 
   if (d-name  d-name[0] != '*')
-   printf ((insn_gen_fn) gen_%s,\n, d-name);
+   printf ({ (rtx (*) (void)) gen_%s },\n, d-name);
   else
-   printf (0,\n);
+   printf ({ 0 },\n);
 
   printf (operand_data[%d],\n, d-operand_number);
   printf (%d,\n, d-n_generator_args);

Fair enough, that makes the printing routine a bit more clean and
removes some code duplication in the declaration.

Stefan


Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-07-11 Thread Andreas Schwab
Stefan Kristiansson stefan.kristians...@saunalahti.fi writes:

 You mean something like this?

Yes, that's what I had in mind.

Andreas.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
And now for something completely different.


Re: [PATCH] Fix illegal cast to rtx (*insn_gen_fn) (rtx, ...)

2013-07-10 Thread Andreas Schwab
Stefan Kristiansson stefan.kristians...@saunalahti.fi writes:

 @@ -291,14 +290,41 @@
  const char *const *multi;
  insn_output_fn function;
} output;
 +  union {
 +rtx (*argc0) (void);
 +rtx (*argc1) (rtx);
 +rtx (*argc2) (rtx, rtx);
 +rtx (*argc3) (rtx, rtx, rtx);
 +rtx (*argc4) (rtx, rtx, rtx, rtx);
 +rtx (*argc5) (rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc6) (rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc10)(rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc11)(rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +  } genfun;
  #else
struct {
  const char *single;
  const char *const *multi;
  insn_output_fn function;
} output;
 +  struct {
 +rtx (*argc0) (void);
 +rtx (*argc1) (rtx);
 +rtx (*argc2) (rtx, rtx);
 +rtx (*argc3) (rtx, rtx, rtx);
 +rtx (*argc4) (rtx, rtx, rtx, rtx);
 +rtx (*argc5) (rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc6) (rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc10)(rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +rtx (*argc11)(rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 +  } genfun;

I don't think there is a need to conditionalize this on
HAVE_DESIGNATED_UNION_INITIALIZERS.  All function pointers are alike, so
it should be good enough to cast on assignment and use the right
alternative on call.

Andreas.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
And now for something completely different.