diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 62 | ||||
-rw-r--r-- | gcc/builtins.c | 46 | ||||
-rw-r--r-- | gcc/builtins.def | 11 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.c | 18 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.md | 4 | ||||
-rw-r--r-- | gcc/config/arm/arm-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 23 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 9 | ||||
-rw-r--r-- | gcc/config/mips/mips-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 13 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 10 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 131 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 25 | ||||
-rw-r--r-- | gcc/config/xtensa/xtensa.c | 38 | ||||
-rw-r--r-- | gcc/config/xtensa/xtensa.md | 4 | ||||
-rw-r--r-- | gcc/doc/md.texi | 12 | ||||
-rw-r--r-- | gcc/optabs.def | 3 |
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") |