configure.in (HAVE_AS_TLS): Add powerpc and powerpc64 tests.
2003-05-12 Janis Johnson <janis187@us.ibm.com> Alan Modra <amodra@bigpond.net.au> Jakub Jelinek <jakub@redhat.com> * 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 <amodra@bigpond.net.au> Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r66742
This commit is contained in:
parent
6cfae22a6b
commit
c4501e6230
8 changed files with 766 additions and 52 deletions
|
@ -1,3 +1,46 @@
|
|||
2003-05-12 Janis Johnson <janis187@us.ibm.com>
|
||||
Alan Modra <amodra@bigpond.net.au>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* 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 <neil@cat.daikokuya.co.uk>
|
||||
|
||||
* Makefile.in (stage2_build, stage3_build, stage4_build):
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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")])
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
92
gcc/configure
vendored
92
gcc/configure
vendored
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue