From 69229b8198e11bbbc5962d3e4ce8ce77ebf737b7 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Sun, 13 Mar 2005 18:03:25 +0000 Subject: [PATCH] configure.ac: Check for MIPS TLS. * configure.ac: Check for MIPS TLS. * configure: Regenerated. * config/mips/mips-protos.h (enum mips_symbol_type): Add SYMBOL_TLS, SYMBOL_TLSGD, SYMBOL_TLSLDM, SYMBOL_DTPREL, SYMBOL_GOTTPREL, and SYMBOL_TPREL. * config/mips/mips.c (mips_regno_to_class): Handle V1_REG. (TARGET_HAVE_TLS, TARGET_CANNOT_FORCE_CONST_MEM): Define. (mips_classify_symbol, mips_symbolic_constant_p) (mips_symbolic_address_p, mips_symbol_insns): Handle TLS symbols. (mips_tls_operand_p, mips_call_tls_get_addr) (mips_legitimize_tls_address, mips_cannot_force_const_mem) (mips_tls_symbol_ref_1): New functions. (mips_legitimize_address, mips_legitimize_const_move): Call mips_legitimize_tls_address. (override_options): Handle V1_REG and TLS symbols. Disable TLS for MIPS16. * config/mips/mips.h (enum reg_class, REG_CLASS_NAMES) (REG_CLASS_CONTENTS, GR_REG_CLASS_P): Include V1_REG. (mips_char_to_class): Document V1_REG. (HAVE_AS_TLS): Provide default. * config/mips/mips.md (UNSPEC_TLS_LDM, UNSPEC_TLS_GET_TP): New constants. (load_got): Renamed from *load_got. Allow when !TARGET_ABICALLS. (tls_get_tp_): New instruction. Co-Authored-By: Joseph Myers From-SVN: r96380 --- gcc/ChangeLog | 29 +++++ gcc/config/mips/mips-protos.h | 17 +++ gcc/config/mips/mips.c | 205 +++++++++++++++++++++++++++++++++- gcc/config/mips/mips.h | 11 +- gcc/config/mips/mips.md | 25 ++++- gcc/configure | 17 +++ gcc/configure.ac | 17 +++ 7 files changed, 316 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 78cdd8968e1..6489c3c438f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2005-03-13 Daniel Jacobowitz + Joseph S. Myers + + * configure.ac: Check for MIPS TLS. + * configure: Regenerated. + * config/mips/mips-protos.h (enum mips_symbol_type): Add + SYMBOL_TLS, SYMBOL_TLSGD, SYMBOL_TLSLDM, SYMBOL_DTPREL, + SYMBOL_GOTTPREL, and SYMBOL_TPREL. + * config/mips/mips.c (mips_regno_to_class): Handle V1_REG. + (TARGET_HAVE_TLS, TARGET_CANNOT_FORCE_CONST_MEM): Define. + (mips_classify_symbol, mips_symbolic_constant_p) + (mips_symbolic_address_p, mips_symbol_insns): Handle TLS symbols. + (mips_tls_operand_p, mips_call_tls_get_addr) + (mips_legitimize_tls_address, mips_cannot_force_const_mem) + (mips_tls_symbol_ref_1): New functions. + (mips_legitimize_address, mips_legitimize_const_move): Call + mips_legitimize_tls_address. + (override_options): Handle V1_REG and TLS symbols. Disable TLS + for MIPS16. + * config/mips/mips.h (enum reg_class, REG_CLASS_NAMES) + (REG_CLASS_CONTENTS, GR_REG_CLASS_P): Include V1_REG. + (mips_char_to_class): Document V1_REG. + (HAVE_AS_TLS): Provide default. + * config/mips/mips.md (UNSPEC_TLS_LDM, UNSPEC_TLS_GET_TP): New + constants. + (load_got): Renamed from *load_got. Allow when + !TARGET_ABICALLS. + (tls_get_tp_): New instruction. + 2005-03-13 Daniel Jacobowitz * configure.ac: Update checks for target tools. diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 8569d429959..4b0b53d1091 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -61,6 +61,17 @@ Boston, MA 02111-1307, USA. */ An UNSPEC wrapper around a function's address. It represents the offset of _gp from the start of the function. + SYMBOL_TLS + A thread-local symbol. + + SYMBOL_TLSGD + SYMBOL_TLSLDM + SYMBOL_DTPREL + SYMBOL_GOTTPREL + SYMBOL_TPREL + UNSPEC wrappers around SYMBOL_TLS, corresponding to the + thread-local storage relocation operators. + SYMBOL_64_HIGH For a 64-bit symbolic address X, this is the value of (%highest(X) << 16) + %higher(X). @@ -82,6 +93,12 @@ enum mips_symbol_type { SYMBOL_GOTOFF_GLOBAL, SYMBOL_GOTOFF_CALL, SYMBOL_GOTOFF_LOADGP, + SYMBOL_TLS, + SYMBOL_TLSGD, + SYMBOL_TLSLDM, + SYMBOL_DTPREL, + SYMBOL_GOTTPREL, + SYMBOL_TPREL, SYMBOL_64_HIGH, SYMBOL_64_MID, SYMBOL_64_LOW diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 6748eae02c5..59fd616b7f5 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -236,6 +236,7 @@ static bool mips_valid_base_register_p (rtx, enum machine_mode, int); static bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode); static bool mips_classify_address (struct mips_address_info *, rtx, enum machine_mode, int); +static bool mips_cannot_force_const_mem (rtx); static int mips_symbol_insns (enum mips_symbol_type); static bool mips16_unextended_reference_p (enum machine_mode mode, rtx, rtx); static rtx mips_force_temporary (rtx, rtx); @@ -601,7 +602,7 @@ static const char *mips_hi_relocs[NUM_SYMBOL_TYPES]; /* Map hard register number to register class */ const enum reg_class mips_regno_to_class[] = { - LEA_REGS, LEA_REGS, M16_NA_REGS, M16_NA_REGS, + LEA_REGS, LEA_REGS, M16_NA_REGS, V1_REG, M16_REGS, M16_REGS, M16_REGS, M16_REGS, LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, @@ -817,6 +818,12 @@ const struct mips_cpu_info mips_cpu_info_table[] = { #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN mips_expand_builtin +#undef TARGET_HAVE_TLS +#define TARGET_HAVE_TLS HAVE_AS_TLS + +#undef TARGET_CANNOT_FORCE_CONST_MEM +#define TARGET_CANNOT_FORCE_CONST_MEM mips_cannot_force_const_mem + struct gcc_target targetm = TARGET_INITIALIZER; /* Classify symbol X, which must be a SYMBOL_REF or a LABEL_REF. */ @@ -835,6 +842,9 @@ mips_classify_symbol (rtx x) gcc_assert (GET_CODE (x) == SYMBOL_REF); + if (SYMBOL_REF_TLS_MODEL (x)) + return SYMBOL_TLS; + if (CONSTANT_POOL_ADDRESS_P (x)) { if (TARGET_MIPS16) @@ -943,7 +953,11 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type) if (UNSPEC_ADDRESS_P (x)) *symbol_type = UNSPEC_ADDRESS_TYPE (x); else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF) - *symbol_type = mips_classify_symbol (x); + { + *symbol_type = mips_classify_symbol (x); + if (*symbol_type == SYMBOL_TLS) + return false; + } else return false; @@ -993,6 +1007,12 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type) case SYMBOL_GOTOFF_GLOBAL: case SYMBOL_GOTOFF_CALL: case SYMBOL_GOTOFF_LOADGP: + case SYMBOL_TLSGD: + case SYMBOL_TLSLDM: + case SYMBOL_DTPREL: + case SYMBOL_TPREL: + case SYMBOL_GOTTPREL: + case SYMBOL_TLS: return false; } gcc_unreachable (); @@ -1090,6 +1110,14 @@ mips_symbolic_address_p (enum mips_symbol_type symbol_type, /* The address will have to be loaded from the GOT first. */ return false; + case SYMBOL_TLSGD: + case SYMBOL_TLSLDM: + case SYMBOL_DTPREL: + case SYMBOL_TPREL: + case SYMBOL_GOTTPREL: + case SYMBOL_TLS: + return false; + case SYMBOL_GOTOFF_PAGE: case SYMBOL_GOTOFF_GLOBAL: case SYMBOL_GOTOFF_CALL: @@ -1154,6 +1182,33 @@ mips_classify_address (struct mips_address_info *info, rtx x, return false; } } + +/* Return true if X is a thread-local symbol. */ + +static bool +mips_tls_operand_p (rtx x) +{ + return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0; +} + +/* Return true if X can not be forced into a constant pool. */ + +static int +mips_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED) +{ + return mips_tls_operand_p (*x); +} + +/* Return true if X can not be forced into a constant pool. */ + +static bool +mips_cannot_force_const_mem (rtx x) +{ + if (! TARGET_HAVE_TLS) + return false; + + return for_each_rtx (&x, &mips_tls_symbol_ref_1, 0); +} /* Return the number of instructions needed to load a symbol of the given type into a register. If valid in an address, the same number @@ -1223,8 +1278,17 @@ mips_symbol_insns (enum mips_symbol_type type) case SYMBOL_64_HIGH: case SYMBOL_64_MID: case SYMBOL_64_LOW: + case SYMBOL_TLSGD: + case SYMBOL_TLSLDM: + case SYMBOL_DTPREL: + case SYMBOL_GOTTPREL: + case SYMBOL_TPREL: /* Check whether the offset is a 16- or 32-bit value. */ return mips_split_p[type] ? 2 : 1; + + case SYMBOL_TLS: + /* We don't treat a bare TLS symbol as a constant. */ + return 0; } gcc_unreachable (); } @@ -1521,6 +1585,114 @@ mips_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset) return plus_constant (reg, offset); } +/* Emit a call to __tls_get_addr. SYM is the TLS symbol we are + referencing, and TYPE is the symbol type to use (either global + dynamic or local dynamic). V0 is an RTX for the return value + location. The entire insn sequence is returned. */ + +static GTY(()) rtx mips_tls_symbol; + +static rtx +mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0) +{ + rtx insn, loc, tga, a0; + + a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST); + + if (!mips_tls_symbol) + mips_tls_symbol = init_one_libfunc ("__tls_get_addr"); + + loc = mips_unspec_address (sym, type); + + start_sequence (); + + emit_insn (gen_rtx_SET (Pmode, a0, + gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, loc))); + tga = gen_rtx_MEM (Pmode, mips_tls_symbol); + insn = emit_call_insn (gen_call_value (v0, tga, const0_rtx, const0_rtx)); + CONST_OR_PURE_CALL_P (insn) = 1; + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), v0); + use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0); + insn = get_insns (); + + end_sequence (); + + return insn; +} + +/* Generate the code to access LOC, a thread local SYMBOL_REF. The + return value will be a valid address and move_operand (either a REG + or a LO_SUM). */ + +static rtx +mips_legitimize_tls_address (rtx loc) +{ + rtx dest, insn, v0, v1, tmp1, tmp2, eqv; + enum tls_model model; + + v0 = gen_rtx_REG (Pmode, GP_RETURN); + v1 = gen_rtx_REG (Pmode, GP_RETURN + 1); + + model = SYMBOL_REF_TLS_MODEL (loc); + + switch (model) + { + case TLS_MODEL_GLOBAL_DYNAMIC: + insn = mips_call_tls_get_addr (loc, SYMBOL_TLSGD, v0); + dest = gen_reg_rtx (Pmode); + emit_libcall_block (insn, dest, v0, loc); + break; + + case TLS_MODEL_LOCAL_DYNAMIC: + insn = mips_call_tls_get_addr (loc, SYMBOL_TLSLDM, v0); + tmp1 = gen_reg_rtx (Pmode); + + /* Attach a unique REG_EQUIV, to allow the RTL optimizers to + share the LDM result with other LD model accesses. */ + eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), + UNSPEC_TLS_LDM); + emit_libcall_block (insn, tmp1, v0, eqv); + + tmp2 = mips_unspec_offset_high (NULL, tmp1, loc, SYMBOL_DTPREL); + dest = gen_rtx_LO_SUM (Pmode, tmp2, + mips_unspec_address (loc, SYMBOL_DTPREL)); + break; + + case TLS_MODEL_INITIAL_EXEC: + tmp1 = gen_reg_rtx (Pmode); + tmp2 = mips_unspec_address (loc, SYMBOL_GOTTPREL); + if (Pmode == DImode) + { + emit_insn (gen_tls_get_tp_di (v1)); + emit_insn (gen_load_gotdi (tmp1, pic_offset_table_rtx, tmp2)); + } + else + { + emit_insn (gen_tls_get_tp_si (v1)); + emit_insn (gen_load_gotsi (tmp1, pic_offset_table_rtx, tmp2)); + } + dest = gen_reg_rtx (Pmode); + emit_insn (gen_add3_insn (dest, tmp1, v1)); + break; + + case TLS_MODEL_LOCAL_EXEC: + + if (Pmode == DImode) + emit_insn (gen_tls_get_tp_di (v1)); + else + emit_insn (gen_tls_get_tp_si (v1)); + + tmp1 = mips_unspec_offset_high (NULL, v1, loc, SYMBOL_TPREL); + dest = gen_rtx_LO_SUM (Pmode, tmp1, + mips_unspec_address (loc, SYMBOL_TPREL)); + break; + + default: + abort (); + } + + return dest; +} /* This function is used to implement LEGITIMIZE_ADDRESS. If *XLOC can be legitimized in a way that the generic machinery might not expect, @@ -1532,6 +1704,12 @@ mips_legitimize_address (rtx *xloc, enum machine_mode mode) { enum mips_symbol_type symbol_type; + if (mips_tls_operand_p (*xloc)) + { + *xloc = mips_legitimize_tls_address (*xloc); + return true; + } + /* See if the address can split into a high part and a LO_SUM. */ if (mips_symbolic_constant_p (*xloc, &symbol_type) && mips_symbolic_address_p (symbol_type, mode) @@ -1707,6 +1885,12 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src) return; } + if (mips_tls_operand_p (src)) + { + emit_move_insn (dest, mips_legitimize_tls_address (src)); + return; + } + /* See if the symbol can be split. For mips16, this is often worse than forcing it in the constant pool since it needs the single-register form of addiu or daddiu. */ @@ -4323,6 +4507,7 @@ override_options (void) GR_REGS); mips_char_to_class['e'] = LEA_REGS; mips_char_to_class['j'] = PIC_FN_ADDR_REG; + mips_char_to_class['v'] = V1_REG; mips_char_to_class['y'] = GR_REGS; mips_char_to_class['z'] = ST_REGS; mips_char_to_class['B'] = COP0_REGS; @@ -4511,6 +4696,22 @@ override_options (void) mips_lo_relocs[SYMBOL_GOTOFF_LOADGP] = "%lo(%neg(%gp_rel("; } + /* Thread-local relocation operators. */ + mips_lo_relocs[SYMBOL_TLSGD] = "%tlsgd("; + mips_lo_relocs[SYMBOL_TLSLDM] = "%tlsldm("; + mips_split_p[SYMBOL_DTPREL] = 1; + mips_hi_relocs[SYMBOL_DTPREL] = "%dtprel_hi("; + mips_lo_relocs[SYMBOL_DTPREL] = "%dtprel_lo("; + mips_lo_relocs[SYMBOL_GOTTPREL] = "%gottprel("; + mips_split_p[SYMBOL_TPREL] = 1; + mips_hi_relocs[SYMBOL_TPREL] = "%tprel_hi("; + mips_lo_relocs[SYMBOL_TPREL] = "%tprel_lo("; + + /* We don't have a thread pointer access instruction on MIPS16, or + appropriate TLS relocations. */ + if (TARGET_MIPS16) + targetm.have_tls = false; + /* Default to working around R4000 errata only if the processor was selected explicitly. */ if ((target_flags_explicit & MASK_FIX_R4000) == 0 diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 0417adda368..2d8695e2e57 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1714,6 +1714,7 @@ enum reg_class T_REG, /* mips16 T register ($24) */ M16_T_REGS, /* mips16 registers plus T register */ PIC_FN_ADDR_REG, /* SVR4 PIC function address register */ + V1_REG, /* Register $v1 ($3) used for TLS access. */ LEA_REGS, /* Every GPR except $25 */ GR_REGS, /* integer registers */ FP_REGS, /* floating point registers */ @@ -1752,6 +1753,7 @@ enum reg_class "T_REG", \ "M16_T_REGS", \ "PIC_FN_ADDR_REG", \ + "V1_REG", \ "LEA_REGS", \ "GR_REGS", \ "FP_REGS", \ @@ -1793,7 +1795,8 @@ enum reg_class { 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* mips16 T register */ \ { 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* mips16 and T regs */ \ { 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* SVR4 PIC function address register */ \ - { 0xfdffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* Every other GPR */ \ + { 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* only $v1 */ \ + { 0xfdffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* Every other GPR except $25 */ \ { 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* integer registers */ \ { 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* floating registers*/ \ { 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000 }, /* hi register */ \ @@ -1849,6 +1852,7 @@ extern const enum reg_class mips_regno_to_class[]; #define GR_REG_CLASS_P(CLASS) \ ((CLASS) == GR_REGS || (CLASS) == M16_REGS || (CLASS) == T_REG \ || (CLASS) == M16_T_REGS || (CLASS) == M16_NA_REGS \ + || (CLASS) == V1_REG \ || (CLASS) == PIC_FN_ADDR_REG || (CLASS) == LEA_REGS) /* This macro is also used later on in the file. */ @@ -1896,6 +1900,7 @@ extern const enum reg_class mips_regno_to_class[]; 'f' Floating point registers 'h' Hi register 'l' Lo register + 'v' $v1 only 'x' Multiply/divide registers 'z' FP Status register 'B' Cop0 register @@ -3031,3 +3036,7 @@ while (0) " TEXT_SECTION_ASM_OP); #endif #endif + +#ifndef HAVE_AS_TLS +#define HAVE_AS_TLS 0 +#endif diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 0a63df09c1a..9948e0627cd 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -45,6 +45,8 @@ (UNSPEC_LOAD_GOT 24) (UNSPEC_GP 25) (UNSPEC_MFHILO 26) + (UNSPEC_TLS_LDM 27) + (UNSPEC_TLS_GET_TP 28) (UNSPEC_ADDRESS_FIRST 100) @@ -3017,12 +3019,12 @@ beq\t%2,%.,1b\;\ ;; We could use MEMs, but an unspec gives more optimization ;; opportunities. -(define_insn "*load_got" +(define_insn "load_got" [(set (match_operand:P 0 "register_operand" "=d") (unspec:P [(match_operand:P 1 "register_operand" "d") (match_operand:P 2 "immediate_operand" "")] UNSPEC_LOAD_GOT))] - "TARGET_ABICALLS" + "" "\t%0,%R2(%1)" [(set_attr "type" "load") (set_attr "mode" "") @@ -5295,6 +5297,25 @@ beq\t%2,%.,1b\;\ [(match_dup 0)] { operands[0] = mips_rewrite_small_data (operands[0]); }) +; Thread-Local Storage + +; The TLS base pointer is acessed via "rdhwr $v1, $29". No current +; MIPS architecture defines this register, and no current +; implementation provides it; instead, any OS which supports TLS is +; expected to trap and emulate this instruction. rdhwr is part of the +; MIPS 32r2 specification, but we use it on any architecture because +; we expect it to be emulated. Use .set to force the assembler to +; accept it. + +(define_insn "tls_get_tp_" + [(set (match_operand:P 0 "register_operand" "=v") + (unspec:P [(const_int 0)] + UNSPEC_TLS_GET_TP))] + "HAVE_AS_TLS && !TARGET_MIPS16" + ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop" + [(set_attr "type" "unknown") + (set_attr "mode" "")]) + ; The MIPS Paired-Single Floating Point and MIPS-3D Instructions. (include "mips-ps-3d.md") diff --git a/gcc/configure b/gcc/configure index d69aa44ebcb..10ff30583be 100755 --- a/gcc/configure +++ b/gcc/configure @@ -13670,6 +13670,23 @@ foo: data8 25 tls_first_minor=13 tls_as_opt=--fatal-warnings ;; + mips*-*-*) + conftest_s=' + .section .tdata,"awT",@progbits +x: + .word 2 + .text + addiu $4, $28, %tlsgd(x) + addiu $4, $28, %tlsldm(x) + lui $4, %dtprel_hi(x) + addiu $4, $4, %dtprel_lo(x) + lw $4, %gottprel(x)($28) + lui $4, %tprel_hi(x) + addiu $4, $4, %tprel_lo(x)' + tls_first_major=2 + tls_first_minor=16 + tls_as_opt='-32 --fatal-warnings' + ;; powerpc-*-*) conftest_s=' .section ".tdata","awT",@progbits diff --git a/gcc/configure.ac b/gcc/configure.ac index 07e2c2f9043..b076ad20129 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -2353,6 +2353,23 @@ foo: data8 25 tls_first_minor=13 tls_as_opt=--fatal-warnings ;; + mips*-*-*) + conftest_s=' + .section .tdata,"awT",@progbits +x: + .word 2 + .text + addiu $4, $28, %tlsgd(x) + addiu $4, $28, %tlsldm(x) + lui $4, %dtprel_hi(x) + addiu $4, $4, %dtprel_lo(x) + lw $4, %gottprel(x)($28) + lui $4, %tprel_hi(x) + addiu $4, $4, %tprel_lo(x)' + tls_first_major=2 + tls_first_minor=16 + tls_as_opt='-32 --fatal-warnings' + ;; powerpc-*-*) conftest_s=' .section ".tdata","awT",@progbits -- 2.30.2