This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] -mjsr option bug fix


Hi,

The -mjsr option in RX should ensure the that BSR instruction is not
generated, only JSR instruction should be generated.
However this does not work as expected: BSR instruction still gets generated
even if -mjsr is passed in the command line.
This is reproducible even if test cases from the gcc testsuite, for example:
gcc.c-torture\compile\920625-1.c
gcc.c-torture\compile\20051216-1.c
gcc.dg\torture\builtin-explog-1.c

The following patch fixes this issue by adding a new constraint to
call_internal and call_value_internal.
The patch also contains a test case which I created as follows:
1. I copied gcc.c-torture\compile\20051216-1.c  to gcc.target\rx and renamed
to mjsr.c
2. added the following lines to scan the assembly files for BSR. If BSR is
present the test fails.
/* { dg-do compile } */
/* { dg-options "-O2 -mjsr" } */
/* { dg-final { scan-assembler-not "bsr" } } */

Regression test is OK, tested with the following command:
make -k check-gcc RUNTESTFLAGS=--target_board=rx-sim

Please let me know if this is OK. Thank you!

Best Regards,
Sebastian

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 256278)
+++ ChangeLog	(working copy)
@@ -1,3 +1,10 @@
+2018-01-05  Sebastian Perta  <sebastian.perta@renesas.com>
+
+	* config/rx/constraints.md: added new constraint CALL_OP_SYMBOL_REF 
+	to allow or block "symbol_ref" depending on value of TARGET_JSR
+	* config/rx/rx.md: use CALL_OP_SYMBOL_REF in call_internal and 
+	call_value_internal insns
+
 2018-01-05  Richard Sandiford  <richard.sandiford@linaro.org>
 
 	* tree-vect-data-refs.c (vect_compute_data_ref_alignment): Don't
Index: config/rx/constraints.md
===================================================================
--- config/rx/constraints.md	(revision 256278)
+++ config/rx/constraints.md	(working copy)
@@ -106,3 +106,9 @@
        )
   )
 )
