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 > >