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>
* configure: Add nds32 target for dwarf2 debug_line checking.
......
......@@ -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 "";
}
......@@ -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 ();
/* ------------------------------------------------------------------------ */
......@@ -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. */
......
......@@ -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")]
)
;; ----------------------------------------------------------------------------
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