+
+(define_constraint "CALL_OP_SYMBOL_REF"
+"constraint for call instructions using symbol ref"
+(and (match_test "!TARGET_JSR")
+     (match_code "symbol_ref"))
+)
Index: config/rx/rx.md
===================================================================
--- config/rx/rx.md	(revision 256278)
+++ config/rx/rx.md	(working copy)
@@ -438,7 +438,7 @@
 )
 
 (define_insn "call_internal"
-  [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol"))
+  [(call (mem:QI (match_operand:SI 0 "rx_call_operand"
"r,CALL_OP_SYMBOL_REF"))
 	 (const_int 0))
    (clobber (reg:CC CC_REG))]
   ""
@@ -466,7 +466,7 @@
 
 (define_insn "call_value_internal"
   [(set (match_operand                  0 "register_operand" "=r,r")
-	(call (mem:QI (match_operand:SI 1 "rx_call_operand"   "r,Symbol"))
+	(call (mem:QI (match_operand:SI 1 "rx_call_operand"
"r,CALL_OP_SYMBOL_REF"))
 	      (const_int 0)))
    (clobber (reg:CC CC_REG))]
   ""
Index: testsuite/gcc.target/rx/mjsr.c
===================================================================
--- testsuite/gcc.target/rx/mjsr.c	(nonexistent)
+++ testsuite/gcc.target/rx/mjsr.c	(working copy)
@@ -0,0 +1,134 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mjsr" } */
+
+void *malloc (__SIZE_TYPE__);
+void *realloc (void *, __SIZE_TYPE__);
+
+struct A { double x, y; };
+struct B { double x0, y0, x1, y1; };
+struct C { int n_points; int dir; struct B bbox; struct A *points; };
+struct D { int n_segs; struct C segs[1]; };
+
+void foo (int, int, int *, int, int *, struct A **, int *, int *,
+	  struct D *, int *, struct D **, int *, int **);
+int baz (struct A, struct A, struct A, struct A);
+
+static void
+bar (struct D *svp, int *n_points_max,
+     struct A p, int *seg_map, int *active_segs, int i)
+{
+  int asi, n_points;
+  struct C *seg;
+
+  asi = seg_map[active_segs[i]];
+  seg = &svp->segs[asi];
+  n_points = seg->n_points;
+  seg->points = ((struct A *)
+		realloc (seg->points, (n_points_max[asi] <<= 1) * sizeof
(struct A)));
+  seg->points[n_points] = p;
+  seg->bbox.y1 = p.y;
+  seg->n_points++;
+}
+
+struct D *
+test (struct D *vp)
+{
+  int *active_segs, n_active_segs, *cursor, seg_idx;
+  double y, share_x;
+  int tmp1, tmp2, asi, i, j, *n_ips, *n_ips_max, n_segs_max;
+  struct A **ips, p_curs, *pts;
+  struct D *new_vp;
+  int *n_points_max, *seg_map, first_share;
+
+  n_segs_max = 16;
+  new_vp = (struct D *) malloc (sizeof (struct D) +
+				(n_segs_max - 1) * sizeof (struct C));
+  new_vp->n_segs = 0;
+
+  if (vp->n_segs == 0)
+    return new_vp;
+
+  active_segs = ((int *) malloc ((vp->n_segs) * sizeof (int)));
+  cursor = ((int *) malloc ((vp->n_segs) * sizeof (int)));
+
+  seg_map = ((int *) malloc ((vp->n_segs) * sizeof (int)));
+  n_ips = ((int *) malloc ((vp->n_segs) * sizeof (int)));
+  n_ips_max = ((int *) malloc ((vp->n_segs) * sizeof (int)));
+  ips = ((struct A * *) malloc ((vp->n_segs) * sizeof (struct A *)));
+
+  n_points_max = ((int *) malloc ((n_segs_max) * sizeof (int)));
+
+  n_active_segs = 0;
+  seg_idx = 0;
+  y = vp->segs[0].points[0].y;
+  while (seg_idx < vp->n_segs || n_active_segs > 0)
+    {
+      for (i = 0; i < n_active_segs; i++)
+	{
+	  asi = active_segs[i];
+	  if (vp->segs[asi].n_points - 1 == cursor[asi] &&
+	      vp->segs[asi].points[cursor[asi]].y == y)
+	    i--;
+	}
+
+      while (seg_idx < vp->n_segs && y == vp->segs[seg_idx].points[0].y)
+	{
+	  cursor[seg_idx] = 0;
+	  n_ips[seg_idx] = 1;
+	  n_ips_max[seg_idx] = 2;
+	  ips[seg_idx] =
+	    ((struct A *) malloc ((n_ips_max[seg_idx]) * sizeof (struct
A)));
+	  ips[seg_idx][0] = vp->segs[seg_idx].points[0];
+	  pts = ((struct A *) malloc ((16) * sizeof (struct A)));
+	  pts[0] = vp->segs[seg_idx].points[0];
+	  tmp1 = seg_idx;
+	  for (j = i; j < n_active_segs; j++)
+	    {
+	      tmp2 = active_segs[j];
+	      active_segs[j] = tmp1;
+	      tmp1 = tmp2;
+	    }
+	  active_segs[n_active_segs] = tmp1;
+	  n_active_segs++;
+	  seg_idx++;
+	}
+      first_share = -1;
+      share_x = 0;
+
+      for (i = 0; i < n_active_segs; i++)
+	{
+	  asi = active_segs[i];
+	  p_curs = ips[asi][1];
+	  if (p_curs.y == y)
+	    {
+	      bar (new_vp, n_points_max,
+		   p_curs, seg_map, active_segs, i);
+
+	      n_ips[asi]--;
+	      for (j = 0; j < n_ips[asi]; j++)
+		ips[asi][j] = ips[asi][j + 1];
+
+	      if (first_share < 0 || p_curs.x != share_x)
+		{
+		  foo (first_share, i,
+		       active_segs, n_active_segs,
+		       cursor, ips, n_ips, n_ips_max, vp, seg_map,
+		       &new_vp, &n_segs_max, &n_points_max);
+		  first_share = i;
+		  share_x = p_curs.x;
+		}
+	    }
+	  else
+	    {
+	      foo (first_share, i,
+		   active_segs, n_active_segs,
+		   cursor, ips, n_ips, n_ips_max, vp, seg_map,
+		   &new_vp, &n_segs_max, &n_points_max);
+	      first_share = -1;
+	    }
+	}
+    }
+  return new_vp;
+}
+
+/* { dg-final { scan-assembler-not "bsr" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]