LGTM.

Kito Cheng <k...@andestech.com> 於 2019年3月26日 週二 下午1:29寫道:

> From: Monk Chiang <m...@andestech.com>
>
> Monk Chiang  <sh.chian...@gmail.com>
> Kito Cheng  <kito.ch...@gmail.com>
> Shiva Chen  <shiva0...@gmail.com>
>
> ChangeLog
> gcc/
>         * config/nds32/nds32-md-auxiliary.c (nds32_legitimize_pic_address):
>         Use new PIC pattern.
>         (nds32_legitimize_tls_address): Use new TLS pattern.
>         (nds32_output_symrel): New.
>         * config/nds32/nds32-protos.h (nds32_output_symrel): Declare.
>         (nds32_alloc_relax_group_id): Ditto.
>         * config/nds32/nds32-relax-opt.c (nds32_alloc_relax_group_id):
>         New.
>         (nds32_group_insns): Use nds32_alloc_relax_group_id instead of
>         use relax_group_id.
>         (nds32_group_tls_insn): Ditto.
>         (nds32_group_float_insns): Ditto.
>         * config/nds32/nds32.md (tls_le): New.
>         (sym_got): Ditto.
>
> gcc/testsuite/
>
>         * gcc.target/nds32/pic.c: New.
>         * gcc.target/nds32/tls-le.c: Ditto.
> ---
>  gcc/config/nds32/nds32-md-auxiliary.c   | 43
> ++++++++++++++++++++++-----------
>  gcc/config/nds32/nds32-protos.h         |  3 +++
>  gcc/config/nds32/nds32-relax-opt.c      | 19 ++++++++-------
>  gcc/config/nds32/nds32.md               | 27 +++++++++++++++++++++
>  gcc/testsuite/gcc.target/nds32/pic.c    | 42
> ++++++++++++++++++++++++++++++++
>  gcc/testsuite/gcc.target/nds32/tls-le.c | 17 +++++++++++++
>  6 files changed, 128 insertions(+), 23 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/nds32/pic.c
>  create mode 100644 gcc/testsuite/gcc.target/nds32/tls-le.c
>
> diff --git a/gcc/config/nds32/nds32-md-auxiliary.c
> b/gcc/config/nds32/nds32-md-auxiliary.c
> index 3c510cf..35fcc64 100644
> --- a/gcc/config/nds32/nds32-md-auxiliary.c
> +++ b/gcc/config/nds32/nds32-md-auxiliary.c
> @@ -3493,6 +3493,7 @@ nds32_legitimize_pic_address (rtx x)
>    rtx addr = x;
>    rtx reg = gen_reg_rtx (Pmode);
>    rtx pat;
> +  int relax_group_id = nds32_alloc_relax_group_id ();
>
>    if (GET_CODE (x) == LABEL_REF
>        || (GET_CODE (x) == SYMBOL_REF
> @@ -3501,16 +3502,14 @@ nds32_legitimize_pic_address (rtx x)
>      {
>        addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOTOFF);
>        addr = gen_rtx_CONST (SImode, addr);
> -      emit_insn (gen_sethi (reg, addr));
> -      emit_insn (gen_lo_sum (reg, reg, addr));
> +      emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
>        x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
>      }
>    else if (GET_CODE (x) == SYMBOL_REF)
>      {
>        addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOT);
>        addr = gen_rtx_CONST (SImode, addr);
> -      emit_insn (gen_sethi (reg, addr));
> -      emit_insn (gen_lo_sum (reg, reg, addr));
> +      emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
>
>        x = gen_const_mem (SImode, gen_rtx_PLUS (Pmode,
> pic_offset_table_rtx,
>                                                reg));
> @@ -3534,8 +3533,7 @@ nds32_legitimize_pic_address (rtx x)
>           pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), UNSPEC_GOTOFF);
>           pat = gen_rtx_PLUS (Pmode, pat, op1);
>           pat = gen_rtx_CONST (Pmode, pat);
> -         emit_insn (gen_sethi (reg, pat));
> -         emit_insn (gen_lo_sum (reg, reg, pat));
> +         emit_insn (gen_sym_got (reg, pat, GEN_INT (relax_group_id)));
>           x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
>         }
>        else if (GET_CODE (op0) == SYMBOL_REF
> @@ -3544,8 +3542,8 @@ nds32_legitimize_pic_address (rtx x)
>           /* This is a constant offset from a @GOT symbol reference.  */
>           addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), UNSPEC_GOT);
>           addr = gen_rtx_CONST (SImode, addr);
> -         emit_insn (gen_sethi (reg, addr));
> -         emit_insn (gen_lo_sum (reg, reg, addr));
> +         emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
> +
>           addr = gen_const_mem (SImode, gen_rtx_PLUS (Pmode,
>                                                       pic_offset_table_rtx,
>                                                       reg));
> @@ -3668,6 +3666,7 @@ nds32_legitimize_tls_address (rtx x)
>    rtx tmp_reg;
>    rtx tp_reg = gen_rtx_REG (Pmode, TP_REGNUM);
>    rtx pat, insns, reg0;
> +  int relax_group_id = nds32_alloc_relax_group_id ();
>
>    if (GET_CODE (x) == SYMBOL_REF)
>      switch (SYMBOL_REF_TLS_MODEL (x))
> @@ -3685,7 +3684,7 @@ nds32_legitimize_tls_address (rtx x)
>         reg0 = gen_rtx_REG (Pmode, 0);
>         /* If we can confirm all clobber reigsters, it doesn't have to use
> call
>            instruction.  */
> -       insns = emit_call_insn (gen_tls_desc (pat, GEN_INT (0)));
> +       insns = emit_call_insn (gen_tls_desc (pat, GEN_INT
> (relax_group_id)));
>         use_reg (&CALL_INSN_FUNCTION_USAGE (insns), pic_offset_table_rtx);
>         RTL_CONST_CALL_P (insns) = 1;
>         tmp_reg = gen_reg_rtx (SImode);
> @@ -3697,7 +3696,7 @@ nds32_legitimize_tls_address (rtx x)
>         pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSIE);
>         tmp_reg  = gen_reg_rtx (SImode);
>         pat = gen_rtx_CONST (SImode, pat);
> -       emit_insn (gen_tls_ie (tmp_reg, pat, GEN_INT (0)));
> +       emit_insn (gen_tls_ie (tmp_reg, pat, GEN_INT (relax_group_id)));
>         if (flag_pic)
>           emit_use (pic_offset_table_rtx);
>         x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
> @@ -3711,8 +3710,7 @@ nds32_legitimize_tls_address (rtx x)
>         tmp_reg  = gen_reg_rtx (SImode);
>         pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLE);
>         pat = gen_rtx_CONST (SImode, pat);
> -       emit_insn (gen_sethi (tmp_reg, pat));
> -       emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
> +       emit_insn (gen_tls_le (tmp_reg, pat, GEN_INT (relax_group_id)));
>         x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
>         break;
>
> @@ -3734,8 +3732,7 @@ nds32_legitimize_tls_address (rtx x)
>           pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, base), UNSPEC_TLSLE);
>           pat = gen_rtx_PLUS (SImode, pat, addend);
>           pat = gen_rtx_CONST (SImode, pat);
> -         emit_insn (gen_sethi (tmp_reg, pat));
> -         emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
> +         emit_insn (gen_tls_le (tmp_reg, pat, GEN_INT (relax_group_id)));
>           x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
>         }
>      }
> @@ -3914,3 +3911,21 @@ nds32_output_tls_ie (rtx *operands)
>    output_asm_insn (pattern, operands);
>    return "";
>  }
> +
> +const char *
> +nds32_output_symrel (rtx *operands)
> +{
> +  char pattern[1000];
> +
> +  if (TARGET_RELAX_HINT)
> +    snprintf (pattern, sizeof (pattern),
> +             ".relax_hint %%2\n\tsethi %%0, hi20(%%1)\n\t"
> +             ".relax_hint %%2\n\tori %%0, %%0, lo12(%%1)");
> +  else
> +    snprintf (pattern, sizeof (pattern),
> +             "sethi %%0, hi20(%%1)\n\t"
> +             "ori %%0, %%0, lo12(%%1)");
> +
> +  output_asm_insn (pattern, operands);
> +  return "";
> +}
> diff --git a/gcc/config/nds32/nds32-protos.h
> b/gcc/config/nds32/nds32-protos.h
> index 38aaca9..aaa65d6 100644
> --- a/gcc/config/nds32/nds32-protos.h
> +++ b/gcc/config/nds32/nds32-protos.h
> @@ -256,6 +256,7 @@ extern const char *nds32_output_call (rtx, rtx *, rtx,
>                                       const char *, const char *, bool);
>  extern const char *nds32_output_tls_desc (rtx *);
>  extern const char *nds32_output_tls_ie (rtx *);
> +extern const char *nds32_output_symrel (rtx *);
>
>  /* Auxiliary functions to output stack push/pop instruction.  */
>
> @@ -369,4 +370,6 @@ extern bool
> nds32_use_load_post_increment(machine_mode);
>  extern rtl_opt_pass *make_pass_nds32_relax_opt (gcc::context *);
>  extern rtl_opt_pass *make_pass_nds32_fp_as_gp (gcc::context *);
>
> +extern int nds32_alloc_relax_group_id ();
> +
>  /*
> ------------------------------------------------------------------------ */
> diff --git a/gcc/config/nds32/nds32-relax-opt.c
> b/gcc/config/nds32/nds32-relax-opt.c
> index 25be202..5da2753 100644
> --- a/gcc/config/nds32/nds32-relax-opt.c
> +++ b/gcc/config/nds32/nds32-relax-opt.c
> @@ -78,6 +78,12 @@ static int relax_group_id = 0;
>        lwi37    $rb, [(sym)]
>        swi37    $rc, [(sym)] */
>
> +int
> +nds32_alloc_relax_group_id ()
> +{
> +  return relax_group_id++;
> +}
> +
>  /* Return true if is load/store with REG addressing mode
>     and memory mode is SImode.  */
>  static bool
> @@ -345,7 +351,7 @@ nds32_group_insns (rtx_insn *sethi)
>         return;
>      }
>
> -  group_id = GEN_INT (relax_group_id);
> +  group_id = GEN_INT (nds32_alloc_relax_group_id ());
>    /* Insert .relax_* directive for sethi.  */
>    emit_insn_before (gen_relax_group (group_id), sethi);
>
> @@ -378,8 +384,6 @@ nds32_group_insns (rtx_insn *sethi)
>             }
>         }
>      }
> -
> -  relax_group_id++;
>  }
>
>  /* Convert relax group id in rtl.  */
> @@ -389,6 +393,7 @@ nds32_group_tls_insn (rtx insn)
>  {
>    rtx pat = PATTERN (insn);
>    rtx unspec_relax_group = XEXP (XVECEXP (pat, 0, 1), 0);
> +  int group_id = nds32_alloc_relax_group_id ();
>
>    while (GET_CODE (pat) != SET && GET_CODE (pat) == PARALLEL)
>      {
> @@ -398,10 +403,8 @@ nds32_group_tls_insn (rtx insn)
>    if (GET_CODE (unspec_relax_group) == UNSPEC
>        && XINT (unspec_relax_group, 1) == UNSPEC_VOLATILE_RELAX_GROUP)
>      {
> -      XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (relax_group_id);
> +      XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (group_id);
>      }
> -
> -  relax_group_id++;
>  }
>
>  static bool
> @@ -472,7 +475,7 @@ nds32_group_float_insns (rtx_insn *insn)
>         return;
>      }
>
> -  group_id = GEN_INT (relax_group_id);
> +  group_id = GEN_INT (nds32_alloc_relax_group_id ());
>    /* Insert .relax_* directive for insn.  */
>    emit_insn_before (gen_relax_group (group_id), insn);
>
> @@ -487,8 +490,6 @@ nds32_group_float_insns (rtx_insn *insn)
>        /* Insert .relax_* directive.  */
>         emit_insn_before (gen_relax_group (group_id), use_insn);
>      }
> -
> -  relax_group_id++;
>  }
>
>  /* Group the relax candidate instructions for linker.  */
> diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md
> index f9eba0a..1e5f8de 100644
> --- a/gcc/config/nds32/nds32.md
> +++ b/gcc/config/nds32/nds32.md
> @@ -2365,6 +2365,20 @@
>     (set_attr "type" "misc")]
>  )
>
> +;; There is a unspec operand to record RELAX_GROUP number because each
> +;; emitted instruction need a relax_hint above it.
> +(define_insn "tls_le"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +       (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")]
> UNSPEC_TLS_IE))
> +   (use (unspec [(match_operand:SI 2 "immediate_operand" "i")]
> UNSPEC_VOLATILE_RELAX_GROUP))]
> +  ""
> +  {
> +    return nds32_output_symrel (operands);
> +  }
> +  [(set_attr "length" "8")
> +   (set_attr "type"   "misc")]
> +)
> +
>  ;; The pattern is for some relaxation groups that have to keep addsi3 in
> 32-bit mode.
>  (define_insn "addsi3_32bit"
>    [(set (match_operand:SI 0 "register_operand"             "=r")
> @@ -2376,4 +2390,17 @@
>     (set_attr "length"  "4")
>     (set_attr "feature" "v1")])
>
> +;; Patterns for PIC.
> +(define_insn "sym_got"
> +  [(set (match_operand:SI 0 "register_operand" "=r")
> +       (unspec:SI [(match_operand:SI 1 "nds32_symbolic_operand" "i")]
> UNSPEC_GOT))
> +   (use (unspec [(match_operand:SI 2 "immediate_operand" "i")]
> UNSPEC_VOLATILE_RELAX_GROUP))]
> +  ""
> +  {
> +    return nds32_output_symrel (operands);
> +  }
> +  [(set_attr "length" "8")
> +   (set_attr "type"   "misc")]
> +)
> +
>  ;;
> ----------------------------------------------------------------------------
> diff --git a/gcc/testsuite/gcc.target/nds32/pic.c
> b/gcc/testsuite/gcc.target/nds32/pic.c
> new file mode 100644
> index 0000000..ef62f50
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/nds32/pic.c
> @@ -0,0 +1,42 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fPIC -fdump-rtl-final" } */
> +
> +struct __locale_struct
> +{
> +  struct __locale_data *__locales[13];
> +};
> +
> +struct __locale_data
> +{
> +  const char *name;
> +};
> +
> +extern struct __locale_struct _nl_global_locale __attribute__
> ((visibility ("hidden")));
> +
> +static void
> +setdata (int category, struct __locale_data *data)
> +{
> +  _nl_global_locale.__locales[category] = data;
> +}
> +
> +char *
> +setlocale (int category, const char *locale)
> +{
> +  char *composite;
> +
> +  struct __locale_data *newdata[13];
> +
> +  for (category = 0; category < 13; ++category)
> +    if (category != 6)
> +      {
> +        setdata (category, newdata[category]);
> +      }
> +  return composite;
> +}
> +
> +/* Check that PIC pattern only generate one RTL pattern for sethi and ori
> +   to pass verify_rtx_sharing when build GCC with --enable-checking=yes.
> */
> +/* { dg-final { scan-rtl-dump "sym_got" "final" } } */
> +
> +/* Check that PIC patterns have been grouped by correct group ID. */
> +/* { dg-final { scan-assembler ".relax_hint \[1-9\]" } } */
> diff --git a/gcc/testsuite/gcc.target/nds32/tls-le.c
> b/gcc/testsuite/gcc.target/nds32/tls-le.c
> new file mode 100644
> index 0000000..69a8058
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/nds32/tls-le.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile { target *-*-linux* } } */
> +/* { dg-options "-O2 -ftls-model=initial-exec -fdump-rtl-final" } */
> +
> +__thread int lala;
> +__thread int baba;
> +void foo ()
> +{
> +  lala++;
> +  baba++;
> +}
> +
> +/* Check that TLS LE pattern only generate one RTL pattern for sethi and
> ori
> +   to pass verify_rtx_sharing when build GCC with --enable-checking=yes.
> */
> +/* { dg-final { scan-rtl-dump "tls_le" "final" } } */
> +
> +/* Check that TLS LE patterns have been grouped by correct group ID. */
> +/* { dg-final { scan-assembler ".relax_hint \[1-9\]" } } */
> --
> 1.8.3.1
>
>

Reply via email to