configure.in (HAVE_AS_TLS): Add s390-*-* and s390x-*-* cases.

* configure.in (HAVE_AS_TLS): Add s390-*-* and s390x-*-* cases.
	* configure: Regenerate.

	* config/s390/s390-protos.h (tls_symbolic_operand): Add prototype.
	(tls_symbolic_reference_mentioned_p): Add prototype.
	(s390_tls_get_offset): Add prototype.
	(emit_pic_move): Remove prototype, replace by ...
	(emit_symbolic_move): .. this new prototype.

	* config/s390/s390.c (TARGET_HAVE_TLS): Conditionally define.
	(tls_model_chars): New global variable.
	(s390_encode_section_info): Encode TLS model.
	Use targetm.binds_local_p to check for local symbols.
	(s390_strip_name_encoding): New function.
	(TARGET_STRIP_NAME_ENCODING): Define.

	(get_thread_pointer): New function.
	(legitimize_tls_address): New function.
	(legitimize_address): Call it.
	(emit_pic_move): Remove, replace by ...
	(emit_symbolic_move): ... this new function.

	(larl_operand): Handle TLS operands.
	(legitimate_constant_p): Likewise.
	(s390_decompose_address): Likewise.
	(s390_cannot_force_const_mem): New function.
	(TARGET_CANNOT_FORCE_CONST_MEM): Define.

	(s390_output_symbolic_const): Handle TLS unspecs.
	(print_operand): New code 'J'.
	(machine_function): Add struct member 'some_ld_name'.
	(get_some_local_dynamic_name, get_some_local_dynamic_name_1): New.

	(enum s390_builtin): New type.
	(code_for_builtin_64, code_for_builtin_31): New global variables.
	(s390_init_builtins, s390_expand_builtin): New functions.
	(TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): Define.

	* config/s390/s390.h (TLS_SYMBOLIC_CONST): New macro.
	(ASM_OUTPUT_LABELREF): Define.
	(ASM_OUTPUT_SPECIAL_POOL_ENTRY): Handle TLS constants.

	* config/s390/s390.md: Define TLS UNSPEC constants.
	("movdi", "movsi"): Handle TLS operands.
	("get_tp_64", "get_tp_31", "set_tp_64", "set_tp_31"): New insns.
	("*tls_load_64", "*tls_load_31"): New insns.
	("call_value_tls", "call_value_tls_exp"): New expanders.
	("brasl_tls", "bras_tls", "basr_tls_64", "basr_tls_31",
	"bas_tls_64", "bas_tls_31"): New insns.

From-SVN: r61714
This commit is contained in:
Ulrich Weigand 2003-01-24 17:10:22 +00:00 committed by Ulrich Weigand
parent 475c1d0989
commit fd3cd001d5
7 changed files with 1044 additions and 65 deletions

View file

@ -1,3 +1,55 @@
2003-01-24 Ulrich Weigand <uweigand@de.ibm.com>
* configure.in (HAVE_AS_TLS): Add s390-*-* and s390x-*-* cases.
* configure: Regenerate.
* config/s390/s390-protos.h (tls_symbolic_operand): Add prototype.
(tls_symbolic_reference_mentioned_p): Add prototype.
(s390_tls_get_offset): Add prototype.
(emit_pic_move): Remove prototype, replace by ...
(emit_symbolic_move): .. this new prototype.
* config/s390/s390.c (TARGET_HAVE_TLS): Conditionally define.
(tls_model_chars): New global variable.
(s390_encode_section_info): Encode TLS model.
Use targetm.binds_local_p to check for local symbols.
(s390_strip_name_encoding): New function.
(TARGET_STRIP_NAME_ENCODING): Define.
(get_thread_pointer): New function.
(legitimize_tls_address): New function.
(legitimize_address): Call it.
(emit_pic_move): Remove, replace by ...
(emit_symbolic_move): ... this new function.
(larl_operand): Handle TLS operands.
(legitimate_constant_p): Likewise.
(s390_decompose_address): Likewise.
(s390_cannot_force_const_mem): New function.
(TARGET_CANNOT_FORCE_CONST_MEM): Define.
(s390_output_symbolic_const): Handle TLS unspecs.
(print_operand): New code 'J'.
(machine_function): Add struct member 'some_ld_name'.
(get_some_local_dynamic_name, get_some_local_dynamic_name_1): New.
(enum s390_builtin): New type.
(code_for_builtin_64, code_for_builtin_31): New global variables.
(s390_init_builtins, s390_expand_builtin): New functions.
(TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): Define.
* config/s390/s390.h (TLS_SYMBOLIC_CONST): New macro.
(ASM_OUTPUT_LABELREF): Define.
(ASM_OUTPUT_SPECIAL_POOL_ENTRY): Handle TLS constants.
* config/s390/s390.md: Define TLS UNSPEC constants.
("movdi", "movsi"): Handle TLS operands.
("get_tp_64", "get_tp_31", "set_tp_64", "set_tp_31"): New insns.
("*tls_load_64", "*tls_load_31"): New insns.
("call_value_tls", "call_value_tls_exp"): New expanders.
("brasl_tls", "bras_tls", "basr_tls_64", "basr_tls_31",
"bas_tls_64", "bas_tls_31"): New insns.
2003-01-24 Nathan Sidwell <nathan@codesourcery.com>
* config/rs6000/rs6000.c (rs6000_parse_abi_options): Make sure

View file

