[AArch64][TLSLE][3/3] Implement local executable mode for all memory model
authorJiong Wang <jiwang@gcc.gnu.org>
Wed, 26 Aug 2015 13:09:35 +0000 (13:09 +0000)
committerJiong Wang <jiwang@gcc.gnu.org>
Wed, 26 Aug 2015 13:09:35 +0000 (13:09 +0000)
2015-08-26  Marcus Shawcroft  <marcus.shawcroft@arm.com>
    Jiong Wang  <jiong.wang@arm.com>
gcc/
* config/aarch64/aarch64.c (initialize_aarch64_tls_size): Set default
tls size for tiny, small, large memory model.
(aarch64_load_symref_appropriately): Support new symbol types.
(aarch64_expand_mov_immediate): Likewise.
(aarch64_print_operand): Likewise.
(aarch64_classify_tls_symbol): Likewise.
* config/aarch64/aarch64-protos.h (aarch64_symbol_context): Likewise.
(aarch64_symbol_type): Likewise.
* config/aarch64/aarch64.md (tlsle): Deleted.
(tlsle12_<mode>): New define_insn.
(tlsle24_<mode>): Likewise.
(tlsle32_<mode>): Likewise.
(tlsle48_<mode>): Likewise.
* doc/sourcebuild.texi (AArch64-specific attributes): Document
"aarch64_tlsle32".

gcc/testsuite/
* lib/target-supports.exp (check_effective_target_aarch64_tlsle32):
New test directive.
* gcc.target/aarch64/tlsle_1.x: New test source.
* gcc.target/aarch64/tlsle12_1.c: New testcase.
* gcc.target/aarch64/tlsle24_1.c: Likewise.
* gcc.target/aarch64/tlsle32_1.c: Likewise.

From-SVN: r227215

gcc/ChangeLog
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/tlsle12_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/tlsle24_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/tlsle32_1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/tlsle_1.x [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp

index 04f52ebcbc077186149d2088ae1e07971eca1475..57458876ce106c24936086581be5ab7a5b0f4604 100644 (file)
@@ -1,3 +1,22 @@
+2015-08-26  Marcus Shawcroft  <marcus.shawcroft@arm.com>
+           Jiong Wang  <jiong.wang@arm.com>
+
+       * config/aarch64/aarch64.c (initialize_aarch64_tls_size): Set default
+       tls size for tiny, small, large memory model.
+       (aarch64_load_symref_appropriately): Support new symbol types.
+       (aarch64_expand_mov_immediate): Likewise.
+       (aarch64_print_operand): Likewise.
+       (aarch64_classify_tls_symbol): Likewise.
+       * config/aarch64/aarch64-protos.h (aarch64_symbol_context): Likewise.
+       (aarch64_symbol_type): Likewise.
+       * config/aarch64/aarch64.md (tlsle): Deleted.
+       (tlsle12_<mode>): New define_insn.
+       (tlsle24_<mode>): Likewise.
+       (tlsle32_<mode>): Likewise.
+       (tlsle48_<mode>): Likewise.
+       * doc/sourcebuild.texi (AArch64-specific attributes): Document
+       "aarch64_tlsle32".
+
 2015-08-26  Matthew Wahab  <matthew.wahab@arm.com>
 
        * config/arm/arm-protos.h (FL_NONE): New.
index 55f287e2335eb3e9198aeaaf82671ba13be1aed9..59c364dc72ea651a8dd891817a676c4f183abd97 100644 (file)
@@ -74,7 +74,10 @@ enum aarch64_symbol_context
    SYMBOL_SMALL_TLSGD
    SYMBOL_SMALL_TLSDESC
    SYMBOL_SMALL_GOTTPREL
+   SYMBOL_TLSLE12
    SYMBOL_TLSLE24
+   SYMBOL_TLSLE32
+   SYMBOL_TLSLE48
    Each of these represents a thread-local symbol, and corresponds to the
    thread local storage relocation operator for the symbol being referred to.
 
@@ -111,7 +114,10 @@ enum aarch64_symbol_type
   SYMBOL_SMALL_GOTTPREL,
   SYMBOL_TINY_ABSOLUTE,
   SYMBOL_TINY_GOT,
+  SYMBOL_TLSLE12,
   SYMBOL_TLSLE24,
+  SYMBOL_TLSLE32,
+  SYMBOL_TLSLE48,
   SYMBOL_FORCE_TO_MEM
 };
 
index b473e4af7d7ad85f59897efcf5ffa52866cbf3f5..626589859e7358536e1e0783950514d976011140 100644 (file)
@@ -1114,14 +1114,43 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
        return;
       }
 
