TLS relocations do not support offsets, so add a new constraint Usb and
predicate aarch64_tls_symref to ensure only plain symbol_ref is allowed.
In the future UNSPEC could be removed in some cases and some patterns could
be shared in a single insn.
Passes regress, OK for commit?
gcc:
* config/aarch64/aarch64.md (tlsgd_small_<mode>): Update constraints.
(tlsie_small_<mode>): Likewise.
(tlsie_small_sidi): Likewise.
(tlsie_tiny_<mode>): Likewise.
(tlsie_tiny_sidi): Likewise.
(tlsle12_<mode>): Likewise.
(tlsle24_<mode>): Likewise.
(tlsle32_<mode>): Likewise.
(tlsle48_<mode>): Likewise.
(tlsdesc_small_<mode>): Likewise.
(tlsdesc_small_advsimd_<mode>): Likewise.
(tlsdesc_small_advsimd_<mode>): Likewise.
* config/aarch64/aarch64.cc (aarch64_expand_mov_immediate): Ensure
all TLS symbols have any offsets split off.
* config/aarch64/constraints.md (Usb): New constraint for symbol_ref.
* config/aarch64/predicates.md (aarch64_tls_symref): New predicate for
TLS.
(aarch64_tls_ie_symref): Remove.
(aarch64_tls_le_symref): Remove.
---
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index
cd5ed154c7ac93f0585c031d6f42f176fa276edf..de448249ebd98004410757943fc80af671866e2a
100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -6763,13 +6763,17 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
return;
- case SYMBOL_SMALL_TLSGD:
- case SYMBOL_SMALL_TLSDESC:
+ case SYMBOL_SMALL_TLSGD:
+ case SYMBOL_SMALL_TLSDESC:
case SYMBOL_SMALL_TLSIE:
case SYMBOL_SMALL_GOT_28K:
case SYMBOL_SMALL_GOT_4G:
case SYMBOL_TINY_GOT:
case SYMBOL_TINY_TLSIE:
+ case SYMBOL_TLSLE12:
+ case SYMBOL_TLSLE24:
+ case SYMBOL_TLSLE32:
+ case SYMBOL_TLSLE48:
if (const_offset != 0)
{
gcc_assert(can_create_pseudo_p ());
@@ -6782,10 +6786,6 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
case SYMBOL_SMALL_ABSOLUTE:
case SYMBOL_TINY_ABSOLUTE:
- case SYMBOL_TLSLE12:
- case SYMBOL_TLSLE24:
- case SYMBOL_TLSLE32:
- case SYMBOL_TLSLE48:
aarch64_load_symref_appropriately (dest, imm, sty);
return;
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index
0ef01e889a6d8b47d4c348c2fd623460804d882e..bab39061c41e122006041ba0e789f5d6fe6e6bbf
100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -8007,7 +8007,7 @@ (define_expand "tlsgd_small_<mode>"
[(parallel [(set (match_operand:PTR 0 "register_operand")
(call (mem:DI (match_dup 2)) (const_int 1)))
(unspec:DI [(const_int 0)] UNSPEC_CALLEE_ABI)
- (unspec:DI [(match_operand 1 "aarch64_valid_symref")]
UNSPEC_GOTSMALLTLS)
+ (unspec:DI [(match_operand 1 "aarch64_tls_symref")]
UNSPEC_GOTSMALLTLS)
(clobber (reg:DI LR_REGNUM))])]
""
{
@@ -8018,7 +8018,7 @@ (define_insn "*tlsgd_small_<mode>"
[(set (match_operand:PTR 0 "register_operand" "")
(call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
(unspec:DI [(const_int 0)] UNSPEC_CALLEE_ABI)
- (unspec:DI [(match_operand 1 "aarch64_valid_symref" "S")]
UNSPEC_GOTSMALLTLS)
+ (unspec:DI [(match_operand 1 "aarch64_tls_symref" "Usb")]
UNSPEC_GOTSMALLTLS)
(clobber (reg:DI LR_REGNUM))
]
""
@@ -8028,7 +8028,7 @@ (define_insn "*tlsgd_small_<mode>"
(define_insn "tlsie_small_<mode>"
[(set (match_operand:PTR 0 "register_operand" "=r")
- (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")]
+ (unspec:PTR [(match_operand 1 "aarch64_tls_symref" "Usb")]
UNSPEC_GOTSMALLTLS))]
""
"adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
@@ -8039,7 +8039,7 @@ (define_insn "tlsie_small_<mode>"
(define_insn "tlsie_small_sidi"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
- (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")]
+ (unspec:SI [(match_operand 1 "aarch64_tls_symref" "Usb")]
UNSPEC_GOTSMALLTLS)))]
""
"adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
@@ -8049,7 +8049,7 @@ (define_insn "tlsie_small_sidi"
(define_insn "tlsie_tiny_<mode>"
[(set (match_operand:PTR 0 "register_operand" "=&r")
- (unspec:PTR [(match_operand 1 "aarch64_tls_ie_symref" "S")
+ (unspec:PTR [(match_operand 1 "aarch64_tls_symref" "Usb")
(match_operand:PTR 2 "register_operand" "r")]
UNSPEC_GOTTINYTLS))]
""
@@ -8061,7 +8061,7 @@ (define_insn "tlsie_tiny_<mode>"
(define_insn "tlsie_tiny_sidi"
[(set (match_operand:DI 0 "register_operand" "=&r")
(zero_extend:DI
- (unspec:SI [(match_operand 1 "aarch64_tls_ie_symref" "S")
+ (unspec:SI [(match_operand 1 "aarch64_tls_symref" "Usb")
(match_operand:DI 2 "register_operand" "r")
]
UNSPEC_GOTTINYTLS)))]
@@ -8074,7 +8074,7 @@ (define_insn "tlsie_tiny_sidi"
(define_insn "tlsle12_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(match_operand:P 1 "register_operand" "r")
- (match_operand 2 "aarch64_tls_le_symref" "S")]
+ (match_operand 2 "aarch64_tls_symref" "Usb")]
UNSPEC_TLSLE12))]
""
"add\\t%<w>0, %<w>1, #%L2";
@@ -8085,7 +8085,7 @@ (define_insn "tlsle12_<mode>"
(define_insn "tlsle24_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(match_operand:P 1 "register_operand" "r")
- (match_operand 2 "aarch64_tls_le_symref" "S")]
+ (match_operand 2 "aarch64_tls_symref" "Usb")]
UNSPEC_TLSLE24))]
""
"add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
@@ -8095,7 +8095,7 @@ (define_insn "tlsle24_<mode>"
(define_insn "tlsle32_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
- (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+ (unspec:P [(match_operand 1 "aarch64_tls_symref" "Usb")]
UNSPEC_TLSLE32))]
""
"movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
@@ -8105,7 +8105,7 @@ (define_insn "tlsle32_<mode>"
(define_insn "tlsle48_<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
- (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+ (unspec:P [(match_operand 1 "aarch64_tls_symref" "Usb")]
UNSPEC_TLSLE48))]
""
"movz\\t%<w>0, #:tprel_g2:%1\;movk\\t%<w>0, #:tprel_g1_nc:%1\;movk\\t%<w>0,
#:tprel_g0_nc:%1"
@@ -8114,7 +8114,7 @@ (define_insn "tlsle48_<mode>"
)
(define_expand "tlsdesc_small_<mode>"
- [(unspec:PTR [(match_operand 0 "aarch64_valid_symref")] UNSPEC_TLSDESC)]
+ [(unspec:PTR [(match_operand 0 "aarch64_tls_symref")] UNSPEC_TLSDESC)]
"TARGET_TLS_DESC"
{
if (TARGET_SVE)
@@ -8136,7 +8136,7 @@ (define_expand "tlsdesc_small_<mode>"
;; R0 and LR.
(define_insn "tlsdesc_small_advsimd_<mode>"
[(set (reg:PTR R0_REGNUM)
- (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
+ (unspec:PTR [(match_operand 0 "aarch64_tls_symref" "Usb")]
UNSPEC_TLSDESC))
(clobber (reg:DI LR_REGNUM))
(clobber (reg:CC CC_REGNUM))
@@ -8153,7 +8153,7 @@ (define_insn "tlsdesc_small_advsimd_<mode>"
(define_insn "tlsdesc_small_sve_<mode>"
[(set (reg:PTR R0_REGNUM)
(call (mem:DI (unspec:PTR
- [(match_operand 0 "aarch64_valid_symref")]
+ [(match_operand 0 "aarch64_tls_symref")]
UNSPEC_TLSDESC))
(const_int 0)))
(unspec:DI [(match_operand:DI 1 "const_int_operand")] UNSPEC_CALLEE_ABI)
diff --git a/gcc/config/aarch64/constraints.md
b/gcc/config/aarch64/constraints.md
index
8760220835b74e87497a696865a5ea7304b9d406..93025bd3e861cb1285bcabe6b1974191f7d79c7f
100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -195,6 +195,11 @@ (define_constraint "Usa"
(match_test "aarch64_symbolic_address_p (op)")
(match_test "aarch64_mov_operand_p (op, GET_MODE (op))")))
+(define_constraint "Usb"
+ "@internal
+ A constraint that matches a symbol_ref."
+ (match_code "symbol_ref"))
+
(define_constraint "Usm"
"A constant that can be used with the S[MIN/MAX] CSSC instructions."
(and (match_code "const_int")
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index
40b0e8b9f02c7eb936edf5245ce6a89611fc52a1..76d42312607ff58834267df3c7415b7d0820e89f
100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -372,48 +372,10 @@ (define_predicate "aarch64_valid_symref"
!= SYMBOL_FORCE_TO_MEM);
})
-(define_predicate "aarch64_tls_ie_symref"
- (match_code "const, symbol_ref, label_ref")
-{
- switch (GET_CODE (op))
- {
- case CONST:
- op = XEXP (op, 0);
- if (GET_CODE (op) != PLUS
- || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
- || GET_CODE (XEXP (op, 1)) != CONST_INT)
- return false;
- op = XEXP (op, 0);
- /* FALLTHRU */
-
- case SYMBOL_REF:
- return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC;
-
- default:
- gcc_unreachable ();
- }
-})
-
-(define_predicate "aarch64_tls_le_symref"
- (match_code "const, symbol_ref, label_ref")
+(define_predicate "aarch64_tls_symref"
+ (match_code "symbol_ref")
{
- switch (GET_CODE (op))
- {
- case CONST:
- op = XEXP (op, 0);
- if (GET_CODE (op) != PLUS
- || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
- || GET_CODE (XEXP (op, 1)) != CONST_INT)
- return false;
- op = XEXP (op, 0);
- /* FALLTHRU */
-
- case SYMBOL_REF:
- return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC;
-
- default:
- gcc_unreachable ();
- }
+ return SYMBOL_REF_TLS_MODEL (op) != TLS_MODEL_NONE;
})
(define_predicate "aarch64_mov_operand"