On 12/7/12 2:52 PM, Chung-Lin Tang wrote: > Core parts adding the new hooks. BUILT_IN_THREAD_POINTER and > BUILT_IN_SET_THREAD_POINTER are different hooks, as some targets only > implement one of them (thread pointer read).
Following Richard H.'s advice, I have revised the patch to use a standard name, as the resulting code really does look cleaner. Thanks, Chung-Lin 2012-08-28 Chung-Lin Tang <clt...@codesourcery.com> * builtins.c (expand_builtin_thread_pointer): New. (expand_builtin_set_thread_pointer): New. (expand_builtin): Add BUILT_IN_THREAD_POINTER, BUILT_IN_SET_THREAD_POINTER expand cases. * builtins.def (BUILT_IN_THREAD_POINTER): New __builtin_thread_pointer builtin. (BUILT_IN_SET_THREAD_POINTER): New __builtin_set_thread_pointer builtin. * optabs.def (get_thread_pointer,set_thread_pointer): New standard names. * doc/md.texi (Standard Names): Document get_thread_pointer and set_thread_pointer patterns.
Index: builtins.c =================================================================== --- builtins.c (revision 190742) +++ builtins.c (working copy) @@ -5744,6 +5744,45 @@ expand_builtin_sync_synchronize (void) expand_mem_thread_fence (MEMMODEL_SEQ_CST); } +static rtx +expand_builtin_thread_pointer (tree exp, rtx target) +{ + enum insn_code icode; + if (!validate_arglist (exp, VOID_TYPE)) + return const0_rtx; + icode = optab_handler (get_thread_pointer_optab, Pmode); + if (icode != CODE_FOR_nothing) + { + struct expand_operand op; + if (!REG_P (target) || GET_MODE (target) != Pmode) + target = gen_reg_rtx (Pmode); + create_output_operand (&op, target, Pmode); + expand_insn (icode, 1, &op); + return target; + } + error ("__builtin_thread_pointer is not supported on this target"); + return const0_rtx; +} + +static void +expand_builtin_set_thread_pointer (tree exp) +{ + enum insn_code icode; + if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE)) + return; + icode = optab_handler (set_thread_pointer_optab, Pmode); + if (icode != CODE_FOR_nothing) + { + struct expand_operand op; + rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, + Pmode, EXPAND_NORMAL); + create_fixed_operand (&op, val); + expand_insn (icode, 1, &op); + return; + } + error ("__builtin_set_thread_pointer is not supported on this target"); +} + /* Expand an expression EXP that calls a built-in function, with result going to TARGET if that's convenient @@ -6809,6 +6848,13 @@ expand_builtin (tree exp, rtx target, rtx subtarge maybe_emit_free_warning (exp); break; + case BUILT_IN_THREAD_POINTER: + return expand_builtin_thread_pointer (exp, target); + + case BUILT_IN_SET_THREAD_POINTER: + expand_builtin_set_thread_pointer (exp); + return const0_rtx; + default: /* just do library call, if unknown builtin */ break; } Index: builtins.def =================================================================== --- builtins.def (revision 190742) +++ builtins.def (working copy) @@ -782,6 +782,17 @@ DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_p DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_EXIT, "__cyg_profile_func_exit", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST, false, false, false, ATTR_NULL, true, true) +/* TLS thread pointer related builtins. */ +DEF_BUILTIN (BUILT_IN_THREAD_POINTER, "__builtin_thread_pointer", + BUILT_IN_NORMAL, BT_FN_PTR, BT_LAST, + false, false, true, ATTR_CONST_NOTHROW_LIST, true, + targetm.have_tls) + +DEF_BUILTIN (BUILT_IN_SET_THREAD_POINTER, "__builtin_set_thread_pointer", + BUILT_IN_NORMAL, BT_FN_VOID_PTR, BT_LAST, + false, false, true, ATTR_NOTHROW_LIST, true, + targetm.have_tls) + /* TLS emulation. */ DEF_BUILTIN (BUILT_IN_EMUTLS_GET_ADDRESS, targetm.emutls.get_address, BUILT_IN_NORMAL, Index: doc/md.texi =================================================================== --- doc/md.texi (revision 190742) +++ doc/md.texi (working copy) @@ -6133,6 +6133,18 @@ If this pattern is not specified, all memory model @code{__ATOMIC_RELAXED} will result in issuing a @code{sync_synchronize} barrier pattern. +@cindex @code{get_thread_pointer@var{mode}} instruction pattern +@cindex @code{set_thread_pointer@var{mode}} instruction pattern +@item @samp{get_thread_pointer@var{mode}} +@itemx @samp{set_thread_pointer@var{mode}} +These patterns emit code that reads/sets the TLS thread pointer. Currently, +these are only needed if the target needs to support the +@code{__builtin_thread_pointer} and @code{__builtin_set_thread_pointer} +builtins. + +The get/set patterns have a single output/input operand respectively, +with @var{mode} intended to be @code{Pmode}. + @cindex @code{stack_protect_set} instruction pattern @item @samp{stack_protect_set} Index: optabs.def =================================================================== --- optabs.def (revision 190742) +++ optabs.def (working copy) @@ -306,3 +306,6 @@ OPTAB_D (atomic_sub_fetch_optab, "atomic_sub_fetch OPTAB_D (atomic_sub_optab, "atomic_sub$I$a") OPTAB_D (atomic_xor_fetch_optab, "atomic_xor_fetch$I$a") OPTAB_D (atomic_xor_optab, "atomic_xor$I$a") + +OPTAB_D (get_thread_pointer_optab, "get_thread_pointer$I$a") +OPTAB_D (set_thread_pointer_optab, "set_thread_pointer$I$a") Index: doc/md.texi =================================================================== --- doc/md.texi (revision 190742) +++ doc/md.texi (working copy) @@ -6133,6 +6133,18 @@ If this pattern is not specified, all memory model @code{__ATOMIC_RELAXED} will result in issuing a @code{sync_synchronize} barrier pattern. +@cindex @code{get_thread_pointer@var{mode}} instruction pattern +@cindex @code{set_thread_pointer@var{mode}} instruction pattern +@item @samp{get_thread_pointer@var{mode}} +@itemx @samp{set_thread_pointer@var{mode}} +These patterns emit code that reads/sets the TLS thread pointer. Currently, +these are only needed if the target needs to support the +@code{__builtin_thread_pointer} and @code{__builtin_set_thread_pointer} +builtins. + +The get/set patterns have a single output/input operand respectively, +with @var{mode} intended to be @code{Pmode}. + @cindex @code{stack_protect_set} instruction pattern @item @samp{stack_protect_set}