PING
> -----Original Message-----
> From: Sebastian Perta [mailto:sebastian.pe...@renesas.com]
> Sent: 08 January 2018 10:57
> To: gcc-patches@gcc.gnu.org
> Subject: [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.pe...@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.sandif...@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" } } */