+    case SYMBOL_TLSLE12:
     case SYMBOL_TLSLE24:
+    case SYMBOL_TLSLE32:
+    case SYMBOL_TLSLE48:
       {
+       machine_mode mode = GET_MODE (dest);
        rtx tp = aarch64_load_tp (NULL);
 
-       if (GET_MODE (dest) != Pmode)
-         tp = gen_lowpart (GET_MODE (dest), tp);
+       if (mode != Pmode)
+         tp = gen_lowpart (mode, tp);
+
+       switch (type)
+         {
+         case SYMBOL_TLSLE12:
+           emit_insn ((mode == DImode ? gen_tlsle12_di : gen_tlsle12_si)
+                       (dest, tp, imm));
+           break;
+         case SYMBOL_TLSLE24:
+           emit_insn ((mode == DImode ? gen_tlsle24_di : gen_tlsle24_si)
+                       (dest, tp, imm));
+         break;
+         case SYMBOL_TLSLE32:
+           emit_insn ((mode == DImode ? gen_tlsle32_di : gen_tlsle32_si)
+                       (dest, imm));
+           emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3)
+                       (dest, dest, tp));
+         break;
+         case SYMBOL_TLSLE48:
+           emit_insn ((mode == DImode ? gen_tlsle48_di : gen_tlsle48_si)
+                       (dest, imm));
+           emit_insn ((mode == DImode ? gen_adddi3 : gen_addsi3)
+                       (dest, dest, tp));
+           break;
+         default:
+           gcc_unreachable ();
+         }
 
-       emit_insn (gen_tlsle (dest, tp, imm));
        set_unique_reg_note (get_last_insn (), REG_EQUIV, imm);
        return;
       }
@@ -1676,7 +1705,10 @@ 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;
 
@@ -4579,6 +4611,10 @@ aarch64_print_operand (FILE *f, rtx x, char code)
          asm_fprintf (asm_out_file, ":gottprel_lo12:");
          break;
 
+       case SYMBOL_TLSLE12:
+         asm_fprintf (asm_out_file, ":tprel_lo12:");
+         break;
+
        case SYMBOL_TLSLE24:
          asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
          break;
@@ -8695,7 +8731,16 @@ aarch64_classify_tls_symbol (rtx x)
       return SYMBOL_SMALL_GOTTPREL;
 
     case TLS_MODEL_LOCAL_EXEC:
-      return SYMBOL_TLSLE24;
+      if (aarch64_tls_size == 12)
+       return SYMBOL_TLSLE12;
+      else if (aarch64_tls_size == 24)
+       return SYMBOL_TLSLE24;
+      else if (aarch64_tls_size == 32)
+       return SYMBOL_TLSLE32;
+      else if (aarch64_tls_size == 48)
+       return SYMBOL_TLSLE48;
+      else
+       gcc_unreachable ();
 
     case TLS_MODEL_EMULATED:
     case TLS_MODEL_NONE:
index f8c44683752130d8557dc160f7bb2b62147fb2c2..deac21150b575199a850b30db3ba5c4870bbc0fc 100644 (file)
     UNSPEC_ST4_LANE
     UNSPEC_TLS
     UNSPEC_TLSDESC
-    UNSPEC_TLSLE
+    UNSPEC_TLSLE12
+    UNSPEC_TLSLE24
+    UNSPEC_TLSLE32
+    UNSPEC_TLSLE48
     UNSPEC_USHL_2S
     UNSPEC_VSTRUCTDUMMY
     UNSPEC_SP_SET
    (set_attr "length" "8")]
 )
 
-(define_expand "tlsle"
-  [(set (match_operand 0 "register_operand" "=r")
-        (unspec [(match_operand 1 "register_operand" "r")
-                   (match_operand 2 "aarch64_tls_le_symref" "S")]
-                   UNSPEC_TLSLE))]
+(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")]
+                  UNSPEC_TLSLE12))]
   ""
-{
-  machine_mode mode = GET_MODE (operands[0]);
-  emit_insn ((mode == DImode
-             ? gen_tlsle_di
-             : gen_tlsle_si) (operands[0], operands[1], operands[2]));
-  DONE;
-})
+  "add\\t%<w>0, %<w>1, #%L2";
+  [(set_attr "type" "alu_sreg")
+   (set_attr "length" "4")]
+)
 
-(define_insn "tlsle_<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")]
-                  UNSPEC_TLSLE))]
+       (unspec:P [(match_operand:P 1 "register_operand" "r")
+                  (match_operand 2 "aarch64_tls_le_symref" "S")]
+                  UNSPEC_TLSLE24))]
   ""
   "add\\t%<w>0, %<w>1, #%G2, lsl #12\;add\\t%<w>0, %<w>0, #%L2"
