aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorChung-Lin Tang <cltang@codesourcery.com>2012-10-11 15:05:44 +0000
committerChung-Lin Tang <cltang@gcc.gnu.org>2012-10-11 15:05:44 +0000
commitf959607b40d11dc4a0636797feeee9adac9f8a02 (patch)
tree21a7244b43175e5f9f9368c389ea7a5e40186615 /gcc
parent0fdce8752b88cdc8b05cf09d90fec25468b12e6f (diff)
downloadgcc-f959607b40d11dc4a0636797feeee9adac9f8a02.zip
gcc-f959607b40d11dc4a0636797feeee9adac9f8a02.tar.gz
gcc-f959607b40d11dc4a0636797feeee9adac9f8a02.tar.bz2
builtins.c (expand_builtin_thread_pointer): New.
2012-10-11 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. * config/alpha/alpha.md (get_thread_pointerdi): Rename from load_tp. (set_thread_pointerdi): Rename from set_tp. * config/alpha/alpha.c (alpha_legitimize_address_1): Change gen_load_tp calls to gen_get_thread_pointerdi. (alpha_builtin): Remove ALPHA_BUILTIN_THREAD_POINTER, ALPHA_BUILTIN_SET_THREAD_POINTER. (code_for_builtin): Remove CODE_FOR_load_tp, CODE_FOR_set_tp. (alpha_init_builtins): Remove __builtin_thread_pointer, __builtin_set_thread_pointer machine-specific builtins. (alpha_expand_builtin_thread_pointer): Add hook function for TARGET_EXPAND_BUILTIN_THREAD_POINTER. (alpha_expand_builtin_set_thread_pointer): Add hook function for TARGET_EXPAND_BUILTIN_SET_THREAD_POINTER. (alpha_fold_builtin): Remove ALPHA_BUILTIN_THREAD_POINTER, ALPHA_BUILTIN_SET_THREAD_POINTER cases. * config/arm/arm.md (get_thread_pointersi): New pattern. * config/arm/arm-protos.h (arm_load_tp): Add extern declaration. * config/arm/arm.c (arm_load_tp): Remove static. (arm_builtins): Remove ARM_BUILTIN_THREAD_POINTER. (arm_init_tls_builtins): Remove function. (arm_init_builtins): Remove call to arm_init_tls_builtins(). (arm_expand_builtin): Remove ARM_BUILTIN_THREAD_POINTER case. * config/mips/mips.md (get_thread_pointer<mode>): New pattern. * config/mips/mips-protos.h (mips_expand_thread_pointer): Add extern declaration. * config/mips/mips.c (mips_expand_thread_pointer): Renamed from mips_get_tp. (mips_get_tp): New stub calling mips_expand_thread_pointer. * config/s390/s390.c (s390_builtin,code_for_builtin_64, code_for_builtin_31,s390_init_builtins,s390_expand_builtin): Remove. * config/s390/s390.md (get_tp_64,get_tp_31,set_tp_64,set_tp_31): Remove. (get_thread_pointer<mode>,set_thread_pointer<mode>): New, adapted from removed patterns. * config/xtensa/xtensa.md (get_thread_pointersi): Renamed from load_tp. (set_thread_pointersi): Renamed from set_tp. * config/xtensa/xtensa.c (xtensa_legitimize_tls_address): Change gen_load_tp calls to gen_get_thread_pointersi. (xtensa_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER and XTENSA_BUILTIN_SET_THREAD_POINTER. (xtensa_init_builtins): Remove __builtin_thread_pointer, __builtin_set_thread_pointer machine-specific builtins. (xtensa_fold_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER, XTENSA_BUILTIN_SET_THREAD_POINTER cases. (xtensa_expand_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER, XTENSA_BUILTIN_SET_THREAD_POINTER cases. From-SVN: r192364
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog62
-rw-r--r--gcc/builtins.c46
-rw-r--r--gcc/builtins.def11
-rw-r--r--gcc/config/alpha/alpha.c18
-rw-r--r--gcc/config/alpha/alpha.md4
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c23
-rw-r--r--gcc/config/arm/arm.md9
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c13
-rw-r--r--gcc/config/mips/mips.md10
-rw-r--r--gcc/config/s390/s390.c131
-rw-r--r--gcc/config/s390/s390.md25
-rw-r--r--gcc/config/xtensa/xtensa.c38
-rw-r--r--gcc/config/xtensa/xtensa.md4
-rw-r--r--gcc/doc/md.texi12
-rw-r--r--gcc/optabs.def3
17 files changed, 180 insertions, 232 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3ed1e8a..1919873 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,65 @@
+2012-10-11 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.
+ * config/alpha/alpha.md (get_thread_pointerdi): Rename from load_tp.
+ (set_thread_pointerdi): Rename from set_tp.
+ * config/alpha/alpha.c (alpha_legitimize_address_1): Change
+ gen_load_tp calls to gen_get_thread_pointerdi.
+ (alpha_builtin): Remove ALPHA_BUILTIN_THREAD_POINTER,
+ ALPHA_BUILTIN_SET_THREAD_POINTER.
+ (code_for_builtin): Remove CODE_FOR_load_tp, CODE_FOR_set_tp.
+ (alpha_init_builtins): Remove __builtin_thread_pointer,
+ __builtin_set_thread_pointer machine-specific builtins.
+ (alpha_expand_builtin_thread_pointer): Add hook function for
+ TARGET_EXPAND_BUILTIN_THREAD_POINTER.
+ (alpha_expand_builtin_set_thread_pointer): Add hook function for
+ TARGET_EXPAND_BUILTIN_SET_THREAD_POINTER.
+ (alpha_fold_builtin): Remove ALPHA_BUILTIN_THREAD_POINTER,
+ ALPHA_BUILTIN_SET_THREAD_POINTER cases.
+ * config/arm/arm.md (get_thread_pointersi): New pattern.
+ * config/arm/arm-protos.h (arm_load_tp): Add extern declaration.
+ * config/arm/arm.c (arm_load_tp): Remove static.
+ (arm_builtins): Remove ARM_BUILTIN_THREAD_POINTER.
+ (arm_init_tls_builtins): Remove function.
+ (arm_init_builtins): Remove call to arm_init_tls_builtins().
+ (arm_expand_builtin): Remove ARM_BUILTIN_THREAD_POINTER case.
+ * config/mips/mips.md (get_thread_pointer<mode>): New pattern.
+ * config/mips/mips-protos.h (mips_expand_thread_pointer):
+ Add extern declaration.
+ * config/mips/mips.c (mips_expand_thread_pointer):
+ Renamed from mips_get_tp.
+ (mips_get_tp): New stub calling mips_expand_thread_pointer.
+ * config/s390/s390.c (s390_builtin,code_for_builtin_64,
+ code_for_builtin_31,s390_init_builtins,s390_expand_builtin): Remove.
+ * config/s390/s390.md (get_tp_64,get_tp_31,set_tp_64,set_tp_31):
+ Remove.
+ (get_thread_pointer<mode>,set_thread_pointer<mode>):
+ New, adapted from removed patterns.
+ * config/xtensa/xtensa.md (get_thread_pointersi):
+ Renamed from load_tp.
+ (set_thread_pointersi): Renamed from set_tp.
+ * config/xtensa/xtensa.c (xtensa_legitimize_tls_address):
+ Change gen_load_tp calls to gen_get_thread_pointersi.
+ (xtensa_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER and
+ XTENSA_BUILTIN_SET_THREAD_POINTER.
+ (xtensa_init_builtins): Remove __builtin_thread_pointer,
+ __builtin_set_thread_pointer machine-specific builtins.
+ (xtensa_fold_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER,
+ XTENSA_BUILTIN_SET_THREAD_POINTER cases.
+ (xtensa_expand_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER,
+ XTENSA_BUILTIN_SET_THREAD_POINTER cases.
+
2012-10-11 Marc Glisse <marc.glisse@inria.fr>
* doc/extend.texi (Vector Extensions): C++ improvements.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index e6b10ea..fb8d83a 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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 = direct_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 = direct_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 subtarget, enum machine_mode mode,
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;
}
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 69000bc..177bf496 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -782,6 +782,17 @@ DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_profile_func_enter", BUILT_IN_N
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,
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index d726b5a..82135ff 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -963,7 +963,7 @@ alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
scratch = gen_reg_rtx (Pmode);
dest = gen_reg_rtx (Pmode);
- emit_insn (gen_load_tp (tp));
+ emit_insn (gen_get_thread_pointerdi (tp));
emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
emit_insn (gen_adddi3 (dest, tp, scratch));
return dest;
@@ -973,7 +973,7 @@ alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
eqv = gen_rtx_CONST (Pmode, eqv);
tp = gen_reg_rtx (Pmode);
- emit_insn (gen_load_tp (tp));
+ emit_insn (gen_get_thread_pointerdi (tp));
if (alpha_tls_size == 32)
{
insn = gen_rtx_HIGH (Pmode, eqv);
@@ -6328,8 +6328,6 @@ enum alpha_builtin
ALPHA_BUILTIN_AMASK,
ALPHA_BUILTIN_IMPLVER,
ALPHA_BUILTIN_RPCC,
- ALPHA_BUILTIN_THREAD_POINTER,
- ALPHA_BUILTIN_SET_THREAD_POINTER,
ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER,
@@ -6385,8 +6383,6 @@ static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = {
CODE_FOR_builtin_amask,
CODE_FOR_builtin_implver,
CODE_FOR_builtin_rpcc,
- CODE_FOR_load_tp,
- CODE_FOR_set_tp,
CODE_FOR_builtin_establish_vms_condition_handler,
CODE_FOR_builtin_revert_vms_condition_handler,
@@ -6544,14 +6540,6 @@ alpha_init_builtins (void)
alpha_dimode_u, NULL_TREE);
alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins), ftype);
- ftype = build_function_type_list (ptr_type_node, NULL_TREE);
- alpha_builtin_function ("__builtin_thread_pointer", ftype,
- ALPHA_BUILTIN_THREAD_POINTER, ECF_NOTHROW);
-
- ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
- alpha_builtin_function ("__builtin_set_thread_pointer", ftype,
- ALPHA_BUILTIN_SET_THREAD_POINTER, ECF_NOTHROW);
-
if (TARGET_ABI_OPEN_VMS)
{
ftype = build_function_type_list (ptr_type_node, ptr_type_node,
@@ -7088,8 +7076,6 @@ alpha_fold_builtin (tree fndecl, int n_args, tree *op,
case ALPHA_BUILTIN_AMASK:
case ALPHA_BUILTIN_IMPLVER:
case ALPHA_BUILTIN_RPCC:
- case ALPHA_BUILTIN_THREAD_POINTER:
- case ALPHA_BUILTIN_SET_THREAD_POINTER:
/* None of these are foldable at compile-time. */
default:
return NULL;
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 21c4d2e..cad810c 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -4365,7 +4365,7 @@
;; For userland, we load the thread pointer from the TCB.
;; For the kernel, we load the per-cpu private value.
-(define_insn "load_tp"
+(define_insn "get_thread_pointerdi"
[(set (match_operand:DI 0 "register_operand" "=v")
(unspec:DI [(const_int 0)] UNSPEC_TP))]
"TARGET_ABI_OSF"
@@ -4382,7 +4382,7 @@
;; quantity for CSE, we have to use a volatile unspec, and then there's
;; not much point in creating an R16_REG register class.
-(define_expand "set_tp"
+(define_expand "set_thread_pointerdi"
[(set (reg:DI 16) (match_operand:DI 0 "input_operand" ""))
(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
"TARGET_ABI_OSF"
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index c590ef4..010e7fc 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -163,6 +163,7 @@ extern int arm_attr_length_push_multi(rtx, rtx);
extern void arm_expand_compare_and_swap (rtx op[]);
extern void arm_split_compare_and_swap (rtx op[]);
extern void arm_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx);
+extern rtx arm_load_tp (rtx);
#if defined TREE_CODE
extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6ba0276..866385c 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6279,7 +6279,7 @@ get_tls_get_addr (void)
return tls_get_addr_libfunc;
}
-static rtx
+rtx
arm_load_tp (rtx target)
{
if (!target)
@@ -19155,8 +19155,6 @@ enum arm_builtins
ARM_BUILTIN_WMERGE,
- ARM_BUILTIN_THREAD_POINTER,
-
ARM_BUILTIN_NEON_BASE,
ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE + ARRAY_SIZE (neon_builtin_data)
@@ -20196,20 +20194,6 @@ arm_init_iwmmxt_builtins (void)
}
static void
-arm_init_tls_builtins (void)
-{
- tree ftype, decl;
-
- ftype = build_function_type (ptr_type_node, void_list_node);
- decl = add_builtin_function ("__builtin_thread_pointer", ftype,
- ARM_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
- TREE_NOTHROW (decl) = 1;
- TREE_READONLY (decl) = 1;
- arm_builtin_decls[ARM_BUILTIN_THREAD_POINTER] = decl;
-}
-
-static void
arm_init_fp16_builtins (void)
{
tree fp16_type = make_node (REAL_TYPE);
@@ -20221,8 +20205,6 @@ arm_init_fp16_builtins (void)
static void
arm_init_builtins (void)
{
- arm_init_tls_builtins ();
-
if (TARGET_REALLY_IWMMXT)
arm_init_iwmmxt_builtins ();
@@ -21334,9 +21316,6 @@ arm_expand_builtin (tree exp,
}
return arm_expand_binop_builtin (icode, exp, target);
- case ARM_BUILTIN_THREAD_POINTER:
- return arm_load_tp (target);
-
default:
break;
}
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 43a9f1f..201cbda 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -11501,6 +11501,15 @@
""
)
+(define_expand "get_thread_pointersi"
+ [(match_operand:SI 0 "s_register_operand" "=r")]
+ ""
+ "
+ {
+ arm_load_tp (operands[0]);
+ DONE;
+ }")
+
;; Load the load/store multiple patterns
(include "ldmstm.md")
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 708d6bb..f2c5c0d 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -351,6 +351,8 @@ extern void mips_expand_vec_reduc (rtx, rtx, rtx (*)(rtx, rtx, rtx));
extern void mips_expand_vec_minmax (rtx, rtx, rtx,
rtx (*) (rtx, rtx, rtx), bool);
+extern rtx mips_expand_thread_pointer (rtx);
+
extern bool mips_eh_uses (unsigned int);
extern bool mips_epilogue_uses (unsigned int);
extern void mips_final_prescan_insn (rtx, rtx *, int);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 4073a15..bbd0fc4 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2884,12 +2884,11 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
/* Return a pseudo register that contains the current thread pointer. */
-static rtx
-mips_get_tp (void)
+rtx
+mips_expand_thread_pointer (rtx tp)
{
- rtx tp, fn;
+ rtx fn;
- tp = gen_reg_rtx (Pmode);
if (TARGET_MIPS16)
{
mips_need_mips16_rdhwr_p = true;
@@ -2904,6 +2903,12 @@ mips_get_tp (void)
return tp;
}
+static rtx
+mips_get_tp (void)
+{
+ return mips_expand_thread_pointer (gen_reg_rtx (Pmode));
+}
+
/* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
its address. The return value will be both a valid address and a valid
SET_SRC (either a REG or a LO_SUM). */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 570e785..c7dd875 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -6880,6 +6880,16 @@
[(set_attr "type" "call")
(set_attr "length" "12")
(set_attr "mode" "<MODE>")])
+
+;; Named pattern for expanding thread pointer reference.
+(define_expand "get_thread_pointer<mode>"
+ [(match_operand:P 0 "register_operand" "=d")]
+ "HAVE_AS_TLS"
+{
+ mips_expand_thread_pointer (operands[0]);
+ DONE;
+})
+
;; Synchronization instructions.
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index a9a1af5..4ce1dc9 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9294,132 +9294,6 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
return build_va_arg_indirect_ref (addr);
}
-
-/* Builtins. */
-
-enum s390_builtin
-{
- S390_BUILTIN_THREAD_POINTER,
- S390_BUILTIN_SET_THREAD_POINTER,
-
- S390_BUILTIN_max
-};
-
-static enum insn_code const code_for_builtin_64[S390_BUILTIN_max] = {
- CODE_FOR_get_tp_64,
- CODE_FOR_set_tp_64
-};
-
-static enum insn_code const code_for_builtin_31[S390_BUILTIN_max] = {
- CODE_FOR_get_tp_31,
- CODE_FOR_set_tp_31
-};
-
-static void
-s390_init_builtins (void)
-{
- tree ftype;
-
- ftype = build_function_type_list (ptr_type_node, NULL_TREE);
- add_builtin_function ("__builtin_thread_pointer", ftype,
- S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
-
- ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
- add_builtin_function ("__builtin_set_thread_pointer", ftype,
- S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
-}
-
-/* Expand an expression EXP that calls a built-in function,
- with result going to TARGET if that's convenient
- (and in mode MODE if that's convenient).
- SUBTARGET may be used as the target for computing one of EXP's operands.
- IGNORE is nonzero if the value is to be ignored. */
-
-static rtx
-s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- int ignore ATTRIBUTE_UNUSED)
-{
-#define MAX_ARGS 2
-
- enum insn_code const *code_for_builtin =
- TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
-
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
- enum insn_code icode;
- rtx op[MAX_ARGS], pat;
- int arity;
- bool nonvoid;
- tree arg;
- call_expr_arg_iterator iter;
-
- if (fcode >= S390_BUILTIN_max)
- internal_error ("bad builtin fcode");
- icode = code_for_builtin[fcode];
- if (icode == 0)
- internal_error ("bad builtin fcode");
-
- nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
-
- arity = 0;
- FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
- {
- const struct insn_operand_data *insn_op;
-
- if (arg == error_mark_node)
- return NULL_RTX;
- if (arity > MAX_ARGS)
- return NULL_RTX;
-
- insn_op = &insn_data[icode].operand[arity + nonvoid];
-
- op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
-
- if (!(*insn_op->predicate) (op[arity], insn_op->mode))
- op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
- arity++;
- }
-
- if (nonvoid)
- {
- enum machine_mode tmode = insn_data[icode].operand[0].mode;
- if (!target
- || GET_MODE (target) != tmode
- || !(*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
- }
-
- switch (arity)
- {
- case 0:
- pat = GEN_FCN (icode) (target);
- break;
- case 1:
- if (nonvoid)
- pat = GEN_FCN (icode) (target, op[0]);
- else
- pat = GEN_FCN (icode) (op[0]);
- break;
- case 2:
- pat = GEN_FCN (icode) (target, op[0], op[1]);
- break;
- default:
- gcc_unreachable ();
- }
- if (!pat)
- return NULL_RTX;
- emit_insn (pat);
-
- if (nonvoid)
- return target;
- else
- return const0_rtx;
-}
-
-
/* Output assembly code for the trampoline template to
stdio stream FILE.
@@ -11075,11 +10949,6 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS s390_init_builtins
-#undef TARGET_EXPAND_BUILTIN
-#define TARGET_EXPAND_BUILTIN s390_expand_builtin
-
#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA s390_output_addr_const_extra
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 439d78c..efe1a47 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -8710,26 +8710,15 @@
;;- Thread-local storage support.
;;
-(define_expand "get_tp_64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "") (reg:DI TP_REGNUM))]
- "TARGET_64BIT"
- "")
-
-(define_expand "get_tp_31"
- [(set (match_operand:SI 0 "nonimmediate_operand" "") (reg:SI TP_REGNUM))]
- "!TARGET_64BIT"
- "")
-
-(define_expand "set_tp_64"
- [(set (reg:DI TP_REGNUM) (match_operand:DI 0 "nonimmediate_operand" ""))
- (set (reg:DI TP_REGNUM) (unspec_volatile:DI [(reg:DI TP_REGNUM)] UNSPECV_SET_TP))]
- "TARGET_64BIT"
+(define_expand "get_thread_pointer<mode>"
+ [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
+ ""
"")
-(define_expand "set_tp_31"
- [(set (reg:SI TP_REGNUM) (match_operand:SI 0 "nonimmediate_operand" ""))
- (set (reg:SI TP_REGNUM) (unspec_volatile:SI [(reg:SI TP_REGNUM)] UNSPECV_SET_TP))]
- "!TARGET_64BIT"
+(define_expand "set_thread_pointer<mode>"
+ [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
+ (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
+ ""
"")
(define_insn "*set_tp"
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 83eab4b..451a074 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -1899,7 +1899,7 @@ xtensa_legitimize_tls_address (rtx x)
case TLS_MODEL_INITIAL_EXEC:
case TLS_MODEL_LOCAL_EXEC:
tp = gen_reg_rtx (SImode);
- emit_insn (gen_load_tp (tp));
+ emit_insn (gen_get_thread_pointersi (tp));
addend = force_reg (SImode, gen_sym_TPOFF (x));
emit_insn (gen_addsi3 (dest, tp, addend));
break;
@@ -3076,8 +3076,6 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
enum xtensa_builtin
{
XTENSA_BUILTIN_UMULSIDI3,
- XTENSA_BUILTIN_THREAD_POINTER,
- XTENSA_BUILTIN_SET_THREAD_POINTER,
XTENSA_BUILTIN_max
};
@@ -3096,23 +3094,6 @@ xtensa_init_builtins (void)
"__umulsidi3", NULL_TREE);
TREE_NOTHROW (decl) = 1;
TREE_READONLY (decl) = 1;
-
- if (TARGET_THREADPTR)
- {
- ftype = build_function_type_list (ptr_type_node, NULL_TREE);
- decl = add_builtin_function ("__builtin_thread_pointer", ftype,
- XTENSA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
- TREE_READONLY (decl) = 1;
- TREE_NOTHROW (decl) = 1;
-
- ftype = build_function_type_list (void_type_node, ptr_type_node,
- NULL_TREE);
- decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
- XTENSA_BUILTIN_SET_THREAD_POINTER,
- BUILT_IN_MD, NULL, NULL_TREE);
- TREE_NOTHROW (decl) = 1;
- }
}
@@ -3135,10 +3116,6 @@ xtensa_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
fold_convert (unsigned_intDI_type_node, arg1));
break;
- case XTENSA_BUILTIN_THREAD_POINTER:
- case XTENSA_BUILTIN_SET_THREAD_POINTER:
- break;
-
default:
internal_error ("bad builtin code");
break;
@@ -3166,19 +3143,6 @@ xtensa_expand_builtin (tree exp, rtx target,
implement it. If not, just call the function. */
return expand_call (exp, target, ignore);
- case XTENSA_BUILTIN_THREAD_POINTER:
- if (!target || !register_operand (target, Pmode))
- target = gen_reg_rtx (Pmode);
- emit_insn (gen_load_tp (target));
- return target;
-
- case XTENSA_BUILTIN_SET_THREAD_POINTER:
- arg = expand_normal (CALL_EXPR_ARG (exp, 0));
- if (!register_operand (arg, Pmode))
- arg = copy_to_mode_reg (Pmode, arg);
- emit_insn (gen_set_tp (arg));
- return const0_rtx;
-
default:
internal_error ("bad builtin code");
}
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index d6eb548..b87f089 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1714,7 +1714,7 @@
""
"")
-(define_insn "load_tp"
+(define_insn "get_thread_pointersi"
[(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI [(const_int 0)] UNSPEC_TP))]
"TARGET_THREADPTR"
@@ -1723,7 +1723,7 @@
(set_attr "mode" "SI")
(set_attr "length" "3")])
-(define_insn "set_tp"
+(define_insn "set_thread_pointersi"
[(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
UNSPECV_SET_TP)]
"TARGET_THREADPTR"
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 9f2012f..f17d55e 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -6133,6 +6133,18 @@ If this pattern is not specified, all memory models except
@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}
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 9f6b29c..b483b02 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -306,3 +306,6 @@ OPTAB_D (atomic_sub_fetch_optab, "atomic_sub_fetch$I$a")
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")