@@ -319,4 +319,10 @@ enum riscv_entity
#define TARGET_VECTOR_VLS \
(TARGET_VECTOR && riscv_autovec_preference == RVV_SCALABLE)
+/* TLS types. */
+enum riscv_tls_type {
+ TLS_TRADITIONAL,
+ TLS_DESCRIPTORS
+};
+
#endif /* ! GCC_RISCV_OPTS_H */
@@ -33,9 +33,10 @@ enum riscv_symbol_type {
SYMBOL_TLS,
SYMBOL_TLS_LE,
SYMBOL_TLS_IE,
- SYMBOL_TLS_GD
+ SYMBOL_TLS_GD,
+ SYMBOL_TLSDESC,
};
-#define NUM_SYMBOL_TYPES (SYMBOL_TLS_GD + 1)
+#define NUM_SYMBOL_TYPES (SYMBOL_TLSDESC + 1)
/* Classifies an address.
@@ -799,6 +799,7 @@ static int riscv_symbol_insns (enum riscv_symbol_type type)
case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference. */
case SYMBOL_PCREL: return 2; /* AUIPC + the reference. */
case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference. */
+ case SYMBOL_TLSDESC: return 6; /* 4-instruction call + ADD TP + the reference. */
case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference. */
default: gcc_unreachable ();
}
@@ -1601,6 +1602,16 @@ static rtx riscv_tls_add_tp_le (rtx dest, rtx base, rtx sym)
return gen_tls_add_tp_lesi (dest, base, tp, sym);
}
+/* Instruction sequence to call the TLS Descriptor resolver. */
+
+static rtx riscv_tlsdesc (rtx sym, rtx seqno)
+{
+ if (Pmode == DImode)
+ return gen_tlsdescdi (sym, seqno);
+ else
+ return gen_tlsdescsi (sym, seqno);
+}
+
/* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
it appears in a MEM of that mode. Return true if ADDR is a legitimate
constant in that context and can be split into high and low parts.
@@ -1734,7 +1745,7 @@ riscv_call_tls_get_addr (rtx sym, rtx result)
static rtx
riscv_legitimize_tls_address (rtx loc)
{
- rtx dest, tp, tmp;
+ rtx dest, tp, tmp, a0;
enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
#if 0
@@ -1750,9 +1761,24 @@ riscv_legitimize_tls_address (rtx loc)
/* Rely on section anchors for the optimization that LDM TLS
provides. The anchor's address is loaded with GD TLS. */
case TLS_MODEL_GLOBAL_DYNAMIC:
- tmp = gen_rtx_REG (Pmode, GP_RETURN);
- dest = gen_reg_rtx (Pmode);
- emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp, loc);
+ if (TARGET_TLSDESC)
+ {
+ static unsigned seqno;
+ tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
+ a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
+ dest = gen_reg_rtx (Pmode);
+
+ emit_insn (riscv_tlsdesc (loc, GEN_INT (seqno)));
+ emit_insn (gen_add3_insn (dest, a0, tp));
+ seqno++;
+ }
+ else
+ {
+ tmp = gen_rtx_REG (Pmode, GP_RETURN);
+ dest = gen_reg_rtx (Pmode);
+ emit_libcall_block (riscv_call_tls_get_addr (loc, tmp), dest, tmp,
+ loc);
+ }
break;
case TLS_MODEL_INITIAL_EXEC:
@@ -1122,4 +1122,7 @@ extern void riscv_remove_unneeded_save_restore_calls (void);
#define OPTIMIZE_MODE_SWITCHING(ENTITY) (TARGET_VECTOR)
#define NUM_MODES_FOR_MODE_SWITCHING {VXRM_MODE_NONE, riscv_vector::FRM_NONE}
+/* Check TLS Descriptors mechanism is selected. */
+#define TARGET_TLSDESC (riscv_tls_dialect == TLS_DESCRIPTORS)
+
#endif /* ! GCC_RISCV_H */
@@ -47,7 +47,7 @@
UNSPEC_TLS_LE
UNSPEC_TLS_IE
UNSPEC_TLS_GD
-
+ UNSPEC_TLSDESC
;; High part of PC-relative address.
UNSPEC_AUIPC
@@ -121,6 +121,14 @@
(T1_REGNUM 6)
(S0_REGNUM 8)
(S1_REGNUM 9)
+ (A0_REGNUM 10)
+ (A1_REGNUM 11)
+ (A2_REGNUM 12)
+ (A3_REGNUM 13)
+ (A4_REGNUM 14)
+ (A5_REGNUM 15)
+ (A6_REGNUM 16)
+ (A7_REGNUM 17)
(S2_REGNUM 18)
(S3_REGNUM 19)
(S4_REGNUM 20)
@@ -1869,6 +1877,18 @@
[(set_attr "got" "load")
(set_attr "mode" "<MODE>")])
+(define_insn "tlsdesc<mode>"
+ [(set (reg:P A0_REGNUM)
+ (unspec:P
+ [(match_operand:P 0 "symbolic_operand" "")
+ (match_operand:P 1 "const_int_operand")]
+ UNSPEC_TLSDESC))
+ (clobber (reg:SI T0_REGNUM))]
+ "TARGET_TLSDESC"
+ ".LT%1: auipc\ta0, %%tlsdesc_hi(%0)\;<load>\tt0,%%tlsdesc_load_lo(.LT%1)(a0)\;addi\ta0,a0,%%tlsdesc_add_lo(.LT%1)\;jalr\tt0,t0,%%tlsdesc_call(.LT%1)"
+ [(set_attr "type" "multi")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "auipc<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P
@@ -311,3 +311,17 @@ Enum(riscv_autovec_lmul) String(m8) Value(RVV_M8)
-param=riscv-autovec-lmul=
Target RejectNegative Joined Enum(riscv_autovec_lmul) Var(riscv_autovec_lmul) Init(RVV_M1)
-param=riscv-autovec-lmul=<string> Set the RVV LMUL of auto-vectorization in the RISC-V port.
+
+Enum
+Name(tls_type) Type(enum riscv_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(riscv_tls_dialect) Init(TLS_TRADITIONAL) Save
+Specify TLS dialect.
\ No newline at end of file