From c4501e6230543baaf5ad4ff87c0e24498bcb351b Mon Sep 17 00:00:00 2001 From: Janis Johnson Date: Mon, 12 May 2003 22:30:31 +0000 Subject: [PATCH] configure.in (HAVE_AS_TLS): Add powerpc and powerpc64 tests. 2003-05-12 Janis Johnson Alan Modra Jakub Jelinek * configure.in (HAVE_AS_TLS): Add powerpc and powerpc64 tests. * configure: Rebuild. * config/rs6000/rs6000-protos.h: Update. * config/rs6000/rs6000.c (rs6000_tls_size): New. (rs6000_tls_size_string): New. (rs6000_parse_tls_size_option): New. (rs6000_legitimize_tls_address): New. (rs6000_tls_get_addr): New. (rs6000_got_sym): New. (rs6000_tls_symbol_ref): New. (rs6000_tls_symbol_ref_1): New. (rs6000_get_some_local_dynamic_name): New. (rs6000_get_some_local_dynamic_name_1): New. (TARGET_HAVE_TLS): New. (TARGET_CANNOT_FORCE_CONST_MEM): New. (rs6000_override_options): Handle -mtls-size option. (constant_pool_expr_1): Handle TLS symbols. (rs6000_legitimize_address): Handle TLS symbols. (rs6000_tls_referenced_p): New. (rs6000_legitimate_address): Handle TLS symbols. (rs6000_emit_move): Handle TLS symbols. (print_operand): Handle TLS symbols. (uses_TOC): Handle TLS symbols. (rs6000_emit_prologue): Use symbol for unspec constant. * config/rs6000/rs6000.h (HAVE_AS_TLS): New. (some_ld_name): New. (LEGITIMATE_CONSTANT_P): Handle TLS symbols. (PRINT_OPERAND_PUNCT_VALID_P): Handle TLS symbols. (PREDICATE_CODES): Add rs6000_tls_symbol_ref. * config/rs6000/rs6000.md (load_toc_v4_PIC_1, load_toc_v4_PIC_1b): Support TLS. (tls_gd_32, tls_gd_64, tls_ld_32, tls_ld_64, tls_dtprel_32, tls_dtprel_64, tls_dtprel_ha_32, tls_dtprel_ha_64, tls_dtprel_lo_32, tls_dtprel_lo_64, tls_got_dtprel_32, tls_got_dtprel_64, tls_tprel_32, tls_tprel_64, tls_tprel_ha_32, tls_tprel_ha_64, tls_tprel_lo_32, tls_tprel_lo_64, tls_got_tprel_32, tls_got_tprel_64, tls_tls_32, tls_tls_64): New. * config/rs6000/sysv4.h (SUBTARGET_OPTIONS): Add tls_size. Co-Authored-By: Alan Modra Co-Authored-By: Jakub Jelinek From-SVN: r66742 --- gcc/ChangeLog | 43 ++++ gcc/config/rs6000/rs6000-protos.h | 2 + gcc/config/rs6000/rs6000.c | 413 ++++++++++++++++++++++++++++-- gcc/config/rs6000/rs6000.h | 17 +- gcc/config/rs6000/rs6000.md | 188 +++++++++++++- gcc/config/rs6000/sysv4.h | 5 +- gcc/configure | 92 +++++-- gcc/configure.in | 58 +++++ 8 files changed, 766 insertions(+), 52 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c49927c7fd1d..68ed27979ccf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,46 @@ +2003-05-12 Janis Johnson + Alan Modra + Jakub Jelinek + + * configure.in (HAVE_AS_TLS): Add powerpc and powerpc64 tests. + * configure: Rebuild. + * config/rs6000/rs6000-protos.h: Update. + * config/rs6000/rs6000.c (rs6000_tls_size): New. + (rs6000_tls_size_string): New. + (rs6000_parse_tls_size_option): New. + (rs6000_legitimize_tls_address): New. + (rs6000_tls_get_addr): New. + (rs6000_got_sym): New. + (rs6000_tls_symbol_ref): New. + (rs6000_tls_symbol_ref_1): New. + (rs6000_get_some_local_dynamic_name): New. + (rs6000_get_some_local_dynamic_name_1): New. + (TARGET_HAVE_TLS): New. + (TARGET_CANNOT_FORCE_CONST_MEM): New. + (rs6000_override_options): Handle -mtls-size option. + (constant_pool_expr_1): Handle TLS symbols. + (rs6000_legitimize_address): Handle TLS symbols. + (rs6000_tls_referenced_p): New. + (rs6000_legitimate_address): Handle TLS symbols. + (rs6000_emit_move): Handle TLS symbols. + (print_operand): Handle TLS symbols. + (uses_TOC): Handle TLS symbols. + (rs6000_emit_prologue): Use symbol for unspec constant. + * config/rs6000/rs6000.h (HAVE_AS_TLS): New. + (some_ld_name): New. + (LEGITIMATE_CONSTANT_P): Handle TLS symbols. + (PRINT_OPERAND_PUNCT_VALID_P): Handle TLS symbols. + (PREDICATE_CODES): Add rs6000_tls_symbol_ref. + * config/rs6000/rs6000.md (load_toc_v4_PIC_1, load_toc_v4_PIC_1b): + Support TLS. + (tls_gd_32, tls_gd_64, tls_ld_32, tls_ld_64, tls_dtprel_32, + tls_dtprel_64, tls_dtprel_ha_32, tls_dtprel_ha_64, tls_dtprel_lo_32, + tls_dtprel_lo_64, tls_got_dtprel_32, tls_got_dtprel_64, tls_tprel_32, + tls_tprel_64, tls_tprel_ha_32, tls_tprel_ha_64, tls_tprel_lo_32, + tls_tprel_lo_64, tls_got_tprel_32, tls_got_tprel_64, tls_tls_32, + tls_tls_64): New. + * config/rs6000/sysv4.h (SUBTARGET_OPTIONS): Add tls_size. + 2003-05-12 Neil Booth * Makefile.in (stage2_build, stage3_build, stage4_build): diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index b3406bb3b361..8ee39e21bc33 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -195,6 +195,8 @@ extern int rs6000_register_move_cost PARAMS ((enum machine_mode, enum reg_class, enum reg_class)); extern int rs6000_memory_move_cost PARAMS ((enum machine_mode, enum reg_class, int)); +extern bool rs6000_tls_referenced_p PARAMS ((rtx)); +extern int rs6000_tls_symbol_ref PARAMS ((rtx, enum machine_mode)); /* Declare functions in rs6000-c.c */ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 38633d19d4bf..965c3e1ad1ad 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -136,6 +136,10 @@ const char *rs6000_sdata_name = (char *)0; int fixuplabelno = 0; #endif +/* Bit size of immediate TLS offsets and string from which it is decoded. */ +int rs6000_tls_size = 32; +const char *rs6000_tls_size_string; + /* ABI enumeration available for subtarget to use. */ enum rs6000_abi rs6000_current_abi; @@ -286,6 +290,7 @@ static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx)); static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx)); static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree)); static void rs6000_parse_abi_options PARAMS ((void)); +static void rs6000_parse_tls_size_option PARAMS ((void)); static void rs6000_parse_yes_no_option (const char *, const char *, int *); static int first_altivec_reg_to_save PARAMS ((void)); static unsigned int compute_vrsave_mask PARAMS ((void)); @@ -295,6 +300,12 @@ int easy_vector_constant PARAMS ((rtx, enum machine_mode)); static int easy_vector_same PARAMS ((rtx, enum machine_mode)); static bool is_ev64_opaque_type PARAMS ((tree)); static rtx rs6000_dwarf_register_span PARAMS ((rtx)); +static rtx rs6000_legitimize_tls_address PARAMS ((rtx, enum tls_model)); +static rtx rs6000_tls_get_addr PARAMS ((void)); +static rtx rs6000_got_sym PARAMS ((void)); +static inline int rs6000_tls_symbol_ref_1 PARAMS ((rtx *, void *)); +static const char *rs6000_get_some_local_dynamic_name PARAMS ((void)); +static int rs6000_get_some_local_dynamic_name_1 PARAMS ((rtx *, void *)); /* Hash table stuff for keeping track of TOC entries. */ @@ -367,6 +378,10 @@ static const char alt_reg_names[][8] = /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */ #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO)) + +/* Return 1 for a symbol ref for a thread-local storage symbol. */ +#define RS6000_SYMBOL_REF_TLS_P(RTX) \ + (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0) /* Initialize the GCC target structure. */ #undef TARGET_ATTRIBUTE_TABLE @@ -408,6 +423,12 @@ static const char alt_reg_names[][8] = #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility #endif +#undef TARGET_HAVE_TLS +#define TARGET_HAVE_TLS HAVE_AS_TLS + +#undef TARGET_CANNOT_FORCE_CONST_MEM +#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p + #undef TARGET_ASM_FUNCTION_PROLOGUE #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue #undef TARGET_ASM_FUNCTION_EPILOGUE @@ -727,6 +748,9 @@ rs6000_override_options (default_cpu) rs6000_parse_yes_no_option ("float-gprs", rs6000_float_gprs_string, &rs6000_float_gprs); + /* Handle -mtls-size option. */ + rs6000_parse_tls_size_option (); + #ifdef SUBTARGET_OVERRIDE_OPTIONS SUBTARGET_OVERRIDE_OPTIONS; #endif @@ -864,6 +888,23 @@ rs6000_parse_abi_options () error ("unknown ABI specified: '%s'", rs6000_abi_string); } +/* Validate and record the size specified with the -mtls-size option. */ + +static void +rs6000_parse_tls_size_option () +{ + if (rs6000_tls_size_string == 0) + return; + else if (strcmp (rs6000_tls_size_string, "16") == 0) + rs6000_tls_size = 16; + else if (strcmp (rs6000_tls_size_string, "32") == 0) + rs6000_tls_size = 32; + else if (strcmp (rs6000_tls_size_string, "64") == 0) + rs6000_tls_size = 64; + else + error ("bad value `%s' for -mtls-size switch", rs6000_tls_size_string); +} + void optimization_options (level, size) int level ATTRIBUTE_UNUSED; @@ -2236,7 +2277,9 @@ constant_pool_expr_1 (op, have_sym, have_toc) switch (GET_CODE(op)) { case SYMBOL_REF: - if (CONSTANT_POOL_ADDRESS_P (op)) + if (RS6000_SYMBOL_REF_TLS_P (op)) + return 0; + else if (CONSTANT_POOL_ADDRESS_P (op)) { if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode)) { @@ -2462,6 +2505,13 @@ rs6000_legitimize_address (x, oldx, mode) rtx oldx ATTRIBUTE_UNUSED; enum machine_mode mode; { + if (GET_CODE (x) == SYMBOL_REF) + { + enum tls_model model = SYMBOL_REF_TLS_MODEL (x); + if (model != 0) + return rs6000_legitimize_tls_address (x, model); + } + if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == REG && GET_CODE (XEXP (x, 1)) == CONST_INT @@ -2562,6 +2612,253 @@ rs6000_legitimize_address (x, oldx, mode) return NULL_RTX; } +/* Construct the SYMBOL_REF for the tls_get_addr function. */ + +static GTY(()) rtx rs6000_tls_symbol; +static rtx +rs6000_tls_get_addr () +{ + if (!rs6000_tls_symbol) + rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr"); + + return rs6000_tls_symbol; +} + +/* Construct the SYMBOL_REF for TLS GOT references. */ + +static GTY(()) rtx rs6000_got_symbol; +static rtx +rs6000_got_sym () +{ + if (!rs6000_got_symbol) + { + rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); + SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL; + SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL; + } + + return rs6000_got_symbol; +} + +/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute + this (thread-local) address. */ + +static rtx +rs6000_legitimize_tls_address (addr, model) + rtx addr; + enum tls_model model; +{ + rtx dest, insn; + + dest = gen_reg_rtx (Pmode); + if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16) + { + rtx tlsreg; + + if (TARGET_64BIT) + { + tlsreg = gen_rtx_REG (Pmode, 13); + insn = gen_tls_tprel_64 (dest, tlsreg, addr); + } + else + { + tlsreg = gen_rtx_REG (Pmode, 2); + insn = gen_tls_tprel_32 (dest, tlsreg, addr); + } + emit_insn (insn); + } + else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32) + { + rtx tlsreg, tmp; + + tmp = gen_reg_rtx (Pmode); + if (TARGET_64BIT) + { + tlsreg = gen_rtx_REG (Pmode, 13); + insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr); + } + else + { + tlsreg = gen_rtx_REG (Pmode, 2); + insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr); + } + emit_insn (insn); + if (TARGET_64BIT) + insn = gen_tls_tprel_lo_64 (dest, tmp, addr); + else + insn = gen_tls_tprel_lo_32 (dest, tmp, addr); + emit_insn (insn); + } + else + { + rtx r3, got, tga, tmp1, tmp2, eqv; + + if (TARGET_64BIT) + got = gen_rtx_REG (Pmode, TOC_REGISTER); + else + { + if (flag_pic == 1) + got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); + else + { + rtx gsym = rs6000_got_sym (); + got = gen_reg_rtx (Pmode); + if (flag_pic == 0) + rs6000_emit_move (got, gsym, Pmode); + else + { + char buf[30]; + static int tls_got_labelno = 0; + rtx tempLR, lab, tmp3, mem; + rtx first, last; + + ASM_GENERATE_INTERNAL_LABEL (buf, "LTLS", tls_got_labelno++); + lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); + tempLR = gen_reg_rtx (Pmode); + tmp1 = gen_reg_rtx (Pmode); + tmp2 = gen_reg_rtx (Pmode); + tmp3 = gen_reg_rtx (Pmode); + mem = gen_rtx_MEM (Pmode, tmp1); + RTX_UNCHANGING_P (mem) = 1; + + first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, lab, + gsym)); + emit_move_insn (tmp1, tempLR); + emit_move_insn (tmp2, mem); + emit_insn (gen_addsi3 (tmp3, tmp1, tmp2)); + last = emit_move_insn (got, tmp3); + REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, gsym, + REG_NOTES (last)); + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, + REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, + REG_NOTES (last)); + } + } + } + + if (model == TLS_MODEL_GLOBAL_DYNAMIC) + { + r3 = gen_rtx_REG (Pmode, 3); + if (TARGET_64BIT) + insn = gen_tls_gd_64 (r3, got, addr); + else + insn = gen_tls_gd_32 (r3, got, addr); + start_sequence (); + emit_insn (insn); + tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ()); + insn = gen_call_value (r3, tga, const0_rtx, const0_rtx); + insn = emit_call_insn (insn); + CONST_OR_PURE_CALL_P (insn) = 1; + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3); + insn = get_insns (); + end_sequence (); + emit_libcall_block (insn, dest, r3, addr); + } + else if (model == TLS_MODEL_LOCAL_DYNAMIC) + { + r3 = gen_rtx_REG (Pmode, 3); + if (TARGET_64BIT) + insn = gen_tls_ld_64 (r3, got); + else + insn = gen_tls_ld_32 (r3, got); + start_sequence (); + emit_insn (insn); + tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ()); + insn = gen_call_value (r3, tga, const0_rtx, const0_rtx); + insn = emit_call_insn (insn); + CONST_OR_PURE_CALL_P (insn) = 1; + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3); + insn = get_insns (); + end_sequence (); + tmp1 = gen_reg_rtx (Pmode); + eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), + UNSPEC_TLSLD); + emit_libcall_block (insn, tmp1, r3, eqv); + if (rs6000_tls_size == 16) + { + if (TARGET_64BIT) + insn = gen_tls_dtprel_64 (dest, tmp1, addr); + else + insn = gen_tls_dtprel_32 (dest, tmp1, addr); + } + else if (rs6000_tls_size == 32) + { + tmp2 = gen_reg_rtx (Pmode); + if (TARGET_64BIT) + insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr); + else + insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr); + emit_insn (insn); + if (TARGET_64BIT) + insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr); + else + insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr); + } + else + { + tmp2 = gen_reg_rtx (Pmode); + if (TARGET_64BIT) + insn = gen_tls_got_dtprel_64 (tmp2, got, addr); + else + insn = gen_tls_got_dtprel_32 (tmp2, got, addr); + emit_insn (insn); + insn = gen_rtx_SET (Pmode, dest, + gen_rtx_PLUS (Pmode, tmp2, tmp1)); + } + emit_insn (insn); + } + else + { + /* IE, or 64 bit offset LE. */ + tmp2 = gen_reg_rtx (Pmode); + if (TARGET_64BIT) + insn = gen_tls_got_tprel_64 (tmp2, got, addr); + else + insn = gen_tls_got_tprel_32 (tmp2, got, addr); + emit_insn (insn); + if (TARGET_64BIT) + insn = gen_tls_tls_64 (dest, tmp2, addr); + else + insn = gen_tls_tls_32 (dest, tmp2, addr); + emit_insn (insn); + } + } + + return dest; +} + +/* Return 1 if X is a SYMBOL_REF for a TLS symbol. This is used in + instruction definitions. */ + +int +rs6000_tls_symbol_ref (x, mode) + rtx x; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + return RS6000_SYMBOL_REF_TLS_P (x); +} + +/* Return 1 if X contains a thread-local symbol. */ + +bool +rs6000_tls_referenced_p (x) + rtx x; +{ + return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0); +} + +/* Return 1 if *X is a thread-local symbol. This is the same as + rs6000_tls_symbol_ref except for the type of the unused argument. */ + +static inline int +rs6000_tls_symbol_ref_1 (x, data) + rtx *x; + void *data ATTRIBUTE_UNUSED; +{ + return RS6000_SYMBOL_REF_TLS_P (*x); +} + /* The convention appears to be to define this wherever it is used. With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P is now used here. */ @@ -2730,6 +3027,8 @@ rs6000_legitimate_address (mode, x, reg_ok_strict) rtx x; int reg_ok_strict; { + if (RS6000_SYMBOL_REF_TLS_P (x)) + return 0; if (legitimate_indirect_address_p (x, reg_ok_strict)) return 1; if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC) @@ -3051,6 +3350,15 @@ rs6000_emit_move (dest, source, mode) } } + /* Recognize the case where operand[1] is a reference to thread-local + data and load its address to a register. */ + if (GET_CODE (operands[1]) == SYMBOL_REF) + { + enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]); + if (model != 0) + operands[1] = rs6000_legitimize_tls_address (operands[1], model); + } + /* Handle the case where reload calls us with an invalid address. */ if (reload_in_progress && mode == Pmode && (! general_operand (operands[1], mode) @@ -7822,6 +8130,48 @@ extract_ME (op) return i; } +/* Locate some local-dynamic symbol still in use by this function + so that we can print its name in some tls_ld pattern. */ + +static const char * +rs6000_get_some_local_dynamic_name () +{ + rtx insn; + + if (cfun->machine->some_ld_name) + return cfun->machine->some_ld_name; + + for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) + if (INSN_P (insn) + && for_each_rtx (&PATTERN (insn), + rs6000_get_some_local_dynamic_name_1, 0)) + return cfun->machine->some_ld_name; + + abort (); +} + +/* Helper function for rs6000_get_some_local_dynamic_name. */ + +static int +rs6000_get_some_local_dynamic_name_1 (px, data) + rtx *px; + void *data ATTRIBUTE_UNUSED; +{ + rtx x = *px; + + if (GET_CODE (x) == SYMBOL_REF) + { + const char *str = XSTR (x, 0); + if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC) + { + cfun->machine->some_ld_name = str; + return 1; + } + } + + return 0; +} + /* Print an operand. Recognize special options, documented below. */ #if TARGET_ELF @@ -8436,6 +8786,10 @@ print_operand (file, x, code) output_addr_const (file, x); return; + case '&': + assemble_name (file, rs6000_get_some_local_dynamic_name ()); + return; + default: output_operand_lossage ("invalid %%xn code"); } @@ -10204,27 +10558,35 @@ get_TOC_alias_set () } /* This retuns nonzero if the current function uses the TOC. This is - determined by the presence of (unspec ... UNSPEC_TOC), which is - generated by the various load_toc_* patterns. */ + determined by the presence of (unspec ... UNSPEC_TOC) or + use (unspec ... UNSPEC_TOC), which are generated by the various + load_toc_* patterns. */ int uses_TOC () { - rtx insn; + rtx insn; - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (INSN_P (insn)) - { - rtx pat = PATTERN (insn); - int i; + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if (INSN_P (insn)) + { + rtx pat = PATTERN (insn); + int i; - if (GET_CODE (pat) == PARALLEL) - for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++) - if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC - && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == UNSPEC_TOC) - return 1; - } - return 0; + if (GET_CODE (pat) == PARALLEL) + for (i = 0; i < XVECLEN (pat, 0); i++) + { + rtx sub = XVECEXP (pat, 0, i); + if (GET_CODE (sub) == USE) + { + sub = XEXP (sub, 0); + if (GET_CODE (sub) == UNSPEC + && XINT (sub, 1) == UNSPEC_TOC) + return 1; + } + } + } + return 0; } rtx @@ -11090,7 +11452,7 @@ rs6000_emit_prologue () && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])) { /* If emit_load_toc_table will use the link register, we need to save - it. We use R11 for this purpose because emit_load_toc_table + it. We use R12 for this purpose because emit_load_toc_table can use register 0. This allows us to use a plain 'blr' to return from the procedure more often. */ int save_LR_around_toc_setup = (TARGET_ELF @@ -11099,14 +11461,14 @@ rs6000_emit_prologue () && ! info->lr_save_p && EXIT_BLOCK_PTR->pred != NULL); if (save_LR_around_toc_setup) - emit_move_insn (gen_rtx_REG (Pmode, 11), - gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)); - - rs6000_emit_load_toc_table (TRUE); - - if (save_LR_around_toc_setup) - emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), - gen_rtx_REG (Pmode, 11)); + { + rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM); + rs6000_maybe_dead (emit_move_insn (frame_ptr_rtx, lr)); + rs6000_emit_load_toc_table (TRUE); + rs6000_maybe_dead (emit_move_insn (lr, frame_ptr_rtx)); + } + else + rs6000_emit_load_toc_table (TRUE); } #if TARGET_MACHO @@ -13033,7 +13395,6 @@ rs6000_longcall_ref (call_ref) return force_reg (Pmode, call_ref); } - #ifdef USING_ELFOS_H diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 58cf454d8cfd..589963be6d3b 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -211,6 +211,10 @@ extern int target_flags; #define TARGET_UPDATE (! TARGET_NO_UPDATE) #define TARGET_FUSED_MADD (! TARGET_NO_FUSED_MADD) +#ifndef HAVE_AS_TLS +#define HAVE_AS_TLS 0 +#endif + #ifdef IN_LIBGCC2 /* For libgcc2 we make sure this is a compile time constant */ #if defined (__64BIT__) || defined (__powerpc64__) @@ -1675,6 +1679,8 @@ typedef struct machine_function GTY(()) int sysv_varargs_p; /* Flags if __builtin_return_address (n) with n >= 1 was used. */ int ra_needs_full_frame; + /* Some local-dynamic symbol. */ + const char *some_ld_name; /* Whether the instruction chain has been scanned already. */ int insn_chain_scanned_p; } machine_function; @@ -2012,9 +2018,10 @@ typedef struct rs6000_args acceptable. */ #define LEGITIMATE_CONSTANT_P(X) \ - (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode \ - || (TARGET_POWERPC64 && GET_MODE (X) == DImode) \ - || easy_fp_constant (X, GET_MODE (X))) + ((GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode \ + || (TARGET_POWERPC64 && GET_MODE (X) == DImode) \ + || easy_fp_constant (X, GET_MODE (X))) \ + && !rs6000_tls_referenced_p (X)) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. @@ -2643,7 +2650,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ /* Define which CODE values are valid. */ #define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ - ((CODE) == '.') + ((CODE) == '.' || (CODE) == '&') /* Print a memory address as an operand to reference that memory location. */ @@ -2674,6 +2681,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ {"reg_or_logical_cint_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ {"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \ {"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \ + {"rs6000_tls_symbol_ref", {SYMBOL_REF}}, \ {"easy_fp_constant", {CONST_DOUBLE}}, \ {"easy_vector_constant", {CONST_VECTOR}}, \ {"easy_vector_constant_add_self", {CONST_VECTOR}}, \ @@ -2697,6 +2705,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ {"count_register_operand", {REG}}, \ {"xer_operand", {REG}}, \ {"symbol_ref_operand", {SYMBOL_REF}}, \ + {"rs6000_tls_symbol_ref", {SYMBOL_REF}}, \ {"call_operand", {SYMBOL_REF, REG}}, \ {"current_file_function_operand", {SYMBOL_REF}}, \ {"input_operand", {SUBREG, MEM, REG, CONST_INT, \ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a40dc2b0293f..d2149d7a222f 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -9718,6 +9718,186 @@ && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" "stfq%U0%X0 %1,%0") +;; TLS support. + +;; "b" output constraint here and on tls_ld to support tls linker optimization. +(define_insn "tls_gd_32" + [(set (match_operand:SI 0 "register_operand" "=b") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD))] + "HAVE_AS_TLS && !TARGET_64BIT" + "addi %0,%1,%2@got@tlsgd") + +(define_insn "tls_gd_64" + [(set (match_operand:DI 0 "register_operand" "=b") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGD))] + "HAVE_AS_TLS && TARGET_64BIT" + "addi %0,%1,%2@got@tlsgd") + +(define_insn "tls_ld_32" + [(set (match_operand:SI 0 "register_operand" "=b") + (unspec:SI [(match_operand:SI 1 "register_operand" "b")] + UNSPEC_TLSLD))] + "HAVE_AS_TLS && !TARGET_64BIT" + "addi %0,%1,%&@got@tlsld") + +(define_insn "tls_ld_64" + [(set (match_operand:DI 0 "register_operand" "=b") + (unspec:DI [(match_operand:DI 1 "register_operand" "b")] + UNSPEC_TLSLD))] + "HAVE_AS_TLS && TARGET_64BIT" + "addi %0,%1,%&@got@tlsld") + +(define_insn "tls_dtprel_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPREL))] + "HAVE_AS_TLS && !TARGET_64BIT" + "addi %0,%1,%2@dtprel") + +(define_insn "tls_dtprel_64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPREL))] + "HAVE_AS_TLS && TARGET_64BIT" + "addi %0,%1,%2@dtprel") + +(define_insn "tls_dtprel_ha_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPRELHA))] + "HAVE_AS_TLS && !TARGET_64BIT" + "addis %0,%1,%2@dtprel@ha") + +(define_insn "tls_dtprel_ha_64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPRELHA))] + "HAVE_AS_TLS && TARGET_64BIT" + "addis %0,%1,%2@dtprel@ha") + +(define_insn "tls_dtprel_lo_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPRELLO))] + "HAVE_AS_TLS && !TARGET_64BIT" + "addi %0,%1,%2@dtprel@l") + +(define_insn "tls_dtprel_lo_64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSDTPRELLO))] + "HAVE_AS_TLS && TARGET_64BIT" + "addi %0,%1,%2@dtprel@l") + +(define_insn "tls_got_dtprel_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTDTPREL))] + "HAVE_AS_TLS && !TARGET_64BIT" + "lwz %0,%2@got@dtprel(%1)") + +(define_insn "tls_got_dtprel_64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTDTPREL))] + "HAVE_AS_TLS && TARGET_64BIT" + "ld %0,%2@got@dtprel(%1)") + +(define_insn "tls_tprel_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPREL))] + "HAVE_AS_TLS && !TARGET_64BIT" + "addi %0,%1,%2@tprel") + +(define_insn "tls_tprel_64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPREL))] + "HAVE_AS_TLS && TARGET_64BIT" + "addi %0,%1,%2@tprel") + +(define_insn "tls_tprel_ha_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPRELHA))] + "HAVE_AS_TLS && !TARGET_64BIT" + "addis %0,%1,%2@tprel@ha") + +(define_insn "tls_tprel_ha_64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPRELHA))] + "HAVE_AS_TLS && TARGET_64BIT" + "addis %0,%1,%2@tprel@ha") + +(define_insn "tls_tprel_lo_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPRELLO))] + "HAVE_AS_TLS && !TARGET_64BIT" + "addi %0,%1,%2@tprel@l") + +(define_insn "tls_tprel_lo_64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTPRELLO))] + "HAVE_AS_TLS && TARGET_64BIT" + "addi %0,%1,%2@tprel@l") + +;; "b" output contraint here and on tls_tls input to support linker tls +;; optimization. The linker may edit the instructions emitted by a +;; tls_got_tprel/tls_tls pair to addis,addi. +(define_insn "tls_got_tprel_32" + [(set (match_operand:SI 0 "register_operand" "=b") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTTPREL))] + "HAVE_AS_TLS && !TARGET_64BIT" + "lwz %0,%2@got@tprel(%1)") + +(define_insn "tls_got_tprel_64" + [(set (match_operand:DI 0 "register_operand" "=b") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSGOTTPREL))] + "HAVE_AS_TLS && TARGET_64BIT" + "ld %0,%2@got@tprel(%1)") + +(define_insn "tls_tls_32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand:SI 1 "register_operand" "b") + (match_operand:SI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTLS))] + "HAVE_AS_TLS && !TARGET_64BIT" + "add %0,%1,%2@tls") + +(define_insn "tls_tls_64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "b") + (match_operand:DI 2 "rs6000_tls_symbol_ref" "")] + UNSPEC_TLSTLS))] + "HAVE_AS_TLS && TARGET_64BIT" + "add %0,%1,%2@tls") + ;; Next come insns related to the calling sequence. ;; ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). @@ -9895,7 +10075,7 @@ (define_insn "load_toc_v4_PIC_1" [(set (match_operand:SI 0 "register_operand" "=l") (match_operand:SI 1 "immediate_operand" "s")) - (unspec [(match_dup 1)] UNSPEC_TOC)] + (use (unspec [(match_dup 1)] UNSPEC_TOC))] "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" "bcl 20,31,%1\\n%1:" [(set_attr "type" "branch") @@ -9904,10 +10084,10 @@ (define_insn "load_toc_v4_PIC_1b" [(set (match_operand:SI 0 "register_operand" "=l") (match_operand:SI 1 "immediate_operand" "s")) - (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")] - UNSPEC_TOCPTR)] + (use (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")] + UNSPEC_TOCPTR))] "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" - "bcl 20,31,%1\\n\\t.long %2-%1+4\\n%1:" + "bcl 20,31,%1+4\\n%1:\\n\\t.long %2-%1" [(set_attr "type" "branch") (set_attr "length" "8")]) diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index e48bf6c41fc6..d6b0f31088d2 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -79,12 +79,15 @@ extern enum rs6000_sdata_type rs6000_sdata; /* Strings provided by SUBTARGET_OPTIONS */ extern const char *rs6000_abi_name; extern const char *rs6000_sdata_name; +extern const char *rs6000_tls_size_string; /* For -mtls-size= */ /* Override rs6000.h definition. */ #undef SUBTARGET_OPTIONS #define SUBTARGET_OPTIONS \ { "call-", &rs6000_abi_name, N_("Select ABI calling convention"), 0}, \ - { "sdata=", &rs6000_sdata_name, N_("Select method for sdata handling"), 0} + { "sdata=", &rs6000_sdata_name, N_("Select method for sdata handling"), 0}, \ + { "tls-size=", &rs6000_tls_size_string, \ + N_("Specify bit size of immediate TLS offsets"), 0 } /* Max # of bytes for variables to automatically be put into the .sdata or .sdata2 sections. */ diff --git a/gcc/configure b/gcc/configure index 0ad779403e4e..fe5e6b39f7a0 100755 --- a/gcc/configure +++ b/gcc/configure @@ -8196,6 +8196,64 @@ foo: data8 25 tls_first_major=2 tls_first_minor=13 ;; + powerpc-*-*) + conftest_s=' + .section ".tdata","awT",@progbits + .align 2 +ld0: .space 4 +ld1: .space 4 +x1: .space 4 +x2: .space 4 +x3: .space 4 + .text + addi 3,31,ld0@got@tlsgd + bl __tls_get_addr + addi 3,31,x1@got@tlsld + bl __tls_get_addr + addi 9,3,x1@dtprel + addis 9,3,x2@dtprel@ha + addi 9,9,x2@dtprel@l + lwz 9,x3@got@tprel(31) + add 9,9,x@tls + addi 9,2,x1@tprel + addis 9,2,x2@tprel@ha + addi 9,9,x2@tprel@l' + tls_first_major=2 + tls_first_minor=14 + ;; + powerpc64-*-*) + conftest_s=' + .section ".tdata","awT",@progbits + .align 3 +ld0: .space 8 +ld1: .space 8 +x1: .space 8 +x2: .space 8 +x3: .space 8 + .text + addi 3,2,ld0@got@tlsgd + bl .__tls_get_addr + nop + addi 3,2,ld1@toc + bl .__tls_get_addr + nop + addi 3,2,x1@got@tlsld + bl .__tls_get_addr + nop + addi 9,3,x1@dtprel + bl .__tls_get_addr + nop + addis 9,3,x2@dtprel@ha + addi 9,9,x2@dtprel@l + bl .__tls_get_addr + nop + ld 9,x3@got@dtprel(2) + add 9,9,3 + bl .__tls_get_addr + nop' + tls_first_major=2 + tls_first_minor=14 + ;; s390-*-*) conftest_s=' .section ".tdata","awT",@progbits @@ -8265,7 +8323,7 @@ case "$target" in # All TARGET_ABI_OSF targets. alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*) echo $ac_n "checking assembler supports explicit relocations""... $ac_c" 1>&6 -echo "configure:8269: checking assembler supports explicit relocations" >&5 +echo "configure:8327: checking assembler supports explicit relocations" >&5 if eval "test \"`echo '$''{'gcc_cv_as_explicit_relocs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8318,7 +8376,7 @@ EOF ;; sparc*-*-*) echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6 -echo "configure:8322: checking assembler .register pseudo-op support" >&5 +echo "configure:8380: checking assembler .register pseudo-op support" >&5 if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8346,7 +8404,7 @@ EOF fi echo $ac_n "checking assembler supports -relax""... $ac_c" 1>&6 -echo "configure:8350: checking assembler supports -relax" >&5 +echo "configure:8408: checking assembler supports -relax" >&5 if eval "test \"`echo '$''{'gcc_cv_as_relax_opt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8374,7 +8432,7 @@ EOF fi echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6 -echo "configure:8378: checking assembler and linker support unaligned pc related relocs" >&5 +echo "configure:8436: checking assembler and linker support unaligned pc related relocs" >&5 if eval "test \"`echo '$''{'gcc_cv_as_sparc_ua_pcrel'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8401,7 +8459,7 @@ EOF fi echo $ac_n "checking assembler and linker support unaligned pc related relocs against hidden symbols""... $ac_c" 1>&6 -echo "configure:8405: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5 +echo "configure:8463: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5 if eval "test \"`echo '$''{'gcc_cv_as_sparc_ua_pcrel_hidden'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8441,7 +8499,7 @@ EOF fi echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6 -echo "configure:8445: checking for assembler offsetable %lo() support" >&5 +echo "configure:8503: checking for assembler offsetable %lo() support" >&5 if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8480,7 +8538,7 @@ EOF i[34567]86-*-* | x86_64-*-*) echo $ac_n "checking assembler instructions""... $ac_c" 1>&6 -echo "configure:8484: checking assembler instructions" >&5 +echo "configure:8542: checking assembler instructions" >&5 gcc_cv_as_instructions= if test $in_tree_gas = yes ; then if test $gcc_cv_gas_major_version -eq 2 \ @@ -8514,7 +8572,7 @@ EOF echo "$ac_t""$gcc_cv_as_instructions" 1>&6 echo $ac_n "checking assembler GOTOFF in data directives""... $ac_c" 1>&6 -echo "configure:8518: checking assembler GOTOFF in data directives" >&5 +echo "configure:8576: checking assembler GOTOFF in data directives" >&5 gcc_cv_as_gotoff_in_data=no if test $in_tree_gas = yes ; then if test $gcc_cv_gas_major_version -eq 2 \ @@ -8548,7 +8606,7 @@ EOF ia64*-*-*) echo $ac_n "checking assembler supports ltoffx and ldxmov""... $ac_c" 1>&6 -echo "configure:8552: checking assembler supports ltoffx and ldxmov" >&5 +echo "configure:8610: checking assembler supports ltoffx and ldxmov" >&5 if eval "test \"`echo '$''{'gcc_cv_as_ltoffx_ldxmov_relocs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8593,7 +8651,7 @@ EOF esac echo $ac_n "checking assembler dwarf2 debug_line support""... $ac_c" 1>&6 -echo "configure:8597: checking assembler dwarf2 debug_line support" >&5 +echo "configure:8655: checking assembler dwarf2 debug_line support" >&5 gcc_cv_as_dwarf2_debug_line=no # ??? Not all targets support dwarf2 debug_line, even within a version # of gas. Moreover, we need to emit a valid instruction to trigger any @@ -8655,7 +8713,7 @@ fi echo "$ac_t""$gcc_cv_as_dwarf2_debug_line" 1>&6 echo $ac_n "checking assembler --gdwarf2 support""... $ac_c" 1>&6 -echo "configure:8659: checking assembler --gdwarf2 support" >&5 +echo "configure:8717: checking assembler --gdwarf2 support" >&5 gcc_cv_as_gdwarf2_flag=no if test $in_tree_gas = yes ; then if test $gcc_cv_gas_major_version -eq 2 \ @@ -8689,7 +8747,7 @@ fi echo "$ac_t""$gcc_cv_as_gdwarf2_flag" 1>&6 echo $ac_n "checking assembler --gstabs support""... $ac_c" 1>&6 -echo "configure:8693: checking assembler --gstabs support" >&5 +echo "configure:8751: checking assembler --gstabs support" >&5 gcc_cv_as_gstabs_flag=no if test $in_tree_gas = yes ; then if test $gcc_cv_gas_major_version -eq 2 \ @@ -8722,7 +8780,7 @@ fi echo "$ac_t""$gcc_cv_as_gstabs_flag" 1>&6 echo $ac_n "checking linker read-only and read-write section mixing""... $ac_c" 1>&6 -echo "configure:8726: checking linker read-only and read-write section mixing" >&5 +echo "configure:8784: checking linker read-only and read-write section mixing" >&5 gcc_cv_ld_ro_rw_mix=unknown if test $in_tree_ld = yes ; then if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then @@ -8760,7 +8818,7 @@ fi echo "$ac_t""$gcc_cv_ld_ro_rw_mix" 1>&6 echo $ac_n "checking linker PT_GNU_EH_FRAME support""... $ac_c" 1>&6 -echo "configure:8764: checking linker PT_GNU_EH_FRAME support" >&5 +echo "configure:8822: checking linker PT_GNU_EH_FRAME support" >&5 gcc_cv_ld_eh_frame_hdr=no if test $in_tree_ld = yes ; then if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then @@ -8784,7 +8842,7 @@ echo "$ac_t""$gcc_cv_ld_eh_frame_hdr" 1>&6 case "$target" in mips*-*-*) echo $ac_n "checking whether libgloss uses STARTUP directives consistently""... $ac_c" 1>&6 -echo "configure:8788: checking whether libgloss uses STARTUP directives consistently" >&5 +echo "configure:8846: checking whether libgloss uses STARTUP directives consistently" >&5 gcc_cv_mips_libgloss_startup=no gcc_cv_libgloss_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/libgloss if test "x$exec_prefix" = xNONE; then @@ -8812,7 +8870,7 @@ EOF echo "$ac_t""$gcc_cv_mips_libgloss_startup" 1>&6 echo $ac_n "checking whether the assembler has explicit relocation support""... $ac_c" 1>&6 -echo "configure:8816: checking whether the assembler has explicit relocation support" >&5 +echo "configure:8874: checking whether the assembler has explicit relocation support" >&5 if test x$gcc_cv_mips_explicit_relocs = x; then gcc_cv_mips_explicit_relocs=no if test x$gcc_cv_as != x; then @@ -9007,7 +9065,7 @@ fi echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 -echo "configure:9011: checking whether to enable maintainer-specific portions of Makefiles" >&5 +echo "configure:9069: checking whether to enable maintainer-specific portions of Makefiles" >&5 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval="$enable_maintainer_mode" diff --git a/gcc/configure.in b/gcc/configure.in index 773813e7dd45..f0e5d7524745 100644 --- a/gcc/configure.in +++ b/gcc/configure.in @@ -2123,6 +2123,64 @@ foo: data8 25 tls_first_major=2 tls_first_minor=13 ;; + powerpc-*-*) + conftest_s=' + .section ".tdata","awT",@progbits + .align 2 +ld0: .space 4 +ld1: .space 4 +x1: .space 4 +x2: .space 4 +x3: .space 4 + .text + addi 3,31,ld0@got@tlsgd + bl __tls_get_addr + addi 3,31,x1@got@tlsld + bl __tls_get_addr + addi 9,3,x1@dtprel + addis 9,3,x2@dtprel@ha + addi 9,9,x2@dtprel@l + lwz 9,x3@got@tprel(31) + add 9,9,x@tls + addi 9,2,x1@tprel + addis 9,2,x2@tprel@ha + addi 9,9,x2@tprel@l' + tls_first_major=2 + tls_first_minor=14 + ;; + powerpc64-*-*) + conftest_s=' + .section ".tdata","awT",@progbits + .align 3 +ld0: .space 8 +ld1: .space 8 +x1: .space 8 +x2: .space 8 +x3: .space 8 + .text + addi 3,2,ld0@got@tlsgd + bl .__tls_get_addr + nop + addi 3,2,ld1@toc + bl .__tls_get_addr + nop + addi 3,2,x1@got@tlsld + bl .__tls_get_addr + nop + addi 9,3,x1@dtprel + bl .__tls_get_addr + nop + addis 9,3,x2@dtprel@ha + addi 9,9,x2@dtprel@l + bl .__tls_get_addr + nop + ld 9,x3@got@dtprel(2) + add 9,9,3 + bl .__tls_get_addr + nop' + tls_first_major=2 + tls_first_minor=14 + ;; s390-*-*) conftest_s=' .section ".tdata","awT",@progbits -- 2.43.5