aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorLulu Cheng <chenglulu@loongson.cn>2023-12-12 16:32:31 +0800
committerLulu Cheng <chenglulu@loongson.cn>2024-01-02 09:33:27 +0800
commit3c20e6263abc361b5eec8a515388959ed4434776 (patch)
treeff26e4a55e8279d87cb6a59cb3d7a8bf1f2493b6 /gcc/config
parentd3d6a96d45108d30395b6506fe4b3a91cd40f573 (diff)
downloadgcc-3c20e6263abc361b5eec8a515388959ed4434776.zip
gcc-3c20e6263abc361b5eec8a515388959ed4434776.tar.gz
gcc-3c20e6263abc361b5eec8a515388959ed4434776.tar.bz2
LoongArch: Added TLS Le Relax support.
Check whether the assembler supports tls le relax. If it supports it, the assembly instruction sequence of tls le relax will be generated by default. The original way to obtain the tls le symbol address: lu12i.w $rd, %le_hi20(sym) ori $rd, $rd, %le_lo12(sym) add.{w/d} $rd, $rd, $tp If the assembler supports tls le relax, the following sequence is generated: lu12i.w $rd, %le_hi20_r(sym) add.{w/d} $rd,$rd,$tp,%le_add_r(sym) addi.{w/d} $rd,$rd,%le_lo12_r(sym) gcc/ChangeLog: * config.in: Regenerate. * config/loongarch/loongarch-opts.h (HAVE_AS_TLS_LE_RELAXATION): Define. * config/loongarch/loongarch.cc (loongarch_legitimize_tls_address): Added TLS Le Relax support. (loongarch_print_operand_reloc): Add the output string of TLS Le Relax. * config/loongarch/loongarch.md (@add_tls_le_relax<mode>): New template. * configure: Regenerate. * configure.ac: Check if binutils supports TLS le relax. gcc/testsuite/ChangeLog: * lib/target-supports.exp: Add a function to check whether binutil supports TLS Le Relax. * gcc.target/loongarch/tls-le-relax.c: New test.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/loongarch/loongarch-opts.h4
-rw-r--r--gcc/config/loongarch/loongarch.cc46
-rw-r--r--gcc/config/loongarch/loongarch.md12
3 files changed, 59 insertions, 3 deletions
diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
index d091359..e46f79a 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -114,4 +114,8 @@ struct loongarch_flags {
#define HAVE_AS_TLS 0
#endif
+#ifndef HAVE_AS_TLS_LE_RELAXATION
+#define HAVE_AS_TLS_LE_RELAXATION 0
+#endif
+
#endif /* LOONGARCH_OPTS_H */
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 9f2b3e9..db83232 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2997,7 +2997,29 @@ loongarch_legitimize_tls_address (rtx loc)
case TLS_MODEL_LOCAL_EXEC:
{
- /* la.tls.le; tp-relative add. */
+ /* la.tls.le; tp-relative add.
+
+ normal:
+ lu12i.w $rd, %le_hi20(sym)
+ ori $rd, $rd, %le_lo12(sym)
+ add.{w/d} $rd, $rd, $tp
+ (st.{w/d}/ld.{w/d} $rs, $rd, 0)
+
+ tls le relax:
+ lu12i.w $rd, %le_hi20_r(sym)
+ add.{w/d} $rd,$rd,$tp
+ addi.{w/d} $rd,$rd,%le_lo12_r(sym)
+ (st.{w/d}/ld.{w/d} $rs, $rd, 0)
+
+ extreme (When the code model is set to extreme, the TLS le Relax
+ instruction sequence is not generated):
+ lu12i.w $rd, %le_hi20(sym)
+ ori $rd, $rd, %le_lo12(sym)
+ lu32i.d $rd, %le64_lo20(sym)
+ lu52i.d $rd, $rd, %le64_hi12(sym)
+ add.d $rd, $rd, $tp
+ (st.{w/d}/ld.{w/d} $rs, $rd, 0) */
+
tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
tmp1 = gen_reg_rtx (Pmode);
dest = gen_reg_rtx (Pmode);
@@ -3008,7 +3030,20 @@ loongarch_legitimize_tls_address (rtx loc)
tmp3 = gen_reg_rtx (Pmode);
rtx high = gen_rtx_HIGH (Pmode, copy_rtx (tmp2));
high = loongarch_force_temporary (tmp3, high);
- emit_insn (gen_ori_l_lo12 (Pmode, tmp1, high, tmp2));
+
+ /* The assembler does not implement tls le relax support when the
+ code model is extreme, so when the code model is extreme, the
+ old symbol address acquisition method is still used. */
+ if (HAVE_AS_TLS_LE_RELAXATION && !TARGET_CMODEL_EXTREME)
+ {
+ emit_insn (gen_add_tls_le_relax (Pmode, dest, high,
+ tp, loc));
+ loongarch_emit_move (dest,
+ gen_rtx_LO_SUM (Pmode, dest, tmp2));
+ return dest;
+ }
+ else
+ emit_insn (gen_ori_l_lo12 (Pmode, tmp1, high, tmp2));
if (TARGET_CMODEL_EXTREME)
{
@@ -5940,7 +5975,12 @@ loongarch_print_operand_reloc (FILE *file, rtx op, bool hi64_part,
gcc_unreachable ();
}
else
- reloc = hi_reloc ? "%le_hi20" : "%le_lo12";
+ {
+ if (HAVE_AS_TLS_LE_RELAXATION && !TARGET_CMODEL_EXTREME)
+ reloc = hi_reloc ? "%le_hi20_r" : "%le_lo12_r";
+ else
+ reloc = hi_reloc ? "%le_hi20" : "%le_lo12";
+ }
break;
case SYMBOL_TLSGD:
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 47c1c56..4dd578b 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -73,6 +73,7 @@
UNSPEC_LOAD_FROM_GOT
UNSPEC_PCALAU12I
UNSPEC_PCALAU12I_GR
+ UNSPEC_ADD_TLS_LE_RELAX
UNSPEC_ORI_L_LO12
UNSPEC_LUI_L_HI20
UNSPEC_LUI_H_LO20
@@ -2503,6 +2504,17 @@
"pcalau12i\t%0,%%pc_hi20(%1)"
[(set_attr "type" "move")])
+(define_insn "@add_tls_le_relax<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P [(match_operand:P 1 "register_operand" "r")
+ (match_operand:P 2 "register_operand" "r")
+ (match_operand:P 3 "symbolic_operand")]
+ UNSPEC_ADD_TLS_LE_RELAX))]
+ "HAVE_AS_TLS_LE_RELAXATION"
+ "add.<d>\t%0,%1,%2,%%le_add_r(%3)"
+ [(set_attr "type" "move")]
+)
+
(define_insn "@ori_l_lo12<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(match_operand:P 1 "register_operand" "r")