[PATCH] LoongArch: Add support for TLS descriptors
mengqinggang
mengqinggang@loongson.cn
Fri Dec 1 09:55:24 GMT 2023
Generate la.tls.desc macro instruction for TLS descriptors model.
la.tls.desc expand to
pcalau12i $a0, %desc_pc_hi20(a)
ld.d $a1, $a0, %desc_ld_pc_lo12(a)
addi.d $a0, $a0, %desc_add_pc_lo12(a)
jirl $ra, $a1, %desc_call(a)
The default is TLS descriptors, but can be configure with
-mtls-dialect={desc,trad}.
gcc/ChangeLog:
* config.gcc: Add --with_tls to change the TLS flavor.
* config/loongarch/genopts/loongarch.opt.in: Add -mtls-dialect to
configure TLS flavor.
* config/loongarch/loongarch-opts.h (enum loongarch_tls_type): New.
* config/loongarch/loongarch-protos.h (NUM_SYMBOL_TYPES): New.
* config/loongarch/loongarch.cc (loongarch_symbol_insns): Add
instruction sequence length data for TLS DESC.
(loongarch_legitimize_tls_address): New TLS DESC instruction sequence.
* config/loongarch/loongarch.h (TARGET_TLS_DESC): New.
* config/loongarch/loongarch.md (@got_load_tls_desc<mode>): New.
* config/loongarch/loongarch.opt: Regenerated.
---
gcc/config.gcc | 16 ++++++-
gcc/config/loongarch/genopts/loongarch.opt.in | 14 ++++++
gcc/config/loongarch/loongarch-opts.h | 6 +++
gcc/config/loongarch/loongarch-protos.h | 3 +-
gcc/config/loongarch/loongarch.cc | 45 +++++++++++++++----
gcc/config/loongarch/loongarch.h | 9 ++++
gcc/config/loongarch/loongarch.md | 15 +++++++
gcc/config/loongarch/loongarch.opt | 14 ++++++
8 files changed, 111 insertions(+), 11 deletions(-)
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 748430194f3..5b3120dff6d 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2545,6 +2545,7 @@ loongarch*-*-linux*)
# Force .init_array support. The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
+ with_tls=${with_tls:-desc}
;;
loongarch*-*-elf*)
@@ -2557,6 +2558,7 @@ loongarch*-*-elf*)
# For .init_array support. The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
+ with_tls=${with_tls:-desc}
;;
mips*-*-netbsd*) # NetBSD/mips, either endian.
@@ -4986,7 +4988,7 @@ case "${target}" in
;;
loongarch*-*)
- supported_defaults="abi arch tune fpu simd multilib-default strict-align-lib"
+ supported_defaults="abi arch tune fpu simd multilib-default strict-align-lib tls"
# Local variables
unset \
@@ -5244,6 +5246,18 @@ case "${target}" in
with_multilib_list="${abi_base}/${abi_ext}"
fi
+ # Handle --with-tls.
+ case "$with_tls" in
+ "" \
+ | trad | desc)
+ # OK
+ ;;
+ *)
+ echo "Unknown TLS method used in --with-tls=$with_tls" 1>&2
+ exit 1
+ ;;
+ esac
+
# Check if the configured default ABI combination is included in
# ${with_multilib_list}.
loongarch_multilib_list_sane=no
diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
index 8af6cc6f532..4a2ae80f25b 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -254,3 +254,17 @@ default value is 4.
; CPUCFG independantly, so we use bit flags to specify them.
Variable
HOST_WIDE_INT isa_evolution = 0
+
+Enum
+Name(tls_type) Type(enum loongarch_tls_type)
+The possible TLS dialects:
+
+EnumValue
+Enum(tls_type) String(trad) Value(TLS_TRADITIONAL)
+
+EnumValue
+Enum(tls_type) String(desc) Value(TLS_DESCRIPTORS)
+
+mtls-dialect=
+Target RejectNegative Joined Enum(tls_type) Var(loongarch_tls_dialect) Init(TLS_DESCRIPTORS) Save
+Specify TLS dialect.
diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
index fa3773223bc..28cd08712f4 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -115,4 +115,10 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target,
#define HAVE_AS_TLS 0
#endif
+/* TLS types. */
+enum loongarch_tls_type {
+ TLS_TRADITIONAL,
+ TLS_DESCRIPTORS
+};
+
#endif /* LOONGARCH_OPTS_H */
diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h
index cb8fc36b086..4b3f942da90 100644
--- a/gcc/config/loongarch/loongarch-protos.h
+++ b/gcc/config/loongarch/loongarch-protos.h
@@ -53,8 +53,9 @@ enum loongarch_symbol_type {
SYMBOL_TLS_LE,
SYMBOL_TLSGD,
SYMBOL_TLSLDM,
+ SYMBOL_TLS_DESC,
};
-#define NUM_SYMBOL_TYPES (SYMBOL_TLSLDM + 1)
+#define NUM_SYMBOL_TYPES (SYMBOL_TLS_DESC + 1)
/* Routines implemented in loongarch.cc. */
extern rtx loongarch_emit_move (rtx, rtx);
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index d3896d72bc2..c53e88dc82f 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2004,6 +2004,9 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode)
case SYMBOL_TLSLDM:
return 3;
+ case SYMBOL_TLS_DESC:
+ return 4;
+
case SYMBOL_PCREL64:
return 5;
@@ -2919,24 +2922,48 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
static rtx
loongarch_legitimize_tls_address (rtx loc)
{
- rtx dest, tp, tmp, tmp1, tmp2, tmp3;
+ rtx dest, tp, tmp, tmp1, tmp2, tmp3, a0; /* a1? */
enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
rtx_insn *insn;
switch (model)
{
case TLS_MODEL_LOCAL_DYNAMIC:
- tmp = gen_rtx_REG (Pmode, GP_RETURN);
- dest = gen_reg_rtx (Pmode);
- insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSLDM, tmp);
- emit_libcall_block (insn, dest, tmp, loc);
+ if (TARGET_TLS_DESC)
+ {
+ a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
+ dest = gen_reg_rtx (Pmode);
+ tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
+
+ emit_insn (gen_got_load_tls_desc (Pmode, a0, loc));
+ emit_insn (gen_add3_insn (dest, a0, tp));
+ }
+ else
+ {
+ tmp = gen_rtx_REG (Pmode, GP_RETURN);
+ dest = gen_reg_rtx (Pmode);
+ insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSLDM, tmp);
+ emit_libcall_block (insn, dest, tmp, loc);
+ }
break;
case TLS_MODEL_GLOBAL_DYNAMIC:
- tmp = gen_rtx_REG (Pmode, GP_RETURN);
- dest = gen_reg_rtx (Pmode);
- insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSGD, tmp);
- emit_libcall_block (insn, dest, tmp, loc);
+ if (TARGET_TLS_DESC)
+ {
+ a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
+ dest = gen_reg_rtx (Pmode);
+ tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
+
+ emit_insn (gen_got_load_tls_desc (Pmode, a0, loc));
+ emit_insn (gen_add3_insn (dest, a0, tp));
+ }
+ else
+ {
+ tmp = gen_rtx_REG (Pmode, GP_RETURN);
+ dest = gen_reg_rtx (Pmode);
+ insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSGD, tmp);
+ emit_libcall_block (insn, dest, tmp, loc);
+ }
break;
case TLS_MODEL_INITIAL_EXEC:
diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
index 115222e70fd..f474cdc2857 100644
--- a/gcc/config/loongarch/loongarch.h
+++ b/gcc/config/loongarch/loongarch.h
@@ -25,6 +25,15 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_SUPPORTS_WIDE_INT 1
+/* Check TLS Descriptors mechanism is selected. */
+#define TARGET_TLS_DESC (loongarch_tls_dialect == TLS_DESCRIPTORS)
+
+/* --with-tls is ignored if -mtls-dialect is specified. */
+/*
+#define OPTION_DEFAULT_SPECS \
+ {"tls", "%{!mtls-dialect=*:-mtls-dialect=%(VALUE)}"}, \
+*/
+
/* Macros to silence warnings about numbers being signed in traditional
C and unsigned in ISO C when compiled on 32-bit hosts. */
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index cd4ed495697..71f46c9d2fe 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -55,6 +55,7 @@ (define_c_enum "unspec" [
UNSPEC_TLS_LD
UNSPEC_TLS_LE
UNSPEC_TLS_IE
+ UNSPEC_TLS_DESC
;; Stack tie
UNSPEC_TIE
@@ -114,6 +115,8 @@ (define_c_enum "unspecv" [
(define_constants
[(RETURN_ADDR_REGNUM 1)
(TP_REGNUM 2)
+ (A0_REGNUM 4)
+ (A1_REGNUM 5)
(T0_REGNUM 12)
(T1_REGNUM 13)
(S0_REGNUM 23)
@@ -2436,6 +2439,18 @@ (define_insn "store_word<mode>"
;; Thread-Local Storage
+(define_insn "@got_load_tls_desc<mode>"
+ [(set (match_operand:P 0 "register_operand" "=r")
+ (unspec:P
+ [(match_operand:P 1 "symbolic_operand" "")]
+ UNSPEC_TLS_DESC))
+ (clobber (reg:SI A1_REGNUM))
+ (clobber (reg:SI RETURN_ADDR_REGNUM))]
+ "TARGET_TLS_DESC"
+ "la.tls.desc\t%0,%1"
+ [(set_attr "got" "load")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@got_load_tls_gd<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P
diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt
index 4d36e3ec4de..ad2e770e1e6 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -278,3 +278,17 @@ Support amcas[_db].{b/h/w/d} instructions.
mld-seq-sa
Target Mask(ISA_LD_SEQ_SA) Var(isa_evolution)
Do not need load-load barriers (dbar 0x700).
+
+Enum
+Name(tls_type) Type(enum loongarch_tls_type)
+The possible TLS dialects:
+
+EnumValue
+Enum(tls_type) String(trad) Value(TLS_TRADITIONAL)
+
+EnumValue
+Enum(tls_type) String(desc) Value(TLS_DESCRIPTORS)
+
+mtls-dialect=
+Target RejectNegative Joined Enum(tls_type) Var(loongarch_tls_dialect) Init(TLS_DESCRIPTORS) Save
+Specify TLS dialect.
--
2.36.0
More information about the Gcc-patches
mailing list