Commit 0398ae78 by Monk Chiang Committed by Chung-Ju Wu

[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 <kito.cheng@gmail.com>
Co-Authored-By: Shiva Chen <shiva0217@gmail.com>

From-SVN: r270361
parent 1a9825f7
2019-04-15 Monk Chiang <sh.chiang04@gmail.com>
Kito Cheng <kito.cheng@gmail.com>
Shiva Chen <shiva0217@gmail.com>
* 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.
2019-04-15 Chung-Ju Wu <jasonwucj@gmail.com> 2019-04-15 Chung-Ju Wu <jasonwucj@gmail.com>
* configure: Add nds32 target for dwarf2 debug_line checking. * configure: Add nds32 target for dwarf2 debug_line checking.
......
...@@ -3493,6 +3493,7 @@ nds32_legitimize_pic_address (rtx x) ...@@ -3493,6 +3493,7 @@ nds32_legitimize_pic_address (rtx x)
rtx addr = x; rtx addr = x;
rtx reg = gen_reg_rtx (Pmode); rtx reg = gen_reg_rtx (Pmode);
rtx pat; rtx pat;
int relax_group_id = nds32_alloc_relax_group_id ();
if (GET_CODE (x) == LABEL_REF if (GET_CODE (x) == LABEL_REF
|| (GET_CODE (x) == SYMBOL_REF || (GET_CODE (x) == SYMBOL_REF
...@@ -3501,16 +3502,14 @@ nds32_legitimize_pic_address (rtx x) ...@@ -3501,16 +3502,14 @@ nds32_legitimize_pic_address (rtx x)
{ {
addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOTOFF); addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOTOFF);
addr = gen_rtx_CONST (SImode, addr); addr = gen_rtx_CONST (SImode, addr);
emit_insn (gen_sethi (reg, addr)); emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
emit_insn (gen_lo_sum (reg, reg, addr));
x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx); x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
} }
else if (GET_CODE (x) == SYMBOL_REF) else if (GET_CODE (x) == SYMBOL_REF)
{ {
addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOT); addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_GOT);
addr = gen_rtx_CONST (SImode, addr); addr = gen_rtx_CONST (SImode, addr);
emit_insn (gen_sethi (reg, addr)); emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
emit_insn (gen_lo_sum (reg, reg, addr));
x = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, pic_offset_table_rtx, x = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
reg)); reg));
...@@ -3534,8 +3533,7 @@ nds32_legitimize_pic_address (rtx x) ...@@ -3534,8 +3533,7 @@ nds32_legitimize_pic_address (rtx x)
pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), UNSPEC_GOTOFF); pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), UNSPEC_GOTOFF);
pat = gen_rtx_PLUS (Pmode, pat, op1); pat = gen_rtx_PLUS (Pmode, pat, op1);
pat = gen_rtx_CONST (Pmode, pat); pat = gen_rtx_CONST (Pmode, pat);
emit_insn (gen_sethi (reg, pat)); emit_insn (gen_sym_got (reg, pat, GEN_INT (relax_group_id)));
emit_insn (gen_lo_sum (reg, reg, pat));
x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx); x = gen_rtx_PLUS (Pmode, reg, pic_offset_table_rtx);
} }
else if (GET_CODE (op0) == SYMBOL_REF else if (GET_CODE (op0) == SYMBOL_REF
...@@ -3544,8 +3542,8 @@ nds32_legitimize_pic_address (rtx x) ...@@ -3544,8 +3542,8 @@ nds32_legitimize_pic_address (rtx x)
/* This is a constant offset from a @GOT symbol reference. */ /* This is a constant offset from a @GOT symbol reference. */
addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), UNSPEC_GOT); addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), UNSPEC_GOT);
addr = gen_rtx_CONST (SImode, addr); addr = gen_rtx_CONST (SImode, addr);
emit_insn (gen_sethi (reg, addr)); emit_insn (gen_sym_got (reg, addr, GEN_INT (relax_group_id)));
emit_insn (gen_lo_sum (reg, reg, addr));
addr = gen_const_mem (SImode, gen_rtx_PLUS (Pmode, addr = gen_const_mem (SImode, gen_rtx_PLUS (Pmode,
pic_offset_table_rtx, pic_offset_table_rtx,
reg)); reg));
...@@ -3668,6 +3666,7 @@ nds32_legitimize_tls_address (rtx x) ...@@ -3668,6 +3666,7 @@ nds32_legitimize_tls_address (rtx x)
rtx tmp_reg; rtx tmp_reg;
rtx tp_reg = gen_rtx_REG (Pmode, TP_REGNUM); rtx tp_reg = gen_rtx_REG (Pmode, TP_REGNUM);
rtx pat, insns, reg0; rtx pat, insns, reg0;
int relax_group_id = nds32_alloc_relax_group_id ();
if (GET_CODE (x) == SYMBOL_REF) if (GET_CODE (x) == SYMBOL_REF)
switch (SYMBOL_REF_TLS_MODEL (x)) switch (SYMBOL_REF_TLS_MODEL (x))
...@@ -3685,7 +3684,7 @@ nds32_legitimize_tls_address (rtx x) ...@@ -3685,7 +3684,7 @@ nds32_legitimize_tls_address (rtx x)
reg0 = gen_rtx_REG (Pmode, 0); reg0 = gen_rtx_REG (Pmode, 0);
/* If we can confirm all clobber reigsters, it doesn't have to use call /* If we can confirm all clobber reigsters, it doesn't have to use call
instruction. */ 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); use_reg (&CALL_INSN_FUNCTION_USAGE (insns), pic_offset_table_rtx);
RTL_CONST_CALL_P (insns) = 1; RTL_CONST_CALL_P (insns) = 1;
tmp_reg = gen_reg_rtx (SImode); tmp_reg = gen_reg_rtx (SImode);
...@@ -3697,7 +3696,7 @@ nds32_legitimize_tls_address (rtx x) ...@@ -3697,7 +3696,7 @@ nds32_legitimize_tls_address (rtx x)
pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSIE); pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSIE);
tmp_reg = gen_reg_rtx (SImode); tmp_reg = gen_reg_rtx (SImode);
pat = gen_rtx_CONST (SImode, pat); 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) if (flag_pic)
emit_use (pic_offset_table_rtx); emit_use (pic_offset_table_rtx);
x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg); x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
...@@ -3711,8 +3710,7 @@ nds32_legitimize_tls_address (rtx x) ...@@ -3711,8 +3710,7 @@ nds32_legitimize_tls_address (rtx x)
tmp_reg = gen_reg_rtx (SImode); tmp_reg = gen_reg_rtx (SImode);
pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLE); pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_TLSLE);
pat = gen_rtx_CONST (SImode, pat); pat = gen_rtx_CONST (SImode, pat);
emit_insn (gen_sethi (tmp_reg, pat)); emit_insn (gen_tls_le (tmp_reg, pat, GEN_INT (relax_group_id)));
emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg); x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
break; break;
...@@ -3734,8 +3732,7 @@ nds32_legitimize_tls_address (rtx x) ...@@ -3734,8 +3732,7 @@ nds32_legitimize_tls_address (rtx x)
pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, base), UNSPEC_TLSLE); pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, base), UNSPEC_TLSLE);
pat = gen_rtx_PLUS (SImode, pat, addend); pat = gen_rtx_PLUS (SImode, pat, addend);
pat = gen_rtx_CONST (SImode, pat); pat = gen_rtx_CONST (SImode, pat);
emit_insn (gen_sethi (tmp_reg, pat)); emit_insn (gen_tls_le (tmp_reg, pat, GEN_INT (relax_group_id)));
emit_insn (gen_lo_sum (tmp_reg, tmp_reg, pat));
x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg); x = gen_rtx_PLUS (Pmode, tmp_reg, tp_reg);
} }
} }
...@@ -3914,3 +3911,21 @@ nds32_output_tls_ie (rtx *operands) ...@@ -3914,3 +3911,21 @@ nds32_output_tls_ie (rtx *operands)
output_asm_insn (pattern, operands); output_asm_insn (pattern, operands);
return ""; 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 "";
}
...@@ -256,6 +256,7 @@ extern const char *nds32_output_call (rtx, rtx *, rtx, ...@@ -256,6 +256,7 @@ extern const char *nds32_output_call (rtx, rtx *, rtx,
const char *, const char *, bool); const char *, const char *, bool);
extern const char *nds32_output_tls_desc (rtx *); extern const char *nds32_output_tls_desc (rtx *);
extern const char *nds32_output_tls_ie (rtx *); extern const char *nds32_output_tls_ie (rtx *);
extern const char *nds32_output_symrel (rtx *);
/* Auxiliary functions to output stack push/pop instruction. */ /* Auxiliary functions to output stack push/pop instruction. */
...@@ -369,4 +370,6 @@ extern bool nds32_use_load_post_increment(machine_mode); ...@@ -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_relax_opt (gcc::context *);
extern rtl_opt_pass *make_pass_nds32_fp_as_gp (gcc::context *); extern rtl_opt_pass *make_pass_nds32_fp_as_gp (gcc::context *);
extern int nds32_alloc_relax_group_id ();
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
...@@ -78,6 +78,12 @@ static int relax_group_id = 0; ...@@ -78,6 +78,12 @@ static int relax_group_id = 0;
lwi37 $rb, [(sym)] lwi37 $rb, [(sym)]
swi37 $rc, [(sym)] */ swi37 $rc, [(sym)] */
int
nds32_alloc_relax_group_id ()
{
return relax_group_id++;
}
/* Return true if is load/store with REG addressing mode /* Return true if is load/store with REG addressing mode
and memory mode is SImode. */ and memory mode is SImode. */
static bool static bool
...@@ -345,7 +351,7 @@ nds32_group_insns (rtx_insn *sethi) ...@@ -345,7 +351,7 @@ nds32_group_insns (rtx_insn *sethi)
return; return;
} }
group_id = GEN_INT (relax_group_id); group_id = GEN_INT (nds32_alloc_relax_group_id ());
/* Insert .relax_* directive for sethi. */ /* Insert .relax_* directive for sethi. */
emit_insn_before (gen_relax_group (group_id), sethi); emit_insn_before (gen_relax_group (group_id), sethi);
...@@ -378,8 +384,6 @@ nds32_group_insns (rtx_insn *sethi) ...@@ -378,8 +384,6 @@ nds32_group_insns (rtx_insn *sethi)
} }
} }
} }
relax_group_id++;
} }
/* Convert relax group id in rtl. */ /* Convert relax group id in rtl. */
...@@ -389,6 +393,7 @@ nds32_group_tls_insn (rtx insn) ...@@ -389,6 +393,7 @@ nds32_group_tls_insn (rtx insn)
{ {
rtx pat = PATTERN (insn); rtx pat = PATTERN (insn);
rtx unspec_relax_group = XEXP (XVECEXP (pat, 0, 1), 0); 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) while (GET_CODE (pat) != SET && GET_CODE (pat) == PARALLEL)
{ {
...@@ -398,10 +403,8 @@ nds32_group_tls_insn (rtx insn) ...@@ -398,10 +403,8 @@ nds32_group_tls_insn (rtx insn)
if (GET_CODE (unspec_relax_group) == UNSPEC if (GET_CODE (unspec_relax_group) == UNSPEC
&& XINT (unspec_relax_group, 1) == UNSPEC_VOLATILE_RELAX_GROUP) && 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 static bool
...@@ -472,7 +475,7 @@ nds32_group_float_insns (rtx_insn *insn) ...@@ -472,7 +475,7 @@ nds32_group_float_insns (rtx_insn *insn)
return; return;
} }
group_id = GEN_INT (relax_group_id); group_id = GEN_INT (nds32_alloc_relax_group_id ());
/* Insert .relax_* directive for insn. */ /* Insert .relax_* directive for insn. */
emit_insn_before (gen_relax_group (group_id), insn); emit_insn_before (gen_relax_group (group_id), insn);
...@@ -487,8 +490,6 @@ nds32_group_float_insns (rtx_insn *insn) ...@@ -487,8 +490,6 @@ nds32_group_float_insns (rtx_insn *insn)
/* Insert .relax_* directive. */ /* Insert .relax_* directive. */
emit_insn_before (gen_relax_group (group_id), use_insn); emit_insn_before (gen_relax_group (group_id), use_insn);
} }
relax_group_id++;
} }
/* Group the relax candidate instructions for linker. */ /* Group the relax candidate instructions for linker. */
......
...@@ -2365,6 +2365,20 @@ ...@@ -2365,6 +2365,20 @@
(set_attr "type" "misc")] (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. ;; The pattern is for some relaxation groups that have to keep addsi3 in 32-bit mode.
(define_insn "addsi3_32bit" (define_insn "addsi3_32bit"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
...@@ -2376,4 +2390,17 @@ ...@@ -2376,4 +2390,17 @@
(set_attr "length" "4") (set_attr "length" "4")
(set_attr "feature" "v1")]) (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")]
)
;; ---------------------------------------------------------------------------- ;; ----------------------------------------------------------------------------
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment