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
This commit is contained in:
Chung-Lin Tang 2012-10-11 15:05:44 +00:00 committed by Chung-Lin Tang
parent 0fdce8752b
commit f959607b40
17 changed files with 180 additions and 232 deletions

View File

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

View File

@ -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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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"

View File

@ -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);

View File

@ -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)
@ -20195,20 +20193,6 @@ arm_init_iwmmxt_builtins (void)
#undef iwmmx2_mbuiltin
}
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)
{
@ -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;
}

View File

@ -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")

View File

@ -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);

View File

@ -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). */

View File

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

View File

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

View File

@ -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_thread_pointer<mode>"
[(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
""
"")
(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 "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"

View File

@ -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");
}

View File

@ -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"

View File

@ -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}

View File

@ -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")