[PATCH 1/6] Thread pointer built-in functions, core parts

Chung-Lin Tang cltang@codesourcery.com
Tue Aug 28 08:13:00 GMT 2012


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  <cltang@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.

-------------- next part --------------
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}
 


More information about the Gcc-patches mailing list