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:
parent
0fdce8752b
commit
f959607b40
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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). */
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user