configure.in (HAVE_AS_TLS): Add alpha tests.

* configure.in (HAVE_AS_TLS): Add alpha tests.
	* configure: Rebuild.
	* config/alpha/alpha.c (TARGET_AS_TLS): New.
	(alpha_tls_size, alpha_tls_size_string): New.
	(overide_options): Set it.  Always install machine_status hooks.
	(input_operand): Accept got tls predicates.
	(local_symbol_p): Merge into ...
	(local_symbolic_operand): ... here.  Reject tls symbols.
	(global_symbolic_operand): Likewise.
	(tls_symbolic_operand_1, dtp16_symbolic_operand): New.
	(dtp32_symbolic_operand, gotdtp_symbolic_operand): New.
	(tp16_symbolic_operand, tp32_symbolic_operand): New.
	(gottp_symbolic_operand, tls_symbolic_operand_type): New.
	(alpha_encode_section_info): Handle TLS symbols.
	(alpha_strip_name_encoding): Likewise.
	(alpha_legitimate_address_p): Likewise.
	(alpha_legitimize_address): Likewise.
	(alpha_expand_mov): Early exit to avoid nop moves.
	(struct machine_function): Move from unicosmk.h.  Add some_ld_name.
	(alpha_init_machine_status, alpha_mark_machine_status,
	alpha_free_machine_status): Always define.
	(get_some_local_dynamic_name, get_some_local_dynamic_name_1): New.
	(print_operand, print_operand_address): Add TLS relocs.
	* config/alpha/alpha.h (HAVE_AS_TLS): Default 0.
	(MASK_TLS_KERNEL, TARGET_TLS_KERNEL): New.
	(TARGET_SWITCHES): Add -mtls-kernel.
	(alpha_tls_size, alpha_tls_size_string): New.
	(TARGET_OPTIONS): Add -mtls-size=.
	(reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS,
	REGNO_REG_CLASS, REG_CLASS_FROM_LETTER): Add R0_REG.
	(ASM_OUTPUT_LABELREF): Skip %.
	(PRINT_OPERAND_PUNCT_VALID_P): Add &.
	(PREDICATE_CODES): Update.
	* config/alpha/alpha.md (UNSPEC_TLSGD_CALL, UNSPEC_TLSLDM_CALL,
	UNSPEC_TLSGD, UNSPEC_TLSLDM, UNSPEC_DTPREL, UNSPEC_TPREL,
	UNSPEC_TP, UNSPECV_SET_TP): New.
	(adddi_er_lo16_dtp, adddi_er_hi32_dtp, adddi_er_lo32_dtp,
	adddi_er_lo16_tp, adddi_er_hi32_tp, adddi_er_lo32_tp, load_tp,
	set_tp, movdi_er_tlsgd, movdi_er_tlsldm, movdi_er_gotdtp,
	movdi_er_gottp, call_value_osf_tlsgd, call_value_osf_tlsldm): New.
	(call_value_osf_2_er): Accept anything as op4.
	* config/alpha/alpha-protos.h: Update.
	* config/alpha/unicosmk.h (struct machine_function): Move to alpha.c.

From-SVN: r54125
This commit is contained in:
Richard Henderson 2002-05-31 17:19:10 -07:00 committed by Richard Henderson
parent 39e5db1a7c
commit 6f9b006de0
8 changed files with 862 additions and 90 deletions

View File

@ -1,3 +1,49 @@
2002-05-31 Richard Henderson <rth@redhat.com>
* configure.in (HAVE_AS_TLS): Add alpha tests.
* configure: Rebuild.
* config/alpha/alpha.c (TARGET_AS_TLS): New.
(alpha_tls_size, alpha_tls_size_string): New.
(overide_options): Set it. Always install machine_status hooks.
(input_operand): Accept got tls predicates.
(local_symbol_p): Merge into ...
(local_symbolic_operand): ... here. Reject tls symbols.
(global_symbolic_operand): Likewise.
(tls_symbolic_operand_1, dtp16_symbolic_operand): New.
(dtp32_symbolic_operand, gotdtp_symbolic_operand): New.
(tp16_symbolic_operand, tp32_symbolic_operand): New.
(gottp_symbolic_operand, tls_symbolic_operand_type): New.
(alpha_encode_section_info): Handle TLS symbols.
(alpha_strip_name_encoding): Likewise.
(alpha_legitimate_address_p): Likewise.
(alpha_legitimize_address): Likewise.
(alpha_expand_mov): Early exit to avoid nop moves.
(struct machine_function): Move from unicosmk.h. Add some_ld_name.
(alpha_init_machine_status, alpha_mark_machine_status,
alpha_free_machine_status): Always define.
(get_some_local_dynamic_name, get_some_local_dynamic_name_1): New.
(print_operand, print_operand_address): Add TLS relocs.
* config/alpha/alpha.h (HAVE_AS_TLS): Default 0.
(MASK_TLS_KERNEL, TARGET_TLS_KERNEL): New.
(TARGET_SWITCHES): Add -mtls-kernel.
(alpha_tls_size, alpha_tls_size_string): New.
(TARGET_OPTIONS): Add -mtls-size=.
(reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS,
REGNO_REG_CLASS, REG_CLASS_FROM_LETTER): Add R0_REG.
(ASM_OUTPUT_LABELREF): Skip %.
(PRINT_OPERAND_PUNCT_VALID_P): Add &.
(PREDICATE_CODES): Update.
* config/alpha/alpha.md (UNSPEC_TLSGD_CALL, UNSPEC_TLSLDM_CALL,
UNSPEC_TLSGD, UNSPEC_TLSLDM, UNSPEC_DTPREL, UNSPEC_TPREL,
UNSPEC_TP, UNSPECV_SET_TP): New.
(adddi_er_lo16_dtp, adddi_er_hi32_dtp, adddi_er_lo32_dtp,
adddi_er_lo16_tp, adddi_er_hi32_tp, adddi_er_lo32_tp, load_tp,
set_tp, movdi_er_tlsgd, movdi_er_tlsldm, movdi_er_gotdtp,
movdi_er_gottp, call_value_osf_tlsgd, call_value_osf_tlsldm): New.
(call_value_osf_2_er): Accept anything as op4.
* config/alpha/alpha-protos.h: Update.
* config/alpha/unicosmk.h (struct machine_function): Move to alpha.c.
2002-05-31 Zack Weinberg <zack@codesourcery.com>
* cppinit.c (append_include_chain): Always pay attention to

