]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/54760 ([SH] Add __builtin_thread_pointer, __builtin_set_thread_pointer)
authorOleg Endo <olegendo@gcc.gnu.org>
Sat, 6 Oct 2012 11:20:11 +0000 (11:20 +0000)
committerOleg Endo <olegendo@gcc.gnu.org>
Sat, 6 Oct 2012 11:20:11 +0000 (11:20 +0000)
PR target/54760
* config/sh/sh.md (define_constants): Add UNSPECV_GBR.
(get_thread_pointer, set_thread_pointer): New expanders.
(load_gbr): Rename to store_gbr.  Remove GBR_REG use.
(store_gbr): New insn.
* config/sh/sh.c (prepare_move_operands): Use gen_store_gbr instead of
gen_load_gbr in TLS_MODEL_LOCAL_EXEC case.
(sh1_builtin_p): New function.
(signature_args): Add SH_BLTIN_VP.
(bdesc): Add __builtin_thread_pointer and __builtin_set_thread_pointer.

PR target/54760
* gcc.target/sh/pr54760-1.c: New.

From-SVN: r192155

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/sh/pr54760-1.c [new file with mode: 0644]

index 6178f335b689743b04dfd479e914db157db68907..738ab7fad0b2059f184f3ad43a57c1d8c35d3e3f 100644 (file)
@@ -1,3 +1,16 @@
+2012-10-06  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/54760
+       * config/sh/sh.md (define_constants): Add UNSPECV_GBR.
+       (get_thread_pointer, set_thread_pointer): New expanders.
+       (load_gbr): Rename to store_gbr.  Remove GBR_REG use.
+       (store_gbr): New insn.
+       * config/sh/sh.c (prepare_move_operands): Use gen_store_gbr instead of
+       gen_load_gbr in TLS_MODEL_LOCAL_EXEC case.
+       (sh1_builtin_p): New function.
+       (signature_args): Add SH_BLTIN_VP.
+       (bdesc): Add __builtin_thread_pointer and __builtin_set_thread_pointer.
+
 2012-10-05  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        PR rtl-optimization/54739
index 35998793a89a801563f25c019dc3f8c87f93a0aa..3a0689d9486b1f1ae3443340cfbddcb0515a488a 100644 (file)
@@ -1887,7 +1887,7 @@ prepare_move_operands (rtx operands[], enum machine_mode mode)
 
            case TLS_MODEL_LOCAL_EXEC:
              tmp2 = gen_reg_rtx (Pmode);
-             emit_insn (gen_load_gbr (tmp2));
+             emit_insn (gen_store_gbr (tmp2));
              tmp = gen_reg_rtx (Pmode);
              emit_insn (gen_symTPOFF2reg (tmp, op1));
 
@@ -11521,6 +11521,12 @@ shmedia_builtin_p (void)
   return TARGET_SHMEDIA;
 }
 
+static bool
+sh1_builtin_p (void)
+{
+  return TARGET_SH1;
+}
+
 /* describe number and signedness of arguments; arg[0] == result
    (1: unsigned, 2: signed, 4: don't care, 8: pointer 0: no argument */
 /* 9: 64-bit pointer, 10: 32-bit pointer */
@@ -11578,6 +11584,8 @@ static const char signature_args[][4] =
   { 1, 1, 1, 1 },
 #define SH_BLTIN_PV 23
   { 0, 8 },
+#define SH_BLTIN_VP 24
+  { 8, 0 },
 };
 /* mcmv: operands considered unsigned.  */
 /* mmulsum_wq, msad_ubq: result considered unsigned long long.  */
@@ -11753,6 +11761,12 @@ static struct builtin_description bdesc[] =
     CODE_FOR_byterev,  "__builtin_sh_media_BYTEREV", SH_BLTIN_2, 0 },
   { shmedia_builtin_p,
     CODE_FOR_prefetch, "__builtin_sh_media_PREFO", SH_BLTIN_PSSV, 0 },
+
+  { sh1_builtin_p,
+    CODE_FOR_get_thread_pointer, "__builtin_thread_pointer", SH_BLTIN_VP, 0 },
+  { sh1_builtin_p,
+    CODE_FOR_set_thread_pointer, "__builtin_set_thread_pointer",
+    SH_BLTIN_PV, 0 },
 };
 
 static void
index 7a1c4d33a58017365cad9f7530ba60bde38a74b4..eeed561906390d7f809e74519ab3e200cb4d8aa7 100644 (file)
   (UNSPECV_WINDOW_END  10)
   (UNSPECV_CONST_END   11)
   (UNSPECV_EH_RETURN   12)
+  (UNSPECV_GBR         13)
 ])
 
 ;; -------------------------------------------------------------------------
@@ -10029,13 +10030,37 @@ label:
   DONE;
 })
 
-(define_insn "load_gbr"
-  [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
-   (use (reg:SI GBR_REG))]
+;;------------------------------------------------------------------------------
+;; Thread pointer getter and setter.
+;;
+;; On SH the thread pointer is kept in the GBR.
+;; These patterns are usually expanded from the respective built-in functions.
+(define_expand "get_thread_pointer"
+  [(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
+  "TARGET_SH1")
+
+;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
+(define_insn "store_gbr"
+  [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))]
   ""
   "stc gbr,%0"
   [(set_attr "type" "tls_load")])
 
+(define_expand "set_thread_pointer"
+  [(set (reg:SI GBR_REG)
+       (unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
+        UNSPECV_GBR))]
+  "TARGET_SH1")
+
+(define_insn "load_gbr"
+  [(set (reg:SI GBR_REG)
+       (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
+        UNSPECV_GBR))]
+  "TARGET_SH1"
+  "ldc %0,gbr"
+  [(set_attr "type" "move")])
+
+;;------------------------------------------------------------------------------
 ;; case instruction for switch statements.
 
 ;; Operand 0 is index
index 28a4f57a6b5d8d15e05290c7889da70106030b1a..67f7387bbf29bdbaf4fb3bb7302f8e5dd44ee315 100644 (file)
@@ -1,3 +1,8 @@
+2012-10-06  Oleg Endo  <olegendo@gcc.gnu.org>
+
+       PR target/54760
+       * gcc.target/sh/pr54760-1.c: New.
+
 2012-10-05  Jakub Jelinek  <jakub@redhat.com>
 
        * g++.dg/torture/Wsizeof-pointer-memaccess1.C: New test.
diff --git a/gcc/testsuite/gcc.target/sh/pr54760-1.c b/gcc/testsuite/gcc.target/sh/pr54760-1.c
new file mode 100644 (file)
index 0000000..9108a3f
--- /dev/null
@@ -0,0 +1,20 @@
+/* Check that the __builtin_thread_pointer and __builtin_set_thread_pointer
+   built-in functions result in gbr store / load instructions.  */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } }  */
+/* { dg-final { scan-assembler-times "ldc" 1 } } */
+/* { dg-final { scan-assembler-times "stc" 1 } } */
+/* { dg-final { scan-assembler-times "gbr" 2 } } */
+
+void*
+test00 (void)
+{
+  return __builtin_thread_pointer ();
+}
+
+void
+test01 (void* p)
+{
+  __builtin_set_thread_pointer (p);
+}