From 0398ae783ab09680e3adab9f15b949b082935e6b Mon Sep 17 00:00:00 2001 From: Monk Chiang Date: Mon, 15 Apr 2019 07:59:01 +0000 Subject: [NDS32] Rewrite PIC/TLS patterns. 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. Co-Authored-By: Kito Cheng Co-Authored-By: Shiva Chen From-SVN: r270361 --- 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 ++++++++++++++++++++++ 4 files changed, 69 insertions(+), 23 deletions(-) (limited to 'gcc/config/nds32') 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")] +) + ;; ---------------------------------------------------------------------------- -- cgit v1.1