View File

@ -61,6 +61,12 @@ extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int some_small_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int dtp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int dtp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int gotdtp_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int tp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int tp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int gottp_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int call_operand PARAMS ((rtx, enum machine_mode));
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int alpha_comparison_operator PARAMS ((rtx, enum machine_mode));

View File

@ -69,6 +69,10 @@ enum alpha_fp_rounding_mode alpha_fprm;
enum alpha_fp_trap_mode alpha_fptm;
/* Specify bit size of immediate TLS offsets. */
int alpha_tls_size = 32;
/* Strings decoded into the above options. */
const char *alpha_cpu_string; /* -mcpu= */
@ -77,6 +81,7 @@ const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
const char *alpha_mlat_string; /* -mmemory-latency= */
const char *alpha_tls_size_string; /* -mtls-size=[16|32|64] */
/* Save information from a "cmpxx" operation until the branch or scc is
emitted. */
@ -113,6 +118,10 @@ int alpha_this_literal_sequence_number;
int alpha_this_gpdisp_sequence_number;
/* Declarations of static functions. */
static int tls_symbolic_operand_1
PARAMS ((rtx, enum machine_mode, int, int));
static enum tls_model tls_symbolic_operand_type
PARAMS ((rtx));
static bool decl_in_text_section
PARAMS ((tree));
static bool alpha_in_small_data_p
@ -125,8 +134,6 @@ static int some_small_symbolic_operand_1
PARAMS ((rtx *, void *));
static int split_small_symbolic_operand_1
PARAMS ((rtx *, void *));
static bool local_symbol_p
PARAMS ((rtx));
static void alpha_set_memflags_1
PARAMS ((rtx, int, int, int));
static rtx alpha_emit_set_const_1
@ -147,6 +154,10 @@ static const char *get_trap_mode_suffix
PARAMS ((void));
static const char *get_round_mode_suffix
PARAMS ((void));
static const char *get_some_local_dynamic_name
PARAMS ((void));
static int get_some_local_dynamic_name_1
PARAMS ((rtx *, void *));
static rtx set_frame_related_p
PARAMS ((void));
static const char *alpha_lookup_xfloating_lib_func
@ -173,14 +184,12 @@ static void alpha_elf_select_rtx_section
PARAMS ((enum machine_mode, rtx, unsigned HOST_WIDE_INT));
#endif
#if TARGET_ABI_UNICOSMK
static void alpha_init_machine_status
PARAMS ((struct function *p));
static void alpha_mark_machine_status
PARAMS ((struct function *p));
static void alpha_free_machine_status
PARAMS ((struct function *p));
#endif
static void unicosmk_output_deferred_case_vectors PARAMS ((FILE *));
static void unicosmk_gen_dsib PARAMS ((unsigned long *imaskP));
@ -266,6 +275,9 @@ static void unicosmk_unique_section PARAMS ((tree, int));
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
alpha_multipass_dfa_lookahead
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS HAVE_AS_TLS
struct gcc_target targetm = TARGET_INITIALIZER;
/* Parse target option strings. */
@ -385,6 +397,18 @@ override_options ()
error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string);
}
if (alpha_tls_size_string)
{
if (strcmp (alpha_tls_size_string, "16") == 0)
alpha_tls_size = 16;
else if (strcmp (alpha_tls_size_string, "32") == 0)
alpha_tls_size = 32;
else if (strcmp (alpha_tls_size_string, "64") == 0)
alpha_tls_size = 64;
else
error ("bad value `%s' for -mtls-size switch", alpha_tls_size_string);
}
alpha_cpu
= TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
: (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
@ -527,12 +551,10 @@ override_options ()
/* Register variables and functions with the garbage collector. */
#if TARGET_ABI_UNICOSMK
/* Set up function hooks. */
init_machine_status = alpha_init_machine_status;
mark_machine_status = alpha_mark_machine_status;
free_machine_status = alpha_free_machine_status;
#endif
}
/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
@ -857,7 +879,9 @@ input_operand (op, mode)
symbolic operands to be reconstructed from their high/lo_sum
form. */
return (small_symbolic_operand (op, mode)
|| global_symbolic_operand (op, mode));
|| global_symbolic_operand (op, mode)
|| gotdtp_symbolic_operand (op, mode)
|| gottp_symbolic_operand (op, mode));
}
/* This handles both the Windows/NT and OSF cases. */
@ -946,29 +970,13 @@ direct_call_operand (op, mode)
/* Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing
a variable known to be defined in this file. */
static bool
local_symbol_p (op)
rtx op;
{
const char *str = XSTR (op, 0);
/* ??? SYMBOL_REF_FLAG is set for local function symbols, but we
run into problems with the rtl inliner in that the symbol was
once external, but is local after inlining, which results in
unrecognizable insns. */
return (CONSTANT_POOL_ADDRESS_P (op)
/* If @, then alpha_encode_section_info sez it's local. */
|| str[0] == '@'
/* If *$, then ASM_GENERATE_INTERNAL_LABEL sez it's local. */
|| (str[0] == '*' && str[1] == '$'));
}
int
local_symbolic_operand (op, mode)
rtx op;
enum machine_mode mode;
{
const char *str;
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@ -983,7 +991,26 @@ local_symbolic_operand (op, mode)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
return local_symbol_p (op);
/* Easy pickings. */
if (CONSTANT_POOL_ADDRESS_P (op) || STRING_POOL_ADDRESS_P (op))
return 1;
/* ??? SYMBOL_REF_FLAG is set for local function symbols, but we
run into problems with the rtl inliner in that the symbol was
once external, but is local after inlining, which results in
unrecognizable insns. */
str = XSTR (op, 0);
/* If @[VS], then alpha_encode_section_info sez it's local. */
if (str[0] == '@' && (str[1] == 'L' || str[1] == 'S'))
return 1;
/* If *$, then ASM_GENERATE_INTERNAL_LABEL sez it's local. */
if (str[0] == '*' && str[1] == '$')
return 1;
return 0;
}
/* Return true if OP is a SYMBOL_REF or CONST referencing a variable
@ -1015,7 +1042,7 @@ small_symbolic_operand (op, mode)
else
{
str = XSTR (op, 0);
return str[0] == '@' && str[1] == 's';
return str[0] == '@' && str[1] == 'S';
}
}
@ -1027,6 +1054,8 @@ global_symbolic_operand (op, mode)
rtx op;
enum machine_mode mode;
{
const char *str;
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@ -1038,7 +1067,12 @@ global_symbolic_operand (op, mode)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
return ! local_symbol_p (op);
if (local_symbolic_operand (op, mode))
return 0;
/* Also verify that it's not a TLS symbol. */
str = XSTR (op, 0);
return str[0] != '%' && str[0] != '@';
}
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
@ -1091,6 +1125,110 @@ symbolic_operand (op, mode)
return 0;
}
/* Return true if OP is valid for a particular TLS relocation. */
static int
tls_symbolic_operand_1 (op, mode, size, unspec)
rtx op;
enum machine_mode mode;
int size, unspec;
{
const char *str;
int letter;
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
if (GET_CODE (op) != CONST)
return 0;
op = XEXP (op, 0);
if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec)
return 0;
op = XVECEXP (op, 0, 0);
if (GET_CODE (op) != SYMBOL_REF)
return 0;
str = XSTR (op, 0);
if (str[0] == '%')
{
if (size != 64)
return 0;
}
else if (str[0] == '@')
{
if (alpha_tls_size > size)
return 0;
}
else
return 0;
letter = (unspec == UNSPEC_DTPREL ? 'D' : 'T');
return str[1] == letter;
}
/* Return true if OP is valid for 16-bit DTP relative relocations. */
int
dtp16_symbolic_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return tls_symbolic_operand_1 (op, mode, 16, UNSPEC_DTPREL);
}
/* Return true if OP is valid for 32-bit DTP relative relocations. */
int
dtp32_symbolic_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return tls_symbolic_operand_1 (op, mode, 32, UNSPEC_DTPREL);
}
/* Return true if OP is valid for 64-bit DTP relative relocations. */
int
gotdtp_symbolic_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return tls_symbolic_operand_1 (op, mode, 64, UNSPEC_DTPREL);
}
/* Return true if OP is valid for 16-bit TP relative relocations. */
int
tp16_symbolic_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return tls_symbolic_operand_1 (op, mode, 16, UNSPEC_TPREL);
}
/* Return true if OP is valid for 32-bit TP relative relocations. */
int
tp32_symbolic_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return tls_symbolic_operand_1 (op, mode, 32, UNSPEC_TPREL);
}
/* Return true if OP is valid for 64-bit TP relative relocations. */
int
gottp_symbolic_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return tls_symbolic_operand_1 (op, mode, 64, UNSPEC_TPREL);
}
/* Return 1 if OP is a valid Alpha comparison operator. Here we know which
comparisons are valid in which insn. */
@ -1561,6 +1699,54 @@ alpha_tablejump_best_label (insn)
return best_label ? best_label : const0_rtx;
}
/* Return the TLS model to use for SYMBOL. */
static enum tls_model
tls_symbolic_operand_type (symbol)
rtx symbol;
{
const char *str;
if (GET_CODE (symbol) != SYMBOL_REF)
return 0;
str = XSTR (symbol, 0);
if (str[0] == '%')
{
/* ??? Be prepared for -ftls-model=local-dynamic. Perhaps we shouldn't
have separately encoded local-ness. On well, maybe the user will use
attribute visibility next time. At least we don't crash... */
if (str[1] == 'G' || str[1] == 'D')
return TLS_MODEL_GLOBAL_DYNAMIC;
if (str[1] == 'T')
return TLS_MODEL_INITIAL_EXEC;
}
else if (str[0] == '@')
{
if (str[1] == 'D')
{
/* Local dynamic is a waste if we're not going to combine
the __tls_get_addr calls. So avoid it if not optimizing. */
if (optimize)
return TLS_MODEL_LOCAL_DYNAMIC;
else
return TLS_MODEL_GLOBAL_DYNAMIC;
}
if (str[1] == 'T')
{
/* 64-bit local exec is the same as initial exec except without
the dynamic relocation. In either case we use a got entry. */
if (alpha_tls_size == 64)
return TLS_MODEL_INITIAL_EXEC;
else
return TLS_MODEL_LOCAL_EXEC;
}
}
return 0;
}
/* Return true if the function DECL will be placed in the default text
section. */
@ -1622,7 +1808,8 @@ alpha_encode_section_info (decl, first)
int first ATTRIBUTE_UNUSED;
{
const char *symbol_str;
bool is_local, is_small;
bool is_local;
char encoding = 0;
rtx rtl, symbol;
rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
@ -1659,18 +1846,56 @@ alpha_encode_section_info (decl, first)
/* A variable is considered "local" if it is defined in this module. */
is_local = (*targetm.binds_local_p) (decl);
/* Determine if DECL will wind up in .sdata/.sbss. */
is_small = alpha_in_small_data_p (decl);
/* Care for TLS variables. */
if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
{
enum tls_model kind;
if (!flag_pic)
{
if (is_local)
kind = TLS_MODEL_LOCAL_EXEC;
else
kind = TLS_MODEL_INITIAL_EXEC;
}
else if (is_local)
kind = TLS_MODEL_LOCAL_DYNAMIC;
else
kind = TLS_MODEL_GLOBAL_DYNAMIC;
if (kind < flag_tls_default)
kind = flag_tls_default;
switch (kind)
{
case TLS_MODEL_GLOBAL_DYNAMIC:
encoding = 'G';
break;
case TLS_MODEL_LOCAL_DYNAMIC:
encoding = 'D';
break;
case TLS_MODEL_INITIAL_EXEC:
case TLS_MODEL_LOCAL_EXEC:
encoding = 'T';
break;
}
}
else if (is_local)
{
/* Determine if DECL will wind up in .sdata/.sbss. */
if (alpha_in_small_data_p (decl))
encoding = 'S';
else
encoding = 'L';
}
/* Finally, encode this into the symbol string. */
if (is_local)
if (encoding)
{
char *newstr;
size_t len;
if (symbol_str[0] == '@')
if (symbol_str[0] == (is_local ? '@' : '%'))
{
if (symbol_str[1] == (is_small ? 's' : 'v'))
if (symbol_str[1] == encoding)
return;
symbol_str += 2;
}
@ -1678,18 +1903,12 @@ alpha_encode_section_info (decl, first)
len = strlen (symbol_str) + 1;
newstr = alloca (len + 2);
newstr[0] = '@';
newstr[1] = (is_small ? 's' : 'v');
newstr[0] = (is_local ? '@' : '%');
newstr[1] = encoding;
memcpy (newstr + 2, symbol_str, len);
XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
}
else if (symbol_str[0] == '@')
{
/* We're hosed. This can happen when the user adds a weak
attribute after rtl generation. They should have gotten
a warning about unspecified behaviour from varasm.c. */
}
}
/* Undo the effects of the above. */
@ -1698,7 +1917,7 @@ static const char *
alpha_strip_name_encoding (str)
const char *str;
{
if (str[0] == '@')
if (str[0] == '@' || str[0] == '%')
str += 2;
if (str[0] == '*')
str++;
@ -1799,7 +2018,9 @@ alpha_legitimate_address_p (mode, x, strict)
return false;
/* The symbol must be local. */
if (local_symbolic_operand (ofs, Pmode))
if (local_symbolic_operand (ofs, Pmode)
|| dtp32_symbolic_operand (ofs, Pmode)
|| tp32_symbolic_operand (ofs, Pmode))
return true;
}
}
@ -1865,6 +2086,100 @@ alpha_legitimize_address (x, scratch, mode)
/* If this is a local symbol, split the address into HIGH/LO_SUM parts. */
if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
{
rtx r0, r16, eqv, tga, tp, insn, dest, seq;
switch (tls_symbolic_operand_type (x))
{
case TLS_MODEL_GLOBAL_DYNAMIC:
start_sequence ();
r0 = gen_rtx_REG (Pmode, 0);
r16 = gen_rtx_REG (Pmode, 16);
tga = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
dest = gen_reg_rtx (Pmode);
seq = GEN_INT (alpha_next_sequence_number++);
emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
insn = gen_call_value_osf_tlsgd (r0, tga, seq);
insn = emit_call_insn (insn);
CONST_OR_PURE_CALL_P (insn) = 1;
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
insn = get_insns ();
end_sequence ();
emit_libcall_block (insn, dest, r0, x);
return dest;
case TLS_MODEL_LOCAL_DYNAMIC:
start_sequence ();
r0 = gen_rtx_REG (Pmode, 0);
r16 = gen_rtx_REG (Pmode, 16);
tga = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
scratch = gen_reg_rtx (Pmode);
seq = GEN_INT (alpha_next_sequence_number++);
emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
insn = gen_call_value_osf_tlsldm (r0, tga, seq);
insn = emit_call_insn (insn);
CONST_OR_PURE_CALL_P (insn) = 1;
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
insn = get_insns ();
end_sequence ();
eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
UNSPEC_TLSLDM_CALL);
emit_libcall_block (insn, scratch, r0, eqv);
eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL);
eqv = gen_rtx_CONST (Pmode, eqv);
if (alpha_tls_size == 64)
{
dest = gen_reg_rtx (Pmode);
emit_insn (gen_rtx_SET (VOIDmode, dest, eqv));
emit_insn (gen_adddi3 (dest, dest, scratch));
return dest;
}
if (alpha_tls_size == 32)
{
insn = gen_rtx_HIGH (Pmode, eqv);
insn = gen_rtx_PLUS (Pmode, scratch, insn);
scratch = gen_reg_rtx (Pmode);
emit_insn (gen_rtx_SET (VOIDmode, scratch, insn));
}
return gen_rtx_LO_SUM (Pmode, scratch, eqv);
case TLS_MODEL_INITIAL_EXEC:
eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
eqv = gen_rtx_CONST (Pmode, eqv);
tp = gen_reg_rtx (Pmode);
scratch = gen_reg_rtx (Pmode);
dest = gen_reg_rtx (Pmode);
emit_insn (gen_load_tp (tp));
emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
emit_insn (gen_adddi3 (dest, tp, scratch));
return dest;
case TLS_MODEL_LOCAL_EXEC:
eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
eqv = gen_rtx_CONST (Pmode, eqv);
tp = gen_reg_rtx (Pmode);
emit_insn (gen_load_tp (tp));
if (alpha_tls_size == 32)
{
insn = gen_rtx_HIGH (Pmode, eqv);
insn = gen_rtx_PLUS (Pmode, tp, insn);
tp = gen_reg_rtx (Pmode);
emit_insn (gen_rtx_SET (VOIDmode, tp, insn));
}
return gen_rtx_LO_SUM (Pmode, tp, eqv);
}
if (local_symbolic_operand (x, Pmode))
{
if (small_symbolic_operand (x, Pmode))
@ -2589,6 +2904,8 @@ alpha_expand_mov (mode, operands)
tmp = alpha_legitimize_address (operands[1], operands[0], mode);
if (tmp)
{
if (tmp == operands[0])
return true;
operands[1] = tmp;
return false;
}
@ -4906,10 +5223,31 @@ alpha_multipass_dfa_lookahead ()
return (alpha_cpu == PROCESSOR_EV6 ? 4 : 2);
}
/* Machine-specific function data. */
struct machine_function
{
#if TARGET_ABI_UNICOSMK
/* List of call information words for calls from this function. */
struct rtx_def *first_ciw;
struct rtx_def *last_ciw;
int ciw_count;
/* List of deferred case vectors. */
struct rtx_def *addr_list;
#else
#if TARGET_ABI_OSF
const char *some_ld_name;
#else
/* Non-empty struct. */
char dummy;
#endif
#endif
};
/* Register global variables and machine-specific functions with the
garbage collector. */
#if TARGET_ABI_UNICOSMK
static void
alpha_init_machine_status (p)
struct function *p;
@ -4917,10 +5255,15 @@ alpha_init_machine_status (p)
p->machine =
(struct machine_function *) xcalloc (1, sizeof (struct machine_function));
#if TARGET_ABI_UNICOSMK
p->machine->first_ciw = NULL_RTX;
p->machine->last_ciw = NULL_RTX;
p->machine->ciw_count = 0;
p->machine->addr_list = NULL_RTX;
#endif
#if TARGET_ABI_OSF
p->machine->some_ld_name = NULL;
#endif
}
static void
@ -4931,8 +5274,10 @@ alpha_mark_machine_status (p)
if (machine)
{
#if TARGET_ABI_UNICOSMK
ggc_mark_rtx (machine->first_ciw);
ggc_mark_rtx (machine->addr_list);
#endif
}
}
@ -4943,7 +5288,6 @@ alpha_free_machine_status (p)
free (p->machine);
p->machine = NULL;
}
#endif /* TARGET_ABI_UNICOSMK */
/* Functions to save and restore alpha_return_addr_rtx. */
@ -5087,6 +5431,45 @@ get_round_mode_suffix ()
abort ();
}
/* Locate some local-dynamic symbol still in use by this function
so that we can print its name in some movdi_er_tlsldm 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)
{
const char *str = XSTR (x, 0);
if (str[0] == '@' && str[1] == 'D')
{
cfun->machine->some_ld_name = str;
return 1;
}
}
return 0;
}
/* Print an operand. Recognize special options, documented below. */
void
@ -5104,6 +5487,10 @@ print_operand (file, x, code)
assemble_name (file, alpha_fnname);
break;
case '&':
assemble_name (file, get_some_local_dynamic_name ());
break;
case '/':
{
const char *trap = get_trap_mode_suffix ();
@ -5145,13 +5532,30 @@ print_operand (file, x, code)
break;
case 'J':
if (GET_CODE (x) == CONST_INT)
{
if (INTVAL (x) != 0)
fprintf (file, "\t\t!lituse_jsr!%d", (int) INTVAL (x));
}
else
output_operand_lossage ("invalid %%J value");
{
const char *lituse;
if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
{
x = XVECEXP (x, 0, 0);
lituse = "lituse_tlsgd";
}
else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
{
x = XVECEXP (x, 0, 0);
lituse = "lituse_tlsldm";
}
else if (GET_CODE (x) == CONST_INT)
lituse = "lituse_jsr";
else
{
output_operand_lossage ("invalid %%J value");
break;
}
if (x != const0_rtx)
fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
}
break;
case 'r':
@ -5385,6 +5789,19 @@ print_operand (file, x, code)
fprintf (file, "%s", reg_names[REGNO (x)]);
else if (GET_CODE (x) == MEM)
output_address (XEXP (x, 0));
else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
{
switch (XINT (XEXP (x, 0), 1))
{
case UNSPEC_DTPREL:
case UNSPEC_TPREL:
output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
break;
default:
output_operand_lossage ("unknown relocation unspec");
break;
}
}
else
output_addr_const (file, x);
break;
@ -5414,7 +5831,36 @@ print_operand_address (file, addr)
if (GET_CODE (addr) == LO_SUM)
{
output_addr_const (file, XEXP (addr, 1));
const char *reloc16, *reloclo;
rtx op1 = XEXP (addr, 1);
if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
{
op1 = XEXP (op1, 0);
switch (XINT (op1, 1))
{
case UNSPEC_DTPREL:
reloc16 = NULL;
reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
break;
case UNSPEC_TPREL:
reloc16 = NULL;
reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
break;
default:
output_operand_lossage ("unknown relocation unspec");
return;
}
output_addr_const (file, XVECEXP (op1, 0, 0));
}
else
{
reloc16 = "gprel";
reloclo = "gprellow";
output_addr_const (file, op1);
}
if (offset)
{
fputc ('+', file);
@ -5431,7 +5877,7 @@ print_operand_address (file, addr)
abort ();
fprintf (file, "($%d)\t\t!%s", basereg,
(basereg == 29 ? "gprel" : "gprellow"));
(basereg == 29 ? reloc16 : reloclo));
return;
}

View File

@ -137,6 +137,7 @@ extern int target_flags;
extern enum alpha_trap_precision alpha_tp;
extern enum alpha_fp_rounding_mode alpha_fprm;
extern enum alpha_fp_trap_mode alpha_fptm;
extern int alpha_tls_size;
/* This means that floating-point support exists in the target implementation
of the Alpha architecture. This is usually the default. */
@ -208,6 +209,10 @@ extern enum alpha_fp_trap_mode alpha_fptm;
#define MASK_SMALL_DATA (1 << 13)
#define TARGET_SMALL_DATA (target_flags & MASK_SMALL_DATA)
/* This means emit thread pointer loads for kernel not user. */
#define MASK_TLS_KERNEL (1 << 14)
#define TARGET_TLS_KERNEL (target_flags & MASK_TLS_KERNEL)
/* This means that the processor is an EV5, EV56, or PCA56.
Unlike alpha_cpu this is not affected by -mtune= setting. */
#define MASK_CPU_EV5 (1 << 28)
@ -251,6 +256,9 @@ extern enum alpha_fp_trap_mode alpha_fptm;
#ifndef TARGET_FIXUP_EV5_PREFETCH
#define TARGET_FIXUP_EV5_PREFETCH 0
#endif
#ifndef HAVE_AS_TLS
#define HAVE_AS_TLS 0
#endif
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
@ -293,6 +301,8 @@ extern enum alpha_fp_trap_mode alpha_fptm;
N_("Emit 16-bit relocations to the small data areas")}, \
{"large-data", -MASK_SMALL_DATA, \
N_("Emit 32-bit relocations to the small data areas")}, \
{"tls-kernel", MASK_TLS_KERNEL, \
N_("Emit rdval instead of rduniq for thread pointer")}, \
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT \
| TARGET_DEFAULT_EXPLICIT_RELOCS, ""} }
@ -316,6 +326,7 @@ extern const char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */
extern const char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */
extern const char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */
extern const char *alpha_mlat_string; /* For -mmemory-latency= */
extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define TARGET_OPTIONS \
{ \
@ -331,6 +342,8 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
N_("Control the precision given to fp exceptions")}, \
{"memory-latency=", &alpha_mlat_string, \
N_("Tune expected memory latency")}, \
{"tls-size=", &alpha_tls_size_string, \
N_("Specify bit size of immediate TLS offsets")}, \
}
/* This macro defines names of additional specifications to put in the
@ -681,7 +694,7 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
class that represents their union. */
enum reg_class {
NO_REGS, R24_REG, R25_REG, R27_REG,
NO_REGS, R0_REG, R24_REG, R25_REG, R27_REG,
GENERAL_REGS, FLOAT_REGS, ALL_REGS,
LIM_REG_CLASSES
};
@ -690,8 +703,8 @@ enum reg_class {
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
{"NO_REGS", "R24_REG", "R25_REG", "R27_REG", \
#define REG_CLASS_NAMES \
{"NO_REGS", "R0_REG", "R24_REG", "R25_REG", "R27_REG", \
"GENERAL_REGS", "FLOAT_REGS", "ALL_REGS" }
/* Define which registers fit in which classes.
@ -700,6 +713,7 @@ enum reg_class {
#define REG_CLASS_CONTENTS \
{ {0x00000000, 0x00000000}, /* NO_REGS */ \
{0x00000001, 0x00000000}, /* R0_REG */ \
{0x01000000, 0x00000000}, /* R24_REG */ \
{0x02000000, 0x00000000}, /* R25_REG */ \
{0x08000000, 0x00000000}, /* R27_REG */ \
@ -713,7 +727,8 @@ enum reg_class {
or could index an array. */
#define REGNO_REG_CLASS(REGNO) \
((REGNO) == 24 ? R24_REG \
((REGNO) == 0 ? R0_REG \
: (REGNO) == 24 ? R24_REG \
: (REGNO) == 25 ? R25_REG \
: (REGNO) == 27 ? R27_REG \
: (REGNO) >= 32 && (REGNO) <= 62 ? FLOAT_REGS \
@ -730,6 +745,7 @@ enum reg_class {
: (C) == 'b' ? R25_REG \
: (C) == 'c' ? R27_REG \
: (C) == 'f' ? FLOAT_REGS \
: (C) == 'v' ? R0_REG \
: NO_REGS)
/* Define this macro to change register usage conditional on target flags. */
@ -1710,7 +1726,7 @@ do { \
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
do { \
const char *name_ = NAME; \
if (*name_ == '@') \
if (*name_ == '@' || *name == '%') \
name_ += 2; \
if (*name_ == '*') \
name_++; \
@ -1893,7 +1909,7 @@ do { \
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~' \
|| (CODE) == '#' || (CODE) == '*')
|| (CODE) == '#' || (CODE) == '*' || (CODE) == '&')
/* Print a memory address as an operand to reference that memory location. */
@ -1929,6 +1945,12 @@ do { \
{"local_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{"small_symbolic_operand", {SYMBOL_REF, CONST}}, \
{"global_symbolic_operand", {SYMBOL_REF, CONST}}, \
{"dtp16_symbolic_operand", {CONST}}, \
{"dtp32_symbolic_operand", {CONST}}, \
{"gotdtp_symbolic_operand", {CONST}}, \
{"tp16_symbolic_operand", {CONST}}, \
{"tp32_symbolic_operand", {CONST}}, \
{"gottp_symbolic_operand", {CONST}}, \
{"call_operand", {REG, SYMBOL_REF}}, \
{"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \
SYMBOL_REF, CONST, LABEL_REF, HIGH}}, \

View File

@ -1,6 +1,6 @@
;; Machine description for DEC Alpha for GNU C compiler
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
;; 2000, 2001 Free Software Foundation, Inc.
;; 2000, 2001, 2002 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
;;
;; This file is part of GNU CC.
@ -40,6 +40,15 @@
(UNSPEC_LITUSE 12)
(UNSPEC_SIBCALL 13)
(UNSPEC_SYMBOL 14)
;; TLS Support
(UNSPEC_TLSGD_CALL 15)
(UNSPEC_TLSLDM_CALL 16)
(UNSPEC_TLSGD 17)
(UNSPEC_TLSLDM 18)
(UNSPEC_DTPREL 19)
(UNSPEC_TPREL 20)
(UNSPEC_TP 21)
])
;; UNSPEC_VOLATILE:
@ -57,6 +66,7 @@
(UNSPECV_FORCE_MOV 9)
(UNSPECV_LDGP1 10)
(UNSPECV_PLDGP2 11) ; prologue ldgp
(UNSPECV_SET_TP 12)
])
;; Where necessary, the suffixes _le and _be are used to distinguish between
@ -335,6 +345,48 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
""
"")
(define_insn "*adddi_er_lo16_dtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "dtp16_symbolic_operand" "")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!dtprel")
(define_insn "*adddi_er_hi32_dtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
(high:DI (match_operand:DI 2 "dtp32_symbolic_operand" ""))))]
"HAVE_AS_TLS"
"ldah %0,%2(%1)\t\t!dtprelhi")
(define_insn "*adddi_er_lo32_dtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "dtp32_symbolic_operand" "")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!dtprello")
(define_insn "*adddi_er_lo16_tp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "tp16_symbolic_operand" "")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!tprel")
(define_insn "*adddi_er_hi32_tp"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
(high:DI (match_operand:DI 2 "tp32_symbolic_operand" ""))))]
"HAVE_AS_TLS"
"ldah %0,%2(%1)\t\t!tprelhi")
(define_insn "*adddi_er_lo32_tp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "tp32_symbolic_operand" "")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!tprello")
(define_insn "*adddi_er_high_l"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
@ -4805,6 +4857,43 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"!TARGET_ABI_WINDOWS_NT"
"call_pal 0x81"
[(set_attr "type" "ibr")])
;; For userland, we load the thread pointer from the TCB.
;; For the kernel, we load the per-cpu private value.
(define_insn "load_tp"
[(set (match_operand:DI 0 "register_operand" "=v")
(unspec:DI [(const_int 0)] UNSPEC_TP))]
"TARGET_ABI_OSF"
{
if (TARGET_TLS_KERNEL)
return "call_pal 0x32";
else
return "call_pal 0x9e";
}
[(set_attr "type" "ibr")])
;; For completeness, and possibly a __builtin function, here's how to
;; set the thread pointer. Since we don't describe enough of this
;; quantity for CSE, we have to use a volatile unspec, and then there's
;; not much point in creating an R16_REG register class.
(define_expand "set_tp"
[(set (reg:DI 16) (match_operand:DI 0 "input_operand" ""))
(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
"TARGET_ABI_OSF"
"")
(define_insn "*set_tp"
[(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
"TARGET_ABI_OSF"
{
if (TARGET_TLS_KERNEL)
return "call_pal 0x31";
else
return "call_pal 0x9f";
}
[(set_attr "type" "ibr")])
;; Finally, we have the basic data motion insns. The byte and word insns
;; are done via define_expand. Start with the floating-point insns, since
@ -5282,6 +5371,75 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
}
})
(define_insn "movdi_er_tlsgd"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "symbolic_operand" "")
(match_operand 3 "const_int_operand" "")]
UNSPEC_TLSGD))]
"HAVE_AS_TLS"
{
if (INTVAL (operands[3]) == 0)
return "lda %0,%2(%1)\t\t!tlsgd";
else
return "lda %0,%2(%1)\t\t!tlsgd!%3";
})
(define_insn "movdi_er_tlsldm"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
(match_operand 2 "const_int_operand" "")]
UNSPEC_TLSLDM))]
"HAVE_AS_TLS"
{
if (INTVAL (operands[2]) == 0)
return "lda %0,%&(%1)\t\t!tlsldm";
else
return "lda %0,%&(%1)\t\t!tlsldm!%2";
})
(define_insn "*movdi_er_gotdtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "symbolic_operand" "")]
UNSPEC_DTPREL))]
"HAVE_AS_TLS"
"ldq %0,%2(%1)\t\t!gotdtprel"
[(set_attr "type" "ild")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "gotdtp_symbolic_operand" ""))]
"HAVE_AS_TLS && reload_completed"
[(set (match_dup 0)
(unspec:DI [(match_dup 2)
(match_dup 1)] UNSPEC_DTPREL))]
{
operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
operands[2] = pic_offset_table_rtx;
})
(define_insn "*movdi_er_gottp"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "symbolic_operand" "")]
UNSPEC_TPREL))]
"HAVE_AS_TLS"
"ldq %0,%2(%1)\t\t!gottprel"
[(set_attr "type" "ild")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "gottp_symbolic_operand" ""))]
"HAVE_AS_TLS && reload_completed"
[(set (match_dup 0)
(unspec:DI [(match_dup 2)
(match_dup 1)] UNSPEC_TPREL))]
{
operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
operands[2] = pic_offset_table_rtx;
})
(define_insn "*movdi_er_nofix"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
@ -6720,7 +6878,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(plus:DI (pc) (const_int 4)))
(unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
(use (match_operand 3 "" ""))
(use (match_operand 4 "const_int_operand" ""))]
(use (match_operand 4 "" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4"
[(set_attr "type" "jsr")])
@ -6740,6 +6898,70 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(set_attr "type" "jsr")
(set_attr "length" "*,*,8")])
(define_insn_and_split "call_value_osf_tlsgd"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
(const_int 0)))
(unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSGD_CALL)
(use (reg:DI 29))
(clobber (reg:DI 26))]
"HAVE_AS_TLS"
"#"
"&& reload_completed"
[(set (match_dup 3)
(unspec:DI [(match_dup 5)
(match_dup 1)
(match_dup 2)] UNSPEC_LITERAL))
(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(const_int 0)))
(set (reg:DI 26) (plus:DI (pc) (const_int 4)))
(unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE)
(use (match_dup 1))
(use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))])
(set (match_dup 5)
(unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
(set (match_dup 5)
(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
{
operands[3] = gen_rtx_REG (Pmode, 27);
operands[4] = GEN_INT (alpha_next_sequence_number++);
operands[5] = pic_offset_table_rtx;
}
[(set_attr "type" "multi")])
(define_insn_and_split "call_value_osf_tlsldm"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
(const_int 0)))
(unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSLDM_CALL)
(use (reg:DI 29))
(clobber (reg:DI 26))]
"HAVE_AS_TLS"
"#"
"&& reload_completed"
[(set (match_dup 3)
(unspec:DI [(match_dup 5)
(match_dup 1)
(match_dup 2)] UNSPEC_LITERAL))
(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(const_int 0)))
(set (reg:DI 26) (plus:DI (pc) (const_int 4)))
(unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE)
(use (match_dup 1))
(use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))])
(set (reg:DI 29)
(unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
(set (reg:DI 29)
(unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
{
operands[3] = gen_rtx_REG (Pmode, 27);
operands[4] = GEN_INT (alpha_next_sequence_number++);
operands[5] = pic_offset_table_rtx;
}
[(set_attr "type" "multi")])
(define_insn "*call_value_osf_1"
[(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
@ -6815,4 +7037,3 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"TARGET_ABI_UNICOSMK"
"jsr $26,(%1)"
[(set_attr "type" "jsr")])

View File

@ -293,19 +293,6 @@ do { \
#undef EPILOGUE_USES
#define EPILOGUE_USES(REGNO) ((REGNO) == 26 || (REGNO) == 15)
/* Machine-specific function data. */
struct machine_function
{
/* List of call information words for calls from this function. */
struct rtx_def *first_ciw;
struct rtx_def *last_ciw;
int ciw_count;
/* List of deferred case vectors. */
struct rtx_def *addr_list;
};
/* Would have worked, only the stack doesn't seem to be executable
#undef TRAMPOLINE_TEMPLATE
#define TRAMPOLINE_TEMPLATE(FILE) \

48
gcc/configure vendored
View File

@ -7399,6 +7399,28 @@ conftest_s=
tls_first_major=
tls_first_minor=
case "$target" in
alpha*-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
ldq $27,__tls_get_addr($29) !literal!1
lda $16,foo($29) !tlsgd!1
jsr $26,($27),__tls_get_addr !lituse_tlsgd!1
ldq $27,__tls_get_addr($29) !literal!2
lda $16,foo($29) !tlsldm!2
jsr $26,($27),__tls_get_addr !lituse_tlsldm!2
ldq $1,foo($29) !gotdtprel
ldah $2,foo($29) !dtprelhi
lda $3,foo($2) !dtprello
lda $4,foo($29) !dtprel
ldq $1,foo($29) !gottprel
ldah $2,foo($29) !tprelhi
lda $3,foo($2) !tprello
lda $4,foo($29) !tprel'
tls_first_major=2
tls_first_minor=13
;;
i[34567]86-*-*)
conftest_s='
.section ".tdata","awT",@progbits
@ -7463,7 +7485,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:7467: checking assembler supports explicit relocations" >&5
echo "configure:7489: 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
@ -7513,7 +7535,7 @@ EOF
;;
sparc*-*-*)
echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
echo "configure:7517: checking assembler .register pseudo-op support" >&5
echo "configure:7539: 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
@ -7541,7 +7563,7 @@ EOF
fi
echo $ac_n "checking assembler supports -relax""... $ac_c" 1>&6
echo "configure:7545: checking assembler supports -relax" >&5
echo "configure:7567: 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
@ -7569,7 +7591,7 @@ EOF
fi
echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
echo "configure:7573: checking assembler and linker support unaligned pc related relocs" >&5
echo "configure:7595: 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
@ -7596,7 +7618,7 @@ EOF
fi
echo $ac_n "checking assembler and linker support unaligned pc related relocs against hidden symbols""... $ac_c" 1>&6
echo "configure:7600: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5
echo "configure:7622: 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
@ -7637,7 +7659,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:7641: checking for assembler offsetable %lo() support" >&5
echo "configure:7663: 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
@ -7677,7 +7699,7 @@ EOF
i[34567]86-*-* | x86_64-*-*)
echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
echo "configure:7681: checking assembler instructions" >&5
echo "configure:7703: 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
@ -7704,7 +7726,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:7708: checking assembler GOTOFF in data directives" >&5
echo "configure:7730: 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
@ -7734,7 +7756,7 @@ EOF
esac
echo $ac_n "checking assembler dwarf2 debug_line support""... $ac_c" 1>&6
echo "configure:7738: checking assembler dwarf2 debug_line support" >&5
echo "configure:7760: 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
@ -7790,7 +7812,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:7794: checking assembler --gdwarf2 support" >&5
echo "configure:7816: 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
@ -7819,7 +7841,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:7823: checking assembler --gstabs support" >&5
echo "configure:7845: 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
@ -7847,7 +7869,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:7851: checking linker PT_GNU_EH_FRAME support" >&5
echo "configure:7873: 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
@ -8010,7 +8032,7 @@ fi
echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
echo "configure:8014: checking whether to enable maintainer-specific portions of Makefiles" >&5
echo "configure:8036: checking whether to enable maintainer-specific portions of Makefiles" >&5
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then
enableval="$enable_maintainer_mode"

View File

@ -1725,6 +1725,28 @@ tls_first_major=
tls_first_minor=
case "$target" in
changequote(,)dnl
alpha*-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
ldq $27,__tls_get_addr($29) !literal!1
lda $16,foo($29) !tlsgd!1
jsr $26,($27),__tls_get_addr !lituse_tlsgd!1
ldq $27,__tls_get_addr($29) !literal!2
lda $16,foo($29) !tlsldm!2
jsr $26,($27),__tls_get_addr !lituse_tlsldm!2
ldq $1,foo($29) !gotdtprel
ldah $2,foo($29) !dtprelhi
lda $3,foo($2) !dtprello
lda $4,foo($29) !dtprel
ldq $1,foo($29) !gottprel
ldah $2,foo($29) !tprelhi
lda $3,foo($2) !tprello
lda $4,foo($29) !tprel'
tls_first_major=2
tls_first_minor=13
;;
i[34567]86-*-*)
changequote([,])dnl
conftest_s='