On Fri, 2012-10-05 at 21:55 +0900, Kaz Kojima wrote: > Oleg Endo <oleg.e...@t-online.de> wrote: > > Do you mean something like the attached patch as a preparation step? > > (checked with 'make all') > > Yes. The patch is OK with removing the first line of the ChangeLog > entry for PR number.
Done. The attached patch is the next step that adds the thread pointer builtins. The GBR address mode stuff will follow afterwards separately. Tested on rev 192142 with 'make all' and 'make -k check-gcc RUNTESTFLAGS="sh.exp --target_board=sh-sim \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}"' Cheers, Oleg gcc/ChangeLog: 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. testsuite/ChangeLog: PR target/54760 * gcc.target/sh/pr54760-1.c: New.
Index: gcc/testsuite/gcc.target/sh/pr54760-1.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr54760-1.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr54760-1.c (revision 0) @@ -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); +} Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 192142) +++ gcc/config/sh/sh.md (working copy) @@ -175,6 +175,7 @@ (UNSPECV_WINDOW_END 10) (UNSPECV_CONST_END 11) (UNSPECV_EH_RETURN 12) + (UNSPECV_GBR 13) ]) ;; ------------------------------------------------------------------------- @@ -10029,13 +10030,37 @@ 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: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 192142) +++ gcc/config/sh/sh.c (working copy) @@ -1887,7 +1887,7 @@ 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 @@ 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 @@ { 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 @@ 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