aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/aarch64/aarch64.md80
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/tls_1.c17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/tls_2.C30
5 files changed, 140 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2dbe441..8e150de 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
2018-03-13 Richard Sandiford <richard.sandiford@linaro.org>
+ * config/aarch64/aarch64.md (V4_REGNUM, V8_REGNUM, V12_REGNUM)
+ (V20_REGNUM, V24_REGNUM, V28_REGNUM, P1_REGNUM, P2_REGNUM, P3_REGNUM)
+ (P4_REGNUM, P5_REGNUM, P6_REGNUM, P8_REGNUM, P9_REGNUM, P10_REGNUM)
+ (P11_REGNUM, P12_REGNUM, P13_REGNUM, P14_REGNUM): New define_constants.
+ (tlsdesc_small_<mode>): Turn a define_expand and use
+ tlsdesc_small_sve_<mode> for SVE. Rename original define_insn to...
+ (tlsdesc_small_advsimd_<mode>): ...this.
+ (tlsdesc_small_sve_<mode>): New pattern.
+
+2018-03-13 Richard Sandiford <richard.sandiford@linaro.org>
+
* config/aarch64/iterators.md (UNSPEC_SMUL_HIGHPART)
(UNSPEC_UMUL_HIGHPART): New constants.
(MUL_HIGHPART): New int iteraor.
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 417ea35..3a848f8 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -57,7 +57,14 @@
(LR_REGNUM 30)
(SP_REGNUM 31)
(V0_REGNUM 32)
+ (V4_REGNUM 36)
+ (V8_REGNUM 40)
+ (V12_REGNUM 44)
(V15_REGNUM 47)
+ (V16_REGNUM 48)
+ (V20_REGNUM 52)
+ (V24_REGNUM 56)
+ (V28_REGNUM 60)
(V31_REGNUM 63)
(LAST_SAVED_REGNUM 63)
(SFP_REGNUM 64)
@@ -66,7 +73,20 @@
;; Defined only to make the DWARF description simpler.
(VG_REGNUM 67)
(P0_REGNUM 68)
+ (P1_REGNUM 69)
+ (P2_REGNUM 70)
+ (P3_REGNUM 71)
+ (P4_REGNUM 72)
+ (P5_REGNUM 73)
+ (P6_REGNUM 74)
(P7_REGNUM 75)
+ (P8_REGNUM 76)
+ (P9_REGNUM 77)
+ (P10_REGNUM 78)
+ (P11_REGNUM 79)
+ (P12_REGNUM 80)
+ (P13_REGNUM 81)
+ (P14_REGNUM 82)
(P15_REGNUM 83)
]
)
@@ -5787,14 +5807,68 @@
(set_attr "length" "12")]
)
-(define_insn "tlsdesc_small_<mode>"
+(define_expand "tlsdesc_small_<mode>"
+ [(unspec:PTR [(match_operand 0 "aarch64_valid_symref")] UNSPEC_TLSDESC)]
+ "TARGET_TLS_DESC"
+ {
+ if (TARGET_SVE)
+ emit_insn (gen_tlsdesc_small_sve_<mode> (operands[0]));
+ else
+ emit_insn (gen_tlsdesc_small_advsimd_<mode> (operands[0]));
+ DONE;
+ }
+)
+
+;; tlsdesc calls preserve all core and Advanced SIMD registers except
+;; R0 and LR.
+(define_insn "tlsdesc_small_advsimd_<mode>"
[(set (reg:PTR R0_REGNUM)
(unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
- UNSPEC_TLSDESC))
+ UNSPEC_TLSDESC))
(clobber (reg:DI LR_REGNUM))
(clobber (reg:CC CC_REGNUM))
(clobber (match_scratch:DI 1 "=r"))]
- "TARGET_TLS_DESC"
+ "TARGET_TLS_DESC && !TARGET_SVE"
+ "adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
+ [(set_attr "type" "call")
+ (set_attr "length" "16")])
+
+;; For SVE, model tlsdesc calls as clobbering all vector and predicate
+;; registers, on top of the usual R0 and LR. In reality the calls
+;; preserve the low 128 bits of the vector registers, but we don't
+;; yet have a way of representing that in the instruction pattern.
+(define_insn "tlsdesc_small_sve_<mode>"
+ [(set (reg:PTR R0_REGNUM)
+ (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
+ UNSPEC_TLSDESC))
+ (clobber (reg:DI LR_REGNUM))
+ (clobber (reg:CC CC_REGNUM))
+ (clobber (reg:XI V0_REGNUM))
+ (clobber (reg:XI V4_REGNUM))
+ (clobber (reg:XI V8_REGNUM))
+ (clobber (reg:XI V12_REGNUM))
+ (clobber (reg:XI V16_REGNUM))
+ (clobber (reg:XI V20_REGNUM))
+ (clobber (reg:XI V24_REGNUM))
+ (clobber (reg:XI V28_REGNUM))
+ (clobber (reg:VNx2BI P0_REGNUM))
+ (clobber (reg:VNx2BI P1_REGNUM))
+ (clobber (reg:VNx2BI P2_REGNUM))
+ (clobber (reg:VNx2BI P3_REGNUM))
+ (clobber (reg:VNx2BI P4_REGNUM))
+ (clobber (reg:VNx2BI P5_REGNUM))
+ (clobber (reg:VNx2BI P6_REGNUM))
+ (clobber (reg:VNx2BI P7_REGNUM))
+ (clobber (reg:VNx2BI P8_REGNUM))
+ (clobber (reg:VNx2BI P9_REGNUM))
+ (clobber (reg:VNx2BI P10_REGNUM))
+ (clobber (reg:VNx2BI P11_REGNUM))
+ (clobber (reg:VNx2BI P12_REGNUM))
+ (clobber (reg:VNx2BI P13_REGNUM))
+ (clobber (reg:VNx2BI P14_REGNUM))
+ (clobber (reg:VNx2BI P15_REGNUM))
+ (clobber (match_scratch:DI 1 "=r"))]
+ "TARGET_TLS_DESC && TARGET_SVE"
"adrp\\tx0, %A0\;ldr\\t%<w>1, [x0, #%L0]\;add\\t<w>0, <w>0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
[(set_attr "type" "call")
(set_attr "length" "16")])
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1257912..84c64b2e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2018-03-13 Richard Sandiford <richard.sandiford@linaro.org>
+ * gcc.target/aarch64/sve/tls_1.c: New test.
+ * gcc.target/aarch64/sve/tls_2.C: Likewise.
+
+2018-03-13 Richard Sandiford <richard.sandiford@linaro.org>
+
* gcc.target/aarch64/sve/mul_highpart_1.c: New test.
* gcc.target/aarch64/sve/mul_highpart_1_run.c: Likewise.
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/tls_1.c b/gcc/testsuite/gcc.target/aarch64/sve/tls_1.c
new file mode 100644
index 0000000..ca9b908
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/tls_1.c
@@ -0,0 +1,17 @@
+/* { dg-options "-O2 -fPIC -msve-vector-bits=256" } */
+
+typedef unsigned int v8si __attribute__((vector_size(32)));
+
+extern __thread int y;
+
+void
+f (int *a)
+{
+ v8si x;
+ asm volatile ("dup %0.s, #0x11" : "=w" (x) :: "memory");
+ if (*a)
+ asm volatile ("insr %0.s, %w2" : "=w" (x) : "0" (x), "r" (y));
+}
+
+/* { dg-final { scan-assembler {\tst(r|1.)\tz[0-9]} } } */
+/* { dg-final { scan-assembler {\tld(r|1.)\tz[0-9]} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/tls_2.C b/gcc/testsuite/gcc.target/aarch64/sve/tls_2.C
new file mode 100644
index 0000000..c18a737
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/tls_2.C
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC -msve-vector-bits=256" } */
+
+#include <stdint.h>
+
+typedef int8_t v32qi __attribute__((vector_size (32)));
+
+extern __thread int z;
+
+void
+foo (v32qi *a, int *b)
+{
+ v32qi x = a[0], y = a[1];
+ asm volatile ("" :: "w" ((v32qi) { -1, 0, 0, -1, -1, -1, 0, 0,
+ -1, -1, -1, -1, 0, 0, 0, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, 0, 0 } ? x : y)
+ : "memory");
+ if (*b)
+ {
+ x = a[2], y = a[3];
+ asm volatile ("" :: "w" ((v32qi) { -1, 0, 0, -1, -1, -1, 0, 0,
+ -1, -1, -1, -1, 0, 0, 0, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, 0, 0 } ? x : y),
+ "r" (z));
+ }
+}
+
+/* { dg-final { scan-assembler-times {\tldr\tp[0-9]} 2 } } */