@ -43,11 +43,14 @@ extern int s390_single_hi PARAMS ((rtx, enum machine_mode, int));
extern int s390_extract_hi PARAMS ((rtx, enum machine_mode, int));
extern int s390_single_qi PARAMS ((rtx, enum machine_mode, int));
extern int s390_extract_qi PARAMS ((rtx, enum machine_mode, int));
extern int tls_symbolic_operand PARAMS ((rtx));
extern int s390_match_ccmode PARAMS ((rtx, enum machine_mode));
extern enum machine_mode s390_tm_ccmode PARAMS ((rtx, rtx, int));
extern enum machine_mode s390_select_ccmode PARAMS ((enum rtx_code, rtx, rtx));
extern int symbolic_reference_mentioned_p PARAMS ((rtx));
extern int tls_symbolic_reference_mentioned_p PARAMS ((rtx));
extern rtx s390_tls_get_offset PARAMS ((void));
extern int legitimate_la_operand_p PARAMS ((rtx));
extern int preferred_la_operand_p PARAMS ((rtx));
extern int legitimate_pic_operand_p PARAMS ((rtx));
@ -60,7 +63,7 @@ extern enum reg_class s390_preferred_reload_class PARAMS ((rtx, enum reg_class))
extern enum reg_class s390_secondary_input_reload_class PARAMS ((enum reg_class, enum machine_mode, rtx));
extern int s390_plus_operand PARAMS ((rtx, enum machine_mode));
extern void s390_expand_plus_operand PARAMS ((rtx, rtx, rtx));
extern void emit_pic_move PARAMS ((rtx *, enum machine_mode));
extern void emit_symbolic_move PARAMS ((rtx *));
extern void s390_load_address PARAMS ((rtx, rtx));
extern void s390_expand_movstr PARAMS ((rtx, rtx, rtx));
extern void s390_expand_clrstr PARAMS ((rtx, rtx));

View file

