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:
parent
475c1d0989
commit
fd3cd001d5
7 changed files with 1044 additions and 65 deletions
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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); \
|
||||
|
|
|
@ -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
65
gcc/configure
vendored
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
:
|
||||
|
|
Loading…
Add table
Reference in a new issue