aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/nds32
diff options
context:
space:
mode:
authorMonk Chiang <sh.chiang04@gmail.com>2019-04-15 07:59:01 +0000
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>2019-04-15 07:59:01 +0000
commit0398ae783ab09680e3adab9f15b949b082935e6b (patch)
tree198302a48c5d861a792dd554e8b775fa4802cace /gcc/config/nds32
parent1a9825f7d489cab7256bc3ff6dd67cdcf1e28922 (diff)
downloadgcc-0398ae783ab09680e3adab9f15b949b082935e6b.zip
gcc-0398ae783ab09680e3adab9f15b949b082935e6b.tar.gz
gcc-0398ae783ab09680e3adab9f15b949b082935e6b.tar.bz2
[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
Diffstat (limited to 'gcc/config/nds32')
-rw-r--r--gcc/config/nds32/nds32-md-auxiliary.c43
-rw-r--r--gcc/config/nds32/nds32-protos.h3
-rw-r--r--gcc/config/nds32/nds32-relax-opt.c19
-rw-r--r--gcc/config/nds32/nds32.md27
4 files changed, 69 insertions, 23 deletions
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")]
+)
+
;; ----------------------------------------------------------------------------