@ -54,6 +54,11 @@ static bool s390_assemble_integer PARAMS ((rtx, unsigned int, int));
static void s390_select_rtx_section PARAMS ((enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
static void s390_encode_section_info PARAMS ((tree, int));
static const char *s390_strip_name_encoding PARAMS ((const char *));
static bool s390_cannot_force_const_mem PARAMS ((rtx));
static void s390_init_builtins PARAMS ((void));
static rtx s390_expand_builtin PARAMS ((tree, rtx, rtx,
enum machine_mode, int));
static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
HOST_WIDE_INT, tree));
static enum attr_type s390_safe_attr_type PARAMS ((rtx));
@ -81,6 +86,20 @@ static int s390_use_dfa_pipeline_interface PARAMS ((void));
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING s390_strip_name_encoding
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS true
#endif
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS s390_init_builtins
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN s390_expand_builtin
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK s390_output_mi_thunk
@ -106,6 +125,9 @@ static int s390_sr_alias_set = 0;
emitted. */
rtx s390_compare_op0, s390_compare_op1;
/* The encoding characters for the four TLS models present in ELF. */
static char const tls_model_chars[] = " GLil";
/* Structure used to hold the components of a S/390 memory
address. A legitimate address on S/390 is of the general
form
@ -149,6 +171,9 @@ struct machine_function GTY(())
/* Size of stack frame. */
HOST_WIDE_INT frame_size;
/* Some local-dynamic TLS symbol name. */
const char *some_ld_name;
};
static int s390_match_ccmode_set PARAMS ((rtx, enum machine_mode));
@ -157,6 +182,10 @@ static const char *s390_branch_condition_mnemonic PARAMS ((rtx, int));
static int check_mode PARAMS ((rtx, enum machine_mode *));
static int general_s_operand PARAMS ((rtx, enum machine_mode, int));
static int s390_decompose_address PARAMS ((rtx, struct s390_address *));
static rtx get_thread_pointer PARAMS ((void));
static rtx legitimize_tls_address PARAMS ((rtx, rtx));
static const char *get_some_local_dynamic_name PARAMS ((void));
static int get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
static int reg_used_in_mem_p PARAMS ((int, rtx));
static int addr_generation_dependency_p PARAMS ((rtx, rtx));
static int s390_split_branches PARAMS ((rtx, bool *));
@ -1012,6 +1041,7 @@ larl_operand (op, mode)
if (GET_CODE (op) == LABEL_REF)
return 1;
if (GET_CODE (op) == SYMBOL_REF
&& !tls_symbolic_operand (op)
&& (!flag_pic || SYMBOL_REF_FLAG (op)
|| CONSTANT_POOL_ADDRESS_P (op)))
return 1;
@ -1034,17 +1064,22 @@ larl_operand (op, mode)
if (GET_CODE (op) == LABEL_REF)
return 1;
if (GET_CODE (op) == SYMBOL_REF
&& !tls_symbolic_operand (op)
&& (!flag_pic || SYMBOL_REF_FLAG (op)
|| CONSTANT_POOL_ADDRESS_P (op)))
return 1;
/* Now we must have a @GOTENT offset or @PLT stub. */
/* Now we must have a @GOTENT offset or @PLT stub
or an @INDNTPOFF TLS offset. */
if (GET_CODE (op) == UNSPEC
&& XINT (op, 1) == 111)
return 1;
if (GET_CODE (op) == UNSPEC
&& XINT (op, 1) == 113)
return 1;
if (GET_CODE (op) == UNSPEC
&& XINT (op, 1) == UNSPEC_INDNTPOFF)
return 1;
return 0;
}
@ -1193,6 +1228,23 @@ bras_sym_operand (op, mode)
return 0;
}
/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
otherwise return 0. */
int
tls_symbolic_operand (op)
register rtx op;
{
const char *symbol_str;
if (GET_CODE (op) != SYMBOL_REF)
return 0;
symbol_str = XSTR (op, 0);
if (symbol_str[0] != '%')
return 0;
return strchr (tls_model_chars, symbol_str[1]) - tls_model_chars;
}
/* Return true if OP is a load multiple operation. It is known to be a
PARALLEL and the first section will be tested.
@ -1352,6 +1404,37 @@ symbolic_reference_mentioned_p (op)
return 0;
}
/* Return true if OP contains a reference to a thread-local symbol. */
int
tls_symbolic_reference_mentioned_p (op)
rtx op;
{
register const char *fmt;
register int i;
if (GET_CODE (op) == SYMBOL_REF)
return tls_symbolic_operand (op);
fmt = GET_RTX_FORMAT (GET_CODE (op));
for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
{
if (fmt[i] == 'E')
{
register int j;
for (j = XVECLEN (op, i) - 1; j >= 0; j--)
if (tls_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
return 1;
}
else if (fmt[i] == 'e' && tls_symbolic_reference_mentioned_p (XEXP (op, i)))
return 1;
}
return 0;
}
/* Return true if OP is a legitimate general operand when
generating PIC code. It is given that flag_pic is on
@ -1366,7 +1449,7 @@ legitimate_pic_operand_p (op)
return 1;
/* Reject everything else; must be handled
via emit_pic_move. */
via emit_symbolic_move. */
return 0;
}
@ -1381,22 +1464,87 @@ legitimate_constant_p (op)
if (!SYMBOLIC_CONST (op))
return 1;
/* In the PIC case, symbolic constants must *not* be
forced into the literal pool. We accept them here,
so that they will be handled by emit_pic_move. */
if (flag_pic)
/* Accept immediate LARL operands. */
if (TARGET_64BIT && larl_operand (op, VOIDmode))
return 1;
/* Even in the non-PIC case, we can accept immediate
LARL operands here. */
if (TARGET_64BIT)
return larl_operand (op, VOIDmode);
/* Thread-local symbols are never legal constants. This is
so that emit_call knows that computing such addresses
might require a function call. */
if (TLS_SYMBOLIC_CONST (op))
return 0;
/* In the PIC case, symbolic constants must *not* be
forced into the literal pool. We accept them here,
so that they will be handled by emit_symbolic_move. */
if (flag_pic)
return 1;
/* All remaining non-PIC symbolic constants are
forced into the literal pool. */
return 0;
}
/* Determine if it's legal to put X into the constant pool. This
is not possible if X contains the address of a symbol that is
not constant (TLS) or not known at final link time (PIC). */
static bool
s390_cannot_force_const_mem (x)
rtx x;
{
switch (GET_CODE (x))
{
case CONST_INT:
case CONST_DOUBLE:
/* Accept all non-symbolic constants. */
return false;
case LABEL_REF:
/* Labels are OK iff we are non-PIC. */
return flag_pic != 0;
case SYMBOL_REF:
/* 'Naked' TLS symbol references are never OK,
non-TLS symbols are OK iff we are non-PIC. */
if (tls_symbolic_operand (x))
return true;
else
return flag_pic != 0;
case CONST:
return s390_cannot_force_const_mem (XEXP (x, 0));
case PLUS:
case MINUS:
return s390_cannot_force_const_mem (XEXP (x, 0))
|| s390_cannot_force_const_mem (XEXP (x, 1));
case UNSPEC:
switch (XINT (x, 1))
{
/* Only lt-relative or GOT-relative UNSPECs are OK. */
case 100:
case 104:
case 112:
case 114:
case UNSPEC_TLSGD:
case UNSPEC_TLSLDM:
case UNSPEC_NTPOFF:
case UNSPEC_DTPOFF:
case UNSPEC_GOTNTPOFF:
case UNSPEC_INDNTPOFF:
return false;
default:
return true;
}
break;
default:
abort ();
}
}
/* Returns true if the constant value OP is a legitimate general
operand during and after reload. The difference to
legitimate_constant_p is that this function will not accept
@ -1726,10 +1874,11 @@ s390_decompose_address (addr, out)
}
/* In the small-PIC case, the linker converts @GOT12
offsets to possible displacements. */
and @GOTNTPOFF offsets to possible displacements. */
else if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == UNSPEC
&& XINT (XEXP (disp, 0), 1) == 110)
&& (XINT (XEXP (disp, 0), 1) == 110
|| XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
{
if (flag_pic != 1)
return FALSE;
@ -1779,12 +1928,6 @@ s390_decompose_address (addr, out)
|| !CONSTANT_POOL_ADDRESS_P (disp))
return FALSE;
/* In 64-bit PIC mode we cannot accept symbolic
constants in the constant pool. */
if (TARGET_64BIT && flag_pic
&& SYMBOLIC_CONST (get_pool_constant (disp)))
return FALSE;
/* If we have an offset, make sure it does not
exceed the size of the constant pool entry. */
if (offset && offset >= GET_MODE_SIZE (get_pool_mode (disp)))
@ -2196,18 +2339,237 @@ legitimize_pic_address (orig, reg)
return new;
}
/* Load the thread pointer into a register. */
static rtx
get_thread_pointer ()
{
rtx tp;
tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
tp = force_reg (Pmode, tp);
mark_reg_pointer (tp, BITS_PER_WORD);
return tp;
}
/* Construct the SYMBOL_REF for the tls_get_offset function. */
static GTY(()) rtx s390_tls_symbol;
rtx
s390_tls_get_offset ()
{
if (!s390_tls_symbol)
s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
return s390_tls_symbol;
}
/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
this (thread-local) address. REG may be used as temporary. */
static rtx
legitimize_tls_address (addr, reg)
rtx addr;
rtx reg;
{
rtx new, tls_call, temp, base, r2, insn;
if (GET_CODE (addr) == SYMBOL_REF)
switch (tls_symbolic_operand (addr))
{
case TLS_MODEL_GLOBAL_DYNAMIC:
start_sequence ();
r2 = gen_rtx_REG (Pmode, 2);
tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLSGD);
new = gen_rtx_CONST (Pmode, tls_call);
new = force_const_mem (Pmode, new);
emit_move_insn (r2, new);
emit_call_insn (gen_call_value_tls (r2, tls_call));
insn = get_insns ();
end_sequence ();
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
temp = gen_reg_rtx (Pmode);
emit_libcall_block (insn, temp, r2, new);
new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
if (reg != 0)
{
s390_load_address (reg, new);
new = reg;
}
break;
case TLS_MODEL_LOCAL_DYNAMIC:
start_sequence ();
r2 = gen_rtx_REG (Pmode, 2);
tls_call = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM);
new = gen_rtx_CONST (Pmode, tls_call);
new = force_const_mem (Pmode, new);
emit_move_insn (r2, new);
emit_call_insn (gen_call_value_tls (r2, tls_call));
insn = get_insns ();
end_sequence ();
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TLSLDM_NTPOFF);
temp = gen_reg_rtx (Pmode);
emit_libcall_block (insn, temp, r2, new);
new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
base = gen_reg_rtx (Pmode);
s390_load_address (base, new);
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_DTPOFF);
new = gen_rtx_CONST (Pmode, new);
new = force_const_mem (Pmode, new);
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
new = gen_rtx_PLUS (Pmode, base, temp);
if (reg != 0)
{
s390_load_address (reg, new);
new = reg;
}
break;
case TLS_MODEL_INITIAL_EXEC:
if (flag_pic == 1)
{
/* Assume GOT offset < 4k. This is handled the same way
in both 31- and 64-bit code. */
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
new = gen_rtx_CONST (Pmode, new);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
new = gen_rtx_MEM (Pmode, new);
RTX_UNCHANGING_P (new) = 1;
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
}
else if (TARGET_64BIT)
{
/* If the GOT offset might be >= 4k, we determine the position
of the GOT entry via a PC-relative LARL. */
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
new = gen_rtx_CONST (Pmode, new);
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
new = gen_rtx_MEM (Pmode, temp);
RTX_UNCHANGING_P (new) = 1;
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
}
else if (flag_pic)
{
/* If the GOT offset might be >= 4k, we have to load it
from the literal pool. */
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTNTPOFF);
new = gen_rtx_CONST (Pmode, new);
new = force_const_mem (Pmode, new);
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
new = gen_rtx_MEM (Pmode, new);
RTX_UNCHANGING_P (new) = 1;
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
temp = gen_reg_rtx (Pmode);
emit_insn (gen_rtx_SET (Pmode, temp, new));
}
else
{
/* In position-dependent code, load the absolute address of
the GOT entry from the literal pool. */
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_INDNTPOFF);
new = gen_rtx_CONST (Pmode, new);
new = force_const_mem (Pmode, new);
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
new = temp;
new = gen_rtx_MEM (Pmode, new);
RTX_UNCHANGING_P (new) = 1;
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, new, addr), UNSPEC_TLS_LOAD);
temp = gen_reg_rtx (Pmode);
emit_insn (gen_rtx_SET (Pmode, temp, new));
}
new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
if (reg != 0)
{
s390_load_address (reg, new);
new = reg;
}
break;
case TLS_MODEL_LOCAL_EXEC:
new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_NTPOFF);
new = gen_rtx_CONST (Pmode, new);
new = force_const_mem (Pmode, new);
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
new = gen_rtx_PLUS (Pmode, get_thread_pointer (), temp);
if (reg != 0)
{
s390_load_address (reg, new);
new = reg;
}
break;
default:
abort ();
}
else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == UNSPEC)
{
switch (XINT (XEXP (addr, 0), 1))
{
case UNSPEC_INDNTPOFF:
if (TARGET_64BIT)
new = addr;
else
abort ();
break;
default:
abort ();
}
}
else
abort (); /* for now ... */
return new;
}
/* Emit insns to move operands[1] into operands[0]. */
void
emit_pic_move (operands, mode)
emit_symbolic_move (operands)
rtx *operands;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (Pmode, operands[1]);
else
else if (TLS_SYMBOLIC_CONST (operands[1]))
operands[1] = legitimize_tls_address (operands[1], temp);
else if (flag_pic)
operands[1] = legitimize_pic_address (operands[1], temp);
}
@ -2230,7 +2592,14 @@ legitimize_address (x, oldx, mode)
{
rtx constant_term = const0_rtx;
if (flag_pic)
if (TLS_SYMBOLIC_CONST (x))
{
x = legitimize_tls_address (x, 0);
if (legitimate_address_p (mode, x, FALSE))
return x;
}
else if (flag_pic)
{
if (SYMBOLIC_CONST (x)
|| (GET_CODE (x) == PLUS
@ -2642,6 +3011,48 @@ s390_simplify_dwarf_addr (orig_x)
return orig_x;
}
/* Locate some local-dynamic symbol still in use by this function
so that we can print its name in local-dynamic base patterns. */
static const char *
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), get_some_local_dynamic_name_1, 0))
return cfun->machine->some_ld_name;
abort ();
}
static int
get_some_local_dynamic_name_1 (px, data)
rtx *px;
void *data ATTRIBUTE_UNUSED;
{
rtx x = *px;
if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
{
x = get_pool_constant (x);
return for_each_rtx (&x, get_some_local_dynamic_name_1, 0);
}
if (GET_CODE (x) == SYMBOL_REF
&& tls_symbolic_operand (x) == TLS_MODEL_LOCAL_DYNAMIC)
{
cfun->machine->some_ld_name = XSTR (x, 0);
return 1;
}
return 0;
}
/* Output symbolic constant X in assembler syntax to
stdio stream FILE. */
@ -2714,6 +3125,30 @@ s390_output_symbolic_const (file, x)
fprintf (file, "@PLT-");
s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
break;
case UNSPEC_TLSGD:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@TLSGD");
break;
case UNSPEC_TLSLDM:
assemble_name (file, get_some_local_dynamic_name ());
fprintf (file, "@TLSLDM");
break;
case UNSPEC_DTPOFF:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@DTPOFF");
break;
case UNSPEC_NTPOFF:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@NTPOFF");
break;
case UNSPEC_GOTNTPOFF:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@GOTNTPOFF");
break;
case UNSPEC_INDNTPOFF:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@INDNTPOFF");
break;
default:
output_operand_lossage ("invalid UNSPEC as operand (2)");
break;
@ -2759,6 +3194,7 @@ print_operand_address (file, addr)
'C': print opcode suffix for branch condition.
'D': print opcode suffix for inverse branch condition.
'J': print tls_load/tls_gdcall/tls_ldcall suffix
'O': print only the displacement of a memory reference.
'R': print only the base register of a memory reference.
'N': print the second word of a DImode operand.
@ -2784,6 +3220,26 @@ print_operand (file, x, code)
fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
return;
case 'J':
if (GET_CODE (x) == SYMBOL_REF)
{
fprintf (file, "%s", ":tls_load:");
output_addr_const (file, x);
}
else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD)
{
fprintf (file, "%s", ":tls_gdcall:");
output_addr_const (file, XVECEXP (x, 0, 0));
}
else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM)
{
fprintf (file, "%s", ":tls_ldcall:");
assemble_name (file, get_some_local_dynamic_name ());
}
else
abort ();
return;
case 'O':
{
struct s390_address ad;
@ -5530,6 +5986,134 @@ s390_va_arg (valist, type)
}
/* Builtins. */
enum s390_builtin
{
S390_BUILTIN_THREAD_POINTER,
S390_BUILTIN_SET_THREAD_POINTER,
S390_BUILTIN_max
};
static unsigned int const code_for_builtin_64[S390_BUILTIN_max] = {
CODE_FOR_get_tp_64,
CODE_FOR_set_tp_64
};
static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
CODE_FOR_get_tp_31,
CODE_FOR_set_tp_31
};
static void
s390_init_builtins ()
{
tree ftype;
ftype = build_function_type (ptr_type_node, void_list_node);
builtin_function ("__builtin_thread_pointer", ftype,
S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
NULL, NULL_TREE);
ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
builtin_function ("__builtin_set_thread_pointer", ftype,
S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
NULL, NULL_TREE);
}
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
(and in mode MODE if that's convenient).
SUBTARGET may be used as the target for computing one of EXP's operands.
IGNORE is nonzero if the value is to be ignored. */
static rtx
s390_expand_builtin (exp, target, subtarget, mode, ignore)
tree exp;
rtx target;
rtx subtarget ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
int ignore ATTRIBUTE_UNUSED;
{
#define MAX_ARGS 2
unsigned int const *code_for_builtin =
TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
tree arglist = TREE_OPERAND (exp, 1);
enum insn_code icode;
rtx op[MAX_ARGS], pat;
int arity;
bool nonvoid;
if (fcode >= S390_BUILTIN_max)
internal_error ("bad builtin fcode");
icode = code_for_builtin[fcode];
if (icode == 0)
internal_error ("bad builtin fcode");
nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
for (arglist = TREE_OPERAND (exp, 1), arity = 0;
arglist;
arglist = TREE_CHAIN (arglist), arity++)
{
const struct insn_operand_data *insn_op;
tree arg = TREE_VALUE (arglist);
if (arg == error_mark_node)
return NULL_RTX;
if (arity > MAX_ARGS)
return NULL_RTX;
insn_op = &insn_data[icode].operand[arity + nonvoid];
op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, 0);
if (!(*insn_op->predicate) (op[arity], insn_op->mode))
op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
}
if (nonvoid)
{
enum machine_mode tmode = insn_data[icode].operand[0].mode;
if (!target
|| GET_MODE (target) != tmode
|| !(*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
}
switch (arity)
{
case 0:
pat = GEN_FCN (icode) (target);
break;
case 1:
if (nonvoid)
pat = GEN_FCN (icode) (target, op[0]);
else
pat = GEN_FCN (icode) (op[0]);
break;
case 2:
pat = GEN_FCN (icode) (target, op[0], op[1]);
break;
default:
abort ();
}
if (!pat)
return NULL_RTX;
emit_insn (pat);
if (nonvoid)
return target;
else
return const0_rtx;
}
/* Output assembly code for the trampoline template to
stdio stream FILE.
@ -5689,28 +6273,85 @@ s390_select_rtx_section (mode, x, align)
function_section (current_function_decl);
}
/* If using PIC, mark a SYMBOL_REF for a non-global symbol so that we
may access it directly in the GOT. */
/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
into its name and SYMBOL_REF_FLAG. */
static void
s390_encode_section_info (decl, first)
tree decl;
int first ATTRIBUTE_UNUSED;
{
if (flag_pic)
{
rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
? TREE_CST_RTL (decl) : DECL_RTL (decl));
bool local_p = (*targetm.binds_local_p) (decl);
rtx rtl, symbol;
if (GET_CODE (rtl) == MEM)
rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
if (GET_CODE (rtl) != MEM)
return;
symbol = XEXP (rtl, 0);
if (GET_CODE (symbol) != SYMBOL_REF)
return;
/* When using PIC, SYMBOL_REF_FLAG marks non-global symbols
that can be accessed directly. */
if (flag_pic)
SYMBOL_REF_FLAG (symbol) = local_p;
/* Encode thread-local data with %[GLil] for "global dynamic",
"local dynamic", "initial exec" or "local exec" TLS models,
respectively. */
if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
{
const char *symbol_str = XSTR (symbol, 0);
char *newstr;
size_t len;
enum tls_model kind = decl_tls_model (decl);
if (!flag_pic)
{
SYMBOL_REF_FLAG (XEXP (rtl, 0))
= (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
|| ! TREE_PUBLIC (decl));
/* We don't allow non-pic code for shared libraries,
so don't generate GD/LD TLS models for non-pic code. */
switch (kind)
{
case TLS_MODEL_GLOBAL_DYNAMIC:
kind = TLS_MODEL_INITIAL_EXEC; break;
case TLS_MODEL_LOCAL_DYNAMIC:
kind = TLS_MODEL_LOCAL_EXEC; break;
default:
break;
}
}
if (symbol_str[0] == '%')
{
if (symbol_str[1] == tls_model_chars[kind])
return;
symbol_str += 2;
}
len = strlen (symbol_str) + 1;
newstr = alloca (len + 2);
newstr[0] = '%';
newstr[1] = tls_model_chars[kind];
memcpy (newstr + 2, symbol_str, len);
XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
}
}
/* Undo the above when printing symbol names. */
static const char *
s390_strip_name_encoding (str)
const char *str;
{
if (str[0] == '%')
str += 2;
if (str[0] == '*')
str += 1;
return str;
}
/* Output thunk to FILE that implements a C++ virtual function call (with
multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment

View file

@ -793,6 +793,10 @@ CUMULATIVE_ARGS;
|| GET_CODE (X) == LABEL_REF \
|| (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
#define TLS_SYMBOLIC_CONST(X) \
((GET_CODE (X) == SYMBOL_REF && tls_symbolic_operand (X)) \
|| (GET_CODE (X) == CONST && tls_symbolic_reference_mentioned_p (X)))
/* Condition codes. */
@ -970,6 +974,10 @@ extern int flag_pic;
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
fprintf ((FILE), "\t.set\t.,.+%u\n", (SIZE))
/* Output a reference to a user-level label named NAME. */
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
asm_fprintf ((FILE), "%U%s", (*targetm.strip_name_encoding) (NAME))
/* The LOCAL_LABEL_PREFIX variable is used by dbxelf.h. */
#define LOCAL_LABEL_PREFIX "."
@ -1051,10 +1059,9 @@ extern int s390_nr_constants;
\
case MODE_INT: \
case MODE_PARTIAL_INT: \
if (flag_pic \
&& (GET_CODE (EXP) == CONST \
|| GET_CODE (EXP) == SYMBOL_REF \
|| GET_CODE (EXP) == LABEL_REF )) \
if (GET_CODE (EXP) == CONST \
|| GET_CODE (EXP) == SYMBOL_REF \
|| GET_CODE (EXP) == LABEL_REF) \
{ \
fputs (integer_asm_op (UNITS_PER_WORD, TRUE), FILE); \
s390_output_symbolic_const (FILE, EXP); \

View file

@ -44,6 +44,35 @@
;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
;;
;;
;; UNSPEC usage
;;
(define_constants
[; TLS relocation specifiers
(UNSPEC_TLSGD 500)
(UNSPEC_TLSLDM 501)
(UNSPEC_NTPOFF 502)
(UNSPEC_DTPOFF 503)
(UNSPEC_GOTNTPOFF 504)
(UNSPEC_INDNTPOFF 505)
; TLS support
(UNSPEC_TP 510)
(UNSPEC_TLSLDM_NTPOFF 511)
(UNSPEC_TLS_LOAD 512)
])
;;
;; UNSPEC_VOLATILE usage
;;
(define_constants
[; TLS support
(UNSPECV_SET_TP 500)
])
;; Processor type. This attribute must exactly match the processor_type
;; enumeration in s390.h.
@ -938,18 +967,15 @@
; movdi instruction pattern(s).
;
;; If generating PIC code and operands[1] is a symbolic CONST, emit a
;; move to get the address of the symbolic object from the GOT.
(define_expand "movdi"
[(set (match_operand:DI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" ""))]
""
"
{
/* Handle PIC symbolic constants. */
if (TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1]))
emit_pic_move (operands, DImode);
/* Handle symbolic constants. */
if (TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
emit_symbolic_move (operands);
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
@ -1099,18 +1125,15 @@
; movsi instruction pattern(s).
;
;; If generating PIC code and operands[1] is a symbolic CONST, emit a
;; move to get the address of the symbolic object from the GOT.
(define_expand "movsi"
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
""
"
{
/* Handle PIC symbolic constants. */
if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1]))
emit_pic_move (operands, SImode);
/* Handle symbolic constants. */
if (!TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
emit_symbolic_move (operands);
/* expr.c tries to load an effective address using
force_reg. This fails because we don't have a
@ -6461,6 +6484,189 @@
(set_attr "type" "jsr")])
;;
;;- Thread-local storage support.
;;
(define_insn "get_tp_64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=??d,Q")
(unspec:DI [(const_int 0)] UNSPEC_TP))]
"TARGET_64BIT"
"@
ear\\t%0,%%a0\;sllg\\t%0,%0,32\;ear\\t%0,%%a1
stam\\t%%a0,%%a1,%0"
[(set_attr "op_type" "NN,RS")
(set_attr "atype" "reg,*")
(set_attr "type" "o3,*")
(set_attr "length" "14,*")])
(define_insn "get_tp_31"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,Q")
(unspec:SI [(const_int 0)] UNSPEC_TP))]
"!TARGET_64BIT"
"@
ear\\t%0,%%a0
stam\\t%%a0,%%a0,%0"
[(set_attr "op_type" "RRE,RS")])
(define_insn "set_tp_64"
[(unspec_volatile [(match_operand:DI 0 "general_operand" "??d,Q")] UNSPECV_SET_TP)
(clobber (match_scratch:SI 1 "=d,X"))]
"TARGET_64BIT"
"@
sar\\t%%a1,%0\;srlg\\t%1,%0,32\;sar\\t%%a0,%1
lam\\t%%a0,%%a1,%0"
[(set_attr "op_type" "NN,RS")
(set_attr "atype" "reg,*")
(set_attr "type" "o3,*")
(set_attr "length" "14,*")])
(define_insn "set_tp_31"
[(unspec_volatile [(match_operand:SI 0 "general_operand" "d,Q")] UNSPECV_SET_TP)]
"!TARGET_64BIT"
"@
sar\\t%%a0,%0
lam\\t%%a0,%%a0,%0"
[(set_attr "op_type" "RRE,RS")])
(define_insn "*tls_load_64"
[(set (match_operand:DI 0 "register_operand" "=d")
(unspec:DI [(match_operand:DI 1 "memory_operand" "m")
(match_operand:DI 2 "" "")]
UNSPEC_TLS_LOAD))]
"TARGET_64BIT"
"lg\\t%0,%1%J2"
[(set_attr "op_type" "RXE")])
(define_insn "*tls_load_31"
[(set (match_operand:SI 0 "register_operand" "=d")
(unspec:SI [(match_operand:SI 1 "memory_operand" "m")
(match_operand:SI 2 "" "")]
UNSPEC_TLS_LOAD))]
"!TARGET_64BIT"
"l\\t%0,%1%J2"
[(set_attr "op_type" "RX")])
(define_expand "call_value_tls"
[(set (match_operand 0 "" "")
(call (const_int 0) (const_int 0)))
(use (match_operand 1 "" ""))]
""
"
{
rtx insn, sym;
if (!flag_pic)
abort ();
sym = s390_tls_get_offset ();
sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
sym = gen_rtx_CONST (Pmode, sym);
/* Unless we can use the bras(l) insn, force the
routine address into a register. */
if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
{
rtx target = gen_reg_rtx (Pmode);
emit_move_insn (target, sym);
sym = target;
}
sym = gen_rtx_MEM (QImode, sym);
/* Emit insn. */
insn = emit_call_insn (
gen_call_value_tls_exp (operands[0], sym, const0_rtx,
gen_rtx_REG (Pmode, RETURN_REGNUM),
operands[1]));
/* The calling convention of __tls_get_offset uses the
GOT register implicitly. */
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), operands[0]);
CONST_OR_PURE_CALL_P (insn) = 1;
DONE;
}")
(define_expand "call_value_tls_exp"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand 1 "" "")
(match_operand 2 "" "")))
(clobber (match_operand 3 "" ""))
(use (match_operand 4 "" ""))])]
""
"")
(define_insn "brasl_tls"
[(set (match_operand 0 "register_operand" "=df")
(call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
(match_operand:SI 2 "const_int_operand" "n")))
(clobber (match_operand:DI 3 "register_operand" "=r"))
(use (match_operand:DI 4 "" ""))]
"TARGET_64BIT"
"brasl\\t%3,%1%J4"
[(set_attr "op_type" "RIL")
(set_attr "type" "jsr")])
(define_insn "bras_tls"
[(set (match_operand 0 "register_operand" "=df")
(call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
(match_operand:SI 2 "const_int_operand" "n")))
(clobber (match_operand:SI 3 "register_operand" "=r"))
(use (match_operand:SI 4 "" ""))]
"TARGET_SMALL_EXEC"
"bras\\t%3,%1%J4"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
(define_insn "basr_tls_64"
[(set (match_operand 0 "register_operand" "=df")
(call (mem:QI (match_operand:DI 1 "register_operand" "a"))
(match_operand:SI 2 "const_int_operand" "n")))
(clobber (match_operand:DI 3 "register_operand" "=r"))
(use (match_operand:DI 4 "" ""))]
"TARGET_64BIT"
"basr\\t%3,%1%J4"
[(set_attr "op_type" "RR")
(set_attr "type" "jsr")])
(define_insn "basr_tls_31"
[(set (match_operand 0 "register_operand" "=df")
(call (mem:QI (match_operand:SI 1 "register_operand" "a"))
(match_operand:SI 2 "const_int_operand" "n")))
(clobber (match_operand:SI 3 "register_operand" "=r"))
(use (match_operand:SI 4 "" ""))]
"!TARGET_64BIT"
"basr\\t%3,%1%J4"
[(set_attr "op_type" "RR")
(set_attr "type" "jsr")
(set_attr "atype" "agen")])
(define_insn "bas_tls_64"
[(set (match_operand 0 "register_operand" "=df")
(call (mem:QI (match_operand:QI 1 "address_operand" "p"))
(match_operand:SI 2 "const_int_operand" "n")))
(clobber (match_operand:DI 3 "register_operand" "=r"))
(use (match_operand:DI 4 "" ""))]
"TARGET_64BIT"
"bas\\t%3,%a1%J4"
[(set_attr "op_type" "RX")
(set_attr "type" "jsr")
(set_attr "atype" "agen")])
(define_insn "bas_tls_31"
[(set (match_operand 0 "register_operand" "=df")
(call (mem:QI (match_operand:QI 1 "address_operand" "p"))
(match_operand:SI 2 "const_int_operand" "n")))
(clobber (match_operand:SI 3 "register_operand" "=r"))
(use (match_operand:SI 4 "" ""))]
"!TARGET_64BIT"
"bas\\t%3,%a1%J4"
[(set_attr "op_type" "RX")
(set_attr "type" "jsr")
(set_attr "atype" "agen")])
;;
;;- Miscellaneous instructions.
;;

65
gcc/configure vendored
View file

@ -7942,6 +7942,41 @@ foo: data8 25
tls_first_major=2
tls_first_minor=13
;;
s390-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
.long foo@TLSGD
.long foo@TLSLDM
.long foo@DTPOFF
.long foo@NTPOFF
.long foo@GOTNTPOFF
.long foo@INDNTPOFF
l %r1,foo@GOTNTPOFF(%r12)
l %r1,0(%r1):tls_load:foo
bas %r14,0(%r1,%r13):tls_gdcall:foo
bas %r14,0(%r1,%r13):tls_ldcall:foo'
tls_first_major=2
tls_first_minor=14
;;
s390x-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
.quad foo@TLSGD
.quad foo@TLSLDM
.quad foo@DTPOFF
.quad foo@NTPOFF
.quad foo@GOTNTPOFF
lg %r1,foo@GOTNTPOFF(%r12)
larl %r1,foo@INDNTPOFF
brasl %r14,__tls_get_offset@PLT:tls_gdcall:foo
brasl %r14,__tls_get_offset@PLT:tls_ldcall:foo'
tls_first_major=2
tls_first_minor=14
;;
esac
if test -z "$tls_first_major"; then
:
@ -7972,7 +8007,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:7976: checking assembler supports explicit relocations" >&5
echo "configure:8011: 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
@ -8022,7 +8057,7 @@ EOF
;;
sparc*-*-*)
echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
echo "configure:8026: checking assembler .register pseudo-op support" >&5
echo "configure:8061: 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
@ -8050,7 +8085,7 @@ EOF
fi
echo $ac_n "checking assembler supports -relax""... $ac_c" 1>&6
echo "configure:8054: checking assembler supports -relax" >&5
echo "configure:8089: 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
@ -8078,7 +8113,7 @@ EOF
fi
echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
echo "configure:8082: checking assembler and linker support unaligned pc related relocs" >&5
echo "configure:8117: 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
@ -8105,7 +8140,7 @@ EOF
fi
echo $ac_n "checking assembler and linker support unaligned pc related relocs against hidden symbols""... $ac_c" 1>&6
echo "configure:8109: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5
echo "configure:8144: 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
@ -8145,7 +8180,7 @@ EOF
fi
echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
echo "configure:8149: checking for assembler offsetable %lo() support" >&5
echo "configure:8184: 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
@ -8184,7 +8219,7 @@ EOF
i[34567]86-*-* | x86_64-*-*)
echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
echo "configure:8188: checking assembler instructions" >&5
echo "configure:8223: checking assembler instructions" >&5
gcc_cv_as_instructions=
if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 9 -o "$gcc_cv_gas_major_version" -gt 2; then
@ -8211,7 +8246,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:8215: checking assembler GOTOFF in data directives" >&5
echo "configure:8250: checking assembler GOTOFF in data directives" >&5
gcc_cv_as_gotoff_in_data=no
if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x
then
@ -8241,7 +8276,7 @@ EOF
esac
echo $ac_n "checking assembler dwarf2 debug_line support""... $ac_c" 1>&6
echo "configure:8245: checking assembler dwarf2 debug_line support" >&5
echo "configure:8280: 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
@ -8298,7 +8333,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:8302: checking assembler --gdwarf2 support" >&5
echo "configure:8337: checking assembler --gdwarf2 support" >&5
gcc_cv_as_gdwarf2_flag=no
if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x;
then
@ -8327,7 +8362,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:8331: checking assembler --gstabs support" >&5
echo "configure:8366: checking assembler --gstabs support" >&5
gcc_cv_as_gstabs_flag=no
if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x;
then
@ -8355,7 +8390,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:8359: checking linker read-only and read-write section mixing" >&5
echo "configure:8394: checking linker read-only and read-write section mixing" >&5
gcc_cv_ld_ro_rw_mix=unknown
if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; 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
@ -8393,7 +8428,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:8397: checking linker PT_GNU_EH_FRAME support" >&5
echo "configure:8432: checking linker PT_GNU_EH_FRAME support" >&5
gcc_cv_ld_eh_frame_hdr=no
if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; 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
@ -8417,7 +8452,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:8421: checking whether libgloss uses STARTUP directives consistently" >&5
echo "configure:8456: 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
@ -8621,7 +8656,7 @@ fi
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
echo "configure:8625: checking whether to enable maintainer-specific portions of Makefiles" >&5
echo "configure:8660: 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"

View file

@ -1944,6 +1944,41 @@ foo: data8 25
tls_first_major=2
tls_first_minor=13
;;
s390-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
.long foo@TLSGD
.long foo@TLSLDM
.long foo@DTPOFF
.long foo@NTPOFF
.long foo@GOTNTPOFF
.long foo@INDNTPOFF
l %r1,foo@GOTNTPOFF(%r12)
l %r1,0(%r1):tls_load:foo
bas %r14,0(%r1,%r13):tls_gdcall:foo
bas %r14,0(%r1,%r13):tls_ldcall:foo'
tls_first_major=2
tls_first_minor=14
;;
s390x-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
.quad foo@TLSGD
.quad foo@TLSLDM
.quad foo@DTPOFF
.quad foo@NTPOFF
.quad foo@GOTNTPOFF
lg %r1,foo@GOTNTPOFF(%r12)
larl %r1,foo@INDNTPOFF
brasl %r14,__tls_get_offset@PLT:tls_gdcall:foo
brasl %r14,__tls_get_offset@PLT:tls_ldcall:foo'
tls_first_major=2
tls_first_minor=14
;;
esac
if test -z "$tls_first_major"; then
: