constraints.md: added new constraint CALL_OP_SYMBOL_REF to allow or block "symbol_ref"...
authorSebastian Perta <sebastian.perta@renesas.com>
Fri, 9 Feb 2018 16:17:13 +0000 (16:17 +0000)
committerSebastian Perta <sebastianperta@gcc.gnu.org>
Fri, 9 Feb 2018 16:17:13 +0000 (16:17 +0000)
2018-02-09  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

From-SVN: r257529

gcc/ChangeLog
gcc/config/rx/constraints.md
gcc/config/rx/rx.md
gcc/testsuite/gcc.target/rx/mjsr.c [new file with mode: 0644]

index 1d4a3eed64406a94d0ea86ed2dd793a3d2b038de..02a7ea064a8daad458552114011e33270e61107e 100644 (file)
@@ -1,3 +1,10 @@
+2018-02-09  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-02-09  Pierre-Marie de Rodat  <derodat@adacore.com>
 
        PR lto/84213
index 448fc46e168f3c9e9a9c210b45c569c0e34da168..d981f66acf9583dca2ba445d32984b1a94b867b4 100644 (file)
        )
   )
 )
+
+(define_constraint "CALL_OP_SYMBOL_REF"
+"constraint for call instructions using symbol ref"
+(and (match_test "!TARGET_JSR")
+     (match_code "symbol_ref"))
+)
index e642d734a2de3a5c3660f4dd32dc7c2083576e4a..35263b1adc7d513a56e96c35c6bc1ac32770d765 100644 (file)
 )
 
 (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))]
   ""
 
 (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))]
   ""
diff --git a/gcc/testsuite/gcc.target/rx/mjsr.c b/gcc/testsuite/gcc.target/rx/mjsr.c
new file mode 100644 (file)
index 0000000..c73a01b
--- /dev/null
@@ -0,0 +1,134 @@
+/* { dg-do compile } */\r
+/* { dg-options "-O2 -mjsr" } */\r
+\r
+void *malloc (__SIZE_TYPE__);\r
+void *realloc (void *, __SIZE_TYPE__);\r
+\r
+struct A { double x, y; };\r
+struct B { double x0, y0, x1, y1; };\r
+struct C { int n_points; int dir; struct B bbox; struct A *points; };\r
+struct D { int n_segs; struct C segs[1]; };\r
+\r
+void foo (int, int, int *, int, int *, struct A **, int *, int *,\r
+         struct D *, int *, struct D **, int *, int **);\r
+int baz (struct A, struct A, struct A, struct A);\r
+\r
+static void\r
+bar (struct D *svp, int *n_points_max,\r
+     struct A p, int *seg_map, int *active_segs, int i)\r
+{\r
+  int asi, n_points;\r
+  struct C *seg;\r
+\r
+  asi = seg_map[active_segs[i]];\r
+  seg = &svp->segs[asi];\r
+  n_points = seg->n_points;\r
+  seg->points = ((struct A *)\r
+               realloc (seg->points, (n_points_max[asi] <<= 1) * sizeof (struct A)));\r
+  seg->points[n_points] = p;\r
+  seg->bbox.y1 = p.y;\r
+  seg->n_points++;\r
+}\r
+\r
+struct D *\r
+test (struct D *vp)\r
+{\r
+  int *active_segs, n_active_segs, *cursor, seg_idx;\r
+  double y, share_x;\r
+  int tmp1, tmp2, asi, i, j, *n_ips, *n_ips_max, n_segs_max;\r
+  struct A **ips, p_curs, *pts;\r
+  struct D *new_vp;\r
+  int *n_points_max, *seg_map, first_share;\r
+\r
+  n_segs_max = 16;\r
+  new_vp = (struct D *) malloc (sizeof (struct D) +\r
+                               (n_segs_max - 1) * sizeof (struct C));\r
+  new_vp->n_segs = 0;\r
+\r
+  if (vp->n_segs == 0)\r
+    return new_vp;\r
+\r
+  active_segs = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+  cursor = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+\r
+  seg_map = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+  n_ips = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+  n_ips_max = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+  ips = ((struct A * *) malloc ((vp->n_segs) * sizeof (struct A *)));\r
+\r
+  n_points_max = ((int *) malloc ((n_segs_max) * sizeof (int)));\r
+\r
+  n_active_segs = 0;\r
+  seg_idx = 0;\r
+  y = vp->segs[0].points[0].y;\r
+  while (seg_idx < vp->n_segs || n_active_segs > 0)\r
+    {\r
+      for (i = 0; i < n_active_segs; i++)\r
+       {\r
+         asi = active_segs[i];\r
+         if (vp->segs[asi].n_points - 1 == cursor[asi] &&\r
+             vp->segs[asi].points[cursor[asi]].y == y)\r
+           i--;\r
+       }\r
+\r
+      while (seg_idx < vp->n_segs && y == vp->segs[seg_idx].points[0].y)\r
+       {\r
+         cursor[seg_idx] = 0;\r
+         n_ips[seg_idx] = 1;\r
+         n_ips_max[seg_idx] = 2;\r
+         ips[seg_idx] =\r
+           ((struct A *) malloc ((n_ips_max[seg_idx]) * sizeof (struct A)));\r
+         ips[seg_idx][0] = vp->segs[seg_idx].points[0];\r
+         pts = ((struct A *) malloc ((16) * sizeof (struct A)));\r
+         pts[0] = vp->segs[seg_idx].points[0];\r
+         tmp1 = seg_idx;\r
+         for (j = i; j < n_active_segs; j++)\r
+           {\r
+             tmp2 = active_segs[j];\r
+             active_segs[j] = tmp1;\r
+             tmp1 = tmp2;\r
+           }\r
+         active_segs[n_active_segs] = tmp1;\r
+         n_active_segs++;\r
+         seg_idx++;\r
+       }\r
+      first_share = -1;\r
+      share_x = 0;\r
+\r
+      for (i = 0; i < n_active_segs; i++)\r
+       {\r
+         asi = active_segs[i];\r
+         p_curs = ips[asi][1];\r
+         if (p_curs.y == y)\r
+           {\r
+             bar (new_vp, n_points_max,\r
+                  p_curs, seg_map, active_segs, i);\r
+\r
+             n_ips[asi]--;\r
+             for (j = 0; j < n_ips[asi]; j++)\r
+               ips[asi][j] = ips[asi][j + 1];\r
+\r
+             if (first_share < 0 || p_curs.x != share_x)\r
+               {\r
+                 foo (first_share, i,\r
+                      active_segs, n_active_segs,\r
+                      cursor, ips, n_ips, n_ips_max, vp, seg_map,\r
+                      &new_vp, &n_segs_max, &n_points_max);\r
+                 first_share = i;\r
+                 share_x = p_curs.x;\r
+               }\r
+           }\r
+         else\r
+           {\r
+             foo (first_share, i,\r
+                  active_segs, n_active_segs,\r
+                  cursor, ips, n_ips, n_ips_max, vp, seg_map,\r
+                  &new_vp, &n_segs_max, &n_points_max);\r
+             first_share = -1;\r
+           }\r
+       }\r
+    }\r
+  return new_vp;\r
+}\r
+\r
+/* { dg-final { scan-assembler-not "bsr" } } */\r