configure.in (HAVE_AS_TLS): New test.
* configure.in (HAVE_AS_TLS): New test. * config.in, configure: Rebuild. * config/i386/i386.c (TARGET_HAVE_TLS): Set if HAVE_AS_TLS. (ix86_tls_dialect_string, ix86_tls_dialect): New. (override_options): Set it. (tls_model_chars, tls_symbolic_operand): New. (tls_symbolic_operand_1, global_dynamic_symbolic_operand): New. (local_dynamic_symbolic_operand, initial_exec_symbolic_operand): New. (local_exec_symbolic_operand): New. (get_pic_label_name): Merge into output_set_got. (ix86_asm_file_end): Emit pic_label_name if defined. (legitimate_constant_p, constant_address_p): New. (legitimate_pic_operand_p): New. (legitimate_pic_address_disp_p): Handle GOTTPOFF, NTPOFF, DTPOFF. (legitimate_address_p): Likewise. (ix86_encode_section_info): Rename from i386_; handle tls decls. (ix86_strip_name_encoding): New. (get_thread_pointer): New. (legitimize_address): Handle tls symbols. (output_pic_addr_const): Handle GOTTPOFF, TPOFF, NTPOFF, DTPOFF. Remove UNSPEC_PLT. (struct machine_function): Add some_ld_name. (get_some_local_dynamic_name, get_some_local_dynamic_name_1): Set it. (print_operand) [&]: Use it. Handle UNSPEC_TP. (output_addr_const_extra): New. (maybe_get_pool_constant): New. (ix86_split_to_parts): Use it. (ix86_expand_move): Handle tls symbols. (ix86_tls_get_addr): New. * config/i386/i386.h (TARGET_GNU_TLS, TARGET_SUN_TLS): New. (TARGET_OPTIONS): Add tls-dialect. (CONSTANT_ADDRESS_P): Use new out-of-line function. (LEGITIMATE_CONSTANT_P): Likewise. (LEGITIMATE_PIC_OPERAND_P): Likewise. (TARGET_STRIP_NAME_ENCODING): New. (ASM_OUTPUT_LABELREF): New. (PRINT_OPERAND_PUNCT_VALID_P): Add '&'. (OUTPUT_ADDR_CONST_EXTRA): New. (PREDICATE_CODES): Update. (ix86_tls_dialect, ix86_tls_dialect_string): New. * config/i386/i386.md: Regroup and renumber unspec constants. (tls_global_dynamic_gnu, tls_global_dynamic_sun): New. (tls_local_dynamic_base_gnu, tls_local_dynamic_base_sun): New. (tls_global_dynamic, tls_local_dynamic_base): New. (tls_local_dynamic_once): New. * config/i386/i386-protos.h: Update. From-SVN: r53812
This commit is contained in:
parent
821e35ba25
commit
f996902d09
@ -1,3 +1,52 @@
|
||||
2002-05-23 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* configure.in (HAVE_AS_TLS): New test.
|
||||
* config.in, configure: Rebuild.
|
||||
* config/i386/i386.c (TARGET_HAVE_TLS): Set if HAVE_AS_TLS.
|
||||
(ix86_tls_dialect_string, ix86_tls_dialect): New.
|
||||
(override_options): Set it.
|
||||
(tls_model_chars, tls_symbolic_operand): New.
|
||||
(tls_symbolic_operand_1, global_dynamic_symbolic_operand): New.
|
||||
(local_dynamic_symbolic_operand, initial_exec_symbolic_operand): New.
|
||||
(local_exec_symbolic_operand): New.
|
||||
(get_pic_label_name): Merge into output_set_got.
|
||||
(ix86_asm_file_end): Emit pic_label_name if defined.
|
||||
(legitimate_constant_p, constant_address_p): New.
|
||||
(legitimate_pic_operand_p): New.
|
||||
(legitimate_pic_address_disp_p): Handle GOTTPOFF, NTPOFF, DTPOFF.
|
||||
(legitimate_address_p): Likewise.
|
||||
(ix86_encode_section_info): Rename from i386_; handle tls decls.
|
||||
(ix86_strip_name_encoding): New.
|
||||
(get_thread_pointer): New.
|
||||
(legitimize_address): Handle tls symbols.
|
||||
(output_pic_addr_const): Handle GOTTPOFF, TPOFF, NTPOFF, DTPOFF.
|
||||
Remove UNSPEC_PLT.
|
||||
(struct machine_function): Add some_ld_name.
|
||||
(get_some_local_dynamic_name, get_some_local_dynamic_name_1): Set it.
|
||||
(print_operand) [&]: Use it. Handle UNSPEC_TP.
|
||||
(output_addr_const_extra): New.
|
||||
(maybe_get_pool_constant): New.
|
||||
(ix86_split_to_parts): Use it.
|
||||
(ix86_expand_move): Handle tls symbols.
|
||||
(ix86_tls_get_addr): New.
|
||||
* config/i386/i386.h (TARGET_GNU_TLS, TARGET_SUN_TLS): New.
|
||||
(TARGET_OPTIONS): Add tls-dialect.
|
||||
(CONSTANT_ADDRESS_P): Use new out-of-line function.
|
||||
(LEGITIMATE_CONSTANT_P): Likewise.
|
||||
(LEGITIMATE_PIC_OPERAND_P): Likewise.
|
||||
(TARGET_STRIP_NAME_ENCODING): New.
|
||||
(ASM_OUTPUT_LABELREF): New.
|
||||
(PRINT_OPERAND_PUNCT_VALID_P): Add '&'.
|
||||
(OUTPUT_ADDR_CONST_EXTRA): New.
|
||||
(PREDICATE_CODES): Update.
|
||||
(ix86_tls_dialect, ix86_tls_dialect_string): New.
|
||||
* config/i386/i386.md: Regroup and renumber unspec constants.
|
||||
(tls_global_dynamic_gnu, tls_global_dynamic_sun): New.
|
||||
(tls_local_dynamic_base_gnu, tls_local_dynamic_base_sun): New.
|
||||
(tls_global_dynamic, tls_local_dynamic_base): New.
|
||||
(tls_local_dynamic_once): New.
|
||||
* config/i386/i386-protos.h: Update.
|
||||
|
||||
2002-05-23 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* genemit.c (gen_insn): Print file:lineno comment before function.
|
||||
|
@ -528,6 +528,9 @@
|
||||
/* Define if your assembler supports marking sections with SHF_MERGE flag. */
|
||||
#undef HAVE_GAS_SHF_MERGE
|
||||
|
||||
/* Define if your assembler supports thread-local storage. */
|
||||
#undef HAVE_AS_TLS
|
||||
|
||||
/* Define if your assembler supports explicit relocations. */
|
||||
#undef HAVE_AS_EXPLICIT_RELOCS
|
||||
|
||||
|
@ -50,6 +50,11 @@ extern int x86_64_immediate_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int x86_64_zext_immediate_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int const_int_1_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int tls_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int global_dynamic_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int local_dynamic_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int initial_exec_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int local_exec_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int pic_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
|
||||
extern int constant_call_address_operand PARAMS ((rtx, enum machine_mode));
|
||||
@ -83,6 +88,9 @@ extern int ix86_expand_movstr PARAMS ((rtx, rtx, rtx, rtx));
|
||||
extern int ix86_expand_clrstr PARAMS ((rtx, rtx, rtx));
|
||||
extern int ix86_expand_strlen PARAMS ((rtx, rtx, rtx, rtx));
|
||||
|
||||
extern bool legitimate_constant_p PARAMS ((rtx));
|
||||
extern bool constant_address_p PARAMS ((rtx));
|
||||
extern bool legitimate_pic_operand_p PARAMS ((rtx));
|
||||
extern int legitimate_pic_address_disp_p PARAMS ((rtx));
|
||||
extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
|
||||
extern rtx legitimize_pic_address PARAMS ((rtx, rtx));
|
||||
@ -91,6 +99,7 @@ extern rtx legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
|
||||
extern void print_reg PARAMS ((rtx, int, FILE*));
|
||||
extern void print_operand PARAMS ((FILE*, rtx, int));
|
||||
extern void print_operand_address PARAMS ((FILE*, rtx));
|
||||
extern bool output_addr_const_extra PARAMS ((FILE*, rtx));
|
||||
|
||||
extern void split_di PARAMS ((rtx[], int, rtx[], rtx[]));
|
||||
extern void split_ti PARAMS ((rtx[], int, rtx[], rtx[]));
|
||||
@ -198,6 +207,8 @@ extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int));
|
||||
extern void x86_output_mi_thunk PARAMS ((FILE *, int, tree));
|
||||
#endif
|
||||
|
||||
extern rtx ix86_tls_get_addr PARAMS ((void));
|
||||
|
||||
/* In winnt.c */
|
||||
extern void i386_pe_encode_section_info PARAMS ((tree, int));
|
||||
extern const char *i386_pe_strip_name_encoding PARAMS ((const char *));
|
||||
|
@ -544,6 +544,10 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
|
||||
rtx ix86_compare_op0 = NULL_RTX;
|
||||
rtx ix86_compare_op1 = NULL_RTX;
|
||||
|
||||
/* The encoding characters for the four TLS models present in ELF. */
|
||||
|
||||
static char const tls_model_chars[] = "GLil";
|
||||
|
||||
#define MAX_386_STACK_LOCALS 3
|
||||
/* Size of the register save area. */
|
||||
#define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
|
||||
@ -552,6 +556,7 @@ rtx ix86_compare_op1 = NULL_RTX;
|
||||
struct machine_function
|
||||
{
|
||||
rtx stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
|
||||
const char *some_ld_name;
|
||||
int save_varrargs_registers;
|
||||
int accesses_prev_frame;
|
||||
};
|
||||
@ -604,6 +609,9 @@ enum cmodel ix86_cmodel;
|
||||
/* Asm dialect. */
|
||||
const char *ix86_asm_string;
|
||||
enum asm_dialect ix86_asm_dialect = ASM_ATT;
|
||||
/* TLS dialext. */
|
||||
const char *ix86_tls_dialect_string;
|
||||
enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
|
||||
|
||||
/* Which unit we are generating floating point math for. */
|
||||
enum fpmath_unit ix86_fpmath;
|
||||
@ -653,13 +661,17 @@ static char internal_label_prefix[16];
|
||||
static int internal_label_prefix_len;
|
||||
|
||||
static int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
|
||||
static const char *get_pic_label_name PARAMS ((void));
|
||||
static int tls_symbolic_operand_1 PARAMS ((rtx, enum tls_model));
|
||||
static void output_pic_addr_const PARAMS ((FILE *, rtx, int));
|
||||
static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
|
||||
int, int, FILE *));
|
||||
static const char *get_some_local_dynamic_name PARAMS ((void));
|
||||
static int get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
|
||||
static rtx maybe_get_pool_constant PARAMS ((rtx));
|
||||
static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx));
|
||||
static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code,
|
||||
rtx *, rtx *));
|
||||
static rtx get_thread_pointer PARAMS ((void));
|
||||
static rtx gen_push PARAMS ((rtx));
|
||||
static int memory_address_length PARAMS ((rtx addr));
|
||||
static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type));
|
||||
@ -698,7 +710,9 @@ struct ix86_address
|
||||
|
||||
static int ix86_decompose_address PARAMS ((rtx, struct ix86_address *));
|
||||
|
||||
static void i386_encode_section_info PARAMS ((tree, int)) ATTRIBUTE_UNUSED;
|
||||
static void ix86_encode_section_info PARAMS ((tree, int)) ATTRIBUTE_UNUSED;
|
||||
static const char *ix86_strip_name_encoding PARAMS ((const char *))
|
||||
ATTRIBUTE_UNUSED;
|
||||
|
||||
struct builtin_description;
|
||||
static rtx ix86_expand_sse_comi PARAMS ((const struct builtin_description *,
|
||||
@ -831,6 +845,11 @@ static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
|
||||
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
|
||||
ia32_multipass_dfa_lookahead
|
||||
|
||||
#ifdef HAVE_AS_TLS
|
||||
#undef TARGET_HAVE_TLS
|
||||
#define TARGET_HAVE_TLS true
|
||||
#endif
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Sometimes certain combinations of command options do not make
|
||||
@ -1120,6 +1139,17 @@ override_options ()
|
||||
ix86_branch_cost = i;
|
||||
}
|
||||
|
||||
if (ix86_tls_dialect_string)
|
||||
{
|
||||
if (strcmp (ix86_tls_dialect_string, "gnu") == 0)
|
||||
ix86_tls_dialect = TLS_DIALECT_GNU;
|
||||
else if (strcmp (ix86_tls_dialect_string, "sun") == 0)
|
||||
ix86_tls_dialect = TLS_DIALECT_SUN;
|
||||
else
|
||||
error ("bad value (%s) for -mtls-dialect= switch",
|
||||
ix86_tls_dialect_string);
|
||||
}
|
||||
|
||||
/* Keep nonleaf frame pointers. */
|
||||
if (TARGET_OMIT_LEAF_FRAME_POINTER)
|
||||
flag_omit_frame_pointer = 1;
|
||||
@ -2962,6 +2992,70 @@ local_symbolic_operand (op, mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test for various thread-local symbols. See ix86_encode_section_info. */
|
||||
|
||||
int
|
||||
tls_symbolic_operand (op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
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 + 1;
|
||||
}
|
||||
|
||||
static int
|
||||
tls_symbolic_operand_1 (op, kind)
|
||||
rtx op;
|
||||
enum tls_model kind;
|
||||
{
|
||||
const char *symbol_str;
|
||||
|
||||
if (GET_CODE (op) != SYMBOL_REF)
|
||||
return 0;
|
||||
symbol_str = XSTR (op, 0);
|
||||
|
||||
return symbol_str[0] == '%' && symbol_str[1] == tls_model_chars[kind];
|
||||
}
|
||||
|
||||
int
|
||||
global_dynamic_symbolic_operand (op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return tls_symbolic_operand_1 (op, TLS_MODEL_GLOBAL_DYNAMIC);
|
||||
}
|
||||
|
||||
int
|
||||
local_dynamic_symbolic_operand (op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return tls_symbolic_operand_1 (op, TLS_MODEL_LOCAL_DYNAMIC);
|
||||
}
|
||||
|
||||
int
|
||||
initial_exec_symbolic_operand (op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return tls_symbolic_operand_1 (op, TLS_MODEL_INITIAL_EXEC);
|
||||
}
|
||||
|
||||
int
|
||||
local_exec_symbolic_operand (op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return tls_symbolic_operand_1 (op, TLS_MODEL_LOCAL_EXEC);
|
||||
}
|
||||
|
||||
/* Test for a valid operand for a call instruction. Don't allow the
|
||||
arg pointer register or virtual regs since they may decay into
|
||||
reg + const, which the patterns can't handle. */
|
||||
@ -3802,14 +3896,6 @@ ix86_setup_frame_addresses ()
|
||||
|
||||
static char pic_label_name[32];
|
||||
|
||||
static const char *
|
||||
get_pic_label_name ()
|
||||
{
|
||||
if (! pic_label_name[0])
|
||||
ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
|
||||
return pic_label_name;
|
||||
}
|
||||
|
||||
/* This function generates code for -fpic that loads %ebx with
|
||||
the return address of the caller and then returns. */
|
||||
|
||||
@ -3819,7 +3905,7 @@ ix86_asm_file_end (file)
|
||||
{
|
||||
rtx xops[2];
|
||||
|
||||
if (! TARGET_DEEP_BRANCH_PREDICTION || pic_label_name[0] == 0)
|
||||
if (pic_label_name[0] == 0)
|
||||
return;
|
||||
|
||||
/* ??? Binutils 2.10 and earlier has a linkonce elimination bug related
|
||||
@ -3890,7 +3976,10 @@ output_set_got (dest)
|
||||
}
|
||||
else
|
||||
{
|
||||
xops[2] = gen_rtx_SYMBOL_REF (Pmode, get_pic_label_name ());
|
||||
if (! pic_label_name[0])
|
||||
ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
|
||||
|
||||
xops[2] = gen_rtx_SYMBOL_REF (Pmode, pic_label_name);
|
||||
xops[2] = gen_rtx_MEM (QImode, xops[2]);
|
||||
output_asm_insn ("call\t%X2", xops);
|
||||
}
|
||||
@ -4676,6 +4765,114 @@ ix86_find_base_term (x)
|
||||
return term;
|
||||
}
|
||||
|
||||
/* Determine if a given RTX is a valid constant. We already know this
|
||||
satisfies CONSTANT_P. */
|
||||
|
||||
bool
|
||||
legitimate_constant_p (x)
|
||||
rtx x;
|
||||
{
|
||||
rtx inner;
|
||||
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case SYMBOL_REF:
|
||||
/* TLS symbols are not constant. */
|
||||
if (tls_symbolic_operand (x, Pmode))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case CONST:
|
||||
inner = XEXP (x, 0);
|
||||
|
||||
/* Offsets of TLS symbols are never valid.
|
||||
Discourage CSE from creating them. */
|
||||
if (GET_CODE (inner) == PLUS
|
||||
&& tls_symbolic_operand (XEXP (inner, 0), Pmode))
|
||||
return false;
|
||||
|
||||
/* Only some unspecs are valid as "constants". */
|
||||
if (GET_CODE (inner) == UNSPEC)
|
||||
switch (XINT (inner, 1))
|
||||
{
|
||||
case UNSPEC_TPOFF:
|
||||
return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
|
||||
case UNSPEC_TP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Otherwise we handle everything else in the move patterns. */
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Determine if a given RTX is a valid constant address. */
|
||||
|
||||
bool
|
||||
constant_address_p (x)
|
||||
rtx x;
|
||||
{
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case LABEL_REF:
|
||||
case CONST_INT:
|
||||
return true;
|
||||
|
||||
case CONST_DOUBLE:
|
||||
return TARGET_64BIT;
|
||||
|
||||
case CONST:
|
||||
case SYMBOL_REF:
|
||||
return !flag_pic && legitimate_constant_p (x);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Nonzero if the constant value X is a legitimate general operand
|
||||
when generating PIC code. It is given that flag_pic is on and
|
||||
that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
|
||||
|
||||
bool
|
||||
legitimate_pic_operand_p (x)
|
||||
rtx x;
|
||||
{
|
||||
rtx inner;
|
||||
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case CONST:
|
||||
inner = XEXP (x, 0);
|
||||
|
||||
/* Only some unspecs are valid as "constants". */
|
||||
if (GET_CODE (inner) == UNSPEC)
|
||||
switch (XINT (inner, 1))
|
||||
{
|
||||
case UNSPEC_TPOFF:
|
||||
return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
|
||||
case UNSPEC_TP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
|
||||
case SYMBOL_REF:
|
||||
case LABEL_REF:
|
||||
return legitimate_pic_address_disp_p (x);
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if a given CONST RTX is a valid memory displacement
|
||||
in PIC mode. */
|
||||
|
||||
@ -4683,6 +4880,8 @@ int
|
||||
legitimate_pic_address_disp_p (disp)
|
||||
register rtx disp;
|
||||
{
|
||||
bool saw_plus;
|
||||
|
||||
/* In 64bit mode we can allow direct addresses of symbols and labels
|
||||
when they are not dynamic symbols. */
|
||||
if (TARGET_64BIT)
|
||||
@ -4718,23 +4917,40 @@ legitimate_pic_address_disp_p (disp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
saw_plus = false;
|
||||
if (GET_CODE (disp) == PLUS)
|
||||
{
|
||||
if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
|
||||
return 0;
|
||||
disp = XEXP (disp, 0);
|
||||
saw_plus = true;
|
||||
}
|
||||
|
||||
if (GET_CODE (disp) != UNSPEC)
|
||||
return 0;
|
||||
|
||||
/* Must be @GOT or @GOTOFF. */
|
||||
switch (XINT (disp, 1))
|
||||
{
|
||||
case UNSPEC_GOT:
|
||||
if (saw_plus)
|
||||
return false;
|
||||
return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
|
||||
case UNSPEC_GOTOFF:
|
||||
return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
|
||||
case UNSPEC_GOTTPOFF:
|
||||
if (saw_plus)
|
||||
return false;
|
||||
return initial_exec_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
|
||||
case UNSPEC_NTPOFF:
|
||||
/* ??? Could support offset here. */
|
||||
if (saw_plus)
|
||||
return false;
|
||||
return local_exec_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
|
||||
case UNSPEC_DTPOFF:
|
||||
/* ??? Could support offset here. */
|
||||
if (saw_plus)
|
||||
return false;
|
||||
return local_dynamic_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -4873,12 +5089,6 @@ legitimate_address_p (mode, addr, strict)
|
||||
{
|
||||
reason_rtx = disp;
|
||||
|
||||
if (!CONSTANT_ADDRESS_P (disp))
|
||||
{
|
||||
reason = "displacement is not constant";
|
||||
goto report_error;
|
||||
}
|
||||
|
||||
if (TARGET_64BIT)
|
||||
{
|
||||
if (!x86_64_sign_extended_value (disp))
|
||||
@ -4896,8 +5106,30 @@ legitimate_address_p (mode, addr, strict)
|
||||
}
|
||||
}
|
||||
|
||||
if (flag_pic && SYMBOLIC_CONST (disp))
|
||||
if (GET_CODE (disp) == CONST
|
||||
&& GET_CODE (XEXP (disp, 0)) == UNSPEC)
|
||||
switch (XINT (XEXP (disp, 0), 1))
|
||||
{
|
||||
case UNSPEC_GOT:
|
||||
case UNSPEC_GOTOFF:
|
||||
case UNSPEC_GOTPCREL:
|
||||
if (!flag_pic)
|
||||
abort ();
|
||||
goto is_legitimate_pic;
|
||||
|
||||
case UNSPEC_GOTTPOFF:
|
||||
case UNSPEC_NTPOFF:
|
||||
case UNSPEC_DTPOFF:
|
||||
break;
|
||||
|
||||
default:
|
||||
reason = "invalid address unspec";
|
||||
goto report_error;
|
||||
}
|
||||
|
||||
else if (flag_pic && SYMBOLIC_CONST (disp))
|
||||
{
|
||||
is_legitimate_pic:
|
||||
if (TARGET_64BIT && (index || base))
|
||||
{
|
||||
reason = "non-constant pic memory reference";
|
||||
@ -4940,6 +5172,11 @@ legitimate_address_p (mode, addr, strict)
|
||||
goto report_error;
|
||||
}
|
||||
}
|
||||
else if (!CONSTANT_ADDRESS_P (disp))
|
||||
{
|
||||
reason = "displacement is not constant";
|
||||
goto report_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Everything looks valid. */
|
||||
@ -5122,23 +5359,100 @@ legitimize_pic_address (orig, reg)
|
||||
return new;
|
||||
}
|
||||
|
||||
/* If using PIC, mark a SYMBOL_REF for a non-global symbol so that we
|
||||
may access it directly in the GOT. */
|
||||
|
||||
static void
|
||||
i386_encode_section_info (decl, first)
|
||||
ix86_encode_section_info (decl, first)
|
||||
tree decl;
|
||||
int first ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (flag_pic)
|
||||
{
|
||||
rtx rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
|
||||
bool local_p = (*targetm.binds_local_p) (decl);
|
||||
rtx rtl, symbol;
|
||||
|
||||
if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF)
|
||||
SYMBOL_REF_FLAG (XEXP (rtl, 0)) = (*targetm.binds_local_p) (decl);
|
||||
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;
|
||||
|
||||
/* For basic x86, if using PIC, mark a SYMBOL_REF for a non-global
|
||||
symbol so that we may access it directly in the GOT. */
|
||||
|
||||
if (flag_pic)
|
||||
SYMBOL_REF_FLAG (symbol) = local_p;
|
||||
|
||||
/* For ELF, 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;
|
||||
char *newstr;
|
||||
size_t len;
|
||||
enum tls_model kind;
|
||||
|
||||
if (!flag_pic)
|
||||
{
|
||||
if (local_p)
|
||||
kind = TLS_MODEL_LOCAL_EXEC;
|
||||
else
|
||||
kind = TLS_MODEL_INITIAL_EXEC;
|
||||
}
|
||||
/* Local dynamic is inefficient when we're not combining the
|
||||
parts of the address. */
|
||||
else if (optimize && local_p)
|
||||
kind = TLS_MODEL_LOCAL_DYNAMIC;
|
||||
else
|
||||
kind = TLS_MODEL_GLOBAL_DYNAMIC;
|
||||
if (kind < flag_tls_default)
|
||||
kind = flag_tls_default;
|
||||
|
||||
symbol_str = XSTR (symbol, 0);
|
||||
|
||||
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 *
|
||||
ix86_strip_name_encoding (str)
|
||||
const char *str;
|
||||
{
|
||||
if (str[0] == '%')
|
||||
str += 2;
|
||||
if (str [0] == '*')
|
||||
str += 1;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* 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 = gen_rtx_CONST (Pmode, tp);
|
||||
tp = force_reg (Pmode, tp);
|
||||
|
||||
return tp;
|
||||
}
|
||||
|
||||
/* Try machine-dependent ways of modifying an illegitimate address
|
||||
to be legitimate. If we find one, return the new, valid address.
|
||||
This macro is used in only one place: `memory_address' in explow.c.
|
||||
@ -5176,6 +5490,85 @@ legitimize_address (x, oldx, mode)
|
||||
debug_rtx (x);
|
||||
}
|
||||
|
||||
/* Note that tls_symbolic_operand return is biased by 1 to return true. */
|
||||
log = tls_symbolic_operand (x, mode);
|
||||
if (log)
|
||||
{
|
||||
rtx dest, base, off, pic;
|
||||
|
||||
switch (log - 1)
|
||||
{
|
||||
case TLS_MODEL_GLOBAL_DYNAMIC:
|
||||
dest = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_tls_global_dynamic (dest, x));
|
||||
break;
|
||||
|
||||
case TLS_MODEL_LOCAL_DYNAMIC:
|
||||
base = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_tls_local_dynamic_base (base));
|
||||
|
||||
off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
|
||||
off = gen_rtx_CONST (Pmode, off);
|
||||
|
||||
return gen_rtx_PLUS (Pmode, base, off);
|
||||
|
||||
case TLS_MODEL_INITIAL_EXEC:
|
||||
if (flag_pic)
|
||||
{
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
pic = pic_offset_table_rtx;
|
||||
}
|
||||
else
|
||||
{
|
||||
pic = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_set_got (pic));
|
||||
}
|
||||
|
||||
base = get_thread_pointer ();
|
||||
|
||||
off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_GOTTPOFF);
|
||||
off = gen_rtx_CONST (Pmode, off);
|
||||
off = gen_rtx_PLUS (Pmode, pic, off);
|
||||
off = gen_rtx_MEM (Pmode, off);
|
||||
RTX_UNCHANGING_P (off) = 1;
|
||||
set_mem_alias_set (off, ix86_GOT_alias_set ());
|
||||
|
||||
/* Damn Sun for specifing a set of dynamic relocations without
|
||||
considering the two-operand nature of the architecture!
|
||||
We'd be much better off with a "GOTNTPOFF" relocation that
|
||||
already contained the negated constant. */
|
||||
/* ??? Using negl and reg+reg addressing appears to be a lose
|
||||
size-wise. The negl is two bytes, just like the extra movl
|
||||
incurred by the two-operand subl, but reg+reg addressing
|
||||
uses the two-byte modrm form, unlike plain reg. */
|
||||
|
||||
dest = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_subsi3 (dest, base, off));
|
||||
break;
|
||||
|
||||
case TLS_MODEL_LOCAL_EXEC:
|
||||
base = get_thread_pointer ();
|
||||
|
||||
off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
|
||||
TARGET_GNU_TLS ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
|
||||
off = gen_rtx_CONST (Pmode, off);
|
||||
|
||||
if (TARGET_GNU_TLS)
|
||||
return gen_rtx_PLUS (Pmode, base, off);
|
||||
else
|
||||
{
|
||||
dest = gen_reg_rtx (Pmode);
|
||||
emit_insn (gen_subsi3 (dest, base, off));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (flag_pic && SYMBOLIC_CONST (x))
|
||||
return legitimize_pic_address (x, 0);
|
||||
|
||||
@ -5425,12 +5818,21 @@ output_pic_addr_const (file, x, code)
|
||||
case UNSPEC_GOTOFF:
|
||||
fputs ("@GOTOFF", file);
|
||||
break;
|
||||
case UNSPEC_PLT:
|
||||
fputs ("@PLT", file);
|
||||
break;
|
||||
case UNSPEC_GOTPCREL:
|
||||
fputs ("@GOTPCREL(%RIP)", file);
|
||||
break;
|
||||
case UNSPEC_GOTTPOFF:
|
||||
fputs ("@GOTTPOFF", file);
|
||||
break;
|
||||
case UNSPEC_TPOFF:
|
||||
fputs ("@TPOFF", file);
|
||||
break;
|
||||
case UNSPEC_NTPOFF:
|
||||
fputs ("@NTPOFF", file);
|
||||
break;
|
||||
case UNSPEC_DTPOFF:
|
||||
fputs ("@DTPOFF", file);
|
||||
break;
|
||||
default:
|
||||
output_operand_lossage ("invalid UNSPEC as operand");
|
||||
break;
|
||||
@ -5720,6 +6122,43 @@ print_reg (x, code, file)
|
||||
}
|
||||
}
|
||||
|
||||
/* Locate some local-dynamic symbol still in use by this function
|
||||
so that we can print its name in some tls_local_dynamic_base
|
||||
pattern. */
|
||||
|
||||
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
|
||||
&& local_dynamic_symbolic_operand (x, Pmode))
|
||||
{
|
||||
cfun->machine->some_ld_name = XSTR (x, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Meaning of CODE:
|
||||
L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
|
||||
C -- print opcode suffix for set/cmov insn.
|
||||
@ -5744,6 +6183,7 @@ print_reg (x, code, file)
|
||||
D -- print condition for SSE cmp instruction.
|
||||
P -- if PIC, print an @PLT suffix.
|
||||
X -- don't print any sort of PIC '@' suffix for a symbol.
|
||||
& -- print some in-use local-dynamic symbol name.
|
||||
*/
|
||||
|
||||
void
|
||||
@ -5761,6 +6201,10 @@ print_operand (file, x, code)
|
||||
putc ('*', file);
|
||||
return;
|
||||
|
||||
case '&':
|
||||
assemble_name (file, get_some_local_dynamic_name ());
|
||||
return;
|
||||
|
||||
case 'A':
|
||||
if (ASSEMBLER_DIALECT == ASM_ATT)
|
||||
putc ('*', file);
|
||||
@ -6090,6 +6534,18 @@ print_operand (file, x, code)
|
||||
REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
|
||||
fprintf (file, "%s", dstr);
|
||||
}
|
||||
|
||||
else if (GET_CODE (x) == CONST
|
||||
&& GET_CODE (XEXP (x, 0)) == UNSPEC
|
||||
&& XINT (XEXP (x, 0), 1) == UNSPEC_TP)
|
||||
{
|
||||
if (ASSEMBLER_DIALECT == ASM_INTEL)
|
||||
fputs ("DWORD PTR ", file);
|
||||
if (ASSEMBLER_DIALECT == ASM_ATT || USER_LABEL_PREFIX[0] == 0)
|
||||
putc ('%', file);
|
||||
fputs ("gs:0", file);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (code != 'P')
|
||||
@ -6238,6 +6694,43 @@ print_operand_address (file, addr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
output_addr_const_extra (file, x)
|
||||
FILE *file;
|
||||
rtx x;
|
||||
{
|
||||
rtx op;
|
||||
|
||||
if (GET_CODE (x) != UNSPEC)
|
||||
return false;
|
||||
|
||||
op = XVECEXP (x, 0, 0);
|
||||
switch (XINT (x, 1))
|
||||
{
|
||||
case UNSPEC_GOTTPOFF:
|
||||
output_addr_const (file, op);
|
||||
fputs ("@GOTTPOFF", file);
|
||||
break;
|
||||
case UNSPEC_TPOFF:
|
||||
output_addr_const (file, op);
|
||||
fputs ("@TPOFF", file);
|
||||
break;
|
||||
case UNSPEC_NTPOFF:
|
||||
output_addr_const (file, op);
|
||||
fputs ("@NTPOFF", file);
|
||||
break;
|
||||
case UNSPEC_DTPOFF:
|
||||
output_addr_const (file, op);
|
||||
fputs ("@DTPOFF", file);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Split one or more DImode RTL references into pairs of SImode
|
||||
references. The RTL can be REG, offsettable MEM, integer constant, or
|
||||
@ -6775,51 +7268,117 @@ ix86_expand_clear (dest)
|
||||
emit_insn (tmp);
|
||||
}
|
||||
|
||||
/* X is an unchanging MEM. If it is a constant pool reference, return
|
||||
the constant pool rtx, else NULL. */
|
||||
|
||||
static rtx
|
||||
maybe_get_pool_constant (x)
|
||||
rtx x;
|
||||
{
|
||||
x = XEXP (x, 0);
|
||||
|
||||
if (flag_pic)
|
||||
{
|
||||
if (GET_CODE (x) != PLUS)
|
||||
return NULL_RTX;
|
||||
if (XEXP (x, 0) != pic_offset_table_rtx)
|
||||
return NULL_RTX;
|
||||
x = XEXP (x, 1);
|
||||
if (GET_CODE (x) != CONST)
|
||||
return NULL_RTX;
|
||||
x = XEXP (x, 0);
|
||||
if (GET_CODE (x) != UNSPEC)
|
||||
return NULL_RTX;
|
||||
if (XINT (x, 1) != UNSPEC_GOTOFF)
|
||||
return NULL_RTX;
|
||||
x = XVECEXP (x, 0, 0);
|
||||
}
|
||||
|
||||
if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
|
||||
return get_pool_constant (x);
|
||||
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
void
|
||||
ix86_expand_move (mode, operands)
|
||||
enum machine_mode mode;
|
||||
rtx operands[];
|
||||
{
|
||||
int strict = (reload_in_progress || reload_completed);
|
||||
rtx insn;
|
||||
rtx insn, op0, op1, tmp;
|
||||
|
||||
if (flag_pic && mode == Pmode && symbolic_operand (operands[1], Pmode))
|
||||
op0 = operands[0];
|
||||
op1 = operands[1];
|
||||
|
||||
/* ??? We have a slight problem. We need to say that tls symbols are
|
||||
not legitimate constants so that reload does not helpfully reload
|
||||
these constants from a REG_EQUIV, which we cannot handle. (Recall
|
||||
that general- and local-dynamic address resolution requires a
|
||||
function call.)
|
||||
|
||||
However, if we say that tls symbols are not legitimate constants,
|
||||
then emit_move_insn helpfully drop them into the constant pool.
|
||||
|
||||
It is far easier to work around emit_move_insn than reload. Recognize
|
||||
the MEM that we would have created and extract the symbol_ref. */
|
||||
|
||||
if (mode == Pmode
|
||||
&& GET_CODE (op1) == MEM
|
||||
&& RTX_UNCHANGING_P (op1))
|
||||
{
|
||||
/* Emit insns to move operands[1] into operands[0]. */
|
||||
tmp = maybe_get_pool_constant (op1);
|
||||
/* Note that we only care about symbolic constants here, which
|
||||
unlike CONST_INT will always have a proper mode. */
|
||||
if (tmp && GET_MODE (tmp) == Pmode)
|
||||
op1 = tmp;
|
||||
}
|
||||
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
operands[1] = force_reg (Pmode, operands[1]);
|
||||
if (tls_symbolic_operand (op1, Pmode))
|
||||
{
|
||||
op1 = legitimize_address (op1, op1, VOIDmode);
|
||||
if (GET_CODE (op0) == MEM)
|
||||
{
|
||||
tmp = gen_reg_rtx (mode);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, tmp, op1));
|
||||
op1 = tmp;
|
||||
}
|
||||
}
|
||||
else if (flag_pic && mode == Pmode && symbolic_operand (op1, Pmode))
|
||||
{
|
||||
if (GET_CODE (op0) == MEM)
|
||||
op1 = force_reg (Pmode, op1);
|
||||
else
|
||||
{
|
||||
rtx temp = operands[0];
|
||||
rtx temp = op0;
|
||||
if (GET_CODE (temp) != REG)
|
||||
temp = gen_reg_rtx (Pmode);
|
||||
temp = legitimize_pic_address (operands[1], temp);
|
||||
if (temp == operands[0])
|
||||
temp = legitimize_pic_address (op1, temp);
|
||||
if (temp == op0)
|
||||
return;
|
||||
operands[1] = temp;
|
||||
op1 = temp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GET_CODE (operands[0]) == MEM
|
||||
if (GET_CODE (op0) == MEM
|
||||
&& (PUSH_ROUNDING (GET_MODE_SIZE (mode)) != GET_MODE_SIZE (mode)
|
||||
|| !push_operand (operands[0], mode))
|
||||
&& GET_CODE (operands[1]) == MEM)
|
||||
operands[1] = force_reg (mode, operands[1]);
|
||||
|| !push_operand (op0, mode))
|
||||
&& GET_CODE (op1) == MEM)
|
||||
op1 = force_reg (mode, op1);
|
||||
|
||||
if (push_operand (operands[0], mode)
|
||||
&& ! general_no_elim_operand (operands[1], mode))
|
||||
operands[1] = copy_to_mode_reg (mode, operands[1]);
|
||||
if (push_operand (op0, mode)
|
||||
&& ! general_no_elim_operand (op1, mode))
|
||||
op1 = copy_to_mode_reg (mode, op1);
|
||||
|
||||
/* Force large constants in 64bit compilation into register
|
||||
to get them CSEed. */
|
||||
if (TARGET_64BIT && mode == DImode
|
||||
&& immediate_operand (operands[1], mode)
|
||||
&& !x86_64_zero_extended_value (operands[1])
|
||||
&& !register_operand (operands[0], mode)
|
||||
&& immediate_operand (op1, mode)
|
||||
&& !x86_64_zero_extended_value (op1)
|
||||
&& !register_operand (op0, mode)
|
||||
&& optimize && !reload_completed && !reload_in_progress)
|
||||
operands[1] = copy_to_mode_reg (mode, operands[1]);
|
||||
op1 = copy_to_mode_reg (mode, op1);
|
||||
|
||||
if (FLOAT_MODE_P (mode))
|
||||
{
|
||||
@ -6829,13 +7388,13 @@ ix86_expand_move (mode, operands)
|
||||
|
||||
if (strict)
|
||||
;
|
||||
else if (GET_CODE (operands[1]) == CONST_DOUBLE
|
||||
&& register_operand (operands[0], mode))
|
||||
operands[1] = validize_mem (force_const_mem (mode, operands[1]));
|
||||
else if (GET_CODE (op1) == CONST_DOUBLE
|
||||
&& register_operand (op0, mode))
|
||||
op1 = validize_mem (force_const_mem (mode, op1));
|
||||
}
|
||||
}
|
||||
|
||||
insn = gen_rtx_SET (VOIDmode, operands[0], operands[1]);
|
||||
insn = gen_rtx_SET (VOIDmode, op0, op1);
|
||||
|
||||
emit_insn (insn);
|
||||
}
|
||||
@ -8684,13 +9243,14 @@ ix86_split_to_parts (operand, parts, mode)
|
||||
if (size < 2 || size > 3)
|
||||
abort ();
|
||||
|
||||
/* Optimize constant pool reference to immediates. This is used by fp moves,
|
||||
that force all constants to memory to allow combining. */
|
||||
|
||||
if (GET_CODE (operand) == MEM
|
||||
&& GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
|
||||
&& CONSTANT_POOL_ADDRESS_P (XEXP (operand, 0)))
|
||||
operand = get_pool_constant (XEXP (operand, 0));
|
||||
/* Optimize constant pool reference to immediates. This is used by fp
|
||||
moves, that force all constants to memory to allow combining. */
|
||||
if (GET_CODE (operand) == MEM && RTX_UNCHANGING_P (operand))
|
||||
{
|
||||
rtx tmp = maybe_get_pool_constant (operand);
|
||||
if (tmp)
|
||||
operand = tmp;
|
||||
}
|
||||
|
||||
if (GET_CODE (operand) == MEM && !offsettable_memref_p (operand))
|
||||
{
|
||||
@ -9993,6 +10553,24 @@ assign_386_stack_local (mode, n)
|
||||
|
||||
return ix86_stack_locals[(int) mode][n];
|
||||
}
|
||||
|
||||
/* Construct the SYMBOL_REF for the tls_get_addr function. */
|
||||
|
||||
rtx
|
||||
ix86_tls_get_addr ()
|
||||
{
|
||||
static rtx symbol;
|
||||
|
||||
if (!symbol)
|
||||
{
|
||||
symbol = gen_rtx_SYMBOL_REF (Pmode, (TARGET_GNU_TLS
|
||||
? "___tls_get_addr"
|
||||
: "__tls_get_addr"));
|
||||
ggc_add_rtx_root (&symbol, 1);
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
/* Calculate the length of the memory address in the instruction
|
||||
encoding. Does not include the one-byte modrm, opcode, or prefix. */
|
||||
|
@ -282,6 +282,9 @@ extern int x86_prefetch_sse;
|
||||
|
||||
#define TARGET_RED_ZONE (!(target_flags & MASK_NO_RED_ZONE))
|
||||
|
||||
#define TARGET_GNU_TLS (ix86_tls_dialect == TLS_DIALECT_GNU)
|
||||
#define TARGET_SUN_TLS (ix86_tls_dialect == TLS_DIALECT_SUN)
|
||||
|
||||
/* WARNING: Do not mark empty strings for translation, as calling
|
||||
gettext on an empty string does NOT return an empty
|
||||
string. */
|
||||
@ -426,6 +429,8 @@ extern int x86_prefetch_sse;
|
||||
"" /* Undocumented. */ }, \
|
||||
{ "asm=", &ix86_asm_string, \
|
||||
N_("Use given assembler dialect") }, \
|
||||
{ "tls-dialect=", &ix86_tls_dialect_string, \
|
||||
N_("Use given thread-local storage dialect") }, \
|
||||
SUBTARGET_OPTIONS \
|
||||
}
|
||||
|
||||
@ -1876,15 +1881,12 @@ do { \
|
||||
|
||||
#define MAX_REGS_PER_ADDRESS 2
|
||||
|
||||
#define CONSTANT_ADDRESS_P(X) \
|
||||
(GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|
||||
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
|
||||
|| GET_CODE (X) == CONST_DOUBLE)
|
||||
#define CONSTANT_ADDRESS_P(X) constant_address_p (X)
|
||||
|
||||
/* Nonzero if the constant value X is a legitimate general operand.
|
||||
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
|
||||
|
||||
#define LEGITIMATE_CONSTANT_P(X) 1
|
||||
#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
|
||||
|
||||
#ifdef REG_OK_STRICT
|
||||
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
|
||||
@ -1947,9 +1949,7 @@ do { \
|
||||
when generating PIC code. It is given that flag_pic is on and
|
||||
that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
|
||||
|
||||
#define LEGITIMATE_PIC_OPERAND_P(X) \
|
||||
(! SYMBOLIC_CONST (X) \
|
||||
|| legitimate_pic_address_disp_p (X))
|
||||
#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
|
||||
|
||||
#define SYMBOLIC_CONST(X) \
|
||||
(GET_CODE (X) == SYMBOL_REF \
|
||||
@ -2392,7 +2392,20 @@ enum ix86_builtins
|
||||
IX86_BUILTIN_MAX
|
||||
};
|
||||
|
||||
#define TARGET_ENCODE_SECTION_INFO i386_encode_section_info
|
||||
#define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
|
||||
#define TARGET_STRIP_NAME_ENCODING ix86_strip_name_encoding
|
||||
|
||||
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
|
||||
do { \
|
||||
const char *xname = (NAME); \
|
||||
if (xname[0] == '%') \
|
||||
xname += 2; \
|
||||
if (xname[0] == '*') \
|
||||
xname += 1; \
|
||||
else \
|
||||
fputs (user_label_prefix, FILE); \
|
||||
fputs (xname, FILE); \
|
||||
} while (0)
|
||||
|
||||
/* The `FINALIZE_PIC' macro serves as a hook to emit these special
|
||||
codes once the function is being compiled into assembly code, but
|
||||
@ -3047,7 +3060,7 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
|
||||
print_operand function. */
|
||||
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
|
||||
((CODE) == '*' || (CODE) == '+')
|
||||
((CODE) == '*' || (CODE) == '+' || (CODE) == '&')
|
||||
|
||||
/* Print the name of a register based on its machine mode and number.
|
||||
If CODE is 'w', pretend the mode is HImode.
|
||||
@ -3066,6 +3079,12 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
|
||||
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
|
||||
print_operand_address ((FILE), (ADDR))
|
||||
|
||||
#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \
|
||||
do { \
|
||||
if (! output_addr_const_extra (FILE, (X))) \
|
||||
goto FAIL; \
|
||||
} while (0);
|
||||
|
||||
/* Print the name of a register for based on its machine mode and number.
|
||||
This macro is used to print debugging output.
|
||||
This macro is different from PRINT_REG in that it may be used in
|
||||
@ -3195,7 +3214,12 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
|
||||
{"memory_displacement_operand", {MEM}}, \
|
||||
{"cmpsi_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
|
||||
LABEL_REF, SUBREG, REG, MEM, AND}}, \
|
||||
{"long_memory_operand", {MEM}},
|
||||
{"long_memory_operand", {MEM}}, \
|
||||
{"tls_symbolic_operand", {SYMBOL_REF}}, \
|
||||
{"global_dynamic_symbolic_operand", {SYMBOL_REF}}, \
|
||||
{"local_dynamic_symbolic_operand", {SYMBOL_REF}}, \
|
||||
{"initial_exec_symbolic_operand", {SYMBOL_REF}}, \
|
||||
{"local_exec_symbolic_operand", {SYMBOL_REF}},
|
||||
|
||||
/* A list of predicates that do special things with modes, and so
|
||||
should not elicit warnings for VOIDmode match_operand. */
|
||||
@ -3233,6 +3257,15 @@ enum fpmath_unit
|
||||
extern enum fpmath_unit ix86_fpmath;
|
||||
extern const char *ix86_fpmath_string;
|
||||
|
||||
enum tls_dialect
|
||||
{
|
||||
TLS_DIALECT_GNU,
|
||||
TLS_DIALECT_SUN
|
||||
};
|
||||
|
||||
extern enum tls_dialect ix86_tls_dialect;
|
||||
extern const char *ix86_tls_dialect_string;
|
||||
|
||||
enum cmodel {
|
||||
CM_32, /* The traditional 32-bit ABI. */
|
||||
CM_SMALL, /* Assumes all code and data fits in the low 31 bits. */
|
||||
|
@ -53,23 +53,36 @@
|
||||
;; UNSPEC usage:
|
||||
|
||||
(define_constants
|
||||
[(UNSPEC_SCAS 0)
|
||||
(UNSPEC_SIN 1)
|
||||
(UNSPEC_COS 2)
|
||||
(UNSPEC_STACK_PROBE 3)
|
||||
(UNSPEC_STACK_ALLOC 4)
|
||||
(UNSPEC_BSF 5)
|
||||
(UNSPEC_GOT 6)
|
||||
(UNSPEC_GOTOFF 7)
|
||||
(UNSPEC_PLT 8)
|
||||
(UNSPEC_FNSTSW 9)
|
||||
(UNSPEC_SAHF 10)
|
||||
(UNSPEC_FSTCW 11)
|
||||
(UNSPEC_ADD_CARRY 12)
|
||||
[; Relocation specifiers
|
||||
(UNSPEC_GOT 0)
|
||||
(UNSPEC_GOTOFF 1)
|
||||
(UNSPEC_GOTPCREL 2)
|
||||
(UNSPEC_GOTTPOFF 3)
|
||||
(UNSPEC_TPOFF 4)
|
||||
(UNSPEC_NTPOFF 5)
|
||||
(UNSPEC_DTPOFF 6)
|
||||
|
||||
; Prologue support
|
||||
(UNSPEC_STACK_PROBE 10)
|
||||
(UNSPEC_STACK_ALLOC 11)
|
||||
(UNSPEC_SET_GOT 12)
|
||||
(UNSPEC_SSE_PROLOGUE_SAVE 13)
|
||||
(UNSPEC_FLDCW 14)
|
||||
(UNSPEC_GOTPCREL 15)
|
||||
(UNSPEC_SET_GOT 16)
|
||||
|
||||
; TLS support
|
||||
(UNSPEC_TP 15)
|
||||
(UNSPEC_TLS_GD 16)
|
||||
(UNSPEC_TLS_LD_BASE 17)
|
||||
|
||||
; Other random patterns
|
||||
(UNSPEC_SCAS 20)
|
||||
(UNSPEC_SIN 21)
|
||||
(UNSPEC_COS 22)
|
||||
(UNSPEC_BSF 23)
|
||||
(UNSPEC_FNSTSW 24)
|
||||
(UNSPEC_SAHF 25)
|
||||
(UNSPEC_FSTCW 26)
|
||||
(UNSPEC_ADD_CARRY 27)
|
||||
(UNSPEC_FLDCW 28)
|
||||
|
||||
; For SSE/MMX support:
|
||||
(UNSPEC_FIX 30)
|
||||
@ -13330,6 +13343,127 @@
|
||||
;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
|
||||
;; and slower than the two-byte movzx insn needed to do the work in SImode.
|
||||
|
||||
;; Thread-local storage patterns for ELF.
|
||||
;;
|
||||
;; Note that these code sequences must appear exactly as shown
|
||||
;; in order to allow linker relaxation.
|
||||
|
||||
(define_insn "*tls_global_dynamic_gnu"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(unspec:SI [(match_operand:SI 1 "register_operand" "b")
|
||||
(match_operand:SI 2 "tls_symbolic_operand" "")
|
||||
(match_operand:SI 3 "call_insn_operand" "")]
|
||||
UNSPEC_TLS_GD))
|
||||
(clobber (match_scratch:SI 4 "=d"))
|
||||
(clobber (match_scratch:SI 5 "=c"))
|
||||
(clobber (reg:CC 17))]
|
||||
"TARGET_GNU_TLS"
|
||||
"lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "12")])
|
||||
|
||||
(define_insn "*tls_global_dynamic_sun"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(unspec:SI [(match_operand:SI 1 "register_operand" "b")
|
||||
(match_operand:SI 2 "tls_symbolic_operand" "")
|
||||
(match_operand:SI 3 "call_insn_operand" "")]
|
||||
UNSPEC_TLS_GD))
|
||||
(clobber (match_scratch:SI 4 "=d"))
|
||||
(clobber (match_scratch:SI 5 "=c"))
|
||||
(clobber (reg:CC 17))]
|
||||
"TARGET_SUN_TLS"
|
||||
"lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
|
||||
push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "14")])
|
||||
|
||||
(define_expand "tls_global_dynamic"
|
||||
[(parallel [(set (match_operand:SI 0 "register_operand" "")
|
||||
(unspec:SI
|
||||
[(match_dup 2)
|
||||
(match_operand:SI 1 "tls_symbolic_operand" "")
|
||||
(match_dup 3)]
|
||||
UNSPEC_TLS_GD))
|
||||
(clobber (match_scratch:SI 4 ""))
|
||||
(clobber (match_scratch:SI 5 ""))
|
||||
(clobber (reg:CC 17))])]
|
||||
""
|
||||
{
|
||||
if (!flag_pic)
|
||||
abort ();
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
operands[2] = pic_offset_table_rtx;
|
||||
operands[3] = ix86_tls_get_addr ();
|
||||
})
|
||||
|
||||
(define_insn "*tls_local_dynamic_base_gnu"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(unspec:SI [(match_operand:SI 1 "register_operand" "b")
|
||||
(match_operand:SI 2 "call_insn_operand" "")]
|
||||
UNSPEC_TLS_LD_BASE))
|
||||
(clobber (match_scratch:SI 3 "=d"))
|
||||
(clobber (match_scratch:SI 4 "=c"))
|
||||
(clobber (reg:CC 17))]
|
||||
"TARGET_GNU_TLS"
|
||||
"lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "11")])
|
||||
|
||||
(define_insn "*tls_local_dynamic_base_sun"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(unspec:SI [(match_operand:SI 1 "register_operand" "b")
|
||||
(match_operand:SI 2 "call_insn_operand" "")]
|
||||
UNSPEC_TLS_LD_BASE))
|
||||
(clobber (match_scratch:SI 3 "=d"))
|
||||
(clobber (match_scratch:SI 4 "=c"))
|
||||
(clobber (reg:CC 17))]
|
||||
"TARGET_SUN_TLS"
|
||||
"lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
|
||||
push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "13")])
|
||||
|
||||
(define_expand "tls_local_dynamic_base"
|
||||
[(parallel [(set (match_operand:SI 0 "register_operand" "")
|
||||
(unspec:SI [(match_dup 1) (match_dup 2)]
|
||||
UNSPEC_TLS_LD_BASE))
|
||||
(clobber (match_scratch:SI 3 ""))
|
||||
(clobber (match_scratch:SI 4 ""))
|
||||
(clobber (reg:CC 17))])]
|
||||
""
|
||||
{
|
||||
if (!flag_pic)
|
||||
abort ();
|
||||
current_function_uses_pic_offset_table = 1;
|
||||
operands[1] = pic_offset_table_rtx;
|
||||
operands[2] = ix86_tls_get_addr ();
|
||||
})
|
||||
|
||||
;; Local dynamic of a single variable is a lose. Show combine how
|
||||
;; to convert that back to global dynamic.
|
||||
|
||||
(define_insn_and_split "*tls_local_dynamic_once"
|
||||
[(set (match_operand:SI 0 "register_operand" "=a")
|
||||
(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
|
||||
(match_operand:SI 2 "call_insn_operand" "")]
|
||||
UNSPEC_TLS_LD_BASE)
|
||||
(const:SI (unspec:SI
|
||||
[(match_operand:SI 3 "tls_symbolic_operand" "")]
|
||||
UNSPEC_DTPOFF))))
|
||||
(clobber (match_scratch:SI 4 "=d"))
|
||||
(clobber (match_scratch:SI 5 "=c"))
|
||||
(clobber (reg:CC 17))]
|
||||
""
|
||||
"#"
|
||||
""
|
||||
[(parallel [(set (match_dup 0)
|
||||
(unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
|
||||
UNSPEC_TLS_GD))
|
||||
(clobber (match_dup 4))
|
||||
(clobber (match_dup 5))
|
||||
(clobber (reg:CC 17))])]
|
||||
"")
|
||||
|
||||
;; These patterns match the binary 387 instructions for addM3, subM3,
|
||||
;; mulM3 and divM3. There are three patterns for each of DFmode and
|
||||
;; SFmode. The first is the normal insn, the second the same insn but
|
||||
|
82
gcc/configure
vendored
82
gcc/configure
vendored
@ -7244,7 +7244,7 @@ libgcc_visibility=$gcc_cv_as_hidden
|
||||
|
||||
|
||||
echo $ac_n "checking assembler leb128 support""... $ac_c" 1>&6
|
||||
echo "configure:7228: checking assembler leb128 support" >&5
|
||||
echo "configure:7248: checking assembler leb128 support" >&5
|
||||
gcc_cv_as_leb128=no
|
||||
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 11 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
|
||||
@ -7289,7 +7289,7 @@ fi
|
||||
echo "$ac_t""$gcc_cv_as_leb128" 1>&6
|
||||
|
||||
echo $ac_n "checking assembler eh_frame optimization""... $ac_c" 1>&6
|
||||
echo "configure:7273: checking assembler eh_frame optimization" >&5
|
||||
echo "configure:7293: checking assembler eh_frame optimization" >&5
|
||||
gcc_cv_as_eh_frame=no
|
||||
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 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
|
||||
@ -7370,7 +7370,7 @@ fi
|
||||
echo "$ac_t""$gcc_cv_as_eh_frame" 1>&6
|
||||
|
||||
echo $ac_n "checking assembler section merging support""... $ac_c" 1>&6
|
||||
echo "configure:7354: checking assembler section merging support" >&5
|
||||
echo "configure:7374: checking assembler section merging support" >&5
|
||||
gcc_cv_as_shf_merge=no
|
||||
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 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
|
||||
@ -7392,11 +7392,61 @@ EOF
|
||||
fi
|
||||
echo "$ac_t""$gcc_cv_as_shf_merge" 1>&6
|
||||
|
||||
echo $ac_n "checking assembler thread-local storage support""... $ac_c" 1>&6
|
||||
echo "configure:7397: checking assembler thread-local storage support" >&5
|
||||
gcc_cv_as_tls=no
|
||||
conftest_s=
|
||||
tls_first_major=
|
||||
tls_first_minor=
|
||||
case "$target" in
|
||||
i[34567]86-*-*)
|
||||
conftest_s='
|
||||
.section ".tdata","awT",@progbits
|
||||
foo: .long 25
|
||||
.text
|
||||
movl %gs:0, %eax
|
||||
leal foo@TLSGD(,%ebx,1), %eax
|
||||
leal foo@TLSLDM(%ebx), %eax
|
||||
leal foo@DTPOFF(%eax), %edx
|
||||
movl foo@GOTTPOFF(%ebx), %eax
|
||||
subl foo@GOTTPOFF(%ebx), %eax
|
||||
movl $foo@TPOFF, %eax
|
||||
subl $foo@TPOFF, %eax
|
||||
leal foo@NTPOFF(%ecx), %eax'
|
||||
tls_first_major=2
|
||||
tls_first_minor=13
|
||||
;;
|
||||
esac
|
||||
if test -z "$tls_first_major"; then
|
||||
:
|
||||
elif 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 "$tls_first_major" \
|
||||
-a "$gcc_cv_gas_minor_version" -ge "$tls_first_minor" \
|
||||
-o "$gcc_cv_gas_major_version" -gt "$tls_first_major"; then
|
||||
gcc_cv_as_tls=yes
|
||||
fi
|
||||
elif test x$gcc_cv_as != x; then
|
||||
echo "$conftest_s" > conftest.s
|
||||
if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1
|
||||
then
|
||||
gcc_cv_as_tls=yes
|
||||
fi
|
||||
rm -f conftest.s conftest.o
|
||||
fi
|
||||
if test "$gcc_cv_as_tls" = yes; then
|
||||
cat >> confdefs.h <<\EOF
|
||||
#define HAVE_AS_TLS 1
|
||||
EOF
|
||||
|
||||
fi
|
||||
echo "$ac_t""$gcc_cv_as_tls" 1>&6
|
||||
|
||||
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:7380: checking assembler supports explicit relocations" >&5
|
||||
echo "configure:7450: 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
|
||||
@ -7446,7 +7496,7 @@ EOF
|
||||
;;
|
||||
sparc*-*-*)
|
||||
echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
|
||||
echo "configure:7430: checking assembler .register pseudo-op support" >&5
|
||||
echo "configure:7500: 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
|
||||
@ -7474,7 +7524,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking assembler supports -relax""... $ac_c" 1>&6
|
||||
echo "configure:7458: checking assembler supports -relax" >&5
|
||||
echo "configure:7528: 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
|
||||
@ -7502,7 +7552,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
|
||||
echo "configure:7486: checking assembler and linker support unaligned pc related relocs" >&5
|
||||
echo "configure:7556: 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
|
||||
@ -7529,7 +7579,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking assembler and linker support unaligned pc related relocs against hidden symbols""... $ac_c" 1>&6
|
||||
echo "configure:7513: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5
|
||||
echo "configure:7583: 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
|
||||
@ -7570,7 +7620,7 @@ EOF
|
||||
|
||||
if test "x$gcc_cv_as_flags64" != xno; then
|
||||
echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
|
||||
echo "configure:7554: checking for assembler offsetable %lo() support" >&5
|
||||
echo "configure:7624: 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
|
||||
@ -7610,7 +7660,7 @@ EOF
|
||||
|
||||
i[34567]86-*-* | x86_64-*-*)
|
||||
echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
|
||||
echo "configure:7594: checking assembler instructions" >&5
|
||||
echo "configure:7664: 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
|
||||
@ -7637,7 +7687,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:7621: checking assembler GOTOFF in data directives" >&5
|
||||
echo "configure:7691: 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
|
||||
@ -7667,7 +7717,7 @@ EOF
|
||||
esac
|
||||
|
||||
echo $ac_n "checking assembler dwarf2 debug_line support""... $ac_c" 1>&6
|
||||
echo "configure:7651: checking assembler dwarf2 debug_line support" >&5
|
||||
echo "configure:7721: 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
|
||||
@ -7723,7 +7773,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:7707: checking assembler --gdwarf2 support" >&5
|
||||
echo "configure:7777: 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
|
||||
@ -7752,7 +7802,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:7736: checking assembler --gstabs support" >&5
|
||||
echo "configure:7806: 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
|
||||
@ -7780,7 +7830,7 @@ fi
|
||||
echo "$ac_t""$gcc_cv_as_gstabs_flag" 1>&6
|
||||
|
||||
echo $ac_n "checking linker PT_GNU_EH_FRAME support""... $ac_c" 1>&6
|
||||
echo "configure:7764: checking linker PT_GNU_EH_FRAME support" >&5
|
||||
echo "configure:7834: 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
|
||||
@ -7943,7 +7993,7 @@ fi
|
||||
|
||||
|
||||
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
|
||||
echo "configure:7927: checking whether to enable maintainer-specific portions of Makefiles" >&5
|
||||
echo "configure:7997: 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"
|
||||
|
@ -1718,6 +1718,55 @@ if test x"$gcc_cv_as_shf_merge" = xyes; then
|
||||
fi
|
||||
AC_MSG_RESULT($gcc_cv_as_shf_merge)
|
||||
|
||||
AC_MSG_CHECKING(assembler thread-local storage support)
|
||||
gcc_cv_as_tls=no
|
||||
conftest_s=
|
||||
tls_first_major=
|
||||
tls_first_minor=
|
||||
case "$target" in
|
||||
changequote(,)dnl
|
||||
i[34567]86-*-*)
|
||||
changequote([,])dnl
|
||||
conftest_s='
|
||||
.section ".tdata","awT",@progbits
|
||||
foo: .long 25
|
||||
.text
|
||||
movl %gs:0, %eax
|
||||
leal foo@TLSGD(,%ebx,1), %eax
|
||||
leal foo@TLSLDM(%ebx), %eax
|
||||
leal foo@DTPOFF(%eax), %edx
|
||||
movl foo@GOTTPOFF(%ebx), %eax
|
||||
subl foo@GOTTPOFF(%ebx), %eax
|
||||
movl $foo@TPOFF, %eax
|
||||
subl $foo@TPOFF, %eax
|
||||
leal foo@NTPOFF(%ecx), %eax'
|
||||
tls_first_major=2
|
||||
tls_first_minor=13
|
||||
;;
|
||||
esac
|
||||
if test -z "$tls_first_major"; then
|
||||
:
|
||||
elif 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 "$tls_first_major" \
|
||||
-a "$gcc_cv_gas_minor_version" -ge "$tls_first_minor" \
|
||||
-o "$gcc_cv_gas_major_version" -gt "$tls_first_major"; then
|
||||
gcc_cv_as_tls=yes
|
||||
fi
|
||||
elif test x$gcc_cv_as != x; then
|
||||
echo "$conftest_s" > conftest.s
|
||||
if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1
|
||||
then
|
||||
gcc_cv_as_tls=yes
|
||||
fi
|
||||
rm -f conftest.s conftest.o
|
||||
fi
|
||||
if test "$gcc_cv_as_tls" = yes; then
|
||||
AC_DEFINE(HAVE_AS_TLS, 1,
|
||||
[Define if your assembler supports thread-local storage.])
|
||||
fi
|
||||
AC_MSG_RESULT($gcc_cv_as_tls)
|
||||
|
||||
case "$target" in
|
||||
# All TARGET_ABI_OSF targets.
|
||||
alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*)
|
||||
|
Loading…
Reference in New Issue
Block a user