aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/loongarch
diff options
context:
space:
mode:
authormengqinggang <mengqinggang@loongson.cn>2024-04-02 09:57:20 +0800
committerLulu Cheng <chenglulu@loongson.cn>2024-04-02 13:59:12 +0800
commitb253b4695ddac43301bb572895095b9569165ff4 (patch)
tree56bf5a3799d972ff3ba719ee1248e9fd3db42b13 /gcc/config/loongarch
parent6f9ba3ea55477cf1bd3d37e40ad116150c06a75e (diff)
downloadgcc-b253b4695ddac43301bb572895095b9569165ff4.zip
gcc-b253b4695ddac43301bb572895095b9569165ff4.tar.gz
gcc-b253b4695ddac43301bb572895095b9569165ff4.tar.bz2
LoongArch: Add support for TLS descriptors.
Add support for TLS descriptors on normal code model and extreme code model. Normal code model instruction sequence: -mno-explicit-relocs: la.tls.desc $r4, s add.d $r12, $r4, $r2 -mexplicit-relocs: pcalau12i $r4,%desc_pc_hi20(s) addi.d $r4,$r4,%desc_pc_lo12(s) ld.d $r1,$r4,%desc_ld(s) jirl $r1,$r1,%desc_call(s) add.d $r12, $r4, $r2 Extreme code model instruction sequence: -mno-explicit-relocs: la.tls.desc $r4, $r12, s add.d $r12, $r4, $r2 -mexplicit-relocs: pcalau12i $r4,%desc_pc_hi20(s) addi.d $r12,$r0,%desc_pc_lo12(s) lu32i.d $r12,%desc64_pc_lo20(s) lu52i.d $r12,$r12,%desc64_pc_hi12(s) add.d $r4,$r4,$r12 ld.d $r1,$r4,%desc_ld(s) jirl $r1,$r1,%desc_call(s) add.d $r12, $r4, $r2 The default is still traditional TLS model, but can be configured with --with-tls={trad,desc}. The default can change to TLS descriptors once libc and LLVM support this. gcc/ChangeLog: * config.gcc: Add --with-tls option to change TLS flavor. * config/loongarch/genopts/loongarch.opt.in: Add -mtls-dialect to configure TLS flavor. * config/loongarch/loongarch-def.h (struct loongarch_target): Add tls_dialect. * config/loongarch/loongarch-driver.cc (la_driver_init): Add tls flavor. * config/loongarch/loongarch-opts.cc (loongarch_init_target): Add tls_dialect. (loongarch_config_target): Ditto. (loongarch_update_gcc_opt_status): Ditto. * config/loongarch/loongarch-opts.h (loongarch_init_target): Ditto. (TARGET_TLS_DESC): New define. * config/loongarch/loongarch.cc (loongarch_symbol_insns): Add TLS DESC instructions sequence length. (loongarch_legitimize_tls_address): New TLS DESC instruction sequence. (loongarch_option_override_internal): Add la_opt_tls_dialect. (loongarch_option_restore): Add la_target.tls_dialect. * config/loongarch/loongarch.md (@got_load_tls_desc<mode>): Normal code model for TLS DESC. (got_load_tls_desc_off64): Extreme cmode model for TLS DESC. * config/loongarch/loongarch.opt: Regenerate. * config/loongarch/loongarch.opt.urls: Ditto. * doc/invoke.texi: Add a description of the compilation option '-mtls-dialect={trad,desc}'. gcc/testsuite/ChangeLog: * gcc.target/loongarch/cmodel-extreme-1.c: Add -mtls-dialect=trad. * gcc.target/loongarch/cmodel-extreme-2.c: Ditto. * gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c: Ditto. * gcc.target/loongarch/explicit-relocs-medium-call36-auto-tls-ld-gd.c: Ditto. * gcc.target/loongarch/func-call-medium-1.c: Ditto. * gcc.target/loongarch/func-call-medium-2.c: Ditto. * gcc.target/loongarch/func-call-medium-3.c: Ditto. * gcc.target/loongarch/func-call-medium-4.c: Ditto. * gcc.target/loongarch/tls-extreme-macro.c: Ditto. * gcc.target/loongarch/tls-gd-noplt.c: Ditto. * gcc.target/loongarch/explicit-relocs-auto-extreme-tls-desc.c: New test. * gcc.target/loongarch/explicit-relocs-auto-tls-desc.c: New test. * gcc.target/loongarch/explicit-relocs-extreme-tls-desc.c: New test. * gcc.target/loongarch/explicit-relocs-tls-desc.c: New test. Co-authored-by: Lulu Cheng <chenglulu@loongson.cn> Co-authored-by: Xi Ruoyao <xry111@xry111.site>
Diffstat (limited to 'gcc/config/loongarch')
-rw-r--r--gcc/config/loongarch/genopts/loongarch.opt.in14
-rw-r--r--gcc/config/loongarch/loongarch-def.h7
-rw-r--r--gcc/config/loongarch/loongarch-driver.cc2
-rw-r--r--gcc/config/loongarch/loongarch-opts.cc12
-rw-r--r--gcc/config/loongarch/loongarch-opts.h3
-rw-r--r--gcc/config/loongarch/loongarch.cc45
-rw-r--r--gcc/config/loongarch/loongarch.md68
-rw-r--r--gcc/config/loongarch/loongarch.opt14
-rw-r--r--gcc/config/loongarch/loongarch.opt.urls3
9 files changed, 154 insertions, 14 deletions
diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
index a77893d..50ea47a 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -245,6 +245,20 @@ mpass-mrelax-to-as
Driver Var(la_pass_mrelax_to_as) Init(HAVE_AS_MRELAX_OPTION)
Pass -mrelax or -mno-relax option to the assembler.
+Enum
+Name(tls_type) Type(int)
+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(la_opt_tls_dialect) Init(M_OPT_UNSET) Save
+Specify TLS dialect.
+
-param=loongarch-vect-unroll-limit=
Target Joined UInteger Var(la_vect_unroll_limit) Init(6) IntegerRange(1, 64) Param
Used to limit unroll factor which indicates how much the autovectorizer may
diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h
index 0cbf947..60ce3e2 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -180,6 +180,7 @@ struct loongarch_target
int cpu_arch; /* CPU_ */
int cpu_tune; /* same */
int cmodel; /* CMODEL_ */
+ int tls_dialect; /* TLS_ */
};
/* CPU model */
@@ -193,6 +194,12 @@ enum {
N_TUNE_TYPES = 5
};
+/* TLS types. */
+enum {
+ TLS_TRADITIONAL = 0,
+ TLS_DESCRIPTORS = 1
+};
+
/* CPU model properties */
extern loongarch_def_array<const char *, N_ARCH_TYPES>
loongarch_cpu_strings;
diff --git a/gcc/config/loongarch/loongarch-driver.cc b/gcc/config/loongarch/loongarch-driver.cc
index 62658f5..8c4ed34 100644
--- a/gcc/config/loongarch/loongarch-driver.cc
+++ b/gcc/config/loongarch/loongarch-driver.cc
@@ -45,7 +45,7 @@ la_driver_init (int argc ATTRIBUTE_UNUSED, const char **argv ATTRIBUTE_UNUSED)
/* Initialize all fields of la_target. */
loongarch_init_target (&la_target, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET,
M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET,
- 0, 0);
+ M_OPT_UNSET, 0, 0);
return "";
}
diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc
index e600f08..2a6fc41 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -144,6 +144,7 @@ void
loongarch_init_target (struct loongarch_target *target,
int cpu_arch, int cpu_tune, int fpu, int simd,
int abi_base, int abi_ext, int cmodel,
+ int tls_dialect,
HOST_WIDE_INT isa_evolution,
HOST_WIDE_INT isa_evolution_set)
{
@@ -158,6 +159,7 @@ loongarch_init_target (struct loongarch_target *target,
target->abi.base = abi_base;
target->abi.ext = abi_ext;
target->cmodel = cmodel;
+ target->tls_dialect = tls_dialect;
}
@@ -179,7 +181,8 @@ loongarch_config_target (struct loongarch_target *target,
obstack_init (&msg_obstack);
struct {
- int arch, tune, fpu, simd, abi_base, abi_ext, cmodel, abi_flt;
+ int arch, tune, fpu, simd, abi_base, abi_ext, cmodel,
+ tls_dialect, abi_flt;
} constrained = {
M_OPT_ABSENT (target->cpu_arch) ? 0 : 1,
M_OPT_ABSENT (target->cpu_tune) ? 0 : 1,
@@ -188,6 +191,7 @@ loongarch_config_target (struct loongarch_target *target,
M_OPT_ABSENT (target->abi.base) ? 0 : 1,
M_OPT_ABSENT (target->abi.ext) ? 0 : 1,
M_OPT_ABSENT (target->cmodel) ? 0 : 1,
+ M_OPT_ABSENT (target->tls_dialect) ? 0 : 1,
M_OPT_ABSENT (target->abi.base) ? 0 : 1,
};
@@ -556,6 +560,9 @@ fallback:
gcc_unreachable ();
}
+ t.tls_dialect = constrained.tls_dialect ? target->tls_dialect
+ : DEFAULT_TLS_TYPE;
+
/* Cleanup and return. */
obstack_free (&msg_obstack, NULL);
*target = t;
@@ -791,6 +798,9 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target,
/* status of -mcmodel */
opts->x_la_opt_cmodel = target->cmodel;
+ /* status of -mtls-dialect */
+ opts->x_la_opt_tls_dialect = target->tls_dialect;
+
/* status of -mfpu */
opts->x_la_opt_fpu = target->isa.fpu;
diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
index 2d9f592..9844b27 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -39,6 +39,7 @@ void
loongarch_init_target (struct loongarch_target *target,
int cpu_arch, int cpu_tune, int fpu, int simd,
int abi_base, int abi_ext, int cmodel,
+ int tls_dialect,
HOST_WIDE_INT isa_evolutions,
HOST_WIDE_INT isa_evolutions_set);
@@ -105,6 +106,8 @@ struct loongarch_flags {
#define TARGET_64BIT (la_target.isa.base == ISA_BASE_LA64)
#define TARGET_ABI_LP64 ABI_LP64_P(la_target.abi.base)
+#define TARGET_TLS_DESC (la_target.tls_dialect == TLS_DESCRIPTORS)
+
#define ISA_HAS_LSX \
(la_target.isa.simd == ISA_EXT_SIMD_LSX \
|| la_target.isa.simd == ISA_EXT_SIMD_LASX)
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index a69a203..cbc91c9 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2031,7 +2031,7 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode)
case SYMBOL_TLSGD:
case SYMBOL_TLSLDM:
- return 3;
+ return TARGET_TLS_DESC ? 4 : 3;
case SYMBOL_PCREL64:
return 5;
@@ -2933,24 +2933,43 @@ 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;
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);
- break;
-
+ if (!TARGET_TLS_DESC)
+ {
+ 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;
+ }
+ /* Fall through. */
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);
+
+ if (TARGET_CMODEL_EXTREME)
+ emit_insn (gen_got_load_tls_desc_off64 (loc, gen_reg_rtx (DImode)));
+ else
+ emit_insn (gen_got_load_tls_desc (Pmode, 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:
@@ -7654,6 +7673,7 @@ loongarch_option_override_internal (struct loongarch_target *target,
opts->x_la_opt_abi_base,
opts->x_la_opt_abi_ext,
opts->x_la_opt_cmodel,
+ opts->x_la_opt_tls_dialect,
opts->x_la_isa_evolution,
opts_set->x_la_isa_evolution);
@@ -7700,6 +7720,7 @@ loongarch_option_restore (struct gcc_options *,
la_target.isa.evolution = ptr->x_la_isa_evolution;
la_target.cmodel = ptr->x_la_opt_cmodel;
+ la_target.tls_dialect = ptr->x_la_opt_tls_dialect;
}
/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 18fd9c1..a316c8f 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -52,6 +52,8 @@
;; TLS
UNSPEC_TLS
+ UNSPEC_TLS_DESC
+ UNSPEC_TLS_DESC_OFF64
;; Stack tie
UNSPEC_TIE
@@ -127,6 +129,15 @@
(T1_REGNUM 13)
(S0_REGNUM 23)
+ (FCC0_REGNUM 64)
+ (FCC1_REGNUM 65)
+ (FCC2_REGNUM 66)
+ (FCC3_REGNUM 67)
+ (FCC4_REGNUM 68)
+ (FCC5_REGNUM 69)
+ (FCC6_REGNUM 70)
+ (FCC7_REGNUM 71)
+
;; Return path styles
(NORMAL_RETURN 0)
(SIBCALL_RETURN 1)
@@ -2759,6 +2770,63 @@
;; Thread-Local Storage
+(define_insn "@got_load_tls_desc<mode>"
+ [(set (reg:P 4)
+ (unspec:P
+ [(match_operand:P 0 "symbolic_operand" "")]
+ UNSPEC_TLS_DESC))
+ (clobber (reg:SI FCC0_REGNUM))
+ (clobber (reg:SI FCC1_REGNUM))
+ (clobber (reg:SI FCC2_REGNUM))
+ (clobber (reg:SI FCC3_REGNUM))
+ (clobber (reg:SI FCC4_REGNUM))
+ (clobber (reg:SI FCC5_REGNUM))
+ (clobber (reg:SI FCC6_REGNUM))
+ (clobber (reg:SI FCC7_REGNUM))
+ (clobber (reg:SI RETURN_ADDR_REGNUM))]
+ "TARGET_TLS_DESC"
+{
+ return TARGET_EXPLICIT_RELOCS
+ ? "pcalau12i\t$r4,%%desc_pc_hi20(%0)\n\t"
+ "addi.d\t$r4,$r4,%%desc_pc_lo12(%0)\n\t"
+ "ld.d\t$r1,$r4,%%desc_ld(%0)\n\t"
+ "jirl\t$r1,$r1,%%desc_call(%0)"
+ : "la.tls.desc\t$r4,%0";
+}
+ [(set_attr "got" "load")
+ (set_attr "mode" "<MODE>")
+ (set_attr "length" "16")])
+
+(define_insn "got_load_tls_desc_off64"
+ [(set (reg:DI 4)
+ (unspec:DI
+ [(match_operand:DI 0 "symbolic_operand" "")]
+ UNSPEC_TLS_DESC_OFF64))
+ (clobber (reg:SI FCC0_REGNUM))
+ (clobber (reg:SI FCC1_REGNUM))
+ (clobber (reg:SI FCC2_REGNUM))
+ (clobber (reg:SI FCC3_REGNUM))
+ (clobber (reg:SI FCC4_REGNUM))
+ (clobber (reg:SI FCC5_REGNUM))
+ (clobber (reg:SI FCC6_REGNUM))
+ (clobber (reg:SI FCC7_REGNUM))
+ (clobber (reg:SI RETURN_ADDR_REGNUM))
+ (clobber (match_operand:DI 1 "register_operand" "=&r"))]
+ "TARGET_TLS_DESC && TARGET_CMODEL_EXTREME"
+{
+ return TARGET_EXPLICIT_RELOCS
+ ? "pcalau12i\t$r4,%%desc_pc_hi20(%0)\n\t"
+ "addi.d\t%1,$r0,%%desc_pc_lo12(%0)\n\t"
+ "lu32i.d\t%1,%%desc64_pc_lo20(%0)\n\t"
+ "lu52i.d\t%1,%1,%%desc64_pc_hi12(%0)\n\t"
+ "add.d\t$r4,$r4,%1\n\t"
+ "ld.d\t$r1,$r4,%%desc_ld(%0)\n\t"
+ "jirl\t$r1,$r1,%%desc_call(%0)"
+ : "la.tls.desc\t$r4,%1,%0";
+}
+ [(set_attr "got" "load")
+ (set_attr "length" "28")])
+
(define_insn "@load_tls<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 317cd11..773747f 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -253,6 +253,20 @@ mpass-mrelax-to-as
Driver Var(la_pass_mrelax_to_as) Init(HAVE_AS_MRELAX_OPTION)
Pass -mrelax or -mno-relax option to the assembler.
+Enum
+Name(tls_type) Type(int)
+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(la_opt_tls_dialect) Init(M_OPT_UNSET) Save
+Specify TLS dialect.
+
-param=loongarch-vect-unroll-limit=
Target Joined UInteger Var(la_vect_unroll_limit) Init(6) IntegerRange(1, 64) Param
Used to limit unroll factor which indicates how much the autovectorizer may
diff --git a/gcc/config/loongarch/loongarch.opt.urls b/gcc/config/loongarch/loongarch.opt.urls
index 8e16304..88f0bb0 100644
--- a/gcc/config/loongarch/loongarch.opt.urls
+++ b/gcc/config/loongarch/loongarch.opt.urls
@@ -64,6 +64,9 @@ UrlSuffix(gcc/LoongArch-Options.html#index-mdirect-extern-access)
; skipping UrlSuffix for 'mrelax' due to finding no URLs
+mtls-dialect=
+UrlSuffix(gcc/LoongArch-Options.html#index-mtls-dialect-1)
+
mfrecipe
UrlSuffix(gcc/LoongArch-Options.html#index-mfrecipe)