-  [(set_attr "type" "alu_sreg")
+  [(set_attr "type" "multiple")
    (set_attr "length" "8")]
 )
 
+(define_insn "tlsle32_<mode>"
+  [(set (match_operand:P 0 "register_operand" "=r")
+       (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+                  UNSPEC_TLSLE32))]
+  ""
+  "movz\\t%<w>0, #:tprel_g1:%1\;movk\\t%<w>0, #:tprel_g0_nc:%1"
+  [(set_attr "type" "multiple")
+   (set_attr "length" "8")]
+)
+
+(define_insn "tlsle48_<mode>"
+  [(set (match_operand:P 0 "register_operand" "=r")
+       (unspec:P [(match_operand 1 "aarch64_tls_le_symref" "S")]
+                  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"
+  [(set_attr "type" "multiple")
+   (set_attr "length" "12")]
+)
+
 (define_insn "tlsdesc_small_<mode>"
   [(set (reg:PTR R0_REGNUM)
         (unspec:PTR [(match_operand 0 "aarch64_valid_symref" "S")]
index ac549889d7e59f254f96dc0979d33655b48b5e16..7e3828fb05d5ebf9de54b73654317c68b2544ae8 100644 (file)
@@ -1,3 +1,12 @@
+2015-08-26  Jiong Wang  <jiong.wang@arm.com>
+
+       * lib/target-supports.exp (check_effective_target_aarch64_tlsle32):
+       New test directive.
+       * gcc.target/aarch64/tlsle_1.x: New test source.
+       * gcc.target/aarch64/tlsle12_1.c: New testcase.
+       * gcc.target/aarch64/tlsle24_1.c: Likewise.
+       * gcc.target/aarch64/tlsle32_1.c: Likewise.
+
 2015-08-26  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        PR fortran/29600
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle12_1.c b/gcc/testsuite/gcc.target/aarch64/tlsle12_1.c
new file mode 100644 (file)
index 0000000..846aa98
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=12 --save-temps" } */
+
+#include "tlsle_1.x"
+
+/* { dg-final { scan-assembler-times "#:tprel_lo12" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle24_1.c b/gcc/testsuite/gcc.target/aarch64/tlsle24_1.c
new file mode 100644 (file)
index 0000000..e8b14ae
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=24 --save-temps" } */
+
+#include "tlsle_1.x"
+
+/* { dg-final { scan-assembler-times "#:tprel_lo12_nc" 2 } } */
+/* { dg-final { scan-assembler-times "#:tprel_hi12" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle32_1.c b/gcc/testsuite/gcc.target/aarch64/tlsle32_1.c
new file mode 100644 (file)
index 0000000..edc06ba
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-require-effective-target aarch64_tlsle32 } */
+/* { dg-options "-O2 -fpic -ftls-model=local-exec -mtls-size=32 --save-temps" } */
+
+#include "tlsle_1.x"
+
+/* { dg-final { scan-assembler-times "#:tprel_g1" 2 } } */
+/* { dg-final { scan-assembler-times "#:tprel_g0_nc" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tlsle_1.x b/gcc/testsuite/gcc.target/aarch64/tlsle_1.x
new file mode 100644 (file)
index 0000000..d92281b
--- /dev/null
@@ -0,0 +1,14 @@
+void abort (void);
+
+__thread int t0 = 0x10;
+__thread int t1 = 0x10;
+
+int
+main (int argc, char **argv)
+{
+  if (t0 != t1)
+    abort ();
+
+  return  0;
+}
+
index 1a0ad787ac09e101b9205dc88499061a933a3f7f..728d02026b55a784d54de6981f21db79a75ef189 100644 (file)
@@ -977,6 +977,23 @@ proc check_effective_target_aarch64_small_fpic { } {
     }
 }
 
+# On AArch64, instruction sequence for TLS LE under -mtls-size=32 will utilize
+# the relocation modifier "tprel_g0_nc" together with MOVK, it's only supported
+# in binutils since 2015-03-04 as PR gas/17843.
+#
+# This test directive make sure binutils support all features needed by TLS LE
+# under -mtls-size=32 on AArch64.
+
+proc check_effective_target_aarch64_tlsle32 { } {
+    if { [istarget aarch64*-*-*] } {
+       return [check_no_compiler_messages aarch64_tlsle32 object {
+           void foo (void) { asm ("movk x1,#:tprel_g0_nc:t1"); }
+       }]
+    } else {
+       return 0
+    }
+}
+
 # Return 1 if -shared is supported, as in no warnings or errors
 # emitted, 0